Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinsawicki committed May 13, 2013
0 parents commit 6109706
Show file tree
Hide file tree
Showing 10 changed files with 433 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
*.js
.DS_Store
npm-debug.log
5 changes: 5 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.npmignore
*.coffee
script/
.DS_Store
npm-debug.log
36 changes: 36 additions & 0 deletions Gruntfile.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module.exports = (grunt) ->
grunt.initConfig
pkg: grunt.file.readJSON('package.json')

coffee:
glob_to_multiple:
expand: true
cwd: 'src'
src: ['*.coffee']
dest: 'lib'
ext: '.js'

coffeelint:
options:
max_line_length:
level: 'ignore'

src: ['src/*.coffee']
test: ['spec/*.coffee']

shell:
test:
command: 'npm test'
options:
stdout: true
stderr: true
failOnError: true

grunt.loadNpmTasks('grunt-contrib-coffee')
grunt.loadNpmTasks('grunt-shell')
grunt.loadNpmTasks('grunt-coffeelint')

grunt.registerTask 'clean', -> require('rimraf').sync('lib')
grunt.registerTask('lint', ['coffeelint:src', 'coffeelint:test'])
grunt.registerTask('default', ['coffeelint:src', 'coffee'])
grunt.registerTask('test', ['default', 'coffeelint:test', 'shell:test'])
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# season - CSON Node module

Read and write CSON/JSON files seamlessly.

## Installing

```sh
npm install season
```

## Building
* Clone the repository
* Run `npm install`
* Run `grunt` to compile the CoffeeScript code
* Run `grunt test` to run the specs

## Docs

```coffeescript
CSON = require 'season'
```

### CSON.stringify(object)

Convert the object to a CSON string.

`object` - The object to convert to CSON.

Returns the CSON string representation of the given object.

### CSON.readObject(objectPath, callback)

Read the CSON or JSON object at the given path and return it to the callback
once it is read and parsed.

`objectPath` - The string path to a JSON or CSON object file.

`callback` - The callback to call with the error or object once the path
is read and parsed.

### CSON.writeObjectSync(objectPath, object)

Write the object to the given path as either JSON or CSON depending on the
path's extension.

`objectPath` - The string path to a JSON or CSON object file.

`object` - The object to convert to a string and write to the path.

### CSON.isObjectPath(objectPath)

Is the given path a valid object path?

Returns `true` if the path has a `.json` or `.cson` file extension, `false`
otherwise.
3 changes: 3 additions & 0 deletions bin/csonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('../lib/csonc')(process.argv.slice(2))
43 changes: 43 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "season",
"version": "0.0.0",
"description": "CSON utilities",
"licenses": [
{
"type": "MIT",
"url": "http://github.com/atom/season/raw/master/LICENSE.md"
}
],
"main": "./lib/cson.js",
"bin": {
"csonc": "./bin/csonc"
},
"scripts": {
"prepublish": "grunt coffee",
"test": "jasmine-focused --captureExceptions --coffee spec/"
},
"repository": {
"type": "git",
"url": "https://github.com/atom/season.git"
},
"bugs": {
"url": "https://github.com/atom/season/issues"
},
"keywords": [
"cson",
"json"
],
"dependencies": {
"underscore": "~1.4.4",
"coffee-script": "~1.6.2"
},
"devDependencies": {
"jasmine-focused": "~0.1.0",
"grunt-contrib-coffee": "~0.7.0",
"grunt-cli": "~0.1.8",
"grunt": "~0.4.1",
"grunt-shell": "~0.2.2",
"grunt-coffeelint": "0.0.6",
"temp": "~0.5.0"
}
}
101 changes: 101 additions & 0 deletions spec/cson-spec.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
CSON = require '../lib/cson'

describe "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"

describe "when formatting a string", ->
it "returns formatted CSON", ->
expect(CSON.stringify(a: 'b')).toBe "'a': 'b'"

it "escapes single quotes", ->
expect(CSON.stringify(a: "'b'")).toBe "'a': '\\\'b\\\''"

it "doesn't escape double quotes", ->
expect(CSON.stringify(a: '"b"')).toBe "'a': '\"b\"'"

it "escapes newlines", ->
expect(CSON.stringify("a\nb")).toBe "'a\\nb'"

describe "when formatting a boolean", ->
it "returns formatted CSON", ->
expect(CSON.stringify(true)).toBe 'true'
expect(CSON.stringify(false)).toBe 'false'
expect(CSON.stringify(a: true)).toBe "'a': true"
expect(CSON.stringify(a: false)).toBe "'a': false"

