Add initial CSON pretty printer

This commit is contained in:
Kevin Sawicki
2013-02-01 16:15:54 -08:00
parent 672a4a17a7
commit 83b6a93684
2 changed files with 140 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
CSON = require 'cson'
fdescribe "CSON", ->
describe "@stringify(object)", ->
describe "when the object is undefined", ->
it "throws an exception", ->
expect(-> CSON.stringify()).toThrow()
describe "when the object is a function", ->
it "throws an exception", ->
expect(-> CSON.stringify(-> 'function')).toThrow()
describe "when the object contains a function", ->
it "throws an exception", ->
expect(-> CSON.stringify(a: -> 'function')).toThrow()
describe "when formatting an undefined key", ->
it "does not include the key in the formatted CSON", ->
expect(CSON.stringify(b: 1, c: undefined)).toBe "'b': 1\n"
describe "when formatting an empty object", ->
it "returns the empty string", ->
expect(CSON.stringify({})).toBe ""
describe "when formatting a string", ->
it "returns formatted CSON", ->
expect(CSON.stringify(a: 'b')).toBe "'a': 'b'\n"
it "escapes single quotes", ->
expect(CSON.stringify(a: "'b'")).toBe "'a': '\\\'b\\\''\n"
it "doesn't escape double quotes", ->
expect(CSON.stringify(a: '"b"')).toBe "'a': '\"b\"'\n"
describe "when formatting a boolean", ->
it "returns formatted CSON", ->
expect(CSON.stringify(a: true)).toBe "'a': true\n"
expect(CSON.stringify(a: false)).toBe "'a': false\n"
describe "when formatting a number", ->
it "returns formatted CSON", ->
expect(CSON.stringify(a: 14)).toBe "'a': 14\n"
expect(CSON.stringify(a: 1.23)).toBe "'a': 1.23\n"
describe "when formatting null", ->
it "returns formatted CSON", ->
expect(CSON.stringify(a: null)).toBe "'a': null\n"
describe "when formatting an array", ->
it "returns formatted CSON", ->
expect(CSON.stringify(a: ['b'])).toBe "'a': [\n 'b'\n]\n"
expect(CSON.stringify(a: ['b', 4])).toBe "'a': [\n 'b'\n 4\n]\n"
describe "when formatting an object", ->
it "returns formatted CSON", ->
expect(CSON.stringify(a: {b: 'c'})).toBe "'a':\n 'b': 'c'\n"

84
src/stdlib/cson.coffee Normal file
View File

@@ -0,0 +1,84 @@
_ = require 'underscore'
module.exports =
stringifyIndent: (level=0) -> _.multiplyString(' ', Math.max(level, 0))
stringifyString: (string) ->
string = JSON.stringify(string)
string = string[1...-1] # Remove surrounding double quotes
string = string.replace(/\\"/g, '"') # Unescape escaped double quotes
string = string.replace(/'/g, '\\\'') # Escape single quotes
"'#{string}'" # Wrap in single quotes
stringifyBoolean: (boolean) -> "#{boolean}"
stringifyNumber: (number) -> "#{number}"
stringifyNull: -> 'null'
stringifyArray: (array, indentLevel=0) ->
cson = '[\n'
for value in array
cson += @stringifyIndent(indentLevel + 2)
if _.isString(value)
cson += @stringifyString(value)
else if _.isBoolean(value)
cson += @stringifyBoolean(value)
else if _.isNumber(value)
cson += @stringifyNumber(value)
else if _.isNull(value)
cson += @stringifyNull(value)
else if _.isArray(value)
cson += @stringifyArray(value, indentLevel + 2)
else if _.isObject(value)
cson += @stringifyObject(value, indentLevel + 2)
else
throw new Error("Unrecognized type for array value: #{value}")
cson += '\n'
"#{cson}#{@stringifyIndent(indentLevel)}]"
stringifyObject: (object, indentLevel=0) ->
cson = ''
prefix = ''
for key, value of object
continue if value is undefined
if _.isFunction(value)
throw new Error("Function specified as value to key: #{key}")
cson += "#{prefix}#{@stringifyIndent(indentLevel)}'#{key}':"
if _.isString(value)
cson += " #{@stringifyString(value)}"
else if _.isBoolean(value)
cson += " #{@stringifyBoolean(value)}"
else if _.isNumber(value)
cson += " #{@stringifyNumber(value)}"
else if _.isNull(value)
cson += " #{@stringifyNull(value)}"
else if _.isArray(value)
cson += " #{@stringifyArray(value, indentLevel)}"
else if _.isObject(value)
cson += "\n#{@stringifyObject(value, indentLevel + 2)}"
else
throw new Error("Unrecognized value type for key: #{key} with value: #{value}")
prefix = '\n'
cson
stringify: (object) ->
throw new Error("Cannot stringify undefined object") if object is undefined
if _.isFunction(object)
throw new Error("Cannot stringify function: #{object}")
return @stringifyString(object) if _.isString(object)
return @stringifyBoolean(object) if _.isBoolean(object)
return @stringifyNumber(object) if _.isNumber(object)
return @stringifyNull(object) if _.isNull(object)
if _.isArray(object)
cson = @stringifyArray(object)
cson = "#{cson}\n" if cson
return cson
if _.isObject(object)
cson = @stringifyObject(object)
cson = "#{cson}\n" if cson
return cson
throw new Error("Unrecognized type to stringify: #{object}")