Skip to content
This repository was archived by the owner on Sep 6, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
dist
package-lock.json
node_modules
*.log
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: node_js
node_js:
- "6"
- "10"
script:
- npm run lint
- npm test
Expand Down
2 changes: 1 addition & 1 deletion lib/__tests__/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ it('parse', () => {
})

it('parse', () => {
const scss = `.a { background: red; }`
const scss = '.a { background: red; }'
expect(stringify(parse(scss))).toEqual(scss)
})
20 changes: 10 additions & 10 deletions lib/__tests__/input-stream.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,43 @@
const createInputStream = require('../input-stream')

it('returns an new InputStream', () => {
let i = createInputStream()
const i = createInputStream()
expect(i).toMatchSnapshot()
})

describe('#position', () => {
it('defaults the position to 0', () => {
let p = createInputStream().position()
const p = createInputStream().position()
expect(Object.isFrozen(p)).toBe(true)
expect(p).toMatchSnapshot()
})
})

describe('#peek', () => {
it('returns the current character', () => {
let i = createInputStream('hello')
const i = createInputStream('hello')
expect(i.peek()).toEqual('h')
})
it('returns the current character with an offset', () => {
let i = createInputStream('hello')
const i = createInputStream('hello')
expect(i.peek(1)).toEqual('e')
})
})