describe "when formatting a number", ->
it "returns formatted CSON", ->
expect(CSON.stringify(54321.012345)).toBe '54321.012345'
expect(CSON.stringify(a: 14)).toBe "'a': 14"
expect(CSON.stringify(a: 1.23)).toBe "'a': 1.23"

describe "when formatting null", ->
it "returns formatted CSON", ->
expect(CSON.stringify(null)).toBe 'null'
expect(CSON.stringify(a: null)).toBe "'a': null"

describe "when formatting an array", ->
describe "when the array is empty", ->
it "puts the array on a single line", ->
expect(CSON.stringify([])).toBe "[]"

it "returns formatted CSON", ->
expect(CSON.stringify(a: ['b'])).toBe "'a': [\n 'b'\n]"
expect(CSON.stringify(a: ['b', 4])).toBe "'a': [\n 'b'\n 4\n]"

describe "when the array has an undefined value", ->
it "formats the undefined value as null", ->
expect(CSON.stringify(['a', undefined, 'b'])).toBe "[\n 'a'\n null\n 'b'\n]"

describe "when the array contains an object", ->
it "wraps the object in {}", ->
expect(CSON.stringify([{a:'b', a1: 'b1'}, {c: 'd'}])).toBe "[\n {\n 'a': 'b'\n 'a1': 'b1'\n }\n {\n 'c': 'd'\n }\n]"

describe "when formatting an object", ->
describe "when the object is empty", ->
it "returns {}", ->
expect(CSON.stringify({})).toBe "{}"

it "returns formatted CSON", ->
expect(CSON.stringify(a: {b: 'c'})).toBe "'a':\n 'b': 'c'"
expect(CSON.stringify(a:{})).toBe "'a': {}"
expect(CSON.stringify(a:[])).toBe "'a': []"

describe "when converting back to an object", ->
it "produces the original object", ->
object =
showInvisibles: true
fontSize: 20
core:
themes: ['a', 'b']
whitespace:
ensureSingleTrailingNewline: true

cson = CSON.stringify(object)
CoffeeScript = require 'coffee-script'
evaledObject = CoffeeScript.eval(cson, bare: true)
expect(evaledObject).toEqual object

describe ".isObjectPath(objectPath)", ->
it "returns true if the path has an object extension", ->
expect(CSON.isObjectPath('/test2.json')).toBe true
expect(CSON.isObjectPath('/a/b.cson')).toBe true
expect(CSON.isObjectPath()).toBe false
expect(CSON.isObjectPath(null)).toBe false
expect(CSON.isObjectPath('')).toBe false
expect(CSON.isObjectPath('a/b/c.txt')).toBe false
37 changes: 37 additions & 0 deletions spec/csonc-spec.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
path = require 'path'
fs = require 'fs'
temp = require 'temp'
csonc = require '../lib/csonc'

describe "CSON compilation to JSON", ->
[compileDir, inputFile, outputFile] = []

beforeEach ->
compileDir = temp.mkdirSync('season-compile-dir-')
inputFile = path.join(compileDir, 'input.cson')
outputFile = path.join(compileDir, 'input.json')
spyOn(process, 'exit')
spyOn(console, 'error')

it "logs an error and exits when no input file is specified", ->
csonc([])
expect(process.exit.mostRecentCall.args[0]).toBe 1
expect(console.error.mostRecentCall.args[0].length).toBeGreaterThan 0

it "logs an error and exits when no input file is specified", ->
csonc(['./input.cson'])
expect(process.exit.mostRecentCall.args[0]).toBe 1
expect(console.error.mostRecentCall.args[0].length).toBeGreaterThan 0

describe "when a valid CSON file is specified", ->
it "converts the file to JSON and writes it out", ->
fs.writeFileSync(inputFile, 'a: 3')
csonc([inputFile, outputFile])
expect(fs.readFileSync(outputFile, {encoding: 'utf8'})).toBe '{\n "a": 3\n}\n'

describe "when an invalid CSON file is specified", ->
it "logs an error and exits", ->
fs.writeFileSync(inputFile, '1234')
csonc([inputFile, outputFile])
expect(process.exit.mostRecentCall.args[0]).toBe 1
expect(console.error.mostRecentCall.args[0].length).toBeGreaterThan 0
Loading

0 comments on commit 6109706

Please sign in to comment.