Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

js-beautify

Package Overview
Dependencies
Maintainers
2
Versions
128
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

js-beautify - npm Package Compare versions

Comparing version 1.5.5 to 1.5.6

2

bower.json
{
"name": "js-beautify",
"version": "1.5.4",
"version": "1.5.6",
"main": [

@@ -5,0 +5,0 @@ "./js/lib/beautify.js",

# Changelog
## v1.5.6
### Description
* JSX support!
* Alternative Newline Characters
* CSS and JS comment formatting fixes
* General bug fixing
### Closed Issues
* Fix tokenizer's bracket pairs' open stack ([#693](https://github.com/beautify-web/js-beautify/pull/693))
* Indentation is incorrect for HTML5 void tag <source> ([#692](https://github.com/beautify-web/js-beautify/issues/692))
* Line wrapping breaks at the wrong place when the line is indented. ([#691](https://github.com/beautify-web/js-beautify/issues/691))
* Publish v1.5.6 ([#687](https://github.com/beautify-web/js-beautify/issues/687))
* Replace existing file fails using python beautifier ([#686](https://github.com/beautify-web/js-beautify/issues/686))
* Pseudo-classes formatted incorrectly and inconsistently with @page ([#661](https://github.com/beautify-web/js-beautify/issues/661))
* doc: add end_with_newline option ([#650](https://github.com/beautify-web/js-beautify/pull/650))
* Improve support for xml parts of jsx (React) => spaces, spread attributes and nested objects break the process ([#646](https://github.com/beautify-web/js-beautify/issues/646))
* html-beautify formats handlebars comments but does not format html comments ([#635](https://github.com/beautify-web/js-beautify/issues/635))
* Support for ES7 async ([#630](https://github.com/beautify-web/js-beautify/issues/630))
* css beautify adding an extra newline after a comment line in a css block ([#609](https://github.com/beautify-web/js-beautify/issues/609))
* No option to "Indent with tabs" for HTML files ([#587](https://github.com/beautify-web/js-beautify/issues/587))
* Function body is indented when followed by a comment ([#583](https://github.com/beautify-web/js-beautify/issues/583))
* JSX support ([#425](https://github.com/beautify-web/js-beautify/issues/425))
* Alternative Newline Characters ([#260](https://github.com/beautify-web/js-beautify/issues/260))
## v1.5.5

@@ -22,3 +49,3 @@

* yield statements are being beautified to their own newlines since 1.5.2 ([#560](https://github.com/beautify-web/js-beautify/issues/560))
* HTML beautifier inserts extra newline into <li>s ending with <code> ([#524](https://github.com/beautify-web/js-beautify/issues/524))
* HTML beautifier inserts extra newline into `<li>`s ending with `<code>` ([#524](https://github.com/beautify-web/js-beautify/issues/524))
* Add wrap_attributes option ([#476](https://github.com/beautify-web/js-beautify/issues/476))

@@ -25,0 +52,0 @@ * Add or preserve empty line between CSS rules ([#467](https://github.com/beautify-web/js-beautify/issues/467))

@@ -5,3 +5,3 @@ # Contributing

## Report issues
If you find a bug, please report it, including environment andexamples of current behavior and what you believe to be the correct behavior. The clearer your description and information, the more likely it is someone will be able to make progress on it.
If you find a bug, please report it, including environment and examples of current behavior and what you believe to be the correct behavior. The clearer your description and information, the more likely it is someone will be able to make progress on it.

@@ -8,0 +8,0 @@ ## Fix issues

@@ -77,2 +77,6 @@ /*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */

if(options.indent_with_tabs){
indentCharacter = '\t';
indentSize = 1;
}

@@ -93,2 +97,3 @@ // tokenizer

function peek(skipWhitespace) {
var result = '';
var prev_pos = pos;

@@ -216,12 +221,13 @@ if (skipWhitespace) {

print.newLine = function(keepWhitespace) {
if (!keepWhitespace) {
print.trim();
}
if (output.length) {
if (!keepWhitespace && output[output.length - 1] !== '\n') {
print.trim();
}
if (output.length) {
output.push('\n');
if (basebaseIndentString) {
output.push(basebaseIndentString);
}
}
if (basebaseIndentString) {
output.push(basebaseIndentString);
}
};

@@ -242,5 +248,2 @@ print.singleSpace = function() {

var output = [];
if (basebaseIndentString) {
output.push(basebaseIndentString);
}
/*_____________________--------------------_____________________*/

@@ -263,4 +266,8 @@

} else if (ch === '/' && peek() === '*') { /* css comment */
var header = lookBack("");
print.newLine();
var header = indentLevel === 0;
if (isAfterNewline || header) {
print.newLine();
}
output.push(eatComment());

@@ -272,3 +279,3 @@ print.newLine();

} else if (ch === '/' && peek() === '/') { // single line comment
if (!isAfterNewline && last_top_ch !== '{') {
if (!isAfterNewline && last_top_ch !== '{' ) {
print.trim();

@@ -287,4 +294,14 @@ }

// strip trailing space, if present, for hash property checks
var variableOrRule = peekString(": ,;{}()[]/='\"").replace(/\s$/, '');
var variableOrRule = peekString(": ,;{}()[]/='\"");
if (variableOrRule.match(/[ :]$/)) {
// we have a variable or pseudo-class, add it and insert one space before continuing
next();
variableOrRule = eatString(": ").replace(/\s$/, '');
output.push(variableOrRule);
print.singleSpace();
}
variableOrRule = variableOrRule.replace(/\s$/, '')
// might be a nesting at-rule

@@ -296,8 +313,2 @@ if (variableOrRule in css_beautify.NESTED_AT_RULE) {

}
} else if (': '.indexOf(variableOrRule[variableOrRule.length - 1]) >= 0) {
//we have a variable, add it and insert one space before continuing
next();
variableOrRule = eatString(": ").replace(/\s$/, '');
output.push(variableOrRule);
print.singleSpace();
}

@@ -415,4 +426,9 @@ } else if (ch === '{') {

var sweetCode = output.join('').replace(/[\r\n\t ]+$/, '');
var sweetCode = '';
if (basebaseIndentString) {
sweetCode += basebaseIndentString;
}
sweetCode += output.join('').replace(/[\r\n\t ]+$/, '');
// establish end_with_newline

@@ -419,0 +435,0 @@ if (end_with_newline) {

@@ -56,4 +56,4 @@ /*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */

end_with_newline (false) - end with a newline
extra_liners (default [head,body,/html]) -List of tags that should have an extra newline before them.
e.g.

@@ -70,3 +70,4 @@

'max_preserve_newlines': 5,
'indent_handlebars': false
'indent_handlebars': false,
'extra_liners': ['/html']
});

@@ -104,3 +105,4 @@ */

wrap_attributes_indent_size,
end_with_newline;
end_with_newline,
extra_liners;

@@ -129,3 +131,11 @@ options = options || {};

end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
extra_liners = Array.isArray(options.extra_liners) ?
options.extra_liners.concat() : (typeof options.extra_liners === 'string') ?
options.extra_liners.split(',') : 'head,body,/html'.split(',');
if(options.indent_with_tabs){
indent_character = '\t';
indent_size = 1;
}
function Parser() {

@@ -148,4 +158,4 @@

whitespace: "\n\r\t ".split(''),
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML
extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them
single_token: 'br,input,link,meta,source,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML
extra_liners: extra_liners, //for tags that need a line of whitespace before them
in_array: function(what, arr) {

@@ -161,4 +171,3 @@ for (var i = 0; i < arr.length; i++) {

// Return true iff the given text is composed entirely of
// whitespace.
// Return true if the given text is composed entirely of whitespace.
this.is_whitespace = function(text) {

@@ -228,2 +237,4 @@ for (var n = 0; n < text.length; text++) {

break;
} else if (peek3 === '{{!') {
return [this.get_tag(), 'TK_TAG_HANDLEBARS_COMMENT'];
} else if (this.input.substr(this.pos, 2) === '{{') {

@@ -391,3 +402,3 @@ if (this.get_tag(true) === '{{else}}') {

if (content.length >= 2 && content[content.length - 1] === '{' && content[content.length - 2] === '{') {
if (input_char === '#' || input_char === '/') {
if (input_char === '#' || input_char === '/' || input_char === '!') {
tag_start = this.pos - 3;

@@ -411,2 +422,9 @@ } else {

if (indent_handlebars && content[1] && content[1] === '{' && content[2] && content[2] === '!') { //if we're in a comment, do something special
// We treat all comments as literals, even more than preformatted tags
// we just look for the appropriate close tag
content = [this.get_comment(tag_start)];
break;
}
if (indent_handlebars && tag_start_char === '{' && content.length > 2 && content[content.length - 2] === '}' && content[content.length - 1] === '}') {

@@ -538,2 +556,5 @@ break;

matched = true;
} else if (comment.indexOf('{{!') === 0) { // {{! handlebars comment
delimiter = '}}';
matched = true;
}

@@ -814,2 +835,6 @@ }

break;
case 'TK_TAG_HANDLEBARS_COMMENT':
multi_parser.print_token(multi_parser.token_text);
multi_parser.current_mode = 'TAG';
break;
case 'TK_CONTENT':

@@ -816,0 +841,0 @@ multi_parser.print_token(multi_parser.token_text);

@@ -49,2 +49,3 @@ #!/usr/bin/env node

"indent_char": String,
"eol": String,
"indent_level": Number,

@@ -77,2 +78,3 @@ "indent_with_tabs": Boolean,

"indent_scripts": ["keep", "separate", "normal"],
"extra_liners": [String, Array],
// CLI

@@ -94,2 +96,3 @@ "version": Boolean,

"c": ["--indent_char"],
"e": ["--eol"],
"l": ["--indent_level"],

@@ -121,2 +124,3 @@ "t": ["--indent_with_tabs"],

"S": ["--indent_scripts"],
"E": ["--extra_liners"],
// non-dasherized hybrid shortcuts

@@ -230,2 +234,3 @@ "good-stuff": [

msg.push(' -t, --indent-with-tabs Indent with tabs, overrides -s and -c');
msg.push(' -e, --eol character(s) to use as line terminators. (default newline - "\\n")');
msg.push(' -p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)');

@@ -257,2 +262,3 @@ msg.push(' -m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]');

msg.push(' -U, --unformatted List of tags (defaults to inline) that should not be reformatted');
msg.push(' -E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline');
break;

@@ -259,0 +265,0 @@ case "css":

@@ -125,2 +125,28 @@ /*global js_beautify: true */

// Comments
t('/* test */');
t('.tabs{/* test */}', '.tabs {\n\t/* test */\n}');
t('.tabs{/* test */}', '.tabs {\n\t/* test */\n}');
t('/* header */.tabs {}', '/* header */\n\n.tabs {}');
t('.tabs {\n/* non-header */\nwidth:10px;}', '.tabs {\n\t/* non-header */\n\twidth: 10px;\n}');
t('/* header');
t('// comment');
t('.selector1 {\n\tmargin: 0; /* This is a comment including an url http://domain.com/path/to/file.ext */\n}', '.selector1 {\n\tmargin: 0;\n\t/* This is a comment including an url http://domain.com/path/to/file.ext */\n}');
// single line comment support (less/sass)
t('.tabs{\n// comment\nwidth:10px;\n}', '.tabs {\n\t// comment\n\twidth: 10px;\n}');
t('.tabs{// comment\nwidth:10px;\n}', '.tabs {\n\t// comment\n\twidth: 10px;\n}');
t('//comment\n.tabs{width:10px;}', '//comment\n.tabs {\n\twidth: 10px;\n}');
t('.tabs{//comment\n//2nd single line comment\nwidth:10px;}', '.tabs {\n\t//comment\n\t//2nd single line comment\n\twidth: 10px;\n}');
t('.tabs{width:10px;//end of line comment\n}', '.tabs {\n\twidth: 10px; //end of line comment\n}');
t('.tabs{width:10px;//end of line comment\nheight:10px;}', '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px;\n}');
t('.tabs{width:10px;//end of line comment\nheight:10px;//another\n}', '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}');
// Psuedo-classes vs Variables
t('@page :first {}');
// Assume the colon goes with the @name. If we're in LESS, this is required regardless of the at-string.
t('@page:first {}', '@page: first {}');
t('@page: first {}');
//

@@ -148,20 +174,2 @@

// comments
t("/* test */", "/* test */");
t(".tabs{/* test */}", ".tabs {\n\t/* test */\n}");
t("/* header */.tabs {}", "/* header */\n\n.tabs {}");
t("/* header", "/* header");
t("// comment", "// comment");
t(".selector1 {\n\tmargin: 0; /* This is a comment including an url http://domain.com/path/to/file.ext */\n}",
".selector1 {\n\tmargin: 0;\n\t/* This is a comment including an url http://domain.com/path/to/file.ext */\n}")
//single line comment support (less/sass)
t(".tabs{\n// comment\nwidth:10px;\n}", ".tabs {\n\t// comment\n\twidth: 10px;\n}");
t(".tabs{// comment\nwidth:10px;\n}", ".tabs {\n\t// comment\n\twidth: 10px;\n}");
t("//comment\n.tabs{width:10px;}", "//comment\n.tabs {\n\twidth: 10px;\n}");
t(".tabs{//comment\n//2nd single line comment\nwidth:10px;}", ".tabs {\n\t//comment\n\t//2nd single line comment\n\twidth: 10px;\n}");
t(".tabs{width:10px;//end of line comment\n}", ".tabs {\n\twidth: 10px; //end of line comment\n}");
t(".tabs{width:10px;//end of line comment\nheight:10px;}", ".tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px;\n}");
t(".tabs{width:10px;//end of line comment\nheight:10px;//another\n}", ".tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}");
// separate selectors

@@ -168,0 +176,0 @@ t("#bla, #foo{color:red}", "#bla,\n#foo {\n\tcolor: red\n}");

@@ -56,21 +56,2 @@ /*global js_beautify: true */

}
// Test that handlebars non-block {{}} tags act as content and do not
// get any spacing or line breaks.
if (input.indexOf('content') != -1) {
// Just {{field}}
field_input = input.replace(/content/g, '{{field}}');
field_expectation = expectation.replace(/content/g, '{{field}}');
test_fragment(field_input, field_expectation);
// handlebars comment
field_input = input.replace(/content/g, '{{! comment}}');
field_expectation = expectation.replace(/content/g, '{{! comment}}');
test_fragment(field_input, field_expectation);
// mixed {{field}} and content
field_input = input.replace(/content/g, 'pre{{field1}} {{field2}} {{field3}}post');
field_expectation = expectation.replace(/content/g, 'pre{{field1}} {{field2}} {{field3}}post');
test_fragment(field_input, field_expectation);
}
}

@@ -90,2 +71,3 @@

opts.indent_char = ' ';
opts.indent_with_tabs = false;
opts.preserve_newlines = true;

@@ -95,2 +77,3 @@ opts.jslint_happy = false;

opts.brace_style = 'collapse';
opts.extra_liners = ['html', 'head', '/html'];

@@ -102,3 +85,3 @@ // End With Newline - (eof = "\n")

test_fragment('\n');
// End With Newline - (eof = "")

@@ -109,3 +92,24 @@ opts.end_with_newline = false;

test_fragment('\n', '');
// Custom Extra Liners (empty) - ()
opts.extra_liners = [];
test_fragment('<html><head><meta></head><body><div><p>x</p></div></body></html>', '<html>\n<head>\n <meta>\n</head>\n<body>\n <div>\n <p>x</p>\n </div>\n</body>\n</html>');
// Custom Extra Liners (default) - ()
opts.extra_liners = null;
test_fragment('<html><head></head><body></body></html>', '<html>\n\n<head></head>\n\n<body></body>\n\n</html>');
// Custom Extra Liners (p, string) - ()
opts.extra_liners = 'p,/p';
test_fragment('<html><head><meta></head><body><div><p>x</p></div></body></html>', '<html>\n<head>\n <meta>\n</head>\n<body>\n <div>\n\n <p>x\n\n </p>\n </div>\n</body>\n</html>');
// Custom Extra Liners (p) - ()
opts.extra_liners = ['p', '/p'];
test_fragment('<html><head><meta></head><body><div><p>x</p></div></body></html>', '<html>\n<head>\n <meta>\n</head>\n<body>\n <div>\n\n <p>x\n\n </p>\n </div>\n</body>\n</html>');
// Attribute Wrap - (eof = "\n", indent_attr = " ", over80 = "\n")

@@ -116,3 +120,3 @@ opts.wrap_attributes = 'force';

test_fragment('<img attr0 attr1="123" data-attr2="hello t here"/>', '<img attr0\n attr1="123"\n data-attr2="hello t here" />');
// Attribute Wrap - (eof = "\n", indent_attr = " ", over80 = "\n")

@@ -124,3 +128,3 @@ opts.wrap_attributes = 'force';

test_fragment('<img attr0 attr1="123" data-attr2="hello t here"/>', '<img attr0\n attr1="123"\n data-attr2="hello t here" />');
// Attribute Wrap - (eof = "\n", indent_attr = " ", over80 = "\n")

@@ -132,3 +136,3 @@ opts.wrap_attributes = 'force';

test_fragment('<img attr0 attr1="123" data-attr2="hello t here"/>', '<img attr0\n attr1="123"\n data-attr2="hello t here" />');
// Attribute Wrap - (eof = " ", indent_attr = "", over80 = "\n")

@@ -140,3 +144,3 @@ opts.wrap_attributes = 'auto';

test_fragment('<img attr0 attr1="123" data-attr2="hello t here"/>', '<img attr0 attr1="123" data-attr2="hello t here" />');
// Attribute Wrap - (eof = " ", indent_attr = "", over80 = " ")

@@ -148,3 +152,242 @@ opts.wrap_attributes = 'auto';

test_fragment('<img attr0 attr1="123" data-attr2="hello t here"/>', '<img attr0 attr1="123" data-attr2="hello t here" />');
// Handlebars Indenting Off
opts.indent_handlebars = false;
test_fragment(
'{{#if 0}}\n <div>\n </div>\n{{/if}}',
'{{#if 0}}\n<div>\n</div>\n{{/if}}');
test_fragment(
'<div>\n{{#each thing}}\n {{name}}\n{{/each}}\n</div>',
'<div>\n {{#each thing}} {{name}} {{/each}}\n</div>');
// Handlebars Indenting On - (content = "{{field}}")
opts.indent_handlebars = true;
test_fragment('{{#if 0}}{{/if}}');
test_fragment('{{#if 0}}{{field}}{{/if}}');
test_fragment('{{#if 0}}\n{{/if}}');
test_fragment(
'{{#if words}}{{/if}}',
'{{#if words}}{{/if}}');
test_fragment(
'{{#if words}}{{field}}{{/if}}',
'{{#if words}}{{field}}{{/if}}');
test_fragment(
'{{#if words}}{{field}}{{/if}}',
'{{#if words}}{{field}}{{/if}}');
test_fragment('{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment(
'{{#if 1}}\n<div>\n</div>\n{{/if}}',
'{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment('<div>\n {{#if 1}}\n {{/if}}\n</div>');
test_fragment(
'<div>\n{{#if 1}}\n{{/if}}\n</div>',
'<div>\n {{#if 1}}\n {{/if}}\n</div>');
test_fragment(
'{{#if}}\n{{#each}}\n{{#if}}\n{{field}}\n{{/if}}\n{{#if}}\n{{field}}\n{{/if}}\n{{/each}}\n{{/if}}',
'{{#if}}\n {{#each}}\n {{#if}}\n {{field}}\n {{/if}}\n {{#if}}\n {{field}}\n {{/if}}\n {{/each}}\n{{/if}}');
test_fragment('{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment(
'{{#if 1}}\n {{field}}\n {{else}}\n {{field}}\n{{/if}}',
'{{#if 1}}\n {{field}}\n{{else}}\n {{field}}\n{{/if}}');
test_fragment(
'{{#if 1}}\n {{else}}\n {{/if}}',
'{{#if 1}}\n{{else}}\n{{/if}}');
test_fragment(
'{{#if thing}}\n{{#if otherthing}}\n {{field}}\n {{else}}\n{{field}}\n {{/if}}\n {{else}}\n{{field}}\n{{/if}}',
'{{#if thing}}\n {{#if otherthing}}\n {{field}}\n {{else}}\n {{field}}\n {{/if}}\n{{else}}\n {{field}}\n{{/if}}');
test_fragment(
'<div{{somestyle}}></div>',
'<div {{somestyle}}></div>');
test_fragment(
'<div{{#if test}}class="foo"{{/if}}>{{field}}</div>',
'<div {{#if test}} class="foo" {{/if}}>{{field}}</div>');
test_fragment(
'<div{{#if thing}}{{somestyle}}class="{{class}}"{{else}}class="{{class2}}"{{/if}}>{{field}}</div>',
'<div {{#if thing}} {{somestyle}} class="{{class}}" {{else}} class="{{class2}}" {{/if}}>{{field}}</div>');
test_fragment(
'<span{{#if condition}}class="foo"{{/if}}>{{field}}</span>',
'<span {{#if condition}} class="foo" {{/if}}>{{field}}</span>');
test_fragment('<div unformatted="{{#if}}{{field}}{{/if}}">{{field}}</div>');
test_fragment('<div unformatted="{{#if }} {{field}}{{/if}}">{{field}}</div>');
test_fragment('<div class="{{#if thingIs "value"}}{{field}}{{/if}}"></div>');
test_fragment('<div class="{{#if thingIs \'value\'}}{{field}}{{/if}}"></div>');
test_fragment('<div class=\'{{#if thingIs "value"}}{{field}}{{/if}}\'></div>');
test_fragment('<div class=\'{{#if thingIs \'value\'}}{{field}}{{/if}}\'></div>');
// Handlebars Indenting On - (content = "{{! comment}}")
opts.indent_handlebars = true;
test_fragment('{{#if 0}}{{/if}}');
test_fragment('{{#if 0}}{{! comment}}{{/if}}');
test_fragment('{{#if 0}}\n{{/if}}');
test_fragment(
'{{#if words}}{{/if}}',
'{{#if words}}{{/if}}');
test_fragment(
'{{#if words}}{{! comment}}{{/if}}',
'{{#if words}}{{! comment}}{{/if}}');
test_fragment(
'{{#if words}}{{! comment}}{{/if}}',
'{{#if words}}{{! comment}}{{/if}}');
test_fragment('{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment(
'{{#if 1}}\n<div>\n</div>\n{{/if}}',
'{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment('<div>\n {{#if 1}}\n {{/if}}\n</div>');
test_fragment(
'<div>\n{{#if 1}}\n{{/if}}\n</div>',
'<div>\n {{#if 1}}\n {{/if}}\n</div>');
test_fragment(
'{{#if}}\n{{#each}}\n{{#if}}\n{{! comment}}\n{{/if}}\n{{#if}}\n{{! comment}}\n{{/if}}\n{{/each}}\n{{/if}}',
'{{#if}}\n {{#each}}\n {{#if}}\n {{! comment}}\n {{/if}}\n {{#if}}\n {{! comment}}\n {{/if}}\n {{/each}}\n{{/if}}');
test_fragment('{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment(
'{{#if 1}}\n {{! comment}}\n {{else}}\n {{! comment}}\n{{/if}}',
'{{#if 1}}\n {{! comment}}\n{{else}}\n {{! comment}}\n{{/if}}');
test_fragment(
'{{#if 1}}\n {{else}}\n {{/if}}',
'{{#if 1}}\n{{else}}\n{{/if}}');
test_fragment(
'{{#if thing}}\n{{#if otherthing}}\n {{! comment}}\n {{else}}\n{{! comment}}\n {{/if}}\n {{else}}\n{{! comment}}\n{{/if}}',
'{{#if thing}}\n {{#if otherthing}}\n {{! comment}}\n {{else}}\n {{! comment}}\n {{/if}}\n{{else}}\n {{! comment}}\n{{/if}}');
test_fragment(
'<div{{somestyle}}></div>',
'<div {{somestyle}}></div>');
test_fragment(
'<div{{#if test}}class="foo"{{/if}}>{{! comment}}</div>',
'<div {{#if test}} class="foo" {{/if}}>{{! comment}}</div>');
test_fragment(
'<div{{#if thing}}{{somestyle}}class="{{class}}"{{else}}class="{{class2}}"{{/if}}>{{! comment}}</div>',
'<div {{#if thing}} {{somestyle}} class="{{class}}" {{else}} class="{{class2}}" {{/if}}>{{! comment}}</div>');
test_fragment(
'<span{{#if condition}}class="foo"{{/if}}>{{! comment}}</span>',
'<span {{#if condition}} class="foo" {{/if}}>{{! comment}}</span>');
test_fragment('<div unformatted="{{#if}}{{! comment}}{{/if}}">{{! comment}}</div>');
test_fragment('<div unformatted="{{#if }} {{! comment}}{{/if}}">{{! comment}}</div>');
test_fragment('<div class="{{#if thingIs "value"}}{{! comment}}{{/if}}"></div>');
test_fragment('<div class="{{#if thingIs \'value\'}}{{! comment}}{{/if}}"></div>');
test_fragment('<div class=\'{{#if thingIs "value"}}{{! comment}}{{/if}}\'></div>');
test_fragment('<div class=\'{{#if thingIs \'value\'}}{{! comment}}{{/if}}\'></div>');
// Handlebars Indenting On - (content = "{pre{{field1}} {{field2}} {{field3}}post")
opts.indent_handlebars = true;
test_fragment('{{#if 0}}{{/if}}');
test_fragment('{{#if 0}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}');
test_fragment('{{#if 0}}\n{{/if}}');
test_fragment(
'{{#if words}}{{/if}}',
'{{#if words}}{{/if}}');
test_fragment(
'{{#if words}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}',
'{{#if words}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}');
test_fragment(
'{{#if words}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}',
'{{#if words}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}');
test_fragment('{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment(
'{{#if 1}}\n<div>\n</div>\n{{/if}}',
'{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment('<div>\n {{#if 1}}\n {{/if}}\n</div>');
test_fragment(
'<div>\n{{#if 1}}\n{{/if}}\n</div>',
'<div>\n {{#if 1}}\n {{/if}}\n</div>');
test_fragment(
'{{#if}}\n{{#each}}\n{{#if}}\n{pre{{field1}} {{field2}} {{field3}}post\n{{/if}}\n{{#if}}\n{pre{{field1}} {{field2}} {{field3}}post\n{{/if}}\n{{/each}}\n{{/if}}',
'{{#if}}\n {{#each}}\n {{#if}}\n {pre{{field1}} {{field2}} {{field3}}post\n {{/if}}\n {{#if}}\n {pre{{field1}} {{field2}} {{field3}}post\n {{/if}}\n {{/each}}\n{{/if}}');
test_fragment('{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment(
'{{#if 1}}\n {pre{{field1}} {{field2}} {{field3}}post\n {{else}}\n {pre{{field1}} {{field2}} {{field3}}post\n{{/if}}',
'{{#if 1}}\n {pre{{field1}} {{field2}} {{field3}}post\n{{else}}\n {pre{{field1}} {{field2}} {{field3}}post\n{{/if}}');
test_fragment(
'{{#if 1}}\n {{else}}\n {{/if}}',
'{{#if 1}}\n{{else}}\n{{/if}}');
test_fragment(
'{{#if thing}}\n{{#if otherthing}}\n {pre{{field1}} {{field2}} {{field3}}post\n {{else}}\n{pre{{field1}} {{field2}} {{field3}}post\n {{/if}}\n {{else}}\n{pre{{field1}} {{field2}} {{field3}}post\n{{/if}}',
'{{#if thing}}\n {{#if otherthing}}\n {pre{{field1}} {{field2}} {{field3}}post\n {{else}}\n {pre{{field1}} {{field2}} {{field3}}post\n {{/if}}\n{{else}}\n {pre{{field1}} {{field2}} {{field3}}post\n{{/if}}');
test_fragment(
'<div{{somestyle}}></div>',
'<div {{somestyle}}></div>');
test_fragment(
'<div{{#if test}}class="foo"{{/if}}>{pre{{field1}} {{field2}} {{field3}}post</div>',
'<div {{#if test}} class="foo" {{/if}}>{pre{{field1}} {{field2}} {{field3}}post</div>');
test_fragment(
'<div{{#if thing}}{{somestyle}}class="{{class}}"{{else}}class="{{class2}}"{{/if}}>{pre{{field1}} {{field2}} {{field3}}post</div>',
'<div {{#if thing}} {{somestyle}} class="{{class}}" {{else}} class="{{class2}}" {{/if}}>{pre{{field1}} {{field2}} {{field3}}post</div>');
test_fragment(
'<span{{#if condition}}class="foo"{{/if}}>{pre{{field1}} {{field2}} {{field3}}post</span>',
'<span {{#if condition}} class="foo" {{/if}}>{pre{{field1}} {{field2}} {{field3}}post</span>');
test_fragment('<div unformatted="{{#if}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}">{pre{{field1}} {{field2}} {{field3}}post</div>');
test_fragment('<div unformatted="{{#if }} {pre{{field1}} {{field2}} {{field3}}post{{/if}}">{pre{{field1}} {{field2}} {{field3}}post</div>');
test_fragment('<div class="{{#if thingIs "value"}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}"></div>');
test_fragment('<div class="{{#if thingIs \'value\'}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}"></div>');
test_fragment('<div class=\'{{#if thingIs "value"}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}\'></div>');
test_fragment('<div class=\'{{#if thingIs \'value\'}}{pre{{field1}} {{field2}} {{field3}}post{{/if}}\'></div>');
// Handlebars Indenting On - (content = "{{! \n mult-line\ncomment \n with spacing\n}}")
opts.indent_handlebars = true;
test_fragment('{{#if 0}}{{/if}}');
test_fragment('{{#if 0}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}');
test_fragment('{{#if 0}}\n{{/if}}');
test_fragment(
'{{#if words}}{{/if}}',
'{{#if words}}{{/if}}');
test_fragment(
'{{#if words}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}',
'{{#if words}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}');
test_fragment(
'{{#if words}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}',
'{{#if words}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}');
test_fragment('{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment(
'{{#if 1}}\n<div>\n</div>\n{{/if}}',
'{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment('<div>\n {{#if 1}}\n {{/if}}\n</div>');
test_fragment(
'<div>\n{{#if 1}}\n{{/if}}\n</div>',
'<div>\n {{#if 1}}\n {{/if}}\n</div>');
test_fragment(
'{{#if}}\n{{#each}}\n{{#if}}\n{{! \n mult-line\ncomment \n with spacing\n}}\n{{/if}}\n{{#if}}\n{{! \n mult-line\ncomment \n with spacing\n}}\n{{/if}}\n{{/each}}\n{{/if}}',
'{{#if}}\n {{#each}}\n {{#if}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n {{/if}}\n {{#if}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n {{/if}}\n {{/each}}\n{{/if}}');
test_fragment('{{#if 1}}\n <div>\n </div>\n{{/if}}');
test_fragment(
'{{#if 1}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n {{else}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n{{/if}}',
'{{#if 1}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n{{else}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n{{/if}}');
test_fragment(
'{{#if 1}}\n {{else}}\n {{/if}}',
'{{#if 1}}\n{{else}}\n{{/if}}');
test_fragment(
'{{#if thing}}\n{{#if otherthing}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n {{else}}\n{{! \n mult-line\ncomment \n with spacing\n}}\n {{/if}}\n {{else}}\n{{! \n mult-line\ncomment \n with spacing\n}}\n{{/if}}',
'{{#if thing}}\n {{#if otherthing}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n {{else}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n {{/if}}\n{{else}}\n {{! \n mult-line\ncomment \n with spacing\n}}\n{{/if}}');
test_fragment(
'<div{{somestyle}}></div>',
'<div {{somestyle}}></div>');
test_fragment(
'<div{{#if test}}class="foo"{{/if}}>{{! \n mult-line\ncomment \n with spacing\n}}</div>',
'<div {{#if test}} class="foo" {{/if}}>{{! \n mult-line\ncomment \n with spacing\n}}</div>');
test_fragment(
'<div{{#if thing}}{{somestyle}}class="{{class}}"{{else}}class="{{class2}}"{{/if}}>{{! \n mult-line\ncomment \n with spacing\n}}</div>',
'<div {{#if thing}} {{somestyle}} class="{{class}}" {{else}} class="{{class2}}" {{/if}}>{{! \n mult-line\ncomment \n with spacing\n}}</div>');
test_fragment(
'<span{{#if condition}}class="foo"{{/if}}>{{! \n mult-line\ncomment \n with spacing\n}}</span>',
'<span {{#if condition}} class="foo" {{/if}}>{{! \n mult-line\ncomment \n with spacing\n}}</span>');
test_fragment('<div unformatted="{{#if}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}">{{! \n mult-line\ncomment \n with spacing\n}}</div>');
test_fragment('<div unformatted="{{#if }} {{! \n mult-line\ncomment \n with spacing\n}}{{/if}}">{{! \n mult-line\ncomment \n with spacing\n}}</div>');
test_fragment('<div class="{{#if thingIs "value"}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}"></div>');
test_fragment('<div class="{{#if thingIs \'value\'}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}"></div>');
test_fragment('<div class=\'{{#if thingIs "value"}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}\'></div>');
test_fragment('<div class=\'{{#if thingIs \'value\'}}{{! \n mult-line\ncomment \n with spacing\n}}{{/if}}\'></div>');
// Unclosed html elements
test_fragment('<source>\n<source>');
test_fragment('<br>\n<br>');
test_fragment('<input>\n<input>');
test_fragment('<meta>\n<meta>');
test_fragment('<link>\n<link>');
// Unformatted tags

@@ -154,4 +397,23 @@ test_fragment('<ol>\n <li>b<pre>c</pre></li>\n</ol>');

// Indent with tabs
opts.indent_with_tabs = true;
test_fragment(
'<div>\n<div>\n</div>\n</div>',
'<div>\n\t<div>\n\t</div>\n</div>');
// Indent without tabs
opts.indent_with_tabs = false;
test_fragment(
'<div>\n<div>\n</div>\n</div>',
'<div>\n <div>\n </div>\n</div>');
// New Test Suite
opts.end_with_newline = true;

@@ -366,136 +628,3 @@ test_fragment('', '\n');

// Without the indent option on, handlebars are treated as content.
opts.indent_handlebars = false;
bth('{{#if 0}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}',
'{{#if 0}}\n' +
'<div>\n' +
'</div>\n' +
'{{/if}}');
bth('<div>\n' +
'{{#each thing}}\n' +
' {{name}}\n' +
'{{/each}}\n' +
'</div>',
'<div>\n' +
' {{#each thing}} {{name}} {{/each}}\n' +
'</div>');
opts.indent_handlebars = true;
bth('{{#if 0}}{{/if}}');
bth('{{#if 0}}content{{/if}}');
bth('{{#if 0}}\n' +
'{{/if}}');
bth('{{#if words}}{{/if}}',
'{{#if words}}{{/if}}');
bth('{{#if words}}content{{/if}}',
'{{#if words}}content{{/if}}');
bth('{{#if words}}content{{/if}}',
'{{#if words}}content{{/if}}');
bth('{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}');
bth('{{#if 1}}\n' +
'<div>\n' +
'</div>\n' +
'{{/if}}',
'{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}');
bth('<div>\n' +
' {{#if 1}}\n' +
' {{/if}}\n' +
'</div>');
bth('<div>\n' +
'{{#if 1}}\n' +
'{{/if}}\n' +
'</div>',
'<div>\n' +
' {{#if 1}}\n' +
' {{/if}}\n' +
'</div>');
bth('{{#if}}\n' +
'{{#each}}\n' +
'{{#if}}\n' +
'content\n' +
'{{/if}}\n' +
'{{#if}}\n' +
'content\n' +
'{{/if}}\n' +
'{{/each}}\n' +
'{{/if}}',
'{{#if}}\n' +
' {{#each}}\n' +
' {{#if}}\n' +
' content\n' +
' {{/if}}\n' +
' {{#if}}\n' +
' content\n' +
' {{/if}}\n' +
' {{/each}}\n' +
'{{/if}}');
bth('{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}');
// Test {{else}} aligned with {{#if}} and {{/if}}
bth('{{#if 1}}\n' +
' content\n' +
' {{else}}\n' +
' content\n' +
'{{/if}}',
'{{#if 1}}\n' +
' content\n' +
'{{else}}\n' +
' content\n' +
'{{/if}}');
bth('{{#if 1}}\n' +
' {{else}}\n' +
' {{/if}}',
'{{#if 1}}\n' +
'{{else}}\n' +
'{{/if}}');
bth('{{#if thing}}\n' +
'{{#if otherthing}}\n' +
' content\n' +
' {{else}}\n' +
'content\n' +
' {{/if}}\n' +
' {{else}}\n'+
'content\n' +
'{{/if}}',
'{{#if thing}}\n' +
' {{#if otherthing}}\n' +
' content\n' +
' {{else}}\n' +
' content\n' +
' {{/if}}\n' +
'{{else}}\n'+
' content\n' +
'{{/if}}');
// Test {{}} inside of <> tags, which should be separated by spaces
// for readability, unless they are inside a string.
bth('<div{{somestyle}}></div>',
'<div {{somestyle}}></div>');
bth('<div{{#if test}}class="foo"{{/if}}>content</div>',
'<div {{#if test}} class="foo" {{/if}}>content</div>');
bth('<div{{#if thing}}{{somestyle}}class="{{class}}"{{else}}class="{{class2}}"{{/if}}>content</div>',
'<div {{#if thing}} {{somestyle}} class="{{class}}" {{else}} class="{{class2}}" {{/if}}>content</div>');
bth('<span{{#if condition}}class="foo"{{/if}}>content</span>',
'<span {{#if condition}} class="foo" {{/if}}>content</span>');
bth('<div unformatted="{{#if}}content{{/if}}">content</div>');
bth('<div unformatted="{{#if }} content{{/if}}">content</div>');
// Quotes found inside of Handlebars expressions inside of quoted
// strings themselves should not be considered string delimiters.
bth('<div class="{{#if thingIs "value"}}content{{/if}}"></div>');
bth('<div class="{{#if thingIs \'value\'}}content{{/if}}"></div>');
bth('<div class=\'{{#if thingIs "value"}}content{{/if}}\'></div>');
bth('<div class=\'{{#if thingIs \'value\'}}content{{/if}}\'></div>');
opts.wrap_line_length = 0;

@@ -502,0 +631,0 @@ //...---------1---------2---------3---------4---------5---------6---------7

{
"name": "js-beautify",
"version": "1.5.5",
"version": "1.5.6",
"description": "jsbeautifier.org for node",

@@ -52,3 +52,3 @@ "main": "js/index.js",

"node-static": "~0.7.1",
"mustache": "~0.8.2",
"mustache": "~1.1.0",
"requirejs": "2.1.x",

@@ -55,0 +55,0 @@ "benchmark": "1.0.0"

@@ -6,3 +6,5 @@ # JS Beautifier

[![NPM stats](https://nodei.co/npm/js-beautify.svg?downloadRank=true&downloads=true)](https://www.npmjs.org/package/js-beautify)
This little beautifier will reformat and reindent bookmarklets, ugly

@@ -90,2 +92,3 @@ JavaScript, unpack scripts packed by Dean Edward’s popular packer,

-c, --indent-char Indentation character [" "]
-e, --eol character(s) to use as line terminators. (default newline - "\\n")');
-l, --indent-level Initial indentation level [0]

@@ -115,2 +118,3 @@ -t, --indent-with-tabs Indent with tabs, overrides -s and -c

"indent_char": " ",
"eol": "\n",
"indent_level": 0,

@@ -131,3 +135,4 @@ "indent_with_tabs": false,

"wrap_attributes": "auto",
"wrap_attributes_indent_size": 4
"wrap_attributes_indent_size": 4,
"end_with_newline": false
}

@@ -181,2 +186,3 @@ ```

-n, --end-with-newline End output with newline
-E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline before them.
```

@@ -183,0 +189,0 @@

@@ -26,6 +26,6 @@ exports.test_data = {

tests: [
{ fragment: '', output: '{{eof}}' },
{ fragment: ' .tabs{}', output: ' .tabs {}{{eof}}' },
{ fragment: ' \n\n.tabs{}\n\n\n\n', output: ' .tabs {}{{eof}}' },
{ fragment: '\n', output: '{{eof}}' }
{ fragment: true, input: '', output: '{{eof}}' },
{ fragment: true, input: ' .tabs{}', output: ' .tabs {}{{eof}}' },
{ fragment: true, input: ' \n\n.tabs{}\n\n\n\n', output: ' .tabs {}{{eof}}' },
{ fragment: true, input: '\n', output: '{{eof}}' }
],

@@ -93,4 +93,37 @@ }, {

}, {
name: "Comments",
description: "",
tests: [
{ unchanged: '/* test */' },
{ input: '.tabs{/* test */}', output: '.tabs {\n\t/* test */\n}' },
{ input: '.tabs{/* test */}', output: '.tabs {\n\t/* test */\n}' },
{ input: '/* header */.tabs {}', output: '/* header */\n\n.tabs {}' },
{ input: '.tabs {\n/* non-header */\nwidth:10px;}', output: '.tabs {\n\t/* non-header */\n\twidth: 10px;\n}' },
{ unchanged: '/* header' },
{ unchanged: '// comment' },
{ input: '.selector1 {\n\tmargin: 0; /* This is a comment including an url http://domain.com/path/to/file.ext */\n}',
output: '.selector1 {\n\tmargin: 0;\n\t/* This is a comment including an url http://domain.com/path/to/file.ext */\n}'},
{ comment: "single line comment support (less/sass)",
input:'.tabs{\n// comment\nwidth:10px;\n}', output: '.tabs {\n\t// comment\n\twidth: 10px;\n}' },
{ input: '.tabs{// comment\nwidth:10px;\n}', output: '.tabs {\n\t// comment\n\twidth: 10px;\n}' },
{ input: '//comment\n.tabs{width:10px;}', output: '//comment\n.tabs {\n\twidth: 10px;\n}' },
{ input: '.tabs{//comment\n//2nd single line comment\nwidth:10px;}', output: '.tabs {\n\t//comment\n\t//2nd single line comment\n\twidth: 10px;\n}' },
{ input: '.tabs{width:10px;//end of line comment\n}', output: '.tabs {\n\twidth: 10px; //end of line comment\n}' },
{ input: '.tabs{width:10px;//end of line comment\nheight:10px;}', output: '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px;\n}' },
{ input: '.tabs{width:10px;//end of line comment\nheight:10px;//another\n}', output: '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}' }
],
}, {
name: "Psuedo-classes vs Variables",
description: "",
tests: [
{ unchanged: '@page :first {}' },
{ comment: "Assume the colon goes with the @name. If we're in LESS, this is required regardless of the at-string.",
input: '@page:first {}',
output: '@page: first {}' },
{ unchanged: '@page: first {}' }
],
}, {
}]
}

@@ -5,6 +5,8 @@ exports.test_data = {

{ name: "indent_char", value: "' '" },
{ name: "indent_with_tabs", value: "false" },
{ name: "preserve_newlines", value: "true" },
{ name: "jslint_happy", value: "false" },
{ name: "keep_array_indentation", value: "false" },
{ name: "brace_style", value: "'collapse'" }
{ name: "brace_style", value: "'collapse'" },
{ name: "extra_liners", value: "['html', 'head', '/html']" }
],

@@ -29,8 +31,80 @@ groups: [{

tests: [
{ fragment: '', output: '{{eof}}' },
{ fragment: '<div></div>', output: '<div></div>{{eof}}' },
// { fragment: ' \n\n<div></div>\n\n\n\n', output: ' <div></div>{{eof}}' },
{ fragment: '\n', output: '{{eof}}' }
{ fragment: true, input: '', output: '{{eof}}' },
{ fragment: true, input: '<div></div>', output: '<div></div>{{eof}}' },
// { fragment: true, input: ' \n\n<div></div>\n\n\n\n', output: ' <div></div>{{eof}}' },
{ fragment: true, input: '\n', output: '{{eof}}' }
],
}, {
name: "Custom Extra Liners (empty)",
description: "",
matrix: [
{
options: [
{ name: "extra_liners", value: "[]" }
]
},
],
tests: [
{
fragment: true,
input: '<html><head><meta></head><body><div><p>x</p></div></body></html>',
output: '<html>\n<head>\n <meta>\n</head>\n<body>\n <div>\n <p>x</p>\n </div>\n</body>\n</html>'
}
],
}, {
name: "Custom Extra Liners (default)",
description: "",
matrix: [
{
options: [
{ name: "extra_liners", value: "null" }
]
},
],
tests: [
{
fragment: true,
input: '<html><head></head><body></body></html>',
output: '<html>\n\n<head></head>\n\n<body></body>\n\n</html>'
}
],
}, {
name: "Custom Extra Liners (p, string)",
description: "",
matrix: [
{
options: [
{ name: "extra_liners", value: "'p,/p'" }
]
},
],
tests: [
{
fragment: true,
input: '<html><head><meta></head><body><div><p>x</p></div></body></html>',
output: '<html>\n<head>\n <meta>\n</head>\n<body>\n <div>\n\n <p>x\n\n </p>\n </div>\n</body>\n</html>'
}
],
}, {
name: "Custom Extra Liners (p)",
description: "",
matrix: [
{
options: [
{ name: "extra_liners", value: "['p', '/p']" }
]
},
],
tests: [
{
fragment: true,
input: '<html><head><meta></head><body><div><p>x</p></div></body></html>',
output: '<html>\n<head>\n <meta>\n</head>\n<body>\n <div>\n\n <p>x\n\n </p>\n </div>\n</body>\n</html>'
}
],
}, {
name: "Attribute Wrap",

@@ -82,11 +156,14 @@ description: "Wraps attributes inside of html tags",

{
fragment: '<div attr0 attr1="123" data-attr2="hello t here">This is some text</div>',
fragment: true,
input: '<div attr0 attr1="123" data-attr2="hello t here">This is some text</div>',
output: '<div attr0{{eof}}{{indent_attr}}attr1="123"{{eof}}{{indent_attr}}data-attr2="hello t here">This is some text</div>'
},
{
fragment: '<div lookatthissuperduperlongattributenamewhoahcrazy0="true" attr0 attr1="123" data-attr2="hello t here" heymanimreallylongtoowhocomesupwiththesenames="false">This is some text</div>',
fragment: true,
input: '<div lookatthissuperduperlongattributenamewhoahcrazy0="true" attr0 attr1="123" data-attr2="hello t here" heymanimreallylongtoowhocomesupwiththesenames="false">This is some text</div>',
output: '<div lookatthissuperduperlongattributenamewhoahcrazy0="true"{{eof}}{{indent_attr}}attr0{{eof}}{{indent_attr}}attr1="123"{{eof}}{{indent_attr}}data-attr2="hello t here"{{over80}}{{indent_attr}}heymanimreallylongtoowhocomesupwiththesenames="false">This is some text</div>'
},
{
fragment: '<img attr0 attr1="123" data-attr2="hello t here"/>',
fragment: true,
input: '<img attr0 attr1="123" data-attr2="hello t here"/>',
output: '<img attr0{{eof}}{{indent_attr}}attr1="123"{{eof}}{{indent_attr}}data-attr2="hello t here" />'

@@ -96,2 +173,222 @@ }

}, {
name: "Handlebars Indenting Off",
description: "Test handlebar behavior when indenting is off",
template: "^^^ $$$",
options: [
{ name: "indent_handlebars", value: "false" }
],
tests: [
{ fragment: true,
input_:
'{{#if 0}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}',
output:
'{{#if 0}}\n' +
'<div>\n' +
'</div>\n' +
'{{/if}}' },
{ fragment: true,
input_:
'<div>\n' +
'{{#each thing}}\n' +
' {{name}}\n' +
'{{/each}}\n' +
'</div>',
output:
'<div>\n' +
' {{#each thing}} {{name}} {{/each}}\n' +
'</div>'}
]
}, {
name: "Handlebars Indenting On",
description: "Test handlebar formatting",
template: "^^^ $$$",
matrix: [
{
options: [
{ name: "indent_handlebars", value: "true" }
],
content: '{{field}}'
}, {
options: [
{ name: "indent_handlebars", value: "true" }
],
content: '{{! comment}}'
}, {
options: [
{ name: "indent_handlebars", value: "true" }
],
content: '{pre{{field1}} {{field2}} {{field3}}post'
}
, {
options: [
{ name: "indent_handlebars", value: "true" }
],
content: '{{! \\n mult-line\\ncomment \\n with spacing\\n}}'
}
],
tests: [
{ fragment: true, unchanged: '{{#if 0}}{{/if}}' },
{ fragment: true, unchanged: '{{#if 0}}^^^content$$${{/if}}' },
{ fragment: true, unchanged: '{{#if 0}}\n{{/if}}' },
{ fragment: true,
input_: '{{#if words}}{{/if}}',
output: '{{#if words}}{{/if}}' },
{ fragment: true,
input_: '{{#if words}}^^^content$$${{/if}}',
output: '{{#if words}}^^^content$$${{/if}}' },
{ fragment: true,
input_: '{{#if words}}^^^content$$${{/if}}',
output: '{{#if words}}^^^content$$${{/if}}' },
{ fragment: true,
unchanged:
'{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}' },
{ fragment: true,
input_:
'{{#if 1}}\n' +
'<div>\n' +
'</div>\n' +
'{{/if}}',
output:
'{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}' },
{ fragment: true,
unchanged:
'<div>\n' +
' {{#if 1}}\n' +
' {{/if}}\n' +
'</div>' },
{ fragment: true,
input_:
'<div>\n' +
'{{#if 1}}\n' +
'{{/if}}\n' +
'</div>',
output:
'<div>\n' +
' {{#if 1}}\n' +
' {{/if}}\n' +
'</div>' },
{ fragment: true,
input_:
'{{#if}}\n' +
'{{#each}}\n' +
'{{#if}}\n' +
'^^^content$$$\n' +
'{{/if}}\n' +
'{{#if}}\n' +
'^^^content$$$\n' +
'{{/if}}\n' +
'{{/each}}\n' +
'{{/if}}',
output:
'{{#if}}\n' +
' {{#each}}\n' +
' {{#if}}\n' +
' ^^^content$$$\n' +
' {{/if}}\n' +
' {{#if}}\n' +
' ^^^content$$$\n' +
' {{/if}}\n' +
' {{/each}}\n' +
'{{/if}}' },
{ fragment: true, unchanged: '{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}' },
// Test {{else}} aligned with {{#if}} and {{/if}}
{ fragment: true,
input_:
'{{#if 1}}\n' +
' ^^^content$$$\n' +
' {{else}}\n' +
' ^^^content$$$\n' +
'{{/if}}',
output:
'{{#if 1}}\n' +
' ^^^content$$$\n' +
'{{else}}\n' +
' ^^^content$$$\n' +
'{{/if}}' },
{ fragment: true,
input_:
'{{#if 1}}\n' +
' {{else}}\n' +
' {{/if}}',
output:
'{{#if 1}}\n' +
'{{else}}\n' +
'{{/if}}' },
{ fragment: true,
input_:
'{{#if thing}}\n' +
'{{#if otherthing}}\n' +
' ^^^content$$$\n' +
' {{else}}\n' +
'^^^content$$$\n' +
' {{/if}}\n' +
' {{else}}\n'+
'^^^content$$$\n' +
'{{/if}}',
output:
'{{#if thing}}\n' +
' {{#if otherthing}}\n' +
' ^^^content$$$\n' +
' {{else}}\n' +
' ^^^content$$$\n' +
' {{/if}}\n' +
'{{else}}\n'+
' ^^^content$$$\n' +
'{{/if}}' },
// Test {{}} inside of <> tags, which should be separated by spaces
// for readability, unless they are inside a string.
{ fragment: true,
input_: '<div{{somestyle}}></div>',
output: '<div {{somestyle}}></div>' },
{ fragment: true,
input_: '<div{{#if test}}class="foo"{{/if}}>^^^content$$$</div>',
output: '<div {{#if test}} class="foo" {{/if}}>^^^content$$$</div>' },
{ fragment: true,
input_: '<div{{#if thing}}{{somestyle}}class="{{class}}"{{else}}class="{{class2}}"{{/if}}>^^^content$$$</div>',
output: '<div {{#if thing}} {{somestyle}} class="{{class}}" {{else}} class="{{class2}}" {{/if}}>^^^content$$$</div>' },
{ fragment: true,
input_: '<span{{#if condition}}class="foo"{{/if}}>^^^content$$$</span>',
output: '<span {{#if condition}} class="foo" {{/if}}>^^^content$$$</span>' },
{ fragment: true,
unchanged: '<div unformatted="{{#if}}^^^content$$${{/if}}">^^^content$$$</div>' },
{ fragment: true,
unchanged: '<div unformatted="{{#if }} ^^^content$$${{/if}}">^^^content$$$</div>' },
// Quotes found inside of Handlebars expressions inside of quoted
// strings themselves should not be considered string delimiters.
{ fragment: true,
unchanged: '<div class="{{#if thingIs "value"}}^^^content$$${{/if}}"></div>' },
{ fragment: true,
unchanged: '<div class="{{#if thingIs \\\'value\\\'}}^^^content$$${{/if}}"></div>' },
{ fragment: true,
unchanged: '<div class=\\\'{{#if thingIs "value"}}^^^content$$${{/if}}\\\'></div>' },
{ fragment: true,
unchanged: '<div class=\\\'{{#if thingIs \\\'value\\\'}}^^^content$$${{/if}}\\\'></div>' }
],
}, {
name: "Unclosed html elements",
description: "Unclosed elements should not indent",
options: [],
tests: [
{ fragment: true, unchanged: '<source>\n<source>' },
{ fragment: true, unchanged: '<br>\n<br>' },
{ fragment: true, unchanged: '<input>\n<input>' },
{ fragment: true, unchanged: '<meta>\n<meta>' },
{ fragment: true, unchanged: '<link>\n<link>' }
]
}, {
name: "Unformatted tags",

@@ -101,8 +398,48 @@ description: "Unformatted tag behavior",

tests: [
{ fragment: '<ol>\n <li>b<pre>c</pre></li>\n</ol>' },
{ fragment: '<ol>\n <li>b<code>c</code></li>\n</ol>' },
{ fragment: true, unchanged: '<ol>\n <li>b<pre>c</pre></li>\n</ol>' },
{ fragment: true, unchanged: '<ol>\n <li>b<code>c</code></li>\n</ol>' },
]
}, {
name: "New Test Suite"
}]
name: "Indent with tabs",
description: "Use one tab instead of several spaces for indentation",
template: "^^^ $$$",
options: [
{ name: "indent_with_tabs", value: "true" }
],
tests: [
{ fragment: true,
input_:
'<div>\n' +
'<div>\n' +
'</div>\n' +
'</div>',
output:
'<div>\n' +
'\t<div>\n' +
'\t</div>\n' +
'</div>' }
]
}, {
name: "Indent without tabs",
description: "Use several spaces for indentation",
template: "^^^ $$$",
options: [
{ name: "indent_with_tabs", value: "false" }
],
tests: [
{ fragment: true,
input_:
'<div>\n' +
'<div>\n' +
'</div>\n' +
'</div>',
output:
'<div>\n' +
' <div>\n' +
' </div>\n' +
'</div>' }
]
}, {
name: "New Test Suite"
}],
};

@@ -42,6 +42,6 @@ exports.test_data = {

tests: [
{ fragment: '', output: '{{eof}}' },
{ fragment: ' return .5', output: ' return .5{{eof}}' },
{ fragment: ' \n\nreturn .5\n\n\n\n', output: ' return .5{{eof}}' },
{ fragment: '\n', output: '{{eof}}' }
{ fragment: true, input: '', output: '{{eof}}' },
{ fragment: true, input: ' return .5', output: ' return .5{{eof}}' },
{ fragment: true, input: ' \n\nreturn .5\n\n\n\n', output: ' return .5{{eof}}' },
{ fragment: true, input: '\n', output: '{{eof}}' }
],

@@ -98,2 +98,761 @@ }, {

},
{
name: "Async / await tests",
description: "ES7 async / await tests",
tests: [
{ input: "async function foo() {}" },
{ input: "let w = async function foo() {}" },
{ input: "async function foo() {}\nvar x = await foo();"},
{
comment: "async function as an input to another function",
input: "wrapper(async function foo() {})"},
{
comment: "await on inline anonymous function. should have a space after await",
input_: "async function() {\n var w = await(async function() {\n return await foo();\n })();\n}",
output: "async function() {\n var w = await (async function() {\n return await foo();\n })();\n}"
},
{
comment: "ensure that this doesn't break anyone with the async library",
input: "async.map(function(t) {})"
}
]
},
{
name: "e4x - Test that e4x literals passed through when e4x-option is enabled",
description: "",
options: [
{ name: 'e4x', value: true }
],
tests: [
{ input: 'xml=<a b="c"><d/><e>\n foo</e>x</a>;', output: 'xml = <a b="c"><d/><e>\n foo</e>x</a>;' },
{ unchanged: '<a b=\\\'This is a quoted "c".\\\'/>' },
{ unchanged: '<a b="This is a quoted \\\'c\\\'."/>' },
{ unchanged: '<a b="A quote \\\' inside string."/>' },
{ unchanged: '<a b=\\\'A quote " inside string.\\\'/>' },
{ unchanged: '<a b=\\\'Some """ quotes "" inside string.\\\'/>' },
{
comment: 'Handles inline expressions',
input: 'xml=<{a} b="c"><d/><e v={z}>\n foo</e>x</{a}>;',
output: 'xml = <{a} b="c"><d/><e v={z}>\n foo</e>x</{a}>;' },
{
input: 'xml=<{a} b="c">\n <e v={z}>\n foo</e>x</{a}>;',
output: 'xml = <{a} b="c">\n <e v={z}>\n foo</e>x</{a}>;' },
{
comment: 'xml literals with special characters in elem names - see http://www.w3.org/TR/REC-xml/#NT-NameChar',
unchanged: 'xml = <_:.valid.xml- _:.valid.xml-="123"/>;'
},
{
comment: 'Handles CDATA',
input: 'xml=<![CDATA[ b="c"><d/><e v={z}>\n foo</e>x/]]>;',
output: 'xml = <![CDATA[ b="c"><d/><e v={z}>\n foo</e>x/]]>;' },
{ input: 'xml=<![CDATA[]]>;', output: 'xml = <![CDATA[]]>;' },
{ input: 'xml=<a b="c"><![CDATA[d/></a></{}]]></a>;', output: 'xml = <a b="c"><![CDATA[d/></a></{}]]></a>;' },
{
comment: 'JSX - working jsx from http://prettydiff.com/unit_tests/beautification_javascript_jsx.txt',
unchanged:
[
'var ListItem = React.createClass({',
' render: function() {',
' return (',
' <li className="ListItem">',
' <a href={ "/items/" + this.props.item.id }>',
' this.props.item.name',
' </a>',
' </li>',
' );',
' }',
'});'
]
},
{
unchanged:
[
'var List = React.createClass({',
' renderList: function() {',
' return this.props.items.map(function(item) {',
' return <ListItem item={item} key={item.id} />;',
' });',
' },',
'',
' render: function() {',
' return <ul className="List">',
' this.renderList()',
' </ul>',
' }',
'});'
]
},
{
unchanged:
[
'var Mist = React.createClass({',
' renderList: function() {',
' return this.props.items.map(function(item) {',
' return <ListItem item={return <tag>{item}</tag>} key={item.id} />;',
' });',
' }',
'});',
]
},
{
unchanged:
[
'// JSX',
'var box = <Box>',
' {shouldShowAnswer(user) ?',
' <Answer value={false}>no</Answer> : <Box.Comment>',
' Text Content',
' </Box.Comment>}',
' </Box>;',
'var a = function() {',
' return <tsdf>asdf</tsdf>;',
'};',
'',
'var HelloMessage = React.createClass({',
' render: function() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'});',
'React.render(<HelloMessage name="John" />, mountNode);',
]
},
{
unchanged:
[
'var Timer = React.createClass({',
' getInitialState: function() {',
' return {',
' secondsElapsed: 0',
' };',
' },',
' tick: function() {',
' this.setState({',
' secondsElapsed: this.state.secondsElapsed + 1',
' });',
' },',
' componentDidMount: function() {',
' this.interval = setInterval(this.tick, 1000);',
' },',
' componentWillUnmount: function() {',
' clearInterval(this.interval);',
' },',
' render: function() {',
' return (',
' <div>Seconds Elapsed: {this.state.secondsElapsed}</div>',
' );',
' }',
'});',
'React.render(<Timer />, mountNode);'
]
},
{
unchanged:
[
'var TodoList = React.createClass({',
' render: function() {',
' var createItem = function(itemText) {',
' return <li>{itemText}</li>;',
' };',
' return <ul>{this.props.items.map(createItem)}</ul>;',
' }',
'});'
]
},
{
unchanged:
[
'var TodoApp = React.createClass({',
' getInitialState: function() {',
' return {',
' items: [],',
' text: \\\'\\\'',
' };',
' },',
' onChange: function(e) {',
' this.setState({',
' text: e.target.value',
' });',
' },',
' handleSubmit: function(e) {',
' e.preventDefault();',
' var nextItems = this.state.items.concat([this.state.text]);',
' var nextText = \\\'\\\';',
' this.setState({',
' items: nextItems,',
' text: nextText',
' });',
' },',
' render: function() {',
' return (',
' <div>',
' <h3>TODO</h3>',
' <TodoList items={this.state.items} />',
' <form onSubmit={this.handleSubmit}>',
' <input onChange={this.onChange} value={this.state.text} />',
' <button>{\\\'Add #\\\' + (this.state.items.length + 1)}</button>',
' </form>',
' </div>',
' );',
' }',
'});',
'React.render(<TodoApp />, mountNode);'
]
},
{
input:
[
'var converter = new Showdown.converter();',
'var MarkdownEditor = React.createClass({',
' getInitialState: function() {',
' return {value: \\\'Type some *markdown* here!\\\'};',
' },',
' handleChange: function() {',
' this.setState({value: this.refs.textarea.getDOMNode().value});',
' },',
' render: function() {',
' return (',
' <div className="MarkdownEditor">',
' <h3>Input</h3>',
' <textarea',
' onChange={this.handleChange}',
' ref="textarea"',
' defaultValue={this.state.value} />',
' <h3>Output</h3>',
' <div',
' className="content"',
' dangerouslySetInnerHTML={{',
' __html: converter.makeHtml(this.state.value)',
' }}',
' />',
' </div>',
' );',
' }',
'});',
'React.render(<MarkdownEditor />, mountNode);'
],
output:
[
'var converter = new Showdown.converter();',
'var MarkdownEditor = React.createClass({',
' getInitialState: function() {',
' return {',
' value: \\\'Type some *markdown* here!\\\'',
' };',
' },',
' handleChange: function() {',
' this.setState({',
' value: this.refs.textarea.getDOMNode().value',
' });',
' },',
' render: function() {',
' return (',
' <div className="MarkdownEditor">',
' <h3>Input</h3>',
' <textarea',
' onChange={this.handleChange}',
' ref="textarea"',
' defaultValue={this.state.value} />',
' <h3>Output</h3>',
' <div',
' className="content"',
' dangerouslySetInnerHTML={{',
' __html: converter.makeHtml(this.state.value)',
' }}',
' />',
' </div>',
' );',
' }',
'});',
'React.render(<MarkdownEditor />, mountNode);'
]
},
{
comment: 'JSX - Not quite correct jsx formatting that still works',
input:
[
'var content = (',
' <Nav>',
' {/* child comment, put {} around */}',
' <Person',
' /* multi',
' line',
' comment */',
' //attr="test"',
' name={window.isLoggedIn ? window.name : \\\'\\\'} // end of line comment',
' />',
' </Nav>',
' );',
'var qwer = <DropDown> A dropdown list <Menu> <MenuItem>Do Something</MenuItem> <MenuItem>Do Something Fun!</MenuItem> <MenuItem>Do Something Else</MenuItem> </Menu> </DropDown>;',
'render(dropdown);',
],
output:
[
'var content = (',
' <Nav>',
' {/* child comment, put {} around */}',
' <Person',
' /* multi',
' line',
' comment */',
' //attr="test"',
' name={window.isLoggedIn ? window.name : \\\'\\\'} // end of line comment',
' />',
' </Nav>',
');',
'var qwer = <DropDown> A dropdown list <Menu> <MenuItem>Do Something</MenuItem> <MenuItem>Do Something Fun!</MenuItem> <MenuItem>Do Something Else</MenuItem> </Menu> </DropDown>;',
'render(dropdown);',
]
},
{
comment: [
"Handles messed up tags, as long as it isn't the same name",
"as the root tag. Also handles tags of same name as root tag",
"as long as nesting matches."
],
input_: 'xml=<a x="jn"><c></b></f><a><d jnj="jnn"><f></a ></nj></a>;',
output: 'xml = <a x="jn"><c></b></f><a><d jnj="jnn"><f></a ></nj></a>;' },
{
comment: [
"If xml is not terminated, the remainder of the file is treated",
"as part of the xml-literal (passed through unaltered)"
],
fragment: true,
input_: 'xml=<a></b>\nc<b;',
output: 'xml = <a></b>\nc<b;' },
{
comment: 'Issue #646 = whitespace is allowed in attribute declarations',
unchanged: [
'let a = React.createClass({',
' render() {',
' return (',
' <p className=\\\'a\\\'>',
' <span>c</span>',
' </p>',
' );',
' }',
'});'
]
},
{
unchanged: [
'let a = React.createClass({',
' render() {',
' return (',
' <p className = \\\'b\\\'>',
' <span>c</span>',
' </p>',
' );',
' }',
'});'
]
},
{
unchanged: [
'let a = React.createClass({',
' render() {',
' return (',
' <p className = "c">',
' <span>c</span>',
' </p>',
' );',
' }',
'});'
]
},
{
unchanged: [
'let a = React.createClass({',
' render() {',
' return (',
' <{e} className = {d}>',
' <span>c</span>',
' </{e}>',
' );',
' }',
'});'
]
}
]
},
{
name: "e4x disabled",
description: "",
options: [
{ name: 'e4x', value: false }
],
tests: [
{
input_: 'xml=<a b="c"><d/><e>\n foo</e>x</a>;',
output: 'xml = < a b = "c" > < d / > < e >\n foo < /e>x</a > ;'
}
]
},
{
name: "Multiple braces",
description: "",
template: "^^^ $$$",
options: [],
tests: [
{ input: '{{}/z/}', output: '{\n {}\n /z/\n}' }
]
},
{
name: "jslint and space after anon function",
description: "jslint_happy and space_after_anon_function tests",
matrix: [
{
options: [
{ name: "jslint_happy", value: "true" },
{ name: "space_after_anon_function", value: "true" }
],
f: ' ',
c: ''
}, {
options: [
{ name: "jslint_happy", value: "true" },
{ name: "space_after_anon_function", value: "false" }
],
f: ' ',
c: ''
}, {
options: [
{ name: "jslint_happy", value: "false" },
{ name: "space_after_anon_function", value: "true" }
],
f: ' ',
c: ' '
}, {
options: [
{ name: "jslint_happy", value: "false" },
{ name: "space_after_anon_function", value: "false" }
],
f: '',
c: ' '
}
],
tests: [
{ input_: 'a=typeof(x)',
output: 'a = typeof{{f}}(x)' },
{ input_: 'x();\n\nfunction(){}',
output: 'x();\n\nfunction{{f}}() {}' },
{ input_: 'function () {\n var a, b, c, d, e = [],\n f;\n}',
output: 'function{{f}}() {\n var a, b, c, d, e = [],\n f;\n}' },
{ input_: 'switch(x) {case 0: case 1: a(); break; default: break}',
output: 'switch (x) {\n{{c}}case 0:\n{{c}}case 1:\n{{c}} a();\n{{c}} break;\n{{c}}default:\n{{c}} break\n}' },
{ input: 'switch(x){case -1:break;case !y:break;}',
output: 'switch (x) {\n{{c}}case -1:\n{{c}} break;\n{{c}}case !y:\n{{c}} break;\n}' },
{ comment: 'typical greasemonkey start',
fragment: true,
unchanged: '// comment 2\n(function{{f}}()'
},
{
input_: 'var a2, b2, c2, d2 = 0, c = function() {}, d = \\\'\\\';',
output: 'var a2, b2, c2, d2 = 0,\n c = function{{f}}() {},\n d = \\\'\\\';'
},
{
input_: 'var a2, b2, c2, d2 = 0, c = function() {},\nd = \\\'\\\';',
output: 'var a2, b2, c2, d2 = 0,\n c = function{{f}}() {},\n d = \\\'\\\';'
},
{
input_: 'var o2=$.extend(a);function(){alert(x);}',
output: 'var o2 = $.extend(a);\n\nfunction{{f}}() {\n alert(x);\n}'
},
{ input: 'function*() {\n yield 1;\n}', output: 'function*{{f}}() {\n yield 1;\n}'},
{ unchanged: 'function* x() {\n yield 1;\n}' },
]
}, {
name: "Regression tests",
description: "Ensure specific bugs do not recur",
options: [],
tests: [
{
comment: "Issue 241",
unchanged: [
'obj',
' .last({',
' foo: 1,',
' bar: 2',
' });',
'var test = 1;' ]
},
{
unchanged: [
'obj',
' .last(a, function() {',
' var test;',
' });',
'var test = 1;' ]
},
{
unchanged: [
'obj.first()',
' .second()',
' .last(function(err, response) {',
' console.log(err);',
' });' ]
},
{
comment: "Issue 268 and 275",
unchanged: [
'obj.last(a, function() {',
' var test;',
'});',
'var test = 1;' ]
},
{
unchanged: [
'obj.last(a,',
' function() {',
' var test;',
' });',
'var test = 1;' ]
},
{
input: '(function() {if (!window.FOO) window.FOO || (window.FOO = function() {var b = {bar: "zort"};});})();',
output: [
'(function() {',
' if (!window.FOO) window.FOO || (window.FOO = function() {',
' var b = {',
' bar: "zort"',
' };',
' });',
'})();' ]
},
{
comment: "Issue 281",
unchanged: [
'define(["dojo/_base/declare", "my/Employee", "dijit/form/Button",',
' "dojo/_base/lang", "dojo/Deferred"',
'], function(declare, Employee, Button, lang, Deferred) {',
' return declare(Employee, {',
' constructor: function() {',
' new Button({',
' onClick: lang.hitch(this, function() {',
' new Deferred().then(lang.hitch(this, function() {',
' this.salary * 0.25;',
' }));',
' })',
' });',
' }',
' });',
'});' ]
},
{
unchanged: [
'define(["dojo/_base/declare", "my/Employee", "dijit/form/Button",',
' "dojo/_base/lang", "dojo/Deferred"',
' ],',
' function(declare, Employee, Button, lang, Deferred) {',
' return declare(Employee, {',
' constructor: function() {',
' new Button({',
' onClick: lang.hitch(this, function() {',
' new Deferred().then(lang.hitch(this, function() {',
' this.salary * 0.25;',
' }));',
' })',
' });',
' }',
' });',
' });' ]
},
{
comment: "Issue 459",
unchanged: [
'(function() {',
' return {',
' foo: function() {',
' return "bar";',
' },',
' bar: ["bar"]',
' };',
'}());' ]
},
{
comment: "Issue 505 - strings should end at newline unless continued by backslash",
unchanged: [
'var name = "a;',
'name = "b";' ]
},
{
unchanged: [
'var name = "a;\\\\',
' name = b";' ]
},
{
comment: "Issue 514 - some operators require spaces to distinguish them",
unchanged: 'var c = "_ACTION_TO_NATIVEAPI_" + ++g++ + +new Date;'
},
{
unchanged: 'var c = "_ACTION_TO_NATIVEAPI_" - --g-- - -new Date;'
},
{
comment: "Issue 440 - reserved words can be used as object property names",
unchanged: [
'a = {',
' function: {},',
' "function": {},',
' throw: {},',
' "throw": {},',
' var: {},',
' "var": {},',
' set: {},',
' "set": {},',
' get: {},',
' "get": {},',
' if: {},',
' "if": {},',
' then: {},',
' "then": {},',
' else: {},',
' "else": {},',
' yay: {}',
'};' ]
},
{
comment: "Issue 331 - if-else with braces edge case",
input: 'if(x){a();}else{b();}if(y){c();}',
output: [
'if (x) {',
' a();',
'} else {',
' b();',
'}',
'if (y) {',
' c();',
'}' ]
},
{
comment: "Issue 485 - ensure function declarations behave the same in arrays as elsewhere",
unchanged: [
'var v = ["a",',
' function() {',
' return;',
' }, {',
' id: 1',
' }',
'];' ]
},
{
unchanged: [
'var v = ["a", function() {',
' return;',
'}, {',
' id: 1',
'}];' ]
},
{
comment: "Issue 382 - initial totally cursory support for es6 module export",
unchanged: [
'module "Even" {',
' import odd from "Odd";',
' export function sum(x, y) {',
' return x + y;',
' }',
' export var pi = 3.141593;',
' export default moduleName;',
'}' ]
},
{
unchanged: [
'module "Even" {',
' export default function div(x, y) {}',
'}' ]
},
{
comment: "Issue 508",
unchanged: 'set["name"]'
},
{
unchanged: 'get["name"]'
},
{
fragmeent: true,
unchanged: [
'a = {',
' set b(x) {},',
' c: 1,',
' d: function() {}',
'};' ]
},
{
fragmeent: true,
unchanged: [
'a = {',
' get b() {',
' retun 0;',
' },',
' c: 1,',
' d: function() {}',
'};' ]
},
{
comment: "Issue 298 - do not under indent if/while/for condtionals experesions",
unchanged: [
'\\\'use strict\\\';',
'if ([].some(function() {',
' return false;',
' })) {',
' console.log("hello");',
'}' ]
},
{
comment: "Issue 298 - do not under indent if/while/for condtionals experesions",
unchanged: [
'\\\'use strict\\\';',
'if ([].some(function() {',
' return false;',
' })) {',
' console.log("hello");',
'}' ]
},
{
comment: "Issue 552 - Typescript? Okay... we didn't break it before, so try not to break it now.",
unchanged: [
'class Test {',
' blah: string[];',
' foo(): number {',
' return 0;',
' }',
' bar(): number {',
' return 0;',
' }',
'}' ]
},
{
unchanged: [
'interface Test {',
' blah: string[];',
' foo(): number {',
' return 0;',
' }',
' bar(): number {',
' return 0;',
' }',
'}' ]
},
{
comment: "Issue 583 - Functions with comments after them should still indent correctly.",
unchanged: [
'function exit(code) {',
' setTimeout(function() {',
' phantom.exit(code);',
' }, 0);',
' phantom.onError = function() {};',
'}',
'// Comment' ]
},
]
},
// =======================================================

@@ -109,25 +868,25 @@ // New tests groups should be added above this line.

tests: [
{ input: '' },
{ fragment: ' return .5'},
{ fragment: ' return .5;\n a();' },
{ fragment: ' return .5;\n a();' },
{ fragment: ' return .5;\n a();' },
{ fragment: ' < div'},
{ unchanged: '' },
{ fragment: true, unchanged: ' return .5'},
{ fragment: true, unchanged: ' return .5;\n a();' },
{ fragment: true, unchanged: ' return .5;\n a();' },
{ fragment: true, unchanged: ' return .5;\n a();' },
{ fragment: true, unchanged: ' < div'},
{ input: 'a = 1', output: 'a = 1' },
{ input: 'a=1', output: 'a = 1' },
{ input: '(3) / 2' },
{ unchanged: '(3) / 2' },
{ input: '["a", "b"].join("")' },
{ input: 'a();\n\nb();', output: 'a();\n\nb();' },
{ unchanged: 'a();\n\nb();' },
{ input: 'var a = 1 var b = 2', output: 'var a = 1\nvar b = 2' },
{ input: 'var a=1, b=c[d], e=6;', output: 'var a = 1,\n b = c[d],\n e = 6;' },
{ input: 'var a,\n b,\n c;' },
{ unchanged: 'var a,\n b,\n c;' },
{ input: 'let a = 1 let b = 2', output: 'let a = 1\nlet b = 2' },
{ input: 'let a=1, b=c[d], e=6;', output: 'let a = 1,\n b = c[d],\n e = 6;' },
{ input: 'let a,\n b,\n c;' },
{ unchanged: 'let a,\n b,\n c;' },
{ input: 'const a = 1 const b = 2', output: 'const a = 1\nconst b = 2' },
{ input: 'const a=1, b=c[d], e=6;', output: 'const a = 1,\n b = c[d],\n e = 6;' },
{ input: 'const a,\n b,\n c;' },
{ input: 'a = " 12345 "' },
{ input: "a = \\' 12345 \\'" },
{ input: 'if (a == 1) b = 2;', output: 'if (a == 1) b = 2;' },
{ unchanged: 'const a,\n b,\n c;' },
{ unchanged: 'a = " 12345 "' },
{ unchanged: "a = \\' 12345 \\'" },
{ unchanged: 'if (a == 1) b = 2;' },
{ input: 'if(1){2}else{3}', output: 'if (1) {\n 2\n} else {\n 3\n}' },

@@ -137,15 +896,15 @@ { input: 'if(1||2);', output: 'if (1 || 2);' },

{ input: 'var a = 1 if (2) 3;', output: 'var a = 1\nif (2) 3;' },
{ input: 'a = a + 1' },
{ input: 'a = a == 1' },
{ unchanged: 'a = a + 1' },
{ unchanged: 'a = a == 1' },
{ input: '/12345[^678]*9+/.match(a)' },
{ input: 'a /= 5' },
{ input: 'a = 0.5 * 3' },
{ input: 'a *= 10.55' },
{ input: 'a < .5' },
{ input: 'a <= .5' },
{ unchanged: 'a /= 5' },
{ unchanged: 'a = 0.5 * 3' },
{ unchanged: 'a *= 10.55' },
{ unchanged: 'a < .5' },
{ unchanged: 'a <= .5' },
{ input: 'a<.5', output: 'a < .5' },
{ input: 'a<=.5', output: 'a <= .5' },
{ input: 'a = 0xff;' },
{ unchanged: 'a = 0xff;' },
{ input: 'a=0xff+4', output: 'a = 0xff + 4' },
{ input: 'a = [1, 2, 3, 4]' },
{ unchanged: 'a = [1, 2, 3, 4]' },
{ input: 'F*(g/=f)*g+b', output: 'F * (g /= f) * g + b' },

@@ -169,5 +928,5 @@ { input: 'a.b({c:d})', output: 'a.b({\n c: d\n})' },

{ input: 'a;/* comment */b;', output: "a; /* comment */\nb;" },
{ fragment: 'a;/*\ncomment\n*/b;', output: "a;\n/*\ncomment\n*/\nb;", comment: "simple comments don't get touched at all" },
{ fragment: true, input: 'a;/*\ncomment\n*/b;', output: "a;\n/*\ncomment\n*/\nb;", comment: "simple comments don't get touched at all" },
{ input: 'a;/**\n* javadoc\n*/b;', output: "a;\n/**\n * javadoc\n */\nb;" },
{ fragment: 'a;/**\n\nno javadoc\n*/b;', output: "a;\n/**\n\nno javadoc\n*/\nb;" },
{ fragment: true, input: 'a;/**\n\nno javadoc\n*/b;', output: "a;\n/**\n\nno javadoc\n*/\nb;" },
{ input: 'a;/*\n* javadoc\n*/b;', output: "a;\n/*\n * javadoc\n */\nb;", comment: 'comment blocks detected and reindented even w/o javadoc starter' },

@@ -179,3 +938,3 @@ { input: 'if(a)break;', output: "if (a) break;" },

{ input: 'for(var i=0;;)\na', output: 'for (var i = 0;;)\n a' },
{ input: 'a++;', output: 'a++;' },
{ unchanged: 'a++;' },
{ input: 'for(;;i++)a()', output: 'for (;; i++) a()' },

@@ -199,6 +958,6 @@ { input: 'for(;;i++)\na()', output: 'for (;; i++)\n a()' },

{ input: 'if (foo) bar();\nelse break' },
{ input: 'var a, b;' },
{ input: 'var a = new function();' },
{ fragment: 'new function' },
{ input: 'var a, b' },
{ unchanged: 'var a, b;' },
{ unchanged: 'var a = new function();' },
{ fragment: true, unchanged: 'new function' },
{ unchanged: 'var a, b' },
{ input: '{a:1, b:2}', output: "{\n a: 1,\n b: 2\n}" },

@@ -208,24 +967,24 @@ { input: 'a={1:[-1],2:[+1]}', output: 'a = {\n 1: [-1],\n 2: [+1]\n}' },

{ input: 'if (template.user[n] in bk) foo();' },
{ input: 'return 45', output: "return 45" },
{ input: 'return this.prevObject ||\n\n this.constructor(null);' },
{ input: 'If[1]', output: "If[1]" },
{ input: 'Then[1]', output: "Then[1]" },
{ input: 'a = 1e10', output: "a = 1e10" },
{ input: 'a = 1.3e10', output: "a = 1.3e10" },
{ input: 'a = 1.3e-10', output: "a = 1.3e-10" },
{ input: 'a = -1.3e-10', output: "a = -1.3e-10" },
{ input: 'a = 1e-10', output: "a = 1e-10" },
{ input: 'a = e - 10', output: "a = e - 10" },
{ unchanged: 'return 45' },
{ unchanged: 'return this.prevObject ||\n\n this.constructor(null);' },
{ unchanged: 'If[1]' },
{ unchanged: 'Then[1]' },
{ unchanged: 'a = 1e10' },
{ unchanged: 'a = 1.3e10' },
{ unchanged: 'a = 1.3e-10' },
{ unchanged: 'a = -1.3e-10' },
{ unchanged: 'a = 1e-10' },
{ unchanged: 'a = e - 10' },
{ input: 'a = 11-10', output: "a = 11 - 10" },
{ input: "a = 1;// comment", output: "a = 1; // comment" },
{ input: "a = 1; // comment", output: "a = 1; // comment" },
{ unchanged: "a = 1; // comment" },
{ input: "a = 1;\n // comment", output: "a = 1;\n// comment" },
{ input: 'a = [-1, -1, -1]' },
{ unchanged: 'a = [-1, -1, -1]' },
{ comment: 'The exact formatting these should have is open for discussion, but they are at least reasonable',
input: 'a = [ // comment\n -1, -1, -1\n]' },
{ input: 'var a = [ // comment\n -1, -1, -1\n]' },
{ input: 'a = [ // comment\n -1, // comment\n -1, -1\n]' },
{ input: 'var a = [ // comment\n -1, // comment\n -1, -1\n]' },
unchanged: 'a = [ // comment\n -1, -1, -1\n]' },
{ unchanged: 'var a = [ // comment\n -1, -1, -1\n]' },
{ unchanged: 'a = [ // comment\n -1, // comment\n -1, -1\n]' },
{ unchanged: 'var a = [ // comment\n -1, // comment\n -1, -1\n]' },

@@ -243,9 +1002,9 @@ { input: 'o = [{a:b},{c:d}]', output: 'o = [{\n a: b\n}, {\n c: d\n}]' },

{ input: "{}" },
{ input: "{\n\n}" },
{ unchanged: "{}" },
{ unchanged: "{\n\n}" },
{ input: "do { a(); } while ( 1 );", output: "do {\n a();\n} while (1);" },
{ input: "do {} while (1);" },
{ unchanged: "do {} while (1);" },
{ input: "do {\n} while (1);", output: "do {} while (1);" },
{ input: "do {\n\n} while (1);" },
{ input: "var a = x(a, b, c)" },
{ unchanged: "do {\n\n} while (1);" },
{ unchanged: "var a = x(a, b, c)" },
{ input: "delete x if (a) b();", output: "delete x\nif (a) b();" },

@@ -259,4 +1018,4 @@ { input: "delete x[x] if (a) b();", output: "delete x[x]\nif (a) b();" },

{ input: "function x(){return ! a}", output: "function x() {\n return !a\n}" },
{ input: "x => x", output: "x => x" },
{ input: "(x) => x", output: "(x) => x" },
{ unchanged: "x => x" },
{ unchanged: "(x) => x" },
{ input: "x => { x }", output: "x => {\n x\n}" },

@@ -266,9 +1025,9 @@ { input: "(x) => { x }", output: "(x) => {\n x\n}" },

{ comment: 'a common snippet in jQuery plugins',
input: "settings = $.extend({},defaults,settings);",
input_: "settings = $.extend({},defaults,settings);",
output: "settings = $.extend({}, defaults, settings);" },
// reserved words used as property names
{ input: "$http().then().finally().default()", output: "$http().then().finally().default()" },
{ unchanged: "$http().then().finally().default()" },
{ input: "$http()\n.then()\n.finally()\n.default()", output: "$http()\n .then()\n .finally()\n .default()" },
{ input: "$http().when.in.new.catch().throw()", output: "$http().when.in.new.catch().throw()" },
{ unchanged: "$http().when.in.new.catch().throw()" },
{ input: "$http()\n.when\n.in\n.new\n.catch()\n.throw()", output: "$http()\n .when\n .in\n .new\n .catch()\n .throw()" },

@@ -278,11 +1037,11 @@

{ input: "a = \\'a\\'\nb = \\'b\\'" },
{ input: "a = /reg/exp" },
{ input: "a = /reg/" },
{ input: '/abc/.test()' },
{ input: '/abc/i.test()' },
{ unchanged: "a = \\'a\\'\nb = \\'b\\'" },
{ unchanged: "a = /reg/exp" },
{ unchanged: "a = /reg/" },
{ unchanged: '/abc/.test()' },
{ unchanged: '/abc/i.test()' },
{ input: "{/abc/i.test()}", output: "{\n /abc/i.test()\n}" },
{ input: 'var x=(a)/a;', output: 'var x = (a) / a;' },
{ input: 'x != -1', output: 'x != -1' },
{ unchanged: 'x != -1' },

@@ -298,23 +1057,23 @@ { input: 'for (; s-->0;)t', output: 'for (; s-- > 0;) t' },

{ fragment: '"incomplete-string' },
{ fragment: "\\'incomplete-string" },
{ fragment: '/incomplete-regex' },
{ fragment: '`incomplete-template-string' },
{ fragment: true, unchanged: '"incomplete-string' },
{ fragment: true, unchanged: "\\'incomplete-string" },
{ fragment: true, unchanged: '/incomplete-regex' },
{ fragment: true, unchanged: '`incomplete-template-string' },
{ fragment: '{a:1},{a:2}', output: '{\n a: 1\n}, {\n a: 2\n}' },
{ fragment: 'var ary=[{a:1}, {a:2}];', output: 'var ary = [{\n a: 1\n}, {\n a: 2\n}];' },
{ fragment: true, input: '{a:1},{a:2}', output: '{\n a: 1\n}, {\n a: 2\n}' },
{ fragment: true, input: 'var ary=[{a:1}, {a:2}];', output: 'var ary = [{\n a: 1\n}, {\n a: 2\n}];' },
{ comment: 'incomplete', fragment: '{a:#1', output: '{\n a: #1' },
{ comment: 'incomplete', fragment: '{a:#', output: '{\n a: #' },
{ comment: 'incomplete', fragment: true, input: '{a:#1', output: '{\n a: #1' },
{ comment: 'incomplete', fragment: true, input: '{a:#', output: '{\n a: #' },
{ comment: 'incomplete', fragment: '}}}', output: '}\n}\n}' },
{ comment: 'incomplete', fragment: true, input: '}}}', output: '}\n}\n}' },
{ fragment: '<!--\nvoid();\n// -->', output: '<!--\nvoid();\n// -->' },
{ fragment: true, unchanged: '<!--\nvoid();\n// -->' },
{ comment: 'incomplete regexp', fragment: 'a=/regexp', output: 'a = /regexp' },
{ comment: 'incomplete regexp', fragment: true, input: 'a=/regexp', output: 'a = /regexp' },
{ input: '{a:#1=[],b:#1#,c:#999999#}', output: '{\n a: #1=[],\n b: #1#,\n c: #999999#\n}' },
{ input: "a = 1e+2" },
{ input: "a = 1e-2" },
{ unchanged: "a = 1e+2" },
{ unchanged: "a = 1e-2" },
{ input: "do{x()}while(a>1)", output: "do {\n x()\n} while (a > 1)" },

@@ -324,14 +1083,14 @@

{ fragment: "something();(", output: "something();\n(" },
{ fragment: "#!she/bangs, she bangs\nf=1", output: "#!she/bangs, she bangs\n\nf = 1" },
{ fragment: "#!she/bangs, she bangs\n\nf=1", output: "#!she/bangs, she bangs\n\nf = 1" },
{ fragment: "#!she/bangs, she bangs\n\n/* comment */", output: "#!she/bangs, she bangs\n\n/* comment */" },
{ fragment: "#!she/bangs, she bangs\n\n\n/* comment */", output: "#!she/bangs, she bangs\n\n\n/* comment */" },
{ fragment: "#", output: "#" },
{ fragment: "#!", output: "#!" },
{ fragment: true, input: "something();(", output: "something();\n(" },
{ fragment: true, input: "#!she/bangs, she bangs\nf=1", output: "#!she/bangs, she bangs\n\nf = 1" },
{ fragment: true, input: "#!she/bangs, she bangs\n\nf=1", output: "#!she/bangs, she bangs\n\nf = 1" },
{ fragment: true, unchanged: "#!she/bangs, she bangs\n\n/* comment */" },
{ fragment: true, unchanged: "#!she/bangs, she bangs\n\n\n/* comment */" },
{ fragment: true, unchanged: "#" },
{ fragment: true, unchanged: "#!" },
{ input: "function namespace::something()" },
{ fragment: "<!--\nsomething();\n-->", output: "<!--\nsomething();\n-->" },
{ fragment: "<!--\nif(i<0){bla();}\n-->", output: "<!--\nif (i < 0) {\n bla();\n}\n-->" },
{ fragment: true, unchanged: "<!--\nsomething();\n-->" },
{ fragment: true, input: "<!--\nif(i<0){bla();}\n-->", output: "<!--\nif (i < 0) {\n bla();\n}\n-->" },

@@ -346,9 +1105,9 @@ { input: '{foo();--bar;}', output: '{\n foo();\n --bar;\n}' },

{ input: 'if(true)\n--a;', output: 'if (true)\n --a;' },
{ input: 'elem[array]++;' },
{ input: 'elem++ * elem[array]++;' },
{ input: 'elem-- * -elem[array]++;' },
{ input: 'elem-- + elem[array]++;' },
{ input: 'elem-- - elem[array]++;' },
{ input: 'elem-- - -elem[array]++;' },
{ input: 'elem-- - +elem[array]++;' },
{ unchanged: 'elem[array]++;' },
{ unchanged: 'elem++ * elem[array]++;' },
{ unchanged: 'elem-- * -elem[array]++;' },
{ unchanged: 'elem-- + elem[array]++;' },
{ unchanged: 'elem-- - elem[array]++;' },
{ unchanged: 'elem-- - -elem[array]++;' },
{ unchanged: 'elem-- - +elem[array]++;' },

@@ -366,18 +1125,19 @@

{ input: 'a(/a[b\\\\[\\\\]c]d/);b()', output: "a(/a[b\\\\[\\\\]c]d/);\nb()" },
{ comment: 'incomplete char class', fragment: 'a(/a[b\\\\[', output: "a(/a[b\\\\[" },
{ comment: 'incomplete char class', fragment: true, unchanged: 'a(/a[b\\\\[' },
{ comment: 'allow unescaped / in char classes',
input: 'a(/[a/b]/);b()', output: "a(/[a/b]/);\nb()" },
{ input: 'typeof /foo\\\\//;' },
{ input: 'yield /foo\\\\//;' },
{ input: 'throw /foo\\\\//;' },
{ input: 'do /foo\\\\//;' },
{ input: 'return /foo\\\\//;' },
{ input: 'switch (a) {\n case /foo\\\\//:\n b\n}' },
{ input: 'if (a) /foo\\\\//\nelse /foo\\\\//;' },
{ unchanged: 'typeof /foo\\\\//;' },
{ unchanged: 'yield /foo\\\\//;' },
{ unchanged: 'throw /foo\\\\//;' },
{ unchanged: 'do /foo\\\\//;' },
{ unchanged: 'return /foo\\\\//;' },
{ unchanged: 'switch (a) {\n case /foo\\\\//:\n b\n}' },
{ unchanged: 'if (a) /foo\\\\//\nelse /foo\\\\//;' },
{ input: 'if (foo) /regex/.test();' },
{ input: 'result = yield pgClient.query_(queryString);' },
{ unchanged: 'if (foo) /regex/.test();' },
{ unchanged: "for (index in [1, 2, 3]) /^test$/i.test(s)"},
{ unchanged: 'result = yield pgClient.query_(queryString);' },
{ input: 'function foo() {\n return [\n "one",\n "two"\n ];\n}' },
{ unchanged: 'function foo() {\n return [\n "one",\n "two"\n ];\n}' },
{ input: 'a=[[1,2],[4,5],[7,8]]', output: "a = [\n [1, 2],\n [4, 5],\n [7, 8]\n]" },

@@ -401,6 +1161,88 @@ { input: 'a=[[1,2],[4,5],function(){},[7,8]]',

{ input: '{[x()[0]];indent;}', output: '{\n [x()[0]];\n indent;\n}' },
{ input: '/*\n foo trailing space \n * bar trailing space \n**/',
output: '/*\n foo trailing space \n * bar trailing space \n**/'},
{ input: '{\n /*\n foo \n * bar \n */\n}',
output: '{\n /*\n foo \n * bar \n */\n}'}
{ unchanged: '/*\n foo trailing space \n * bar trailing space \n**/'},
{ unchanged: '{\n /*\n foo \n * bar \n */\n}'},
{ unchanged: 'return ++i' },
{ unchanged: 'return !!x' },
{ unchanged: 'return !x' },
{ input: 'return [1,2]', output: 'return [1, 2]' },
{ unchanged: 'return;' },
{ unchanged: 'return\nfunc' },
{ input: 'catch(e)', output: 'catch (e)' },
{ unchanged: 'yield [1, 2]' },
{ input: 'var a=1,b={foo:2,bar:3},{baz:4,wham:5},c=4;',
output: 'var a = 1,\n b = {\n foo: 2,\n bar: 3\n },\n {\n baz: 4,\n wham: 5\n }, c = 4;' },
{ input: 'var a=1,b={foo:2,bar:3},{baz:4,wham:5},\nc=4;',
output: 'var a = 1,\n b = {\n foo: 2,\n bar: 3\n },\n {\n baz: 4,\n wham: 5\n },\n c = 4;' },
{
comment: 'inline comment',
input_: 'function x(/*int*/ start, /*string*/ foo)',
output: 'function x( /*int*/ start, /*string*/ foo)'
},
{ comment: 'javadoc comment',
input: '/**\n* foo\n*/', output: '/**\n * foo\n */' },
{ input: '{\n/**\n* foo\n*/\n}', output: '{\n /**\n * foo\n */\n}' },
{ comment: 'starless block comment',
unchanged: '/**\nfoo\n*/' },
{ unchanged: '/**\nfoo\n**/' },
{ unchanged: '/**\nfoo\nbar\n**/' },
{ unchanged: '/**\nfoo\n\nbar\n**/' },
{ unchanged: '/**\nfoo\n bar\n**/' },
{ input: '{\n/**\nfoo\n*/\n}', output: '{\n /**\n foo\n */\n}' },
{ input: '{\n/**\nfoo\n**/\n}', output: '{\n /**\n foo\n **/\n}' },
{ input: '{\n/**\nfoo\nbar\n**/\n}', output: '{\n /**\n foo\n bar\n **/\n}' },
{ input: '{\n/**\nfoo\n\nbar\n**/\n}', output: '{\n /**\n foo\n\n bar\n **/\n}' },
{ input: '{\n/**\nfoo\n bar\n**/\n}', output: '{\n /**\n foo\n bar\n **/\n}' },
{ unchanged: '{\n /**\n foo\nbar\n **/\n}' },
{ input: 'var a,b,c=1,d,e,f=2;', output: 'var a, b, c = 1,\n d, e, f = 2;' },
{ input: 'var a,b,c=[],d,e,f=2;', output: 'var a, b, c = [],\n d, e, f = 2;' },
{ unchanged: 'function() {\n var a, b, c, d, e = [],\n f;\n}' },
{ input: 'do/regexp/;\nwhile(1);', output: 'do /regexp/;\nwhile (1);' },
{ input: 'var a = a,\na;\nb = {\nb\n}', output: 'var a = a,\n a;\nb = {\n b\n}' },
{ unchanged: 'var a = a,\n /* c */\n b;' },
{ unchanged: 'var a = a,\n // c\n b;' },
{ comment: 'weird element referencing',
unchanged: 'foo.("bar");' },
{ unchanged: 'if (a) a()\nelse b()\nnewline()' },
{ unchanged: 'if (a) a()\nnewline()' },
{ input: 'a=typeof(x)', output: 'a = typeof(x)' },
{ unchanged: 'var a = function() {\n return null;\n },\n b = false;' },
{ unchanged: 'var a = function() {\n func1()\n}' },
{ unchanged: 'var a = function() {\n func1()\n}\nvar b = function() {\n func2()\n}' },
{ comment: 'code with and without semicolons',
input_: 'var whatever = require("whatever");\nfunction() {\n a = 6;\n}',
output: 'var whatever = require("whatever");\n\nfunction() {\n a = 6;\n}' },
{ input: 'var whatever = require("whatever")\nfunction() {\n a = 6\n}',
output: 'var whatever = require("whatever")\n\nfunction() {\n a = 6\n}' },
{ input: '{"x":[{"a":1,"b":3},\n7,8,8,8,8,{"b":99},{"a":11}]}', output: '{\n "x": [{\n "a": 1,\n "b": 3\n },\n 7, 8, 8, 8, 8, {\n "b": 99\n }, {\n "a": 11\n }\n ]\n}' },
{ input: '{"x":[{"a":1,"b":3},7,8,8,8,8,{"b":99},{"a":11}]}', output: '{\n "x": [{\n "a": 1,\n "b": 3\n }, 7, 8, 8, 8, 8, {\n "b": 99\n }, {\n "a": 11\n }]\n}' },
{ input: '{"1":{"1a":"1b"},"2"}', output: '{\n "1": {\n "1a": "1b"\n },\n "2"\n}' },
{ input: '{a:{a:b},c}', output: '{\n a: {\n a: b\n },\n c\n}' },
{ input: '{[y[a]];keep_indent;}', output: '{\n [y[a]];\n keep_indent;\n}' },
{ input: 'if (x) {y} else { if (x) {y}}', output: 'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}' },
{ unchanged: 'if (foo) one()\ntwo()\nthree()' },
{ unchanged: 'if (1 + foo() && bar(baz()) / 2) one()\ntwo()\nthree()' },
{ unchanged: 'if (1 + foo() && bar(baz()) / 2) one();\ntwo();\nthree();' },
{ input: 'var a=1,b={bang:2},c=3;', output: 'var a = 1,\n b = {\n bang: 2\n },\n c = 3;' },
{ input: 'var a={bing:1},b=2,c=3;', output: 'var a = {\n bing: 1\n },\n b = 2,\n c = 3;' },
],

@@ -407,0 +1249,0 @@ }],

@@ -37,3 +37,18 @@ #!/usr/bin/env node

function isStringOrArray(val) {
return typeof val === 'string' || val instanceof Array;
}
function getTestString(val) {
if (typeof val === 'string') {
return "'" + val.replace(/\n/g,'\\n').replace(/\t/g,'\\t') + "'";
} else if (val instanceof Array) {
return "'" + val.join("\\n' +\n '").replace(/\t/g,'\\t') + "'";
} else {
return null;
}
}
function set_formatters (data, test_method, comment_mark) {
// utility mustache functions

@@ -60,49 +75,99 @@ data.matrix_context_string = function() {

return function(text, render) {
var method_text = test_method;
if (this.fragment) {
method_text = 'test_fragment';
}
// text is ignored for this.
var comment = "";
if (typeof this.comment === "string") {
comment = "\n " + comment_mark + this.comment + '\n ';
var comment = '';
if (typeof this.comment === 'string') {
comment = '\n ' + comment_mark + this.comment + '\n ';
} else if (this.comment instanceof Array) {
comment = "\n " + comment_mark + this.comment.join('\n ' + comment_mark);
comment = '\n ' + comment_mark + this.comment.join('\n ' + comment_mark) + '\n ';
}
var input = "";
var before_input = "";
if (typeof this.input === "string") {
before_input = test_method + "(";
input = "'" + this.input.replace(/\n/g,'\\n').replace(/\t/g,'\\t') + "'";
} else if (this.input instanceof Array) {
before_input = test_method + "(\n ";
input = "'" + this.input.join("\\n' +\n '").replace(/\t/g,'\\t') + "'";
var input = null;
var before_input = method_text + '(';
var before_output = ', ';
} else if (typeof this.fragment === "string") {
before_input = "test_fragment(";
input = "'" + this.fragment.replace(/\n/g,'\\n').replace(/\t/g,'\\t') + "'";
} else if (this.fragment instanceof Array) {
before_input = "test_fragment(\n ";
input = "'" + this.fragment.join("\\n' +\n '").replace(/\t/g,'\\t') + "'";
function set_input(field, opt_newline) {
if (input !== null && isStringOrArray(field)) {
throw "Only one test input field allowed (input, input_, or unchanged): " + input;
}
if (typeof field === 'string' && !opt_newline) {
input = getTestString(field);
} else if (field instanceof Array || (typeof field === 'string' && opt_newline)) {
before_input = method_text + '(\n ';
before_output = ',\n ';
input = getTestString(field);
}
}
input = render(input);
var output = "";
var before_output = "";
if (typeof this.output === "string") {
before_output = ', ';
output = "'" + this.output.replace(/\n/g,'\\n').replace(/\t/g,'\\t') + "'";
set_input(this.input);
// allow underscore for formatting alignment with "output"
set_input(this.input_, true);
// use "unchanged" instead of "input" if there is no output
set_input(this.unchanged);
if(isStringOrArray(this.unchanged) && isStringOrArray(this.output)) {
throw "Cannot specify 'output' with 'unchanged' test input: " + input;
}
if (input === null) {
throw "Missing test input field (input, input_, or unchanged).";
}
var output = null;
if (typeof this.output === 'string') {
output = getTestString(this.output);
} else if (this.output instanceof Array) {
before_output = ',\n ';
output = "'" + this.output.join("\\n' +\n '").replace(/\t/g,'\\t') + "'";
before_input = method_text + '(\n ';
before_output = ',\n ';
output = getTestString(this.output);
} else {
before_output = '';
}
if (input === output) {
throw "Test strings are identical. Omit 'output' and use 'unchanged': " + input;
}
if(output && output.indexOf('<%') !== -1) {
mustache.tags = ['<%', '%>'];
}
input = render(input);
output = render(output);
if(output && output.indexOf('<%') !== -1) {
mustache.tags = ['{{', '}}'];
}
if (output === input) {
output = "";
before_output = "";
before_output = '';
output = '';
}
return comment + before_input + input + before_output + output + ")";
return comment + before_input + input + before_output + output + ')';
}
};
data.set_mustache_tags = function() {
return function(text, render) {
if(this.template) {
mustache.tags = this.template.split(' ');
}
return '';
}
};
data.unset_mustache_tags = function() {
return function(text, render) {
if(this.template) {
mustache.tags = ['{{', '}}'];
}
return '';
}
};
}
generate_tests();

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc