Skip to content
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
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Normalize line endings to LF on checkout, on every platform.
# The test fixtures (and the stringify output they are compared against)
# assume LF, so a CRLF checkout on Windows would break the tests.
* text=auto eol=lf
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Test

on: [push, pull_request]

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [lts/*, latest]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
6 changes: 0 additions & 6 deletions .travis.yml

This file was deleted.

12 changes: 11 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# css [![Build Status](https://travis-ci.org/reworkcss/css.svg?branch=master)](https://travis-ci.org/reworkcss/css)
# css

[![npm package version](https://img.shields.io/npm/v/css) ![npm downloads](https://img.shields.io/npm/dm/css)](https://www.npmjs.com/package/css)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/reworkcss/css/test.yml)](https://github.com/reworkcss/css/actions)
[![License](https://img.shields.io/github/license/reworkcss/css)](https://github.com/reworkcss/css)

> [!NOTE]
> There have not been material changes to this package in 10 years. New changes and bug fixes are not planned. In the event of concrete security issues, changes may still occur. We recommend moving to something else more modern.

> [!TIP]
> Use [@adobe/css-tools](https://github.com/adobe/css-tools) instead

CSS parser / stringifier.

Expand Down
65 changes: 65 additions & 0 deletions package-lock.json

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

9 changes: 1 addition & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,8 @@
"source-map": "^0.6.1",
"source-map-resolve": "^0.6.0"
},
"devDependencies": {
"mocha": "^8.0.1",
"should": "^13.2.3",
"matcha": "^0.7.0",
"bytes": "^3.1.0"
},
"scripts": {
"benchmark": "matcha",
"test": "mocha --require should --reporter spec test/*.js"
"test": "node --test"
},
Comment on lines 16 to 18
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"license": "MIT",
Expand Down
25 changes: 22 additions & 3 deletions test/cases.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
var fs = require('fs');
var path = require('path');
var assert = require('node:assert');
var { describe, it } = require('node:test');
var parse = require('../').parse;
var stringify = require('../').stringify;

Expand All @@ -14,17 +16,17 @@ cases.forEach(function(name) {

it('should match ast.json', function() {
var ast = parseInput();
ast.should.containDeep(JSON.parse(readFile(astFile)));
containDeep(ast, JSON.parse(readFile(astFile)));
});

it('should match output.css', function() {
var output = stringify(parseInput());
output.should.equal(readFile(outputFile).trim());
assert.strictEqual(output, readFile(outputFile).trim());
});

it('should match compressed.css', function() {
var compressed = stringify(parseInput(), { compress: true });
compressed.should.equal(readFile(compressedFile));
assert.strictEqual(compressed, readFile(compressedFile));
});

function parseInput() {
Expand All @@ -42,3 +44,20 @@ function readFile(file) {

return src;
}

// Assert that `actual` deeply contains every property/element of `expected`.
function containDeep(actual, expected) {
if (Array.isArray(expected)) {
assert.ok(Array.isArray(actual));
expected.forEach(function(item, i) {
containDeep(actual[i], item);
});
} else if (expected && typeof expected === 'object') {
assert.ok(actual && typeof actual === 'object');
Object.keys(expected).forEach(function(key) {
containDeep(actual[key], expected[key]);
});
} else {
assert.strictEqual(actual, expected);
}
}
79 changes: 40 additions & 39 deletions test/parse.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var parse = require('../').parse;
var should = require('should');
var assert = require('node:assert');
var { describe, it } = require('node:test');

describe('parse(str)', function() {
it('should save the filename and source', function() {
Expand All @@ -8,50 +9,50 @@ describe('parse(str)', function() {
source: 'booty.css'
});

ast.stylesheet.source.should.equal('booty.css');
assert.strictEqual(ast.stylesheet.source, 'booty.css');

var position = ast.stylesheet.rules[0].position;
position.start.should.be.ok;
position.end.should.be.ok;
position.source.should.equal('booty.css');
position.content.should.equal(css);
assert.ok(position.start);
assert.ok(position.end);
assert.strictEqual(position.source, 'booty.css');
assert.strictEqual(position.content, css);
});

it('should throw when a selector is missing', function() {
should(function() {
assert.throws(function() {
parse('{size: large}');
}).throw();
});

should(function() {
assert.throws(function() {
parse('b { color: red; }\n{ color: green; }\na { color: blue; }');
}).throw();
});
});

it('should throw when a broken comment is found', function () {
should(function() {
assert.throws(function() {
parse('thing { color: red; } /* b { color: blue; }');
}).throw();
});

should(function() {
assert.throws(function() {
parse('/*');
}).throw();
});

/* Nested comments should be fine */
should(function() {
assert.doesNotThrow(function() {
parse('/* /* */');
}).not.throw();
});
});

it('should allow empty property value', function() {
should(function() {
assert.doesNotThrow(function() {
parse('p { color:; }');
}).not.throw();
});
});

it('should not throw with silent option', function () {
should(function() {
assert.doesNotThrow(function() {
parse('thing { color: red; } /* b { color: blue; }', { silent: true });
}).not.throw();
});
});

it('should list the parsing errors and continue parsing', function() {
Expand All @@ -61,18 +62,18 @@ describe('parse(str)', function() {
});

var rules = result.stylesheet.rules;
rules.length.should.be.above(2);
assert.ok(rules.length > 2);

var errors = result.stylesheet.parsingErrors;
errors.length.should.equal(2);
assert.strictEqual(errors.length, 2);

errors[0].should.have.a.property('message');
errors[0].should.have.a.property('reason');
errors[0].should.have.a.property('filename');
errors[0].filename.should.equal('foo.css');
errors[0].should.have.a.property('line');
errors[0].should.have.a.property('column');
errors[0].should.have.a.property('source');
assert.ok('message' in errors[0]);
assert.ok('reason' in errors[0]);
assert.ok('filename' in errors[0]);
assert.strictEqual(errors[0].filename, 'foo.css');
assert.ok('line' in errors[0]);
assert.ok('column' in errors[0]);
assert.ok('source' in errors[0]);

});

Expand All @@ -81,28 +82,28 @@ describe('parse(str)', function() {
'thing { test: value; }\n' +
'@media (min-width: 100px) { thing { test: value; } }');

should(result.parent).equal(null);
assert.strictEqual(result.parent, null);

var rules = result.stylesheet.rules;
rules.length.should.equal(2);
assert.strictEqual(rules.length, 2);

var rule = rules[0];
rule.parent.should.equal(result);
rule.declarations.length.should.equal(1);
assert.strictEqual(rule.parent, result);
assert.strictEqual(rule.declarations.length, 1);

var decl = rule.declarations[0];
decl.parent.should.equal(rule);
assert.strictEqual(decl.parent, rule);

var media = rules[1];
media.parent.should.equal(result);
media.rules.length.should.equal(1);
assert.strictEqual(media.parent, result);
assert.strictEqual(media.rules.length, 1);

rule = media.rules[0];
rule.parent.should.equal(media);
assert.strictEqual(rule.parent, media);

rule.declarations.length.should.equal(1);
assert.strictEqual(rule.declarations.length, 1);
decl = rule.declarations[0];
decl.parent.should.equal(rule);
assert.strictEqual(decl.parent, rule);
});

});
Loading
Loading