Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stringify cson with no indent #37

Merged
merged 3 commits into from
May 12, 2015
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 42 additions & 37 deletions lib/stringify.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 34 additions & 27 deletions src/stringify.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ module.exports = (data, visitor, indent) ->

else 0

return JSON.stringify data, visitor, indent unless indent

indentLine = (line) -> indent + line

indentLines = (str) ->
Expand All @@ -72,7 +70,7 @@ module.exports = (data, visitor, indent) ->
normalized = JSON.parse JSON.stringify data, visitor

visitString = (str) ->
if str.indexOf('\n') == -1
if str.indexOf('\n') == -1 or !indent
JSON.stringify str
else
string = str
Expand All @@ -81,45 +79,54 @@ module.exports = (data, visitor, indent) ->
"'''#{ newlineWrap indentLines string }'''"

visitArray = (arr) ->
items = arr.map (value) ->
serializedValue = visitNode value
if isObject value
"{#{ newlineWrap indentLines serializedValue }}"
else
serializedValue
items = arr.map (value) -> visitNode value, bracesRequired: true

serializedItems = if indent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here - I'd prefer if we keep if and else tokens on one height.

newlineWrap indentLines items.join '\n'
else
items.join ','

array = items.join '\n'
"[#{ newlineWrap indentLines array }]"
"[#{serializedItems}]"

visitObject = (obj) ->
visitObject = (obj, {bracesRequired}) ->
keypairs = for key, value of obj
key = JSON.stringify key unless key.match jsIdentifierRE
serializedValue = visitNode value
if isObject value
if serializedValue == ''
"#{ key }: {}"
serializedValue = visitNode value, bracesRequired: !indent
if indent
serializedValue = if isObject value
"\n#{ indentLines serializedValue }"
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation here doesn't seem to align

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats the proper place for the else. Its matching if is only two lines above, not three

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it does – lines 96 and 98 go together, not 95 and 98.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it. Sorry. Could you maybe change this to something like this:

        serializedValue =
          if isObject value
            "\n#{ indentLines serializedValue }"
          else
            " #{ serializedValue }"

That way it's a bit easier to scan the left side of the code and grok the structure. Partially a question of personal taste but I'm fairly certain that matches our (informal) code style.

"#{ key }:\n#{ indentLines serializedValue }"
" #{ serializedValue }"
"#{ key }:#{ serializedValue }"

if keypairs.length is 0
'{}'
else if indent
serializedKeyPairs = keypairs.join '\n'
if bracesRequired
"{#{ newlineWrap indentLines serializedKeyPairs }}"
else
"#{ key }: #{ serializedValue }"

keypairs.join '\n'
serializedKeyPairs
else
serializedKeyPairs = keypairs.join ','
if bracesRequired
"{#{ serializedKeyPairs }}"
else
serializedKeyPairs

visitNode = (node) ->
visitNode = (node, options = {}) ->
switch typeof node
when 'boolean' then "#{node}"

when 'number'
if isFinite node then "#{node}"
else 'null' # NaN, Infinity and -Infinity

when 'string' then visitString node
when 'string' then visitString node, options

when 'object'
if node == null then 'null'
else if Array.isArray(node) then visitArray(node)
else visitObject(node)
else if Array.isArray(node) then visitArray node, options
else visitObject node, options

out = visitNode normalized
if out == '' then '{}' # the only thing that serializes to '' is an empty object
else out
visitNode normalized
33 changes: 29 additions & 4 deletions test/stringify.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ describe 'CSON.stringify', ->
and I have a sneaky ''' in here, too
"""

it 'handles multi-line strings (with 0 indentation)', ->
equal """
"I am your average multi-line string,\\nand I have a sneaky ''' in here, too"
""", cson """
I am your average multi-line string,
and I have a sneaky ''' in here, too
""", null, 0

it 'handles multi-line strings w/ backslash', ->
test = '\\\n\\'
expected = "'''\n \\\\\n \\\\\n'''"
Expand All @@ -58,6 +66,11 @@ describe 'CSON.stringify', ->
]
''', cson [ [1], null, [], a: 'str', {} ]

it 'handles arrays (with 0 indentation)', ->
equal '''
[[1],null,[],{a:"str"},{}]
''', cson [ [1], null, [], a: 'str', {} ], null, 0

it 'handles objects', ->
equal '''
"": "empty"
Expand All @@ -82,6 +95,22 @@ describe 'CSON.stringify', ->
]
}

it 'handles objects (with 0 indentation)', ->
equal '''
"":"empty","non\\nidentifier":true,default:false,nested:{string:"too"},array:[{},[]]
''', cson {
'': 'empty'
"non\nidentifier": true
default: false
nested: {
string: 'too'
}
array: [
{}
[]
]
}, null, 0

it 'handles NaN and +/-Infinity like JSON.stringify does', ->
equal 'null', cson NaN
equal 'null', cson +Infinity
Expand All @@ -93,10 +122,6 @@ describe 'CSON.stringify', ->
it 'handles functions like JSON.stringify does', ->
equal undefined, cson ->

it 'works just like JSON.stringify when asking for no indentation', ->
equal '{"zeroed":0}', cson zeroed: 0, null, 0
equal '{"empty":""}', cson empty: '', null, ''

it 'accepts no more than ten indentation steps, just like JSON.stringify', ->
equal '''
x:
Expand Down