describe('#next', () => {
it('consumes and returns the next character', () => {
let i = createInputStream('hello')
const i = createInputStream('hello')
expect(i.next()).toEqual('h')
})
it('advances the cursor', () => {
let i = createInputStream('hello')
const i = createInputStream('hello')
expect(i.next()).toEqual('h')
expect(i.position().cursor).toEqual(1)
expect(i.position().line).toEqual(1)
expect(i.position().column).toEqual(1)
})
it('advances the line', () => {
let i = createInputStream('h\ni')
const i = createInputStream('h\ni')
expect(i.next()).toEqual('h')
expect(i.next()).toEqual('\n')
expect(i.next()).toEqual('i')
Expand All @@ -54,11 +54,11 @@ describe('#next', () => {

describe('#eof', () => {
it('returns false if there are more characters', () => {
let i = createInputStream('hello')
const i = createInputStream('hello')
expect(i.eof()).toEqual(false)
})
it('returns true if there are no more characters', () => {
let i = createInputStream('hi')
const i = createInputStream('hi')
expect(i.eof()).toEqual(false)
i.next()
i.next()
Expand All @@ -68,7 +68,7 @@ describe('#eof', () => {

describe('#err', () => {
it('throws an error', () => {
let i = createInputStream('hello')
const i = createInputStream('hello')
i.next()
i.next()
expect(() => {
Expand Down
76 changes: 38 additions & 38 deletions lib/__tests__/token-stream.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,175 +13,175 @@ it('requires an InputStream', () => {
})

it('returns an TokenStream', () => {
let t = createTokenStream(createInputStream())
const t = createTokenStream(createInputStream())
expect(t).toMatchSnapshot()
})

describe('#all', () => {
it('tokenizes all characters in the InputStream', () => {
let t = createTokenStream(createInputStream('hello'))
const t = createTokenStream(createInputStream('hello'))
expect(t.all().length).toEqual(1)
expect(t.eof()).toEqual(true)
})
})

describe('#peek', () => {
it('returns the current token', () => {
let t = createTokenStream(createInputStream('hello'))
const t = createTokenStream(createInputStream('hello'))
expect(t.peek()).toMatchSnapshot()
})
it('returns the current token with an offset', () => {
let t = createTokenStream(createInputStream('hello world'))
const t = createTokenStream(createInputStream('hello world'))
expect(t.peek(1)).toMatchSnapshot()
})
})

describe('#next', () => {
it('consumes returns and the next token', () => {
let t = createTokenStream(createInputStream('hello world'))
const t = createTokenStream(createInputStream('hello world'))
expect(t.next()).toMatchSnapshot()
expect(t.peek()).toMatchSnapshot()
})
describe('tokens', () => {
describe('space', () => {
it('single space', () => {
let t = createTokenStream(createInputStream(' '))
const t = createTokenStream(createInputStream(' '))
expect(t.next()).toMatchSnapshot()
})
it('multiple spaces', () => {
let t = createTokenStream(createInputStream(' hello'))
const t = createTokenStream(createInputStream(' hello'))
expect(t.next()).toMatchSnapshot()
})
it('whitespace characters', () => {
let t = createTokenStream(createInputStream('\n\n\t hello'))
const t = createTokenStream(createInputStream('\n\n\t hello'))
expect(t.next()).toMatchSnapshot()
})
it('carriage return character', () => {
let t = createTokenStream(createInputStream('\r\n hello'))
const t = createTokenStream(createInputStream('\r\n hello'))
expect(t.next()).toMatchSnapshot()
})
})
describe('comment', () => {
it('single comment', () => {
let t = createTokenStream(createInputStream('// Hello\nWorld'))
const t = createTokenStream(createInputStream('// Hello\nWorld'))
expect(t.next()).toMatchSnapshot()
})
it('single comment', () => {
let t = createTokenStream(createInputStream('/** Hello World */'))
const t = createTokenStream(createInputStream('/** Hello World */'))
expect(t.next()).toMatchSnapshot()
})
})
describe('number', () => {
it('integer', () => {
let t = createTokenStream(createInputStream('3'))
const t = createTokenStream(createInputStream('3'))
expect(t.next()).toMatchSnapshot()
})
it('float', () => {
let t = createTokenStream(createInputStream('3.0'))
const t = createTokenStream(createInputStream('3.0'))
expect(t.next()).toMatchSnapshot()
})
it('float (leading decimal)', () => {
let t = createTokenStream(createInputStream('.3'))
const t = createTokenStream(createInputStream('.3'))
expect(t.next()).toMatchSnapshot()
})
})
describe('hex', () => {
it('6 digit lowercase', () => {
let t = createTokenStream(createInputStream('#ff0099'))
const t = createTokenStream(createInputStream('#ff0099'))
expect(t.next()).toMatchSnapshot()
})
it('6 digit uppercase', () => {
let t = createTokenStream(createInputStream('#FF0099'))
const t = createTokenStream(createInputStream('#FF0099'))
expect(t.next()).toMatchSnapshot()
})
it('3 digit lowercase', () => {
let t = createTokenStream(createInputStream('#ff0'))
const t = createTokenStream(createInputStream('#ff0'))
expect(t.next()).toMatchSnapshot()
})
it('3 digit uppercase', () => {
let t = createTokenStream(createInputStream('#FF0'))
const t = createTokenStream(createInputStream('#FF0'))
expect(t.next()).toMatchSnapshot()
})
it('3 digit (trailing invalid)', () => {
let t = createTokenStream(createInputStream('#FF0;'))
const t = createTokenStream(createInputStream('#FF0;'))
expect(t.next()).toMatchSnapshot()
})
it('6 digit numbers', () => {
let t = createTokenStream(createInputStream('#000000'))
const t = createTokenStream(createInputStream('#000000'))
expect(t.next()).toMatchSnapshot()
})
})
describe('atkeyword', () => {
it('works', () => {
let t = createTokenStream(createInputStream('@mixin'))
const t = createTokenStream(createInputStream('@mixin'))
expect(t.next()).toMatchSnapshot()
})
})
describe('puctuation', () => {
it('{', () => {
let t = createTokenStream(createInputStream('{'))
const t = createTokenStream(createInputStream('{'))
expect(t.next()).toMatchSnapshot()
})
})
describe('operator', () => {
it('+', () => {
let t = createTokenStream(createInputStream('+'))
const t = createTokenStream(createInputStream('+'))
expect(t.next()).toMatchSnapshot()
})
it('repeatable', () => {
let t = createTokenStream(createInputStream('&&'))
const t = createTokenStream(createInputStream('&&'))
expect(t.next()).toMatchSnapshot()
})
it('non-repeatable', () => {
let t = createTokenStream(createInputStream('++'))
const t = createTokenStream(createInputStream('++'))
expect(t.next()).toMatchSnapshot()
})
it('repeatable followed by non-repeatable', () => {
let t = createTokenStream(createInputStream('&++'))
const t = createTokenStream(createInputStream('&++'))
expect(t.next()).toMatchSnapshot()
})
})
describe('identifier', () => {
it('checks for valid starting characters', () => {
let t = createTokenStream(createInputStream('_hello world'))
const t = createTokenStream(createInputStream('_hello world'))
expect(t.next()).toMatchSnapshot()
})
it('ignores invalid starting characters', () => {
let t = createTokenStream(createInputStream('0hello world'))
const t = createTokenStream(createInputStream('0hello world'))
expect(t.next()).toMatchSnapshot()
})
})
describe('string', () => {
it('single quotes', () => {
let t = createTokenStream(createInputStream('\'hello\''))
const t = createTokenStream(createInputStream('\'hello\''))
expect(t.next()).toMatchSnapshot()
})
it('double quotes', () => {
let t = createTokenStream(createInputStream('"hello"'))
const t = createTokenStream(createInputStream('"hello"'))
expect(t.next()).toMatchSnapshot()
})
it('escaped characters', () => {
let t = createTokenStream(createInputStream('"hello \\"world\\""'))
const t = createTokenStream(createInputStream('"hello \\"world\\""'))
expect(t.next()).toMatchSnapshot()
})
it('preserves escape characters', () => {
let t = createTokenStream(createInputStream('token(\'\'+myVar+\'font(\\\'world\\\')\')'))
const t = createTokenStream(createInputStream('token(\'\'+myVar+\'font(\\\'world\\\')\')'))
expect(t.all()).toMatchSnapshot()
})
})
describe('variable', () => {
it('works', () => {
let t = createTokenStream(createInputStream('$size'))
const t = createTokenStream(createInputStream('$size'))
expect(t.next()).toMatchSnapshot()
})
})
describe('sink', () => {
it('1', () => {
let t = createTokenStream(createInputStream('($var)'))
const t = createTokenStream(createInputStream('($var)'))
expect(t.all()).toMatchSnapshot()
})
it('2', () => {
let t = createTokenStream(createInputStream('// ($var)\n@mixin myMixin'))
const t = createTokenStream(createInputStream('// ($var)\n@mixin myMixin'))
expect(t.all()).toMatchSnapshot()
})
})
Expand All @@ -190,11 +190,11 @@ describe('#next', () => {

describe('#eof', () => {
it('returns false if there are more tokens', () => {
let t = createTokenStream(createInputStream('hello'))
const t = createTokenStream(createInputStream('hello'))
expect(t.eof()).toEqual(false)
})
it('returns true if there are no more tokens', () => {
let t = createTokenStream(createInputStream('hello world'))
const t = createTokenStream(createInputStream('hello world'))
expect(t.eof()).toEqual(false)
t.next()
t.next()
Expand All @@ -205,7 +205,7 @@ describe('#eof', () => {

describe('#err', () => {
it('throws an error', () => {
let t = createTokenStream(createInputStream('hello world'))
const t = createTokenStream(createInputStream('hello world'))
t.next()
t.next()
expect(() => {
Expand Down
5 changes: 2 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,15 @@ const _stringify = require('./stringify')
* @param {string} css
* @returns {Node}
*/
let parse = (css) =>
_parse(createTokenStream(createInputStream(css)))
const parse = css => _parse(createTokenStream(createInputStream(css)))

/**
* Convert a @{link Node} back into a stirng
*
* @param {Node} node
* @returns {string}
*/
let stringify = (node) => _stringify(node)
const stringify = node => _stringify(node)

module.exports = {
parse,
Expand Down
Loading