<commit_before>import CssSyntaxError from '../lib/css-syntax-error';
import postcss        from '../lib/postcss';

import   stripAnsi from 'strip-ansi';
import   Concat    from 'concat-with-sourcemaps';
import { expect }  from 'chai';
import   path      from 'path';

let parseError = function (css, opts) {
    let error;
    try {
        postcss.parse(css, opts);
    } catch (e) {
        if ( e.name === 'CssSyntaxError' ) {
            error = e;
        } else {
            throw e;
        }
    }
    return error;
};

describe('CssSyntaxError', () => {

    it('saves source', () => {
        let error = parseError('a {\n  content: "\n}');

        expect(error).to.be.a.instanceOf(CssSyntaxError);
        expect(error.name).to.eql('CssSyntaxError');
        expect(error.message).to.be.eql('<css input>:2:12: Unclosed quote');
        expect(error.reason).to.eql('Unclosed quote');
        expect(error.line).to.eql(2);
        expect(error.column).to.eql(12);
        expect(error.source).to.eql('a {\n  content: "\n}');

        expect(error.input).to.eql({
            line:   error.line,
            column: error.column,
            source: error.source
        });
    });

    it('has stack trace', () => {
        expect(parseError('a {\n  content: "\n}').stack)
            .to.match(/test\/css-syntax-error\.es6/);
    });

    it('highlights broken line', () => {
        expect(parseError('a {\n  content: "\n}').showSourceCode(true)).to.eql(
            '\n' +
            'a {\n' +
            '  content: "\n' +
            '           \u001b[1;31m^\u001b[0m\n' +
            '}');
    });

    it('highlights without colors on request', () => {
        expect(parseError('a {').showSourceCode(false)).to.eql(
            '\n' +
            'a {\n' +
            '^');
    });

    it('prints with highlight', () => {
        expect(stripAnsi(parseError('a {').toString())).to.eql(
            'CssSyntaxError: <css input>:1:1: Unclosed block\n' +
            'a {\n' +
            '^');
    });

    it('misses highlights without source', () => {
        let error = parseError('a {');
        error.source = null;
        expect(error.toString()).to.eql(
            'CssSyntaxError: <css input>:1:1: Unclosed block');
    });

    it('uses source map', () => {
        let concat = new Concat(true, 'all.css');
        concat.add('a.css', 'a { }\n');
        concat.add('b.css', '\nb {\n');

        let error = parseError(concat.content, {
            from: 'build/all.css',
            map:  { prev: concat.sourceMap }
        });

        expect(error.file).to.eql(path.resolve('b.css'));
        expect(error.line).to.eql(2);
        expect(error.source).to.not.exist;

        expect(error.input).to.eql({
            file:   path.resolve('build/all.css'),
            line:   3,
            column: 1,
            source: 'a { }\n\nb {\n'
        });
    });<commit_msg>Fix warnings from nodes without source<commit_after>import CssSyntaxError from '../lib/css-syntax-error';
import postcss        from '../lib/postcss';

import   stripAnsi from 'strip-ansi';
import   Concat    from 'concat-with-sourcemaps';
import { expect }  from 'chai';
import   path      from 'path';

let parseError = function (css, opts) {
    let error;
    try {
        postcss.parse(css, opts);
    } catch (e) {
        if ( e.name === 'CssSyntaxError' ) {
            error = e;
        } else {
            throw e;
        }
    }
    return error;
};

describe('CssSyntaxError', () => {

    it('saves source', () => {
        let error = parseError('a {\n  content: "\n}');

        expect(error).to.be.a.instanceOf(CssSyntaxError);
        expect(error.name).to.eql('CssSyntaxError');
        expect(error.message).to.be.eql('<css input>:2:12: Unclosed quote');
        expect(error.reason).to.eql('Unclosed quote');
        expect(error.line).to.eql(2);
        expect(error.column).to.eql(12);
        expect(error.source).to.eql('a {\n  content: "\n}');

        expect(error.input).to.eql({
            line:   error.line,
            column: error.column,
            source: error.source
        });
    });

    it('has stack trace', () => {
        expect(parseError('a {\n  content: "\n}').stack)
            .to.match(/test\/css-syntax-error\.es6/);
    });

    it('highlights broken line', () => {
        expect(parseError('a {\n  content: "\n}').showSourceCode(true)).to.eql(
            '\n' +
            'a {\n' +
            '  content: "\n' +
            '           \u001b[1;31m^\u001b[0m\n' +
            '}');
    });

    it('highlights without colors on request', () => {
        expect(parseError('a {').showSourceCode(false)).to.eql(
            '\n' +
            'a {\n' +
            '^');
    });

    it('prints with highlight', () => {
        expect(stripAnsi(parseError('a {').toString())).to.eql(
            'CssSyntaxError: <css input>:1:1: Unclosed block\n' +
            'a {\n' +
            '^');
    });

    it('misses highlights without source content', () => {
        let error = parseError('a {');
        error.source = null;
        expect(error.toString()).to.eql(
            'CssSyntaxError: <css input>:1:1: Unclosed block');
    });

    it('misses position without source', () => {
        let decl  = postcss.decl({ prop: 'color', value: 'black' });
        let error = decl.error('Test');
        expect(error.toString()).to.eql('CssSyntaxError: <css input>: Test');
    });

    it('uses source map', () => {
        let concat = new Concat(true, 'all.css');
        concat.add('a.css', 'a { }\n');
        concat.add('b.css', '\nb {\n');

        let error = parseError(concat.content, {
            from: 'build/all.css',
            map:  { prev: concat.sourceMap }
        });

        expect(error.file).to.eql(path.resolve('b.css'));
        expect(error.line).to.eql(2);
        expect(error.source).to.not.exist;

        expect(error.input).to.eql({
            file:   path.resolve('build/all.css'),
            line:   3,
            column: 1,
            source: 'a { }\n\nb {\n'
        });
    });
{'fraction_non_alphanumeric': 0.18821791926485068, 'fraction_numerical': 0.007876599934361668, 'mean_word_length': 1.8494623655913978, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '88635', 'n_tokens_mistral': 2021, 'n_tokens_neox': 1961, 'n_words': 364}