├── test
├── compare
│ ├── default
│ │ ├── empty_file-in.js
│ │ ├── empty_file-out.js
│ │ ├── inplace-out.js
│ │ ├── inplace-in.js
│ │ ├── array_pattern-out.js
│ │ ├── array_pattern-in.js
│ │ ├── throw_statement-in.js
│ │ ├── object_pattern-out.js
│ │ ├── throw_statement-out.js
│ │ ├── block_statement-in.js
│ │ ├── jsx-in.js
│ │ ├── jsx-out.js
│ │ ├── object_pattern-in.js
│ │ ├── block_statement-out.js
│ │ ├── comma_operator-in.js
│ │ ├── README.md
│ │ ├── comma_operator-out.js
│ │ ├── do_while_statement-in.js
│ │ ├── member_expression-out.js
│ │ ├── new_expression-out.js
│ │ ├── new_expression-in.js
│ │ ├── member_expression-in.js
│ │ ├── iife-in.js
│ │ ├── do_while_statement-out.js
│ │ ├── flow-in.js
│ │ ├── flow-out.js
│ │ ├── iife-out.js
│ │ ├── while_statement-out.js
│ │ ├── binary_expression-in.js
│ │ ├── binary_expression-out.js
│ │ ├── while_statement-in.js
│ │ ├── for_statement-in.js
│ │ ├── unary_expression-in.js
│ │ ├── unary_expression-out.js
│ │ ├── for_statement-out.js
│ │ ├── logical_expression-in.js
│ │ ├── logical_expression-out.js
│ │ ├── for_of_statement-out.js
│ │ ├── for_in_statement-out.js
│ │ ├── for_of_statement-in.js
│ │ ├── for_in_statement-in.js
│ │ ├── arrow_function_expression-out.js
│ │ ├── conditional_expression-in.js
│ │ ├── conditional_expression-out.js
│ │ ├── array_expression-in.js
│ │ ├── array_expression-out.js
│ │ ├── arrow_function_expression-in.js
│ │ ├── comments-out.js
│ │ ├── class_declaration-in.js
│ │ ├── class_declaration-out.js
│ │ ├── class_expression-in.js
│ │ ├── class_expression-out.js
│ │ ├── module-out.js
│ │ ├── assignment_expression-in.js
│ │ ├── assignment_expression-out.js
│ │ ├── comments-in.js
│ │ ├── module-in.js
│ │ ├── switch_statement-out.js
│ │ ├── switch_statement-in.js
│ │ ├── function_expression-out.js
│ │ ├── var-out.js
│ │ ├── var-in.js
│ │ ├── function_expression-in.js
│ │ ├── try_statement-out.js
│ │ └── try_statement-in.js
│ ├── error
│ │ ├── invalid-1.js
│ │ ├── invalid.json
│ │ └── invalid-2.js
│ ├── rc
│ │ ├── top-in.js
│ │ ├── top-out.js
│ │ ├── package
│ │ │ ├── package-in.js
│ │ │ ├── rc
│ │ │ │ ├── nested-in.js
│ │ │ │ ├── nested-out.js
│ │ │ │ ├── .esformatter
│ │ │ │ └── function.json
│ │ │ ├── package-out.js
│ │ │ ├── nested
│ │ │ │ ├── .esformatter
│ │ │ │ ├── pkg_nested-in.js
│ │ │ │ ├── indent.json
│ │ │ │ ├── pkg_nested-out.js
│ │ │ │ └── package.json
│ │ │ └── package.json
│ │ ├── nested
│ │ │ ├── .esformatter
│ │ │ ├── nested-in.js
│ │ │ └── nested-out.js
│ │ └── .esformatter
│ ├── custom
│ │ ├── commented_config-in.js
│ │ ├── object_pattern-in.js
│ │ ├── basic_function_indent-in.js
│ │ ├── array_bug-in.js
│ │ ├── array_bug-out.js
│ │ ├── basic_function_indent_2-in.js
│ │ ├── commented_config-out.js
│ │ ├── basic_function_indent-out.js
│ │ ├── object_pattern-out.js
│ │ ├── basic_function_indent_2-out.js
│ │ ├── assignment_expression-out.js
│ │ ├── binary_expression-config.json
│ │ ├── assignment_expression-in.js
│ │ ├── member_expression-in.js
│ │ ├── member_expression-out.js
│ │ ├── object_expression-2-in.js
│ │ ├── binary_expression-in.js
│ │ ├── linebreak-before-eof-in.js
│ │ ├── linebreak-before-eof-out.js
│ │ ├── linebreak-before-eof-2-in.js
│ │ ├── top-level-indent-exception-config.json
│ │ ├── variable_declaration-in.js
│ │ ├── multi-indent-config.json
│ │ ├── binary_expression-out.js
│ │ ├── linebreak-before-eof-2-out.js
│ │ ├── one-line-var-declaration-out.js
│ │ ├── one-line-var-declaration-config.json
│ │ ├── one-line-var-declaration-in.js
│ │ ├── linebreak-before-eof-2-config.json
│ │ ├── linebreak-before-eof-config.json
│ │ ├── object_expression-config.json
│ │ ├── object_expression-2-out.js
│ │ ├── function_expression_bug-in.js
│ │ ├── function_expression_bug-out.js
│ │ ├── variable_declaration-config.json
│ │ ├── variable_declaration-out.js
│ │ ├── comment_group-config.json
│ │ ├── multi-indent-in.js
│ │ ├── argumentlist-config.json
│ │ ├── array_bug-config.json
│ │ ├── object_pattern-2-out.js
│ │ ├── negative_indent-config.json
│ │ ├── new_expression-config.json
│ │ ├── for_statement-config.json
│ │ ├── iife-in.js
│ │ ├── arrow_function_expression-out.js
│ │ ├── arrow_function_expression-in.js
│ │ ├── conditional_expression-out.js
│ │ ├── conditional_expression-in.js
│ │ ├── align_comments-config.json
│ │ ├── iife-out.js
│ │ ├── member_expression-config.json
│ │ ├── object_pattern-2-in.js
│ │ ├── arrow_function_expression-config.json
│ │ ├── class-in.js
│ │ ├── expression_parentheses-config.json
│ │ ├── class-out.js
│ │ ├── multi-indent-out.js
│ │ ├── unary_expression-config.json
│ │ ├── iife-config.json
│ │ ├── negative_indent-in.js
│ │ ├── function_expression_bug-config.json
│ │ ├── argumentlist-out.js
│ │ ├── class_declaration-config.json
│ │ ├── negative_indent-out.js
│ │ ├── object_expression-2-config.json
│ │ ├── if_statement_spacy-config.json
│ │ ├── argumentlist-in.js
│ │ ├── README.md
│ │ ├── for_in_statement-config.json
│ │ ├── for_of_statement-config.json
│ │ ├── new_expression-in.js
│ │ ├── basic_function_indent_2-config.json
│ │ ├── new_expression-out.js
│ │ ├── object_pattern-config.json
│ │ ├── object_expression-3-in.js
│ │ ├── align_comments-in.js
│ │ ├── align_comments-out.js
│ │ ├── array_expression-in.js
│ │ ├── object_expression-3-out.js
│ │ ├── array_expression-out.js
│ │ ├── conditional_expression-config.json
│ │ ├── object_pattern-2-config.json
│ │ ├── class-config.json
│ │ ├── array_expression-2-in.js
│ │ ├── assignment_expression-config.json
│ │ ├── if_statement_spacy-in.js
│ │ ├── for_statement-in.js
│ │ ├── call_expression-config.json
│ │ ├── if_statement_spacy-out.js
│ │ ├── call_expression-in.js
│ │ ├── call_expression-out.js
│ │ ├── for_statement-out.js
│ │ ├── commented_config-config.json
│ │ ├── object_expression-3-config.json
│ │ ├── function-expression-config.json
│ │ ├── switch_statement-config.json
│ │ ├── for_in_statement-in.js
│ │ ├── for_of_statement-in.js
│ │ ├── comment_group-in.js
│ │ ├── for_in_statement-out.js
│ │ ├── for_of_statement-out.js
│ │ ├── switch_statement-out.js
│ │ ├── comment_group-out.js
│ │ ├── unary_expression-in.js
│ │ ├── array_expression-2-config.json
│ │ ├── unary_expression-out.js
│ │ ├── top-level-indent-exception-out.js
│ │ ├── array_expression-config.json
│ │ ├── object_expression-in.js
│ │ ├── module-config.json
│ │ ├── switch_statement-in.js
│ │ ├── if_statement-config.json
│ │ ├── top-level-indent-exception-in.js
│ │ ├── expression_parentheses-in.js
│ │ ├── basic_function_indent-config.json
│ │ ├── expression_parentheses-out.js
│ │ ├── object_expression-out.js
│ │ ├── if_statement-in.js
│ │ ├── if_statement-out.js
│ │ ├── array_expression-2-out.js
│ │ ├── class_declaration-in.js
│ │ ├── class_declaration-out.js
│ │ ├── try_statement-config.json
│ │ ├── module-in.js
│ │ ├── module-out.js
│ │ ├── try_statement-in.js
│ │ └── try_statement-out.js
│ ├── fake-preset
│ │ ├── 2-in.js
│ │ ├── 2-out.js
│ │ └── package.json
│ ├── .esformatter
│ └── jquery
│ │ ├── spacing-in.js
│ │ └── spacing-out.js
├── bin
│ ├── config.json
│ └── node_modules
│ │ └── esformatter
│ │ ├── lib
│ │ ├── fake.js
│ │ └── cli.js
│ │ └── package.json
├── pipe
│ ├── bin
│ │ ├── esformatter-pipe-test-1
│ │ └── esformatter-pipe-test-2
│ └── package.json
├── plugin
│ ├── package.json
│ └── esformatter-test-plugin.js
├── preset
│ ├── fake1
│ │ ├── esformatter-preset-fake-1.js
│ │ └── package.json
│ └── fake2
│ │ ├── esformatter-preset-fake-2.js
│ │ └── package.json
├── transform.spec.js
├── runner.js
├── pipe.spec.js
└── helpers.js
├── lib
├── hooks
│ ├── ExportSpecifier.js
│ ├── ThrowStatement.js
│ ├── ExportDefaultDeclaration.js
│ ├── UpdateExpression.js
│ ├── SequenceExpression.js
│ ├── ExportAllDeclaration.js
│ ├── ObjectPattern.js
│ ├── BinaryExpression.js
│ ├── ArrayPattern.js
│ ├── ExportNamedDeclaration.js
│ ├── BlockStatement.js
│ ├── SwitchStatement.js
│ ├── ClassDeclarationAndExpression.js
│ ├── CatchClause.js
│ ├── DoWhileStatement.js
│ ├── LogicalExpression.js
│ ├── ImportDeclaration.js
│ ├── AssignmentExpression.js
│ ├── MethodDefinition.js
│ ├── FunctionDeclaration.js
│ ├── MemberExpression.js
│ ├── ConditionalExpression.js
│ ├── TryStatement.js
│ ├── WhileStatement.js
│ ├── UnaryExpression.js
│ ├── ForStatement.js
│ ├── ForInStatement.js
│ ├── ForOfStatement.js
│ ├── ImportSpecifier.js
│ ├── SwitchCase.js
│ ├── ArrayExpression.js
│ ├── ArrowFunctionExpression.js
│ ├── ReturnStatement.js
│ ├── Params.js
│ └── FunctionExpression.js
├── helpers.js
├── preset
│ ├── default.js
│ ├── default-indent.js
│ └── jquery.js
├── limit.js
├── esformatter.js
├── diff.js
└── format.js
├── .gitignore
├── .travis.yml
├── doc
├── cli.txt
└── presets.md
├── .editorconfig
├── LICENSE.md
└── bin
└── esformatter
/test/compare/default/empty_file-in.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/compare/default/empty_file-out.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/compare/error/invalid-1.js:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | &foo
5 |
--------------------------------------------------------------------------------
/test/compare/default/inplace-out.js:
--------------------------------------------------------------------------------
1 |
2 | var a = 40;
3 |
4 |
--------------------------------------------------------------------------------
/test/compare/error/invalid.json:
--------------------------------------------------------------------------------
1 | {
2 | lorem: ipsum
3 | }
4 |
--------------------------------------------------------------------------------
/test/compare/rc/top-in.js:
--------------------------------------------------------------------------------
1 | function foo(){
2 | bar();
3 | }
4 |
--------------------------------------------------------------------------------
/test/compare/custom/commented_config-in.js:
--------------------------------------------------------------------------------
1 | if(true){doStuff()}
2 |
--------------------------------------------------------------------------------
/test/compare/rc/top-out.js:
--------------------------------------------------------------------------------
1 | function foo(){
2 | bar();
3 | }
4 |
--------------------------------------------------------------------------------
/test/bin/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "preset": "default",
3 | "root": true
4 | }
5 |
--------------------------------------------------------------------------------
/test/compare/custom/object_pattern-in.js:
--------------------------------------------------------------------------------
1 | var {foo,bar,ipsum} = object;
2 |
--------------------------------------------------------------------------------
/test/compare/rc/package/package-in.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | bar();
3 | }
4 |
--------------------------------------------------------------------------------
/test/compare/custom/basic_function_indent-in.js:
--------------------------------------------------------------------------------
1 | function foo(x,y){return x+y;}
2 |
--------------------------------------------------------------------------------
/test/compare/rc/package/rc/nested-in.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | lorem();
3 | }
4 |
--------------------------------------------------------------------------------
/test/compare/custom/array_bug-in.js:
--------------------------------------------------------------------------------
1 | [];
2 |
3 | this.element;
4 |
5 | parts = [];
6 |
--------------------------------------------------------------------------------
/test/compare/custom/array_bug-out.js:
--------------------------------------------------------------------------------
1 | [];
2 |
3 | this.element;
4 |
5 | parts = [];
6 |
--------------------------------------------------------------------------------
/test/compare/custom/basic_function_indent_2-in.js:
--------------------------------------------------------------------------------
1 | function foo(x,y){return x+y;}
2 |
--------------------------------------------------------------------------------
/test/compare/custom/commented_config-out.js:
--------------------------------------------------------------------------------
1 | if(true)
2 | {
3 | doStuff()
4 | }
5 |
--------------------------------------------------------------------------------
/test/compare/rc/package/package-out.js:
--------------------------------------------------------------------------------
1 | function foo()
2 | {
3 | bar();
4 | }
5 |
--------------------------------------------------------------------------------
/test/compare/rc/package/rc/nested-out.js:
--------------------------------------------------------------------------------
1 | function foo () {
2 | lorem();
3 | }
4 |
--------------------------------------------------------------------------------
/test/compare/custom/basic_function_indent-out.js:
--------------------------------------------------------------------------------
1 | function foo ( x,y ){ return x + y; }
2 |
--------------------------------------------------------------------------------
/test/compare/rc/nested/.esformatter:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "value": "\t"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/lib/hooks/ExportSpecifier.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = require('./ImportSpecifier');
4 |
--------------------------------------------------------------------------------
/test/compare/custom/object_pattern-out.js:
--------------------------------------------------------------------------------
1 | var {
2 | foo ,
3 | bar ,
4 | ipsum
5 | } = object;
6 |
--------------------------------------------------------------------------------
/test/compare/custom/basic_function_indent_2-out.js:
--------------------------------------------------------------------------------
1 | function foo(x, y)
2 | {
3 | return x + y;
4 | }
5 |
--------------------------------------------------------------------------------
/test/compare/default/inplace-in.js:
--------------------------------------------------------------------------------
1 | var a =
2 |
3 | 40
4 |
5 | ;
6 |
7 |
--------------------------------------------------------------------------------
/test/compare/rc/package/nested/.esformatter:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "./indent.json"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/test/compare/fake-preset/2-in.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | return [
3 | true,
4 | false
5 | ];
6 | }
7 |
--------------------------------------------------------------------------------
/test/compare/custom/assignment_expression-out.js:
--------------------------------------------------------------------------------
1 | // keep same line
2 | foo=bar; lorem=123
3 | dolor="amet"
4 |
5 |
--------------------------------------------------------------------------------
/test/compare/custom/binary_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "BinaryExpression": 1
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/bin/node_modules/esformatter/lib/fake.js:
--------------------------------------------------------------------------------
1 | throw new Error('this is just a fake file and should not be executed');
2 |
--------------------------------------------------------------------------------
/test/compare/custom/assignment_expression-in.js:
--------------------------------------------------------------------------------
1 | // keep same line
2 | foo=bar; lorem =123
3 | dolor = "amet"
4 |
5 |
--------------------------------------------------------------------------------
/test/compare/custom/member_expression-in.js:
--------------------------------------------------------------------------------
1 | obj[prop];
2 |
3 | // also a MemberExpression
4 | proxy.guid = fn.guid;
5 |
--------------------------------------------------------------------------------
/test/compare/custom/member_expression-out.js:
--------------------------------------------------------------------------------
1 | obj[ prop ];
2 |
3 | // also a MemberExpression
4 | proxy.guid = fn.guid;
5 |
--------------------------------------------------------------------------------
/test/compare/rc/nested/nested-in.js:
--------------------------------------------------------------------------------
1 | // it should merge the config files if nested
2 | function foo() {
3 | bar();
4 | }
5 |
--------------------------------------------------------------------------------
/test/compare/rc/nested/nested-out.js:
--------------------------------------------------------------------------------
1 | // it should merge the config files if nested
2 | function foo(){
3 | bar();
4 | }
5 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-2-in.js:
--------------------------------------------------------------------------------
1 | var a = {
2 | foo:123,
3 | "bar":"baz"
4 | , 'lorem': new Date()
5 | }
6 |
--------------------------------------------------------------------------------
/test/compare/fake-preset/2-out.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | return [
3 | false,
4 | false
5 | ];
6 | }
7 |
--------------------------------------------------------------------------------
/test/compare/custom/binary_expression-in.js:
--------------------------------------------------------------------------------
1 | bar(
2 | 123 /
3 | 456 *
4 | 0.75 ^
5 | 255 |
6 | 98 <<
7 | 1 -
8 | 42
9 | );
10 |
--------------------------------------------------------------------------------
/test/compare/custom/linebreak-before-eof-in.js:
--------------------------------------------------------------------------------
1 | // This file does have a linebreak before eof, but should not after running esformatter
2 |
--------------------------------------------------------------------------------
/test/compare/custom/linebreak-before-eof-out.js:
--------------------------------------------------------------------------------
1 | // This file does have a linebreak before eof, but should not after running esformatter
--------------------------------------------------------------------------------
/test/compare/rc/package/nested/pkg_nested-in.js:
--------------------------------------------------------------------------------
1 | // it should merge the config files if nested
2 | function foo() {
3 | bar();
4 | }
5 |
--------------------------------------------------------------------------------
/test/compare/custom/linebreak-before-eof-2-in.js:
--------------------------------------------------------------------------------
1 | // This file does have a linebreak before eof, but should not after running esformatter
2 |
--------------------------------------------------------------------------------
/test/compare/custom/top-level-indent-exception-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent" : {
3 | "TopLevelFunctionBlock" : 0
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/compare/rc/package/nested/indent.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../rc/function.json",
3 | "indent": {
4 | "value": "\t"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/compare/rc/package/nested/pkg_nested-out.js:
--------------------------------------------------------------------------------
1 | // it should merge the config files if nested
2 | function foo ()
3 | {
4 | bar(); }
5 |
--------------------------------------------------------------------------------
/test/compare/error/invalid-2.js:
--------------------------------------------------------------------------------
1 |
2 | // invalid RegExp
3 | var r = /[\u{61}-b]/ugetqweasdasdlk;
4 |
5 | // some random invalid tokens
6 | $%899
7 |
--------------------------------------------------------------------------------
/test/compare/custom/variable_declaration-in.js:
--------------------------------------------------------------------------------
1 | var asd = 'qwerty';
2 |
3 | var foo = { a: 123, b: 456 };
4 |
5 | var lorem = 987,
6 | ipsum = 876;
7 |
--------------------------------------------------------------------------------
/test/compare/default/array_pattern-out.js:
--------------------------------------------------------------------------------
1 | var [lorem, ipsum] = arr;
2 |
3 | var [x, y, z] = position;
4 |
5 | // #444
6 | var [a,, b] = [1, 2, 3];
7 |
--------------------------------------------------------------------------------
/test/compare/custom/multi-indent-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "FunctionDeclaration": 8,
4 | "MultipleVariableDeclaration": 2
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/compare/custom/binary_expression-out.js:
--------------------------------------------------------------------------------
1 | bar(
2 | 123 /
3 | 456 *
4 | 0.75 ^
5 | 255 |
6 | 98 <<
7 | 1 -
8 | 42
9 | );
10 |
--------------------------------------------------------------------------------
/test/compare/custom/linebreak-before-eof-2-out.js:
--------------------------------------------------------------------------------
1 | // This file does have a linebreak before eof, but should not after running esformatter
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/compare/custom/one-line-var-declaration-out.js:
--------------------------------------------------------------------------------
1 | var var1, var2,
2 | var3 = [],
3 | var4 = {},
4 | var5 = [var1, var2, var3];
5 |
6 | var x, y, z;
7 |
--------------------------------------------------------------------------------
/test/compare/custom/one-line-var-declaration-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "VariableDeclarationWithoutInit" : 0
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/compare/custom/one-line-var-declaration-in.js:
--------------------------------------------------------------------------------
1 | var var1, var2,
2 | var3 = [],
3 | var4 = {},
4 | var5 = [var1, var2, var3];
5 |
6 | var x, y, z;
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __*
2 | coverage/
3 | /node_modules/
4 |
5 | # the inplace test only removes the generated file if it's executed
6 | test/compare/default/inplace-in.js.copy
7 |
--------------------------------------------------------------------------------
/test/compare/custom/linebreak-before-eof-2-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "EndOfFile" : 5
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/compare/custom/linebreak-before-eof-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "EndOfFile" : 0
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "after" : {
4 | "PropertyName" : 1
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-2-out.js:
--------------------------------------------------------------------------------
1 | var a = { foo
2 | :
3 | 123
4 | , "bar"
5 | :
6 | "baz"
7 | , 'lorem'
8 | :
9 | new Date()
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/custom/function_expression_bug-in.js:
--------------------------------------------------------------------------------
1 | class Bug {
2 | fix(author) {}
3 | }
4 |
5 | class BugTwo {
6 | fix( author ) {}
7 | }
8 |
9 | var foo = function () {}
10 |
--------------------------------------------------------------------------------
/test/compare/custom/function_expression_bug-out.js:
--------------------------------------------------------------------------------
1 | class Bug {
2 | fix(author) {}
3 | }
4 |
5 | class BugTwo {
6 | fix( author ) {}
7 | }
8 |
9 | var foo = function () {}
10 |
--------------------------------------------------------------------------------
/test/compare/default/array_pattern-in.js:
--------------------------------------------------------------------------------
1 | var [ lorem , ipsum ] = arr;
2 |
3 | var [
4 | x,
5 | y,
6 | z
7 | ] = position;
8 |
9 | // #444
10 | var [a , , b] = [1,2,3];
11 |
--------------------------------------------------------------------------------
/test/compare/custom/variable_declaration-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "value": " ",
4 | "SingleVariableDeclaration": 1,
5 | "MultipleVariableDeclaration": 0
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/compare/custom/variable_declaration-out.js:
--------------------------------------------------------------------------------
1 | var asd = 'qwerty';
2 |
3 | var foo = {
4 | a: 123,
5 | b: 456
6 | };
7 |
8 | var lorem = 987,
9 | ipsum = 876;
10 |
--------------------------------------------------------------------------------
/test/compare/.esformatter:
--------------------------------------------------------------------------------
1 | // this config file makes sure we won't load plugins or use user settings while
2 | // formatting the test files through the CLI
3 | {
4 | "root": true,
5 | "plugins": []
6 | }
7 |
--------------------------------------------------------------------------------
/test/compare/custom/comment_group-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak": {
3 | "before": {
4 | "CommentGroup": 2
5 | },
6 | "after": {
7 | "CommentGroup": 2
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/rc/package/nested/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "esformatter": {
3 | "lineBreak": {
4 | "before": {
5 | "FunctionDeclarationClosingBrace" : 0
6 | }
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/hooks/ThrowStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _ws = require('rocambole-whitespace');
4 |
5 |
6 | exports.format = function ThrowStatement(node) {
7 | _ws.limit(node.startToken, 'ThrowKeyword');
8 | };
9 |
--------------------------------------------------------------------------------
/test/compare/rc/.esformatter:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "value": " "
4 | },
5 | "whiteSpace": {
6 | "before": {
7 | "FunctionDeclarationOpeningBrace" : 0
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/rc/package/rc/.esformatter:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": [
4 | "./function.json"
5 | ],
6 | "indent": {
7 | "value": "\t",
8 | "FunctionDeclaration": 4
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/custom/multi-indent-in.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | bar({
3 | ipsum: 'dolor'
4 | });
5 |
6 | function amet() {
7 | return 123;
8 | }
9 | }
10 |
11 | var foo = 123,
12 | bar = 'baz';
13 |
--------------------------------------------------------------------------------
/test/pipe/bin/esformatter-pipe-test-1:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var stdin = require('stdin');
4 |
5 | stdin(function(source) {
6 | process.stdout.write(source + '\n// ---- esformatter-pipe-test-1 ---\n');
7 | });
8 |
--------------------------------------------------------------------------------
/test/pipe/bin/esformatter-pipe-test-2:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var stdin = require('stdin');
4 |
5 | stdin(function(source) {
6 | process.stdout.write(source + '\n// ---- esformatter-pipe-test-2 ---\n');
7 | });
8 |
--------------------------------------------------------------------------------
/test/compare/custom/argumentlist-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "ArgumentList" : 1
5 | },
6 | "after" : {
7 | "ArgumentList" : 1
8 | }
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/test/compare/custom/array_bug-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "MemberExpressionClosing" : 1
5 | },
6 | "after" : {
7 | "MemberExpressionOpening" : 1
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/custom/object_pattern-2-out.js:
--------------------------------------------------------------------------------
1 | // #441
2 | var {foo, bar, ipsum} = object;
3 |
4 | var {
5 | foo,
6 | bar,
7 | ipsum
8 | } = object;
9 |
10 | var {
11 | foo,
12 | bar,
13 | ipsum
14 | } = object;
15 |
--------------------------------------------------------------------------------
/test/compare/default/throw_statement-in.js:
--------------------------------------------------------------------------------
1 | function foo(a) {throw new Error('invalid args')
2 | function b() {
3 | throw Error('no new');}
4 | }
5 |
6 | throw "this is an anti-pattern, never throw string, only Error objects";
7 |
8 |
--------------------------------------------------------------------------------
/test/compare/rc/package/rc/function.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "value": " ",
4 | "FunctionDeclaration": 2
5 | },
6 | "whiteSpace": {
7 | "after": {
8 | "FunctionName": 1
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/compare/custom/negative_indent-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | // yes, you can set negative values. "0" is the real noop.
4 | "ObjectExpression": -1,
5 | "ArrayExpression": -2,
6 | "IfStatement": 0
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/compare/custom/new_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace": {
3 | "before": {
4 | "CalleeClosingParentheses": "1"
5 | },
6 | "after": {
7 | "CalleeOpeningParentheses": "1"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/fake-preset/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "testing extends inside package.json",
4 | "esformatter": {
5 | "root": true,
6 | "extends": [
7 | "preset:fake-2"
8 | ]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/custom/for_statement-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "ForStatementExpressionClosing" : 1
5 | },
6 | "after" : {
7 | "ForStatementExpressionOpening" : 1
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/bin/node_modules/esformatter/lib/cli.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.parse = function() {
4 | return null;
5 | };
6 |
7 | exports.run = function() {
8 | console.log('fake-esformatter v0.0.0-alpha');
9 | process.exit(0);
10 | };
11 |
--------------------------------------------------------------------------------
/test/compare/custom/iife-in.js:
--------------------------------------------------------------------------------
1 | // issue #223
2 | (function() {
3 | var x = 1;
4 | foo(bar(), baz());
5 | }());
6 |
7 | // issue #250
8 | (function( $ ) {
9 | x;
10 | }( jQuery ));
11 |
12 | ;!function(x){
13 | console.log(x)
14 | }('bar')
15 |
--------------------------------------------------------------------------------
/test/compare/custom/arrow_function_expression-out.js:
--------------------------------------------------------------------------------
1 | // issue #400
2 | () => process.exit( 0 );
3 | ( example ) => process.exit( 0 );
4 | ( example ) => {
5 | process.exit( 0 );
6 | };
7 | function example() {
8 | return process.exit( 0 );
9 | }
10 |
--------------------------------------------------------------------------------
/test/compare/default/object_pattern-out.js:
--------------------------------------------------------------------------------
1 | const {p, a, c, k, e, f} = g;
2 | const {Link} = require('something');
3 | const {link, button} = require('another');
4 |
5 | var {foo, bar} = object;
6 |
7 | var {type, parties, sentences, ...props} = this.props;
8 |
--------------------------------------------------------------------------------
/test/compare/custom/arrow_function_expression-in.js:
--------------------------------------------------------------------------------
1 | // issue #400
2 | ( ) => process.exit(0 );
3 | ( example ) => process.exit( 0);
4 | (example) => {
5 | process.exit( 0 );
6 | };
7 | function example() {
8 | return process.exit( 0 );
9 | }
10 |
--------------------------------------------------------------------------------
/test/compare/custom/conditional_expression-out.js:
--------------------------------------------------------------------------------
1 | // test the opposite of default settings
2 | a ?foo():bar();
3 |
4 | b = (dolor !== amet) ?'ipsum':'dolor';
5 |
6 | if (true) {
7 | c = !a ?(!foo ?d:function() {
8 | return a;
9 | }):b;
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/default/throw_statement-out.js:
--------------------------------------------------------------------------------
1 | function foo(a) {
2 | throw new Error('invalid args')
3 | function b() {
4 | throw Error('no new');
5 | }
6 | }
7 |
8 | throw "this is an anti-pattern, never throw string, only Error objects";
9 |
10 |
--------------------------------------------------------------------------------
/test/compare/custom/conditional_expression-in.js:
--------------------------------------------------------------------------------
1 | // test the opposite of default settings
2 | a?foo():bar();
3 |
4 | b = (dolor!==amet) ? 'ipsum': 'dolor';
5 |
6 | if(true){
7 | c = !a ?(!foo?d : function(){
8 | return a;
9 | }):b;
10 | }
11 |
--------------------------------------------------------------------------------
/test/bin/node_modules/esformatter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "esformatter",
4 | "description": "this is a fake version of esformatter just to test if CLI can use local version",
5 | "version": "0.0.0-alpha",
6 | "main": "lib/fake.js"
7 | }
8 |
--------------------------------------------------------------------------------
/test/compare/custom/align_comments-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | // using the PascalCase format to ensure we support old format
4 | // this will be deprecated during v1.0!!! favor "alignComments"
5 | // instead
6 | "AlignComments": false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/compare/custom/iife-out.js:
--------------------------------------------------------------------------------
1 | // issue #223
2 | ( function() {
3 | var x = 1;
4 | foo( bar(), baz() );
5 | }() );
6 |
7 | // issue #250
8 | ( function( $ ) {
9 | x;
10 | }( jQuery ) );
11 |
12 | ;!function( x ) {
13 | console.log( x )
14 | }( 'bar' )
15 |
--------------------------------------------------------------------------------
/test/compare/custom/member_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "MemberExpressionClosing" : 1
5 | },
6 | "after" : {
7 | "MemberExpressionOpening" : 1
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/custom/object_pattern-2-in.js:
--------------------------------------------------------------------------------
1 | // #441
2 | var {foo,bar,ipsum} = object;
3 |
4 | var {
5 | foo,
6 | bar,
7 | ipsum
8 | } = object;
9 |
10 | var {
11 |
12 | foo,
13 |
14 | bar,
15 |
16 | ipsum
17 |
18 |
19 |
20 | }
21 |
22 | = object;
23 |
--------------------------------------------------------------------------------
/test/compare/custom/arrow_function_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace": {
3 | "before": {
4 | "ArgumentList": 1,
5 | "ParameterList": 1
6 | },
7 | "after": {
8 | "ArgumentList": 1,
9 | "ParameterList": 1
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/compare/custom/class-in.js:
--------------------------------------------------------------------------------
1 | // issue #384
2 | class Foo extends React.Component {
3 | classFun (a, b, c) {}}
4 |
5 | const {foo, bar} = baz
6 |
7 | function regularFun(a, b, c){}
8 |
9 | // issue #423
10 | class Foo
11 | extends Bar {
12 | fn() {}
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/test/compare/custom/expression_parentheses-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "ExpressionClosingParentheses" : 1
5 | },
6 | "after" : {
7 | "ExpressionOpeningParentheses" : 1
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/compare/custom/class-out.js:
--------------------------------------------------------------------------------
1 | // issue #384
2 | class Foo extends React.Component {
3 | classFun (a,b,c) {}
4 | }
5 |
6 | const {foo, bar} = baz
7 |
8 | function regularFun(a,b,c) {
9 | }
10 |
11 | // issue #423
12 | class Foo
13 | extends Bar {
14 | fn () {}
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/test/compare/default/block_statement-in.js:
--------------------------------------------------------------------------------
1 | {
2 | var foo = 123;
3 | bar(foo)
4 | }
5 |
6 | function dolor() { { let amet = 'maecennas';
7 | console.log(amet) } }
8 |
9 | // #430
10 | function a() { var arr2 = [] }
11 | var x = 1
12 | {
13 | var x = 2
14 | console.log(x) }
15 |
--------------------------------------------------------------------------------
/test/compare/default/jsx-in.js:
--------------------------------------------------------------------------------
1 | var HelloMessage = React.createClass({
2 | // borrowed from react documentation
3 | render: function() {
4 | // render
5 | return
Hello {this.props.name}
;
6 | }
7 | });
8 |
9 | React.render(, mountNode);
10 |
--------------------------------------------------------------------------------
/test/compare/rc/package/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "esformatter": {
3 | "preset": "default",
4 | "indent": {
5 | "value": " "
6 | },
7 | "lineBreak": {
8 | "before": {
9 | "FunctionDeclarationOpeningBrace" : 1
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/compare/default/jsx-out.js:
--------------------------------------------------------------------------------
1 | var HelloMessage = React.createClass({
2 | // borrowed from react documentation
3 | render: function() {
4 | // render
5 | return Hello {this.props.name}
;
6 | }
7 | });
8 |
9 | React.render(, mountNode);
10 |
--------------------------------------------------------------------------------
/test/compare/default/object_pattern-in.js:
--------------------------------------------------------------------------------
1 | const {p, a, c, k, e, f} = g;
2 | const { Link } = require('something');
3 | const { link, button } = require('another');
4 |
5 | var {
6 | foo,
7 | bar
8 | }
9 | = object;
10 |
11 | var { type , parties, sentences, ...props } = this.props;
12 |
--------------------------------------------------------------------------------
/test/compare/custom/multi-indent-out.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | bar({
3 | ipsum: 'dolor'
4 | });
5 |
6 | function amet() {
7 | return 123;
8 | }
9 | }
10 |
11 | var foo = 123,
12 | bar = 'baz';
13 |
--------------------------------------------------------------------------------
/test/compare/custom/unary_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace": {
3 | "before": {
4 | "UnaryExpressionOperator": 1,
5 | "UpdateExpressionOperator": 1
6 | },
7 | "after": {
8 | "UnaryExpressionOperator": 1,
9 | "UpdateExpressionOperator": 1
10 |
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/plugin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "esformatter-test-plugin",
4 | "version": "1.0.0",
5 | "description": "test if esformatter is able to load locally installed plugins from the cli",
6 | "main": "esformatter-test-plugin.js",
7 | "author": "Miller Medeiros",
8 | "license": "ISC"
9 | }
10 |
--------------------------------------------------------------------------------
/test/compare/custom/iife-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace": {
3 | "before": {
4 | "ArgumentList": 1,
5 | "IIFEClosingParentheses": 1,
6 | "ParameterList": 1
7 | },
8 | "after": {
9 | "ArgumentList": 1,
10 | "IIFEOpeningParentheses": 1,
11 | "ParameterList": 1
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/compare/custom/negative_indent-in.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | function dolor(bar) {
3 | var arr = [];
4 | if (bar) {
5 | arr = [
6 | 'weird',
7 | 'indent'
8 | ];
9 | obj = {
10 | 'yes': 'i know it\'s weird',
11 | 'but': 'it tests the rocambole-indent negative rule'
12 | }
13 | }
14 | return arr;
15 | }
16 | return dolor;
17 | }
18 |
--------------------------------------------------------------------------------
/test/compare/default/block_statement-out.js:
--------------------------------------------------------------------------------
1 | {
2 | var foo = 123;
3 | bar(foo)
4 | }
5 |
6 | function dolor() {
7 | {
8 | let amet = 'maecennas';
9 | console.log(amet)
10 | }
11 | }
12 |
13 | // #430
14 | function a() {
15 | var arr2 = []
16 | }
17 | var x = 1
18 | {
19 | var x = 2
20 | console.log(x)
21 | }
22 |
--------------------------------------------------------------------------------
/test/compare/custom/function_expression_bug-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent" : {
3 | "value": " "
4 | },
5 |
6 | "whiteSpace" : {
7 | "value" : " ",
8 | "before" : {
9 | "ParameterList" : -1
10 | },
11 |
12 | "after" : {
13 | "FunctionReservedWord": 1,
14 | "ParameterList" : -1
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/preset/fake1/esformatter-preset-fake-1.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // IMPORTANT: run `npm rm esformatter-preset-fake-1 && npm i test/preset/fake1`
4 | // every time you update this file!
5 |
6 | module.exports = {
7 | plugins: [
8 | require('esformatter-test-plugin')
9 | ],
10 | indent: {
11 | FunctionExpression: 42
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/test/preset/fake2/esformatter-preset-fake-2.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // IMPORTANT: run `npm rm esformatter-preset-fake-2 && npm i test/preset/fake2`
4 | // every time you update this file!
5 |
6 | module.exports = {
7 | extends: [
8 | require('esformatter-preset-fake-1')
9 | ],
10 | indent: {
11 | FunctionDeclaration: 2
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/test/compare/custom/argumentlist-out.js:
--------------------------------------------------------------------------------
1 | call();
2 | call( x );
3 | call( function() {
4 | something();
5 | } );
6 | call( {} );
7 | call( {
8 | x: 1
9 | } );
10 | call( x, {
11 | x: 1
12 | } );
13 | call( x, function() {
14 | x();
15 | } );
16 | call( function() {
17 | x();
18 | }, x );
19 | call( {
20 | x: 1
21 | }, x );
22 | call( [] );
23 | call( [x, y] );
24 |
--------------------------------------------------------------------------------
/test/compare/custom/class_declaration-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak": {
3 | "before": {
4 | "MethodDefinition": 3,
5 | "MethodDefinitionOpeningBrace": 1
6 | },
7 | "after": {
8 | "MethodDefinitionClosingBrace": 3
9 | }
10 | },
11 | "whiteSpace": {
12 | "after": {
13 | "MethodDefinitionName": 1
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/compare/custom/negative_indent-out.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | function dolor(bar) {
3 | var arr = [];
4 | if (bar) {
5 | arr = [
6 | 'weird',
7 | 'indent'
8 | ];
9 | obj = {
10 | 'yes': 'i know it\'s weird',
11 | 'but': 'it tests the rocambole-indent negative rule'
12 | }
13 | }
14 | return arr;
15 | }
16 | return dolor;
17 | }
18 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-2-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak": {
3 | "before": {
4 | "PropertyName": 0,
5 | "PropertyValue": 1
6 | },
7 |
8 | "after": {
9 | "PropertyName": 1,
10 | "PropertyValue": 1
11 | }
12 | },
13 |
14 | "whiteSpace": {
15 | "before": {
16 | "PropertyName": 1
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 | - "10"
5 | - "12"
6 | script:
7 | - "npm test --coverage"
8 | - "npm run-script lint"
9 | branches:
10 | only:
11 | - master
12 | notifications:
13 | irc:
14 | channels:
15 | - "irc.freenode.org#esformatter"
16 | on_success: change
17 | use_notice: true
18 | skip_join: true
19 |
--------------------------------------------------------------------------------
/lib/hooks/ExportDefaultDeclaration.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 |
7 | exports.format = function ExportDefaultDeclaration(node) {
8 | var def = _tk.findNext(node.startToken, 'default');
9 | _br.limit(def, 0);
10 | _ws.limit(def, 1);
11 | };
12 |
--------------------------------------------------------------------------------
/test/compare/custom/if_statement_spacy-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "IfStatementConditionalOpening" : 1,
5 | "IfStatementConditionalClosing" : 1
6 | },
7 | "after" : {
8 | "IfStatementConditionalOpening" : 1,
9 | "IfStatementConditionalClosing" : 1
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/compare/custom/argumentlist-in.js:
--------------------------------------------------------------------------------
1 | call();
2 | call( x );
3 | call( function() {
4 | something();
5 | } );
6 | call( {} );
7 | call( {
8 | x : 1
9 | } );
10 | call( x, {
11 | x : 1
12 | } );
13 | call( x, function() {
14 | x();
15 | } );
16 | call( function() {
17 | x();
18 | }, x );
19 | call( {
20 | x : 1
21 | }, x );
22 | call( [] );
23 | call( [x, y] );
24 |
--------------------------------------------------------------------------------
/test/compare/custom/README.md:
--------------------------------------------------------------------------------
1 | # custom settings tests
2 |
3 | These files are used to test custom settings. It should try to test the
4 | *opposite* of the default settings whenever possible.
5 |
6 | `foo_bar-in.js` will be used as input and will be compared with
7 | `foo_bar-out.js`, `foo_bar-config.json` will be passed as the custom settings
8 | on the `esformatter.parse()` call.
9 |
10 |
--------------------------------------------------------------------------------
/test/compare/default/comma_operator-in.js:
--------------------------------------------------------------------------------
1 | // SequenceExpression (aka. comma operator)
2 |
3 | a,b
4 | a,b,c
5 |
6 | a=3,foo(), bar() ,"baz",c
7 |
8 | it="is" , ("a"),(trap())
9 |
10 | // borrowed from signals.min test a bug related to line breaks and indent
11 | if(e!==-1){if(a =this._bindings[e],a.isOnce()!==b)throw Error('foo');}else a=new h(this,a,b,c,d),this._addBinding(a);
12 |
13 |
--------------------------------------------------------------------------------
/test/compare/custom/for_in_statement-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "ForInStatementOpeningBrace" : 1
5 | }
6 | },
7 | "whiteSpace" : {
8 | "before" : {
9 | "ForInStatementExpressionClosing" : 1
10 | },
11 | "after" : {
12 | "ForInStatementExpressionOpening" : 1
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/compare/custom/for_of_statement-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "ForOfStatementOpeningBrace" : 1
5 | }
6 | },
7 | "whiteSpace" : {
8 | "before" : {
9 | "ForOfStatementExpressionClosing" : 1
10 | },
11 | "after" : {
12 | "ForOfStatementExpressionOpening" : 1
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/preset/fake2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "esformatter-preset-fake-2",
4 | "version": "1.0.0",
5 | "description": "test if esformatter is able to load locally installed presets",
6 | "main": "esformatter-preset-fake-2.js",
7 | "author": "Miller Medeiros",
8 | "license": "MIT",
9 | "dependencies": {
10 | "esformatter-preset-fake-1": "file:../fake1"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/preset/fake1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "esformatter-preset-fake-1",
4 | "version": "1.0.0",
5 | "description": "test if esformatter is able to load locally installed presets",
6 | "main": "esformatter-preset-fake-1.js",
7 | "author": "Miller Medeiros",
8 | "license": "MIT",
9 | "dependencies": {
10 | "esformatter-test-plugin": "file:../../plugin"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/compare/custom/new_expression-in.js:
--------------------------------------------------------------------------------
1 | // issue #254
2 | var now = new Date();
3 | var midnight = new Date(
4 | now.getFullYear(), now.getMonth(), now.getDate() + 1,
5 | 0, 0, 0
6 | );
7 |
8 | // issue #318
9 | var time = new Date;
10 |
11 | // issue #321
12 | var foo = new
13 | Ctor();
14 |
15 | // #434
16 | context = new (window.AudioContext || window.webkitAudioContext)();
17 | new ( a.b );
18 | (foo || bar)();
19 |
--------------------------------------------------------------------------------
/test/compare/custom/basic_function_indent_2-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "FunctionDeclarationOpeningBrace" : 1,
5 | "FunctionDeclarationClosingBrace" : 1,
6 | "ReturnStatement" : 1
7 | },
8 | "after" : {
9 | "FunctionDeclarationOpeningBrace" : 1,
10 | "ReturnStatement" : 1
11 | }
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/test/compare/custom/new_expression-out.js:
--------------------------------------------------------------------------------
1 | // issue #254
2 | var now = new Date();
3 | var midnight = new Date(
4 | now.getFullYear(), now.getMonth(), now.getDate() + 1,
5 | 0, 0, 0
6 | );
7 |
8 | // issue #318
9 | var time = new Date;
10 |
11 | // issue #321
12 | var foo = new Ctor();
13 |
14 | // #434
15 | context = new ( window.AudioContext || window.webkitAudioContext )();
16 | new ( a.b );
17 | ( foo || bar )();
18 |
--------------------------------------------------------------------------------
/test/compare/custom/object_pattern-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak": {
3 | "before": {
4 | "ObjectPatternClosingBrace": 1
5 | },
6 | "after": {
7 | "ObjectPatternOpeningBrace": 1,
8 | "ObjectPatternComma": 1
9 | }
10 | },
11 | "whiteSpace": {
12 | "before": {
13 | "ObjectPatternComma": 1
14 | },
15 | "after": {
16 | "ObjectPatternComma": 1
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/compare/default/README.md:
--------------------------------------------------------------------------------
1 | # default settings tests
2 |
3 | These files are used to test the default settings.
4 |
5 | The default settings should be as *conservative* as possible, [Google
6 | JavaScript Style
7 | Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml)
8 | should be used as a reference.
9 |
10 | `foo_bar-in.js` will be used as input and will be compared with `foo_bar-out.js`.
11 |
12 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-3-in.js:
--------------------------------------------------------------------------------
1 | x({ a:1});
2 | y({
3 | a: 1
4 | });
5 | $.each({ div: "#list1", ul: "#navigation", dl: "#accordion-dl" });
6 |
7 | var x ={ foo:{ bar: true} };
8 | var y= {a: b, c:d, e:{ f: g } };
9 | x = {
10 | props: {
11 | // comment
12 | x: 1
13 | }
14 | };
15 | x = {
16 | b: function b() {
17 | a();
18 | },
19 | a: b,
20 | c,
21 | someMethod () {
22 | bar()
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/test/compare/default/comma_operator-out.js:
--------------------------------------------------------------------------------
1 | // SequenceExpression (aka. comma operator)
2 |
3 | a, b
4 | a, b, c
5 |
6 | a = 3, foo(), bar(), "baz", c
7 |
8 | it = "is", ("a"), (trap())
9 |
10 | // borrowed from signals.min test a bug related to line breaks and indent
11 | if (e !== -1) {
12 | if (a = this._bindings[e], a.isOnce() !== b)
13 | throw Error('foo');
14 | } else a = new h(this, a, b, c, d), this._addBinding(a);
15 |
16 |
--------------------------------------------------------------------------------
/lib/hooks/UpdateExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _limit = require('../limit');
4 |
5 | exports.format = function UpdateExpression(node) {
6 | // we only really care about spaces between the operator and the argument
7 | if (node.startToken.value === node.operator) {
8 | _limit.after(node.startToken, 'UpdateExpressionOperator');
9 | } else {
10 | _limit.before(node.endToken, 'UpdateExpressionOperator');
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/test/compare/custom/align_comments-in.js:
--------------------------------------------------------------------------------
1 | // comment alignment (#209)
2 | switch (foo) {
3 | case bar:
4 | // lorem
5 | baz();
6 | // falls through
7 | // yes, this should be aligned too
8 |
9 | // this should be at same indent level as `baz();`
10 | case biz:
11 | what();
12 | }
13 |
14 | // comment alignment (#270)
15 | try {
16 | bla();
17 | // comment
18 | // too
19 | } catch (e) {
20 | throw e;
21 | }
22 |
--------------------------------------------------------------------------------
/test/compare/custom/align_comments-out.js:
--------------------------------------------------------------------------------
1 | // comment alignment (#209)
2 | switch (foo) {
3 | case bar:
4 | // lorem
5 | baz();
6 | // falls through
7 | // yes, this should be aligned too
8 |
9 | // this should be at same indent level as `baz();`
10 | case biz:
11 | what();
12 | }
13 |
14 | // comment alignment (#270)
15 | try {
16 | bla();
17 | // comment
18 | // too
19 | } catch (e) {
20 | throw e;
21 | }
22 |
--------------------------------------------------------------------------------
/test/compare/custom/array_expression-in.js:
--------------------------------------------------------------------------------
1 | [
2 |
3 | ];
4 |
5 | [1,2,3];
6 |
7 | [1,2,[3,4,[5,6,[7,8,9]]]];
8 |
9 | function fn(){
10 | return [4,5,[6, 7 , 8 ]];
11 | }
12 |
13 | // issue #12
14 | var tuples = [
15 | // comment test
16 | ["resolve", "done", "bla", "resolved"],
17 | ["reject", "fail", "lorem", "rejected"],
18 | [
19 | ["lorem", "ipsum"]
20 | ],
21 | ["notify", "progress", "ipsum"]
22 | ];
23 |
--------------------------------------------------------------------------------
/lib/hooks/SequenceExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _ws = require('rocambole-whitespace');
4 |
5 |
6 | exports.format = function SequenceExpression(node) {
7 | node.expressions.forEach(function(expr, i) {
8 | if (i) {
9 | var operator = expr.startToken.prev;
10 | while (operator.value !== ',') {
11 | operator = operator.prev;
12 | }
13 | _ws.limit(operator, 'CommaOperator');
14 | }
15 | });
16 | };
17 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-3-out.js:
--------------------------------------------------------------------------------
1 | x({ a: 1 });
2 | y({
3 | a: 1
4 | });
5 | $.each({ div: "#list1", ul: "#navigation", dl: "#accordion-dl" });
6 |
7 | var x = { foo: { bar: true } };
8 | var y = { a: b, c: d, e: { f: g } };
9 | x = {
10 | props: {
11 | // comment
12 | x: 1
13 | }
14 | };
15 | x = {
16 | b: function b() {
17 | a();
18 | },
19 | a: b,
20 | c,
21 | someMethod () {
22 | bar()
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/test/compare/custom/array_expression-out.js:
--------------------------------------------------------------------------------
1 | [];
2 |
3 | [ 1 ,2 ,3 ];
4 |
5 | [ 1 ,2 ,[ 3 ,4 ,[ 5 ,6 ,[ 7 ,8 ,9 ] ] ] ];
6 |
7 | function fn() {
8 | return [ 4 ,5 ,[ 6 ,7 ,8 ] ];
9 | }
10 |
11 | // issue #12
12 | var tuples = [
13 | // comment test
14 | [ "resolve" ,"done" ,"bla" ,"resolved" ] ,
15 | [ "reject" ,"fail" ,"lorem" ,"rejected" ] ,
16 | [
17 | [ "lorem" ,"ipsum" ]
18 | ] ,
19 | [ "notify" ,"progress" ,"ipsum" ]
20 | ];
21 |
--------------------------------------------------------------------------------
/test/compare/default/do_while_statement-in.js:
--------------------------------------------------------------------------------
1 | do{console.log(i++)}while(i<100); do{i--}while(i);
2 |
3 | do{
4 | console.log(i++)
5 | }while(i<100)
6 | do{i--}while(i);
7 |
8 | do n--; while(n&&foo());
9 |
10 | do n--; while(n&&foo());do++i;while(amet(i));
11 |
12 | // issue #256
13 | function main() {
14 | do if (true) return 1; while (true);
15 | }
16 |
17 | function main() {
18 | do
19 | if (true) return 1;
20 | while (true);
21 | }
22 |
--------------------------------------------------------------------------------
/test/compare/custom/conditional_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "ConditionalExpression": 0
4 | },
5 | "whiteSpace" : {
6 | "before" : {
7 | "ConditionalExpressionConsequent" : 0,
8 | "ConditionalExpressionAlternate" : 0
9 | },
10 | "after" : {
11 | "ConditionalExpressionConsequent" : 0,
12 | "ConditionalExpressionTest" : 1
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/pipe/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "esformatter-pipe-test",
4 | "version": "1.0.0",
5 | "description": "used to test esformatter pipe option",
6 | "author": "Miller Medeiros",
7 | "bin": {
8 | "esformatter-pipe-test-1": "./bin/esformatter-pipe-test-1",
9 | "esformatter-pipe-test-2": "./bin/esformatter-pipe-test-2"
10 | },
11 | "license": "ISC",
12 | "dependencies": {
13 | "stdin": "0.0.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/helpers.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | exports.shouldIndentChild = shouldIndentChild;
4 | function shouldIndentChild(parent, child, opts) {
5 | // this will avoid indenting objects/arrays/functions twice if they
6 | // are on the right of a BinaryExpression, LogicalExpression or
7 | // UnaryExpression
8 | if (!child || !opts[parent.type + '.' + child.type]) {
9 | return false;
10 | }
11 |
12 | return !child.right || !opts[child.right.type];
13 | }
14 |
--------------------------------------------------------------------------------
/test/compare/default/member_expression-out.js:
--------------------------------------------------------------------------------
1 | obj[prop] = foo.bar;
2 |
3 | BarNamespace['Bar'].Bar["Bar"]('bar').Bar("bar", "bar")
4 |
5 | // should remove these line breaks
6 | foo.bar.ipum();
7 |
8 | // should NOT remove line breaks in this case
9 | lorem
10 | .ipsum
11 | .dolor();
12 |
13 | // issue #378
14 | expected[property] = group[property]
15 | expect(foo)
16 |
17 | bar = f[
18 | 'loremipsumdolorsitamet' + a + '_' + 'somethig_else'
19 | ]
20 | ipsum(bar)
21 |
--------------------------------------------------------------------------------
/test/compare/custom/object_pattern-2-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak": {
3 | "before": {
4 | "ObjectPatternClosingBrace": "<2"
5 | },
6 | "after": {
7 | "ObjectPatternClosingBrace": 0,
8 | "ObjectPatternComma": "<2",
9 | "ObjectPatternOpeningBrace": "<2"
10 | }
11 | },
12 | "whiteSpace": {
13 | "before": {
14 | "ObjectPatternComma": 0
15 | },
16 | "after": {
17 | "ObjectPatternComma": 1
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/lib/hooks/ExportAllDeclaration.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 |
7 | exports.format = function ExportAllDeclaration(node) {
8 | var star = _tk.findNext(node.startToken, '*');
9 | _br.limit(star, 0);
10 | _ws.limit(star, 1);
11 |
12 | var fromKeyword = _tk.findNext(node.startToken, 'from');
13 | _br.limit(fromKeyword, 0);
14 | _ws.limit(fromKeyword, 1);
15 | };
16 |
--------------------------------------------------------------------------------
/test/compare/default/new_expression-out.js:
--------------------------------------------------------------------------------
1 | // issue #254
2 | var now = new Date();
3 | var midnight = new Date(
4 | now.getFullYear(), now.getMonth(), now.getDate() + 1,
5 | 0, 0, 0
6 | );
7 |
8 | // issue #318
9 | var time = new Date;
10 |
11 | // issue #321
12 | var foo = new Ctor();
13 |
14 | // #434
15 | context = new (window.AudioContext || window.webkitAudioContext)();
16 | (foo || bar)();
17 |
18 | // #439
19 | var foo = new // ARRAY_COPY(
20 | Date();
21 |
22 | console.log(foo);
23 |
--------------------------------------------------------------------------------
/test/compare/custom/class-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent" : {
3 | "value": " "
4 | },
5 |
6 | "whiteSpace" : {
7 | "value" : " ",
8 | "before" : {
9 | "ParameterList" : -1
10 | },
11 |
12 | "after" : {
13 | "FunctionReservedWord": 1,
14 | "MethodDefinitionName": 1,
15 | "ParameterComma" : 0,
16 | "ParameterList" : -1
17 | }
18 | },
19 |
20 | "lineBreak": {
21 | "before": {
22 | "ClassExtendsKeyword": -1
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/compare/default/new_expression-in.js:
--------------------------------------------------------------------------------
1 | // issue #254
2 | var now = new Date();
3 | var midnight = new Date(
4 | now.getFullYear(), now.getMonth(), now.getDate() + 1,
5 | 0, 0, 0
6 | );
7 |
8 | // issue #318
9 | var time = new Date;
10 |
11 | // issue #321
12 | var foo = new
13 | Ctor();
14 |
15 | // #434
16 | context = new ( window.AudioContext || window.webkitAudioContext )();
17 | ( foo || bar )();
18 |
19 | // #439
20 | var foo = new // ARRAY_COPY(
21 | Date();
22 |
23 | console.log(foo);
24 |
--------------------------------------------------------------------------------
/test/compare/custom/array_expression-2-in.js:
--------------------------------------------------------------------------------
1 | [
2 |
3 | ];
4 |
5 | [1,2,3];
6 |
7 | [1,2,[3,4,[5,6,[7,8,9]]]];
8 |
9 | function fn(){
10 | // IMPORTANT: we can't break lines here because of ASI!!!
11 | return [4,5,[6, 7 , 8 ]];
12 | }
13 |
14 | // issue #12
15 | var tuples = [
16 | // comment test
17 | ["resolve", "done", "bla", "resolved"],
18 | ["reject", "fail", "lorem", "rejected"],
19 | [
20 | ["lorem", "ipsum"]
21 | ],
22 | ["notify", "progress", "ipsum"]
23 | ];
24 |
--------------------------------------------------------------------------------
/test/compare/default/member_expression-in.js:
--------------------------------------------------------------------------------
1 | obj[ prop ] = foo . bar;
2 |
3 | BarNamespace [ 'Bar' ] . Bar [ "Bar" ] ( 'bar' ) . Bar ( "bar", "bar" )
4 |
5 | // should remove these line breaks
6 | foo.
7 | bar.
8 | ipum();
9 |
10 | // should NOT remove line breaks in this case
11 | lorem
12 | .ipsum
13 | .dolor();
14 |
15 | // issue #378
16 | expected[property] = group[property]
17 | expect(foo)
18 |
19 | bar = f[
20 | 'loremipsumdolorsitamet' + a + '_' + 'somethig_else'
21 | ]
22 | ipsum(bar)
23 |
--------------------------------------------------------------------------------
/test/compare/custom/assignment_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "AssignmentExpression" : -1
5 | },
6 | "after" : {
7 | "AssignmentExpression" : -1
8 | }
9 | },
10 | "whiteSpace" : {
11 | "before" : {
12 | "AssignmentExpression" : 1,
13 | "AssignmentOperator" : 0
14 | },
15 | "after" : {
16 | "AssignmentOperator" : 0
17 | }
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/test/compare/custom/if_statement_spacy-in.js:
--------------------------------------------------------------------------------
1 | if(true){doStuff()}
2 |
3 | if( foo ||bar ){ if (bar === 'bar'){
4 | // nested
5 | log('nested if'); } else { log('nested else')
6 | } }
7 | else if (baz==null)
8 | {
9 | // else if
10 | log('elseif');
11 | }else{
12 | // else
13 | log('else');
14 | // should keep the 2 empty lines
15 |
16 |
17 | }
18 |
19 | if( singleLine )singleLine();
20 |
21 |
22 | // it's a trap!
23 | if (asi && noBraces)
24 | dolor()
25 | else
26 | amet();
27 |
28 |
--------------------------------------------------------------------------------
/lib/hooks/ObjectPattern.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var limit = require('../limit');
4 | var tk = require('rocambole-token');
5 |
6 | exports.format = function ObjectPattern(node) {
7 | limit.around(node.startToken, 'ObjectPatternOpeningBrace');
8 | limit.around(node.endToken, 'ObjectPatternClosingBrace');
9 |
10 | node.properties.forEach(function(prop) {
11 | var comma = tk.findNext(prop.endToken, [',', '}']);
12 | if (comma.value === ',') {
13 | limit.around(comma, 'ObjectPatternComma');
14 | }
15 | });
16 | };
17 |
--------------------------------------------------------------------------------
/test/compare/default/iife-in.js:
--------------------------------------------------------------------------------
1 | (function(i){ function h(a,b,c,d,e){this._listener=b;this._isOnce=c;this.context=d;this._signal=a;this._priority=e||0}i.h=h;}(this));
2 |
3 |
4 | // issue #191
5 | var data = {
6 | items: (function() {
7 | return [1, 2, 3, 4];
8 | }()),
9 | foo: true
10 | };
11 |
12 | // issue #223
13 | ( function() {
14 | var x = 1;
15 | foo(bar(), baz());
16 | }() );
17 |
18 | // issue #250
19 | ( function( $ ) {
20 | x;
21 | }( jQuery ) );
22 |
23 | ;!function( x ) {
24 | console.log( x )
25 | }( 'bar' )
26 |
--------------------------------------------------------------------------------
/test/compare/default/do_while_statement-out.js:
--------------------------------------------------------------------------------
1 | do {
2 | console.log(i++)
3 | } while (i < 100);
4 | do {
5 | i--
6 | } while (i);
7 |
8 | do {
9 | console.log(i++)
10 | } while (i < 100)
11 | do {
12 | i--
13 | } while (i);
14 |
15 | do n--; while (n && foo());
16 |
17 | do n--; while (n && foo());
18 | do ++i; while (amet(i));
19 |
20 | // issue #256
21 | function main() {
22 | do
23 | if (true) return 1;
24 | while (true);
25 | }
26 |
27 | function main() {
28 | do
29 | if (true) return 1;
30 | while (true);
31 | }
32 |
--------------------------------------------------------------------------------
/test/compare/custom/for_statement-in.js:
--------------------------------------------------------------------------------
1 | for (i=0; i 0; --j ) {
17 | x();
18 | }
19 | }
20 |
21 | for(;; ) {
22 | x();
23 | }
24 |
25 | function foo() {
26 | for (var c = this._bindings.length, d;c--;)
27 | x += 1;
28 | return -1;
29 | }
30 |
31 | for ( i = 0;i< 10;i++) foo();
32 | for (i=10; i < 10; i++ )
33 | bar();
34 |
--------------------------------------------------------------------------------
/test/compare/custom/call_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent" : {
3 | "MemberExpression" : 0
4 | },
5 | "lineBreak": {
6 | "before": {
7 | "ArgumentComma" : 0,
8 | "CallExpression": ">=1"
9 | },
10 | "after": {
11 | "ArgumentComma" : 0,
12 | "CallExpression": ">=1"
13 | }
14 | },
15 | "whiteSpace" : {
16 | "before" : {
17 | "ArgumentList" : 1,
18 | "ArgumentComma" : 1
19 | },
20 | "after" : {
21 | "ArgumentList" : 1,
22 | "ArgumentComma" : 0
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/compare/custom/if_statement_spacy-out.js:
--------------------------------------------------------------------------------
1 | if ( true ) {
2 | doStuff()
3 | }
4 |
5 | if ( foo || bar ) {
6 | if ( bar === 'bar' ) {
7 | // nested
8 | log('nested if');
9 | } else {
10 | log('nested else')
11 | }
12 | } else if ( baz == null ) {
13 | // else if
14 | log('elseif');
15 | } else {
16 | // else
17 | log('else');
18 | // should keep the 2 empty lines
19 |
20 |
21 | }
22 |
23 | if ( singleLine ) singleLine();
24 |
25 |
26 | // it's a trap!
27 | if ( asi && noBraces )
28 | dolor()
29 | else
30 | amet();
31 |
32 |
--------------------------------------------------------------------------------
/test/compare/default/flow-in.js:
--------------------------------------------------------------------------------
1 | /**
2 | * important! this file is only to ensure we parse files with Flow annotation
3 | * properly. The formatting of typeAnnotation should be handled by an external
4 | * plugin since not all users will require this feature and implementation is
5 | * pretty complex.
6 | * @flow
7 | */
8 | function foo(a: string, b: number): void {
9 | return a + String(b);
10 | }
11 |
12 | var x: boolean = someBool;
13 |
14 | class Bar {
15 | y: string;
16 | someMethod(a: number): string {
17 | return a * 2;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/compare/default/flow-out.js:
--------------------------------------------------------------------------------
1 | /**
2 | * important! this file is only to ensure we parse files with Flow annotation
3 | * properly. The formatting of typeAnnotation should be handled by an external
4 | * plugin since not all users will require this feature and implementation is
5 | * pretty complex.
6 | * @flow
7 | */
8 | function foo(a: string, b: number): void {
9 | return a + String(b);
10 | }
11 |
12 | var x: boolean = someBool;
13 |
14 | class Bar {
15 | y: string;
16 | someMethod(a: number): string {
17 | return a * 2;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/compare/custom/call_expression-in.js:
--------------------------------------------------------------------------------
1 | foo();
2 |
3 | bar(1,'dolor');ipsum(3,{amet:true},'foo');
4 |
5 | dolor=foo(2)
6 |
7 | // should remove line breaks
8 | foo(a,b,
9 | c,d)
10 |
11 |
12 | // it should indent chained calls if there is a line break between each call
13 | foo.bar()
14 | .ipsum()
15 | .dolor();
16 |
17 | function foo() {
18 | dolor
19 | .amet()
20 | .maecennas();
21 | }
22 |
23 | returned.promise().done(foo)
24 | .done(newDefer.resolve)
25 | .fail(newDefer.reject)
26 | .progress(newDefer.notify);
27 |
28 |
--------------------------------------------------------------------------------
/test/compare/custom/call_expression-out.js:
--------------------------------------------------------------------------------
1 | foo();
2 |
3 | bar( 1 ,'dolor' );
4 | ipsum( 3 ,{
5 | amet: true
6 | } ,'foo' );
7 |
8 | dolor = foo( 2 )
9 |
10 | // should remove line breaks
11 | foo( a ,b ,c ,d )
12 |
13 |
14 | // it should indent chained calls if there is a line break between each call
15 | foo.bar()
16 | .ipsum()
17 | .dolor();
18 |
19 | function foo() {
20 | dolor
21 | .amet()
22 | .maecennas();
23 | }
24 |
25 | returned.promise().done( foo )
26 | .done( newDefer.resolve )
27 | .fail( newDefer.reject )
28 | .progress( newDefer.notify );
29 |
30 |
--------------------------------------------------------------------------------
/test/compare/custom/for_statement-out.js:
--------------------------------------------------------------------------------
1 | for ( i = 0; i < n; ++i ) {
2 | x();
3 | }
4 |
5 | for ( ; i < n; ++i ) {
6 | x();
7 | }
8 |
9 | for ( ;; ++i ) {
10 | x();
11 | }
12 |
13 | for ( i = 0;; ) {
14 | x();
15 | }
16 |
17 | for ( ; i < n; ++i ) {
18 | for ( ; j > 0; --j ) {
19 | x();
20 | }
21 | }
22 |
23 | for ( ;; ) {
24 | x();
25 | }
26 |
27 | function foo() {
28 | for ( var c = this._bindings.length, d; c--; )
29 | x += 1;
30 | return -1;
31 | }
32 |
33 | for ( i = 0; i < 10; i++ ) foo();
34 | for ( i = 10; i < 10; i++ )
35 | bar();
36 |
--------------------------------------------------------------------------------
/test/compare/custom/commented_config-config.json:
--------------------------------------------------------------------------------
1 | /*
2 | * This is an example of comments used on a config.json file
3 | */
4 |
5 | {
6 | // In this style guide we'll have curly brackets on next line :)
7 | "lineBreak" : {
8 | "before" : {
9 | "IfStatementOpeningBrace" : 1
10 | }
11 | },
12 |
13 | // No whitespace between if statement and parenthesis
14 | "whiteSpace" : {
15 | "before" : {
16 | "IfStatementConditionalOpening" : 0,
17 | "IfStatementConditionalClosing" : 0
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/plugin/esformatter-test-plugin.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // IMPORTANT: run `npm rm esformatter-test-plugin && npm i test/plugin` every
4 | // time you update this file!
5 |
6 | exports.setOptions = function(opts, esformatter) {
7 | opts.foo = 'bar';
8 | opts.bar = 123;
9 | // makes sure we are able to read default values and edit it
10 | opts.indent.ArrayExpression += 2;
11 | this.opts = opts;
12 | this.esformatter = esformatter;
13 | };
14 |
15 | exports.tokenBefore = function(token) {
16 | if (token.value === 'true') {
17 | token.value = 'false';
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/lib/preset/default.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | "extends": [
5 | require('./default-indent'),
6 | require('./default-linebreak-before'),
7 | require('./default-linebreak-after'),
8 | require('./default-whitespace-before'),
9 | require('./default-whitespace-after')
10 | ],
11 |
12 | "esformatter": {
13 | "allowShebang": true
14 | },
15 |
16 | "indent": {
17 | "value": " ",
18 | "alignComments": true,
19 | },
20 |
21 | "lineBreak": {
22 | "value": "\n"
23 | },
24 |
25 | "whiteSpace": {
26 | "value": " ",
27 | "removeTrailing": 1
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/test/compare/default/iife-out.js:
--------------------------------------------------------------------------------
1 | (function(i) {
2 | function h(a, b, c, d, e) {
3 | this._listener = b;
4 | this._isOnce = c;
5 | this.context = d;
6 | this._signal = a;
7 | this._priority = e || 0
8 | }
9 | i.h = h;
10 | }(this));
11 |
12 |
13 | // issue #191
14 | var data = {
15 | items: (function() {
16 | return [1, 2, 3, 4];
17 | }()),
18 | foo: true
19 | };
20 |
21 | // issue #223
22 | (function() {
23 | var x = 1;
24 | foo(bar(), baz());
25 | }());
26 |
27 | // issue #250
28 | (function($) {
29 | x;
30 | }(jQuery));
31 |
32 | ;!function(x) {
33 | console.log(x)
34 | }('bar')
35 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-3-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "ObjectExpressionOpeningBrace": -1,
5 | "ObjectExpressionClosingBrace": -1,
6 | "Property": -1
7 | },
8 |
9 | "after": {
10 | "ObjectExpressionOpeningBrace": -1,
11 | "ObjectExpressionClosingBrace": -1,
12 | "Property": -1
13 | }
14 | },
15 |
16 | "whiteSpace" : {
17 | "before": {
18 | "ObjectExpressionClosingBrace": 1
19 | },
20 | "after" : {
21 | "MethodName": 1,
22 | "ObjectExpressionOpeningBrace": 1,
23 | "PropertyValue": -1
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/test/compare/custom/function-expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "after": {
4 | "ParameterComma": 0
5 | }
6 | },
7 | "whiteSpace" : {
8 | "before" : {
9 | "FunctionName" : 1,
10 | "FunctionExpressionOpeningBrace" : 1,
11 | "FunctionExpressionClosingBrace" : 1,
12 | "FunctionGeneratorAsterisk" : 1
13 | },
14 | "after" : {
15 | "FunctionReservedWord": 1,
16 | "FunctionName" : 1,
17 | "FunctionExpressionOpeningBrace" : 1,
18 | "FunctionExpressionClosingBrace" : 1
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/compare/custom/switch_statement-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent" : {
3 | "SwitchStatement" : 0,
4 | "SwitchCase": 1
5 | },
6 | "whiteSpace" : {
7 | "before" : {
8 | "SwitchDiscriminantClosing" : 1
9 | },
10 | "after" : {
11 | "SwitchDiscriminantOpening" : 1
12 | }
13 | },
14 | "lineBreak": {
15 | "before": {
16 | "SwitchOpeningBrace": 1,
17 | "SwitchClosingBrace": 1
18 | },
19 | "after": {
20 | "BreakKeyword": 2,
21 | "SwitchOpeningBrace": 1,
22 | "SwitchClosingBrace": ">= 0"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/compare/default/while_statement-out.js:
--------------------------------------------------------------------------------
1 | // no parens and asi
2 | while (cur = items[i++]) log(cur.name);
3 |
4 | // wrong indent and line breaks
5 | while (
6 | ++n <
7 | 10
8 | ) {
9 | log(n)
10 | }
11 |
12 | // no body
13 | while (foo());
14 |
15 | // break before open curly brace and lots of spaces
16 | while (true) {
17 | // comment inside
18 | foo();
19 | }
20 |
21 | while (n--) {
22 | // nested
23 | while (i++) {
24 | // moar nested
25 | while (z++ < 0) {
26 | // inception
27 | foo();
28 | while (j++) {
29 | // deeper
30 | bar();
31 | }
32 | }
33 | }
34 | }
35 |
36 |
37 | // no body #2
38 | while (true);
39 |
40 |
--------------------------------------------------------------------------------
/test/compare/custom/for_in_statement-in.js:
--------------------------------------------------------------------------------
1 | for(key in obj){doFoo(obj[key]);}
2 | // we do not remove line breaks! (we assume user knows what he is doing)
3 | for( key
4 | in obj )doFoo(obj[key]);
5 |
6 | for(var k in o){
7 | console.log(k, o[k]);
8 | }
9 |
10 | for(key in obj ){
11 | for(prop in obj[key]) {
12 | //indent
13 | console.log(prop)
14 | }
15 | }
16 |
17 | // issue #13 : ForInStatement should not mess with inline object indent
18 | function iss13() {
19 | for (i in {submit : true, change : true, focusin : true}) {
20 | console.log(i);
21 | }
22 | }
23 |
24 | // line breaks and weird spaces
25 | for (key in obj)
26 |
27 | {
28 | doFoo(obj[key]);
29 | }
30 |
--------------------------------------------------------------------------------
/test/compare/custom/for_of_statement-in.js:
--------------------------------------------------------------------------------
1 | for(key of obj){doFoo(obj[key]);}
2 | // we do not remove line breaks! (we assume user knows what he is doing)
3 | for( key
4 | of obj )doFoo(obj[key]);
5 |
6 | for(var k of o){
7 | console.log(k, o[k]);
8 | }
9 |
10 | for(key of obj ){
11 | for(prop of obj[key]) {
12 | //indent
13 | console.log(prop)
14 | }
15 | }
16 |
17 | // issue #13 : ForOfStatement should not mess with inline object indent
18 | function iss13() {
19 | for (i of {submit : true, change : true, focusin : true}) {
20 | console.log(i);
21 | }
22 | }
23 |
24 | // line breaks and weird spaces
25 | for (key of obj)
26 |
27 | {
28 | doFoo(obj[key]);
29 | }
30 |
--------------------------------------------------------------------------------
/test/compare/default/binary_expression-in.js:
--------------------------------------------------------------------------------
1 | 1.33>>>0
2 | foo >> 3 ;
3 | 2+ 2
4 | 3 * 1;
5 | 3<<1
6 | 12 | 255
7 | 12^ 255
8 | ;(++n<10);
9 |
10 | // trailing
11 | 27&64 ;
12 | 15 % 5
13 |
14 | // asi and ExpressionStatement
15 | foo>bar
16 | a < b
17 | ;(a==b);
18 | ( a === b );
19 | a<= b
20 | 3.25 >=b
21 |
22 | // issue #212
23 | var str = '' +
24 | v1 +
25 | 'x' +
26 | // ~~(xx.time/60) +
27 | xx.time +
28 | 'min';
29 |
30 | msg = 'lorem' +
31 | 'ipsum' +
32 | 'dolor' +
33 | // sit
34 | 'amet'
35 |
36 | bar(
37 | 123 /
38 | 456 *
39 | 0.75 ^
40 | 255 |
41 | 98 <<
42 | 1 -
43 | 42
44 | );
45 |
46 | log("foo" +
47 | "bar"
48 | );
49 |
--------------------------------------------------------------------------------
/lib/hooks/BinaryExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _ws = require('rocambole-whitespace');
5 |
6 |
7 | exports.format = function BinaryExpression(node) {
8 | var operator = _tk.findNext(node.left.endToken, node.operator);
9 | _ws.limit(operator, 'BinaryExpressionOperator');
10 | };
11 |
12 | exports.getIndentEdges = function(node) {
13 | // we only add indent for the top most BinaryExpression (in case we have
14 | // multiple operations in a row)
15 | if (node.parent.type === 'BinaryExpression') {
16 | return;
17 | }
18 |
19 | return {
20 | startToken: node.startToken.next,
21 | endToken: node.endToken.next || node.endToken
22 | };
23 | };
24 |
--------------------------------------------------------------------------------
/test/compare/default/binary_expression-out.js:
--------------------------------------------------------------------------------
1 | 1.33 >>> 0
2 | foo >> 3;
3 | 2 + 2
4 | 3 * 1;
5 | 3 << 1
6 | 12 | 255
7 | 12 ^ 255
8 | ;(++n < 10);
9 |
10 | // trailing
11 | 27 & 64;
12 | 15 % 5
13 |
14 | // asi and ExpressionStatement
15 | foo > bar
16 | a < b
17 | ;(a == b);
18 | (a === b);
19 | a <= b
20 | 3.25 >= b
21 |
22 | // issue #212
23 | var str = '' +
24 | v1 +
25 | 'x' +
26 | // ~~(xx.time/60) +
27 | xx.time +
28 | 'min';
29 |
30 | msg = 'lorem' +
31 | 'ipsum' +
32 | 'dolor' +
33 | // sit
34 | 'amet'
35 |
36 | bar(
37 | 123 /
38 | 456 *
39 | 0.75 ^
40 | 255 |
41 | 98 <<
42 | 1 -
43 | 42
44 | );
45 |
46 | log("foo" +
47 | "bar"
48 | );
49 |
--------------------------------------------------------------------------------
/test/compare/custom/comment_group-in.js:
--------------------------------------------------------------------------------
1 | // this is a comment block
2 | // all the lines are considered
3 | // as a single "block" and we can
4 | // add linebreaks before/after
5 | // the whole block
6 | var foo = {
7 | // Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
8 | // tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
9 | // veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
10 | // commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
11 | // velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
12 | // cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
13 | // est laborum.
14 | lorem: "ipsum"
15 | };
16 |
--------------------------------------------------------------------------------
/test/compare/custom/for_in_statement-out.js:
--------------------------------------------------------------------------------
1 | for ( key in obj )
2 | {
3 | doFoo(obj[key]);
4 | }
5 | // we do not remove line breaks! (we assume user knows what he is doing)
6 | for ( key
7 | in obj ) doFoo(obj[key]);
8 |
9 | for ( var k in o )
10 | {
11 | console.log(k, o[k]);
12 | }
13 |
14 | for ( key in obj )
15 | {
16 | for ( prop in obj[key] )
17 | {
18 | //indent
19 | console.log(prop)
20 | }
21 | }
22 |
23 | // issue #13 : ForInStatement should not mess with inline object indent
24 | function iss13() {
25 | for ( i in {submit: true, change: true, focusin: true} )
26 | {
27 | console.log(i);
28 | }
29 | }
30 |
31 | // line breaks and weird spaces
32 | for ( key in obj )
33 | {
34 | doFoo(obj[key]);
35 | }
36 |
--------------------------------------------------------------------------------
/test/compare/custom/for_of_statement-out.js:
--------------------------------------------------------------------------------
1 | for ( key of obj )
2 | {
3 | doFoo(obj[key]);
4 | }
5 | // we do not remove line breaks! (we assume user knows what he is doing)
6 | for ( key
7 | of obj ) doFoo(obj[key]);
8 |
9 | for ( var k of o )
10 | {
11 | console.log(k, o[k]);
12 | }
13 |
14 | for ( key of obj )
15 | {
16 | for ( prop of obj[key] )
17 | {
18 | //indent
19 | console.log(prop)
20 | }
21 | }
22 |
23 | // issue #13 : ForOfStatement should not mess with inline object indent
24 | function iss13() {
25 | for ( i of {submit: true, change: true, focusin: true} )
26 | {
27 | console.log(i);
28 | }
29 | }
30 |
31 | // line breaks and weird spaces
32 | for ( key of obj )
33 | {
34 | doFoo(obj[key]);
35 | }
36 |
--------------------------------------------------------------------------------
/test/compare/custom/switch_statement-out.js:
--------------------------------------------------------------------------------
1 | switch ( event.keyCode )
2 | {
3 | case $.ui.keyCode.ENTER:
4 | case $.ui.keyCode.SPACE:
5 | case $.ui.keyCode.DOWN_ARROW:
6 | // line comment
7 | z();
8 | break
9 |
10 | case $.ui.keyCode.ESCAPE:
11 | y();
12 | break;
13 |
14 | default:
15 | x();
16 | }
17 |
18 | switch ( event.keyCode )
19 | {
20 | case $.ui.keyCode.ENTER:
21 | whatever = 'nothing';
22 | break
23 |
24 | case $.ui.keyCode.ESCAPE:
25 | whatever = 'something';
26 | break;
27 |
28 | default:
29 | x();
30 | }
31 |
32 | call(function() {
33 | switch ( fruit )
34 | {
35 | case Fruit.APPLE:
36 | // line comment
37 | exotic();
38 | break;
39 |
40 | default:
41 | unknown();
42 | }
43 | });
44 |
--------------------------------------------------------------------------------
/test/compare/default/while_statement-in.js:
--------------------------------------------------------------------------------
1 | // no parens and asi
2 | while(cur=items[i++]) log(cur.name);
3 |
4 | // wrong indent and line breaks
5 | while(
6 | ++n <
7 | 10
8 | ) {
9 | log(n)
10 | }
11 |
12 | // no body
13 | while ( foo() );
14 |
15 | // break before open curly brace and lots of spaces
16 | while ( true )
17 | {
18 | // comment inside
19 | foo();
20 | }
21 |
22 | while (n--){
23 | // nested
24 | while(i++){
25 | // moar nested
26 | while(z++<0) {
27 | // inception
28 | foo();
29 | while(j++) {
30 | // deeper
31 | bar();
32 | }
33 | }
34 | }
35 | }
36 |
37 |
38 | // no body #2
39 | while (true )
40 | ;
41 |
42 |
--------------------------------------------------------------------------------
/lib/limit.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // limit amount of consecutive white spaces and line breaks adjacent to a given
4 | // token.
5 |
6 | var _br = require('rocambole-linebreak');
7 | var _ws = require('rocambole-whitespace');
8 |
9 | exports.before = limitBefore;
10 | function limitBefore(token, typeOrValue) {
11 | _br.limitBefore(token, typeOrValue);
12 | _ws.limitBefore(token, typeOrValue);
13 | }
14 |
15 |
16 | exports.after = limitAfter;
17 | function limitAfter(token, typeOrValue) {
18 | _br.limitAfter(token, typeOrValue);
19 | _ws.limitAfter(token, typeOrValue);
20 | }
21 |
22 |
23 | exports.around = limitAround;
24 | function limitAround(token, typeOrValue) {
25 | _br.limit(token, typeOrValue);
26 | _ws.limit(token, typeOrValue);
27 | }
28 |
--------------------------------------------------------------------------------
/test/compare/custom/comment_group-out.js:
--------------------------------------------------------------------------------
1 | // this is a comment block
2 | // all the lines are considered
3 | // as a single "block" and we can
4 | // add linebreaks before/after
5 | // the whole block
6 |
7 | var foo = {
8 |
9 | // Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
10 | // tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
11 | // veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
12 | // commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
13 | // velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
14 | // cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
15 | // est laborum.
16 |
17 | lorem: "ipsum"
18 | };
19 |
--------------------------------------------------------------------------------
/doc/cli.txt:
--------------------------------------------------------------------------------
1 | Usage: esformatter [options] [files...]
2 |
3 | Options:
4 | -v, --version Display the current version.
5 | -h, --help Display help and usage details.
6 | -c, --config Path to custom configuration file.
7 | -p, --preset Set style guide preset ("jquery", "default").
8 | --plugins Comma separated list of plugins.
9 | -i Edit input files in place; use with care!
10 | --diff Check code style and output char diff.
11 | --diff-unified Check code style and output unified diff.
12 | --no-color Remove colors from diff (default if terminal doesn't
13 | support colors).
14 | --color Force colored diffs even if terminal doesn't support it.
15 |
--------------------------------------------------------------------------------
/lib/esformatter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // non-destructive changes to EcmaScript code using an "enhanced" AST for the
4 | // process, it updates the tokens in place and add/remove spaces & line breaks
5 | // based on user settings.
6 | // not using any kind of code rewrite based on string concatenation to avoid
7 | // breaking the program correctness and/or undesired side-effects.
8 |
9 | var plugins = require('./plugins');
10 |
11 | exports.diff = require('./diff');
12 | exports.hooks = require('./hooks');
13 | exports.format = require('./format');
14 | exports.transform = require('./transform');
15 | exports.rc = require('./options').getRc;
16 | exports.register = plugins.register;
17 | exports.unregister = plugins.unregister;
18 | exports.unregisterAll = plugins.unregisterAll;
19 |
--------------------------------------------------------------------------------
/test/compare/default/for_statement-in.js:
--------------------------------------------------------------------------------
1 | for(
2 | var i=0,
3 | n=things.length;
4 | i< n;
5 | i += 1
6 | ){
7 | // 1
8 | things[i];
9 | }
10 |
11 | for (i= 0; i< n;++i) { // 2
12 | things[i]; }
13 |
14 | for (; i< n;++i) { foo(i); /* 3 */ }
15 |
16 |
17 | for (; i< n;++i)
18 | {
19 | // 4
20 | for(; j > 0; --j) {
21 | // 5
22 | things[i][j]; }
23 | }
24 |
25 | // 6
26 | for
27 | (;;) {
28 | things[i];
29 | }
30 |
31 |
32 | // 7 : indent + no braces
33 | function foo() {
34 | for(var c=this._bindings.length,d;c--;)if (d = this._bindings[c], d._listener === a && d.context === b) return c;return -1}
35 |
36 |
37 | // 8: no {}
38 | for (i = 0; i < 10; i++) foo(i);
39 | for (i = 10; i < 10; i++)
40 | bar(i);
41 |
42 |
--------------------------------------------------------------------------------
/test/compare/custom/unary_expression-in.js:
--------------------------------------------------------------------------------
1 | !a
2 | !!foo
3 | !(foo);
4 | ;(!!foo)
5 | !( ! foo );
6 | !!(!foo);
7 |
8 | -x;
9 | - y;
10 |
11 | ~ a; //bitwise NOT is unary
12 |
13 | // these are actually UpdateExpression
14 | ++ foo;
15 | foo ++;
16 | -- bar;
17 | bar --;
18 |
19 | // delete is a UnaryExpression
20 | delete foo.bar; delete bar.amet;
21 |
22 | // issue #347
23 | delete foo['bar']; delete bar['amet'];
24 |
25 | // need to check indent as well
26 | function fn() {
27 | !!(!foo);
28 | delete this.bar
29 | delete this.amet;delete this.ipsum;
30 |
31 | delete this['bar']
32 | delete this['amet'];delete this['ipsum'];
33 | }
34 |
35 | typeof a === "number" ? x : y;
36 |
37 | var s = 'a string';
38 | console.log(typeof s);
39 |
40 | void 0;
41 |
--------------------------------------------------------------------------------
/test/compare/default/unary_expression-in.js:
--------------------------------------------------------------------------------
1 | !a
2 | !!foo
3 | !(foo);
4 | ;(!!foo)
5 | !( ! foo );
6 | !!(!foo);
7 |
8 | -x;
9 | - y;
10 |
11 | ~ a; //bitwise NOT is unary
12 |
13 | // these are actually UpdateExpression
14 | ++ foo;
15 | foo ++;
16 | -- bar;
17 | bar --;
18 |
19 | // delete is a UnaryExpression
20 | delete foo.bar; delete bar.amet;
21 |
22 | // issue #347
23 | delete foo['bar']; delete bar['amet'];
24 |
25 | // need to check indent as well
26 | function fn() {
27 | !!(!foo);
28 | delete this.bar
29 | delete this.amet;delete this.ipsum;
30 |
31 | delete this['bar']
32 | delete this['amet'];delete this['ipsum'];
33 | }
34 |
35 | typeof a === "number" ? x : y;
36 |
37 | var s = 'a string';
38 | console.log(typeof s);
39 |
40 | void 0;
41 |
--------------------------------------------------------------------------------
/test/compare/default/unary_expression-out.js:
--------------------------------------------------------------------------------
1 | !a
2 | !!foo
3 | !(foo);
4 | ;(!!foo)
5 | !(!foo);
6 | !!(!foo);
7 |
8 | -x;
9 | -y;
10 |
11 | ~a; //bitwise NOT is unary
12 |
13 | // these are actually UpdateExpression
14 | ++foo;
15 | foo++;
16 | --bar;
17 | bar--;
18 |
19 | // delete is a UnaryExpression
20 | delete foo.bar;
21 | delete bar.amet;
22 |
23 | // issue #347
24 | delete foo['bar'];
25 | delete bar['amet'];
26 |
27 | // need to check indent as well
28 | function fn() {
29 | !!(!foo);
30 | delete this.bar
31 | delete this.amet;
32 | delete this.ipsum;
33 |
34 | delete this['bar']
35 | delete this['amet'];
36 | delete this['ipsum'];
37 | }
38 |
39 | typeof a === "number" ? x : y;
40 |
41 | var s = 'a string';
42 | console.log(typeof s);
43 |
44 | void 0;
45 |
--------------------------------------------------------------------------------
/lib/hooks/ArrayPattern.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var limit = require('../limit');
4 | var tk = require('rocambole-token');
5 |
6 | exports.format = function ArrayPattern(node) {
7 | limit.around(node.startToken, 'ArrayPatternOpening');
8 | limit.around(node.endToken, 'ArrayPatternClosing');
9 |
10 | // array pattern might be like `[a,,b]`, so second element is actually `null`
11 | // that's why we can't blindly use the el.endToken so we store `searchStart`
12 | var searchStart = node.startToken;
13 | node.elements.forEach(function(el) {
14 | searchStart = tk.findNext(
15 | el ? el.endToken : searchStart,
16 | [',', ']']
17 | );
18 | if (searchStart.value === ',') {
19 | limit.around(searchStart, 'ArrayPatternComma');
20 | }
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/test/compare/custom/array_expression-2-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "ArrayExpressionOpening" : 0,
5 | "ArrayExpressionClosing" : 1
6 | },
7 | "after" : {
8 | "ArrayExpressionOpening" : 1,
9 | "ArrayExpressionClosing" : 0
10 | }
11 | },
12 | "lineBreak" : {
13 | "before" : {
14 | "ArrayExpressionOpening" : ">=1",
15 | "ArrayExpressionClosing" : 1,
16 | "ArrayExpressionComma" : 1,
17 | "VariableDeclarationSemiColon" : -1
18 | },
19 | "after" : {
20 | "ArrayExpressionOpening" : 1,
21 | "ArrayExpressionClosing" : 1,
22 | "ArrayExpressionComma" : 1
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/compare/custom/unary_expression-out.js:
--------------------------------------------------------------------------------
1 | ! a
2 | !! foo
3 | ! (foo);
4 | ;(!! foo)
5 | ! (! foo);
6 | !! (! foo);
7 |
8 | - x;
9 | - y;
10 |
11 | ~ a; //bitwise NOT is unary
12 |
13 | // these are actually UpdateExpression
14 | ++ foo;
15 | foo ++;
16 | -- bar;
17 | bar --;
18 |
19 | // delete is a UnaryExpression
20 | delete foo.bar;
21 | delete bar.amet;
22 |
23 | // issue #347
24 | delete foo['bar'];
25 | delete bar['amet'];
26 |
27 | // need to check indent as well
28 | function fn() {
29 | !! (! foo);
30 | delete this.bar
31 | delete this.amet;
32 | delete this.ipsum;
33 |
34 | delete this['bar']
35 | delete this['amet'];
36 | delete this['ipsum'];
37 | }
38 |
39 | typeof a === "number" ? x : y;
40 |
41 | var s = 'a string';
42 | console.log(typeof s);
43 |
44 | void 0;
45 |
--------------------------------------------------------------------------------
/test/compare/default/for_statement-out.js:
--------------------------------------------------------------------------------
1 | for (
2 | var i = 0,
3 | n = things.length;
4 | i < n;
5 | i += 1
6 | ) {
7 | // 1
8 | things[i];
9 | }
10 |
11 | for (i = 0; i < n; ++i) { // 2
12 | things[i];
13 | }
14 |
15 | for (; i < n; ++i) {
16 | foo(i); /* 3 */
17 | }
18 |
19 |
20 | for (; i < n; ++i) {
21 | // 4
22 | for (; j > 0; --j) {
23 | // 5
24 | things[i][j];
25 | }
26 | }
27 |
28 | // 6
29 | for (;;) {
30 | things[i];
31 | }
32 |
33 |
34 | // 7 : indent + no braces
35 | function foo() {
36 | for (var c = this._bindings.length, d; c--;)
37 | if (d = this._bindings[c], d._listener === a && d.context === b) return c;
38 | return -1
39 | }
40 |
41 |
42 | // 8: no {}
43 | for (i = 0; i < 10; i++) foo(i);
44 | for (i = 10; i < 10; i++)
45 | bar(i);
46 |
47 |
--------------------------------------------------------------------------------
/test/compare/custom/top-level-indent-exception-out.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | // top level block isn't indented
4 | var x = 123;
5 |
6 | setTimeout(function() {
7 | x();
8 | });
9 |
10 | }());
11 |
12 | // don't mess up other code outside a function scope
13 | var x = {
14 | abc: 123
15 | };
16 |
17 | module.exports = function() {
18 |
19 | var x = 123;
20 |
21 | };
22 |
23 | (function(factory) {
24 | if (typeof define === "function" && define.amd) {
25 | // AMD. Register as an anonymous module.
26 | define([
27 | "jquery",
28 | "./core",
29 | "./widget"
30 | ], factory);
31 | } else {
32 | // Browser globals
33 | factory(jQuery);
34 | }
35 | }(function($) {
36 | return $.widget("ui.accordion", {
37 | version: "@VERSION",
38 | options: {}
39 | });
40 | }));
41 |
--------------------------------------------------------------------------------
/test/compare/default/logical_expression-in.js:
--------------------------------------------------------------------------------
1 | a||b
2 | a || foo;
3 | foo&&bar
4 | ;(a||b);
5 | ( a&&b&&c );
6 |
7 |
8 | // expressions
9 | ;(a&&b) ||foo&&bar
10 | ;((a&&b)||c)||d
11 |
12 |
13 | // test line break and indent
14 | if (true) {
15 | var b;this.foo&&this.bar();
16 | }
17 |
18 | (foo || bar); (dolor || amet);
19 |
20 | foo = dolor ||
21 | amet &&
22 | bar
23 |
24 | var foo = dolor &&
25 | amet ||
26 | maecennas
27 |
28 | var foo,
29 | bar = x &&
30 | ( a || b );
31 |
32 | function x() {
33 | return (x || y) &&
34 |
35 | // comment
36 | call();
37 | }
38 |
39 | // issue #380
40 | let property = property || {
41 | name: '111'
42 | }
43 | prop = prop || {
44 | foo: '111'
45 | }
46 |
47 | // issue #421
48 | let foo = foo ||
49 | 42;
50 |
51 | let bar = bar() ||
52 | 42;
--------------------------------------------------------------------------------
/test/compare/custom/array_expression-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "ArrayExpressionOpening" : 0,
5 | "ArrayExpressionClosing" : 1,
6 | "ArrayExpressionComma" : 1
7 | },
8 | "after" : {
9 | "ArrayExpressionOpening" : 1,
10 | "ArrayExpressionClosing" : 0,
11 | "ArrayExpressionComma" : 0
12 | }
13 | },
14 | "lineBreak" : {
15 | "before" : {
16 | "ArrayExpressionOpening" : -1,
17 | "ArrayExpressionClosing" : -1,
18 | "ArrayExpressionComma" : -1
19 | },
20 | "after" : {
21 | "ArrayExpressionOpening" : -1,
22 | "ArrayExpressionClosing" : -1,
23 | "ArrayExpressionComma" : -1
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-in.js:
--------------------------------------------------------------------------------
1 | foo.bar.Baz( {
2 | method2: function () {}, prop : 'dolor amet'
3 | , prop2 : 123
4 | });
5 |
6 |
7 | function foo(a){ amet(123, a, {flag:true}); }
8 | ipsum({flag:true});
9 | ipsum({flag:true,other:false});
10 | ipsum({flag:true,other:false},789,'bar');
11 |
12 |
13 | var obj = {foo:"bar", 'lorem' : 123,
14 | dolor :new Date()
15 | , "re": /\w+/g} ;
16 |
17 | // ObjectEpression within CallExpression needs to indent comments
18 | declare({
19 | // comment
20 | create: {}
21 | });
22 |
23 | this.element
24 | .add()
25 | .set({
26 | // line comment
27 | // one more
28 | prop: "value"
29 | });
30 |
31 | define( name, {
32 | _create: function() {
33 | this.element
34 | .add()
35 | .set({
36 | // line comment
37 | // one more
38 | prop: "value"
39 | });
40 | }
41 | });
42 |
--------------------------------------------------------------------------------
/lib/hooks/ExportNamedDeclaration.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 |
7 | var ImportDeclaration = require('./ImportDeclaration');
8 |
9 | exports.format = function ExportNamedDeclaration(node) {
10 | _br.limitAfter(node.startToken, 0);
11 | _ws.limitAfter(node.startToken, 1);
12 |
13 | // node.specifiers is actually handled by the ExportSpecifier hook!
14 |
15 | if (!node.specifiers.length) return;
16 |
17 | var fromKeyword = _tk.findPrev(node.endToken, 'from');
18 | if (fromKeyword) {
19 | // safeguard against `export { foo, bar };` (no "from")
20 | _br.limit(fromKeyword, 0);
21 | _ws.limit(fromKeyword, 1);
22 | }
23 | };
24 |
25 | exports.getIndentEdges = ImportDeclaration.getIndentEdges;
26 |
--------------------------------------------------------------------------------
/test/compare/default/logical_expression-out.js:
--------------------------------------------------------------------------------
1 | a || b
2 | a || foo;
3 | foo && bar
4 | ;(a || b);
5 | (a && b && c);
6 |
7 |
8 | // expressions
9 | ;(a && b) || foo && bar
10 | ;((a && b) || c) || d
11 |
12 |
13 | // test line break and indent
14 | if (true) {
15 | var b;
16 | this.foo && this.bar();
17 | }
18 |
19 | (foo || bar); (dolor || amet);
20 |
21 | foo = dolor ||
22 | amet &&
23 | bar
24 |
25 | var foo = dolor &&
26 | amet ||
27 | maecennas
28 |
29 | var foo,
30 | bar = x &&
31 | (a || b);
32 |
33 | function x() {
34 | return (x || y) &&
35 |
36 | // comment
37 | call();
38 | }
39 |
40 | // issue #380
41 | let property = property || {
42 | name: '111'
43 | }
44 | prop = prop || {
45 | foo: '111'
46 | }
47 |
48 | // issue #421
49 | let foo = foo ||
50 | 42;
51 |
52 | let bar = bar() ||
53 | 42;
--------------------------------------------------------------------------------
/lib/hooks/BlockStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _limit = require('../limit');
4 |
5 | exports.format = function BlockStatement(node) {
6 | if (!shouldHandle(node)) {
7 | return;
8 | }
9 |
10 | _limit.around(node.startToken, 'BlockStatementOpeningBrace');
11 | _limit.around(node.endToken, 'BlockStatementClosingBrace');
12 | };
13 |
14 | function shouldHandle(node) {
15 | // BlockStatement is very generic and used in a bunch of different cases
16 | // (function/do/while/arrowFunction/for/forOf/...) so we only handle a few
17 | // cases here and let the other hooks take care of everything else
18 | return node.parent.type === 'Program' ||
19 | node.parent.type === 'BlockStatement';
20 | }
21 |
22 | exports.getIndentEdges = function(node) {
23 | if (!shouldHandle(node)) {
24 | return false;
25 | }
26 | return node;
27 | };
28 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; EditorConfig is awesome: http://EditorConfig.org
2 |
3 | ; top-most EditorConfig file
4 | root = true
5 |
6 | ; Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 |
13 | ; test files can have mized indent and there is no way to reset the value so we
14 | ; only add to files/folders that need it
15 | [lib/**]
16 | indent_style = space
17 | indent_size = 2
18 |
19 | [bin/*]
20 | indent_style = space
21 | indent_size = 2
22 |
23 | [test/*.js]
24 | indent_style = space
25 | indent_size = 2
26 |
27 | [package.json]
28 | indent_style = space
29 | indent_size = 2
30 |
31 | ; The test files can have mixed indent, tailing white space, etc...
32 | [test/compare/**]
33 | insert_final_newline = false
34 | trim_trailing_whitespace = false
35 |
36 |
--------------------------------------------------------------------------------
/test/compare/custom/module-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak": {
3 | "before": {
4 | // there is a conflict between the
5 | // lineBreak.after.FunctionDeclarationClosingBrace and the line break
6 | // around nodes logic, so we need to set "before" & "after" for all the
7 | // export/import declarations to override it
8 | "ExportAllDeclaration": 2,
9 | "ExportDefaultDeclaration": 2,
10 | "ExportNamedDeclaration": 2,
11 | "ModuleSpecifierClosingBrace": 1,
12 | "ModuleSpecifierComma": 0
13 | },
14 | "after": {
15 | "ExportAllDeclaration": 2,
16 | "ExportDefaultDeclaration": 2,
17 | "ExportNamedDeclaration": 2,
18 | "ImportDeclaration": 2,
19 | "ModuleSpecifierOpeningBrace": 1,
20 | "ModuleSpecifierClosingBrace": -1,
21 | "ModuleSpecifierComma": 1
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/compare/custom/switch_statement-in.js:
--------------------------------------------------------------------------------
1 | switch ( event.keyCode ) {
2 | case $.ui.keyCode.ENTER :
3 | case $.ui.keyCode.SPACE: case $.ui.keyCode.DOWN_ARROW:
4 | // line comment
5 | z();
6 | break
7 | case $.ui.keyCode.ESCAPE:
8 | y();
9 | break;
10 | default:
11 | x();
12 | }
13 |
14 | switch ( event.keyCode ) {
15 | case $.ui.keyCode.ENTER :
16 | whatever = 'nothing';
17 | break
18 | case $.ui.keyCode.ESCAPE
19 | :
20 | whatever = 'something';
21 | break;
22 | default:
23 | x();
24 | }
25 |
26 | call(function(){
27 | switch (fruit) {
28 | case Fruit.APPLE:
29 | // line comment
30 | exotic();
31 | break;
32 | default:
33 | unknown();
34 | }
35 | });
36 |
--------------------------------------------------------------------------------
/test/compare/custom/if_statement-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineBreak" : {
3 | "before" : {
4 | "IfStatement": ">=1",
5 | "ElseStatement" : 1,
6 | "ElseIfStatement" : 1,
7 | "IfStatementOpeningBrace" : 1,
8 | "ElseStatementOpeningBrace" : 1,
9 | "ElseIfStatementOpeningBrace" : 1,
10 | "LineComment": -1
11 | },
12 | "after": {
13 | "IfStatementOpeningBrace" : 1,
14 | "ElseStatementOpeningBrace" : 1
15 | }
16 | },
17 |
18 | "whiteSpace" : {
19 | "before" : {
20 | "IfStatementConditionalOpening" : 0,
21 | "IfStatementConditionalClosing" : 0
22 | },
23 | "after" : {
24 | "IfStatementConditionalOpening" : 0,
25 | "IfStatementConditionalClosing" : 1
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/hooks/SwitchStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _limit = require('../limit');
5 |
6 |
7 | exports.format = function SwitchStatement(node) {
8 | var opening = _tk.findPrev(node.discriminant.startToken, '(');
9 | var closing = _tk.findNext(node.discriminant.endToken, ')');
10 | var openingBrace = _tk.findNext(closing, '{');
11 | var closingBrace = node.endToken;
12 |
13 | _limit.around(openingBrace, 'SwitchOpeningBrace');
14 | _limit.around(closingBrace, 'SwitchClosingBrace');
15 | _limit.around(opening, 'SwitchDiscriminantOpening');
16 | _limit.around(closing, 'SwitchDiscriminantClosing');
17 |
18 | // cases are handled by SwitchCase hook!
19 |
20 | };
21 |
22 |
23 | exports.getIndentEdges = function(node) {
24 | return {
25 | startToken: _tk.findNext(node.discriminant.endToken, '{'),
26 | endToken: node.endToken
27 | };
28 | };
29 |
--------------------------------------------------------------------------------
/test/compare/custom/top-level-indent-exception-in.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | // top level block isn't indented
4 | var x = 123;
5 |
6 | setTimeout(function() {
7 | x();
8 | });
9 |
10 | }());
11 |
12 | // don't mess up other code outside a function scope
13 | var x = {
14 | abc: 123
15 | };
16 |
17 | module.exports = function() {
18 |
19 | var x = 123;
20 |
21 | };
22 |
23 | (function( factory ) {
24 | if ( typeof define === "function" && define.amd ) {
25 | // AMD. Register as an anonymous module.
26 | define([
27 | "jquery",
28 | "./core",
29 | "./widget"
30 | ], factory );
31 | } else {
32 | // Browser globals
33 | factory( jQuery );
34 | }
35 | }(function( $ ) {
36 | return $.widget( "ui.accordion", {
37 | version: "@VERSION",
38 | options: {}
39 | });
40 | }));
41 |
--------------------------------------------------------------------------------
/test/compare/default/for_of_statement-out.js:
--------------------------------------------------------------------------------
1 | for (key of obj) {
2 | doFoo(obj[key]);
3 | }
4 | // we do not remove line breaks! (we assume user knows what he is doing)
5 | for (key
6 | of obj) doFoo(obj[key]);
7 |
8 | for (var k of o) {
9 | console.log(k, o[k]);
10 | }
11 |
12 | for (key of obj) {
13 | for (prop of obj[key]) {
14 | //indent
15 | console.log(prop)
16 | }
17 | }
18 |
19 | // issue #13 : ForInStatement should not mess with inline object indent
20 | function iss13() {
21 | for (i of {submit: true, change: true, focusin: true}) {
22 | console.log(i);
23 | }
24 | }
25 |
26 | // keep empty statement on one line
27 | var key;
28 | for (key of obj) {}
29 |
30 |
31 |
32 |
33 |
34 |
35 | for (key of obj) {
36 | // line breaks, weird spaces and multiple empty lines before
37 | doFoo(obj[key]);
38 | }
39 |
40 | // no {}
41 | for (key of obj) doFoo(obj[key]);
42 | for (k of o)
43 | fn(o[k]);
44 |
--------------------------------------------------------------------------------
/test/compare/default/for_in_statement-out.js:
--------------------------------------------------------------------------------
1 | for (key in obj) {
2 | doFoo(obj[key]);
3 | }
4 | // we do not remove line breaks! (we assume user knows what he is doing)
5 | for (key
6 | in obj) doFoo(obj[key]);
7 |
8 | for (var k in o) {
9 | console.log(k, o[k]);
10 | }
11 |
12 | for (key in obj) {
13 | for (prop in obj[key]) {
14 | //indent
15 | console.log(prop)
16 | }
17 | }
18 |
19 | // issue #13 : ForInStatement should not mess with inline object indent
20 | function iss13() {
21 | for (i in {submit: true, change: true, focusin: true}) {
22 | console.log(i);
23 | }
24 | }
25 |
26 | // keep empty statement on one line
27 | var key;
28 | for (key in obj) {}
29 |
30 |
31 |
32 |
33 |
34 |
35 | for (key in obj) {
36 | // line breaks, weird spaces and multiple empty lines before
37 | doFoo(obj[key]);
38 | }
39 |
40 | // no {}
41 | for (key in obj) doFoo(obj[key]);
42 | for (k in o)
43 | fn(o[k]);
44 |
45 |
--------------------------------------------------------------------------------
/test/compare/default/for_of_statement-in.js:
--------------------------------------------------------------------------------
1 | for(key of obj){doFoo(obj[key]);}
2 | // we do not remove line breaks! (we assume user knows what he is doing)
3 | for( key
4 | of obj )doFoo(obj[key]);
5 |
6 | for(var k of o){
7 | console.log(k, o[k]);
8 | }
9 |
10 | for(key of obj){
11 | for(prop of obj[key]) {
12 | //indent
13 | console.log(prop)
14 | }
15 | }
16 |
17 | // issue #13 : ForInStatement should not mess with inline object indent
18 | function iss13() {
19 | for (i of {submit : true, change : true, focusin : true}) {
20 | console.log(i);
21 | }
22 | }
23 |
24 | // keep empty statement on one line
25 | var key;
26 | for ( key of obj ) {}
27 |
28 |
29 |
30 |
31 |
32 |
33 | for (key of obj)
34 |
35 | {
36 | // line breaks, weird spaces and multiple empty lines before
37 | doFoo(obj[key]);
38 | }
39 |
40 | // no {}
41 | for ( key of obj ) doFoo(obj[key]);
42 | for ( k of o )
43 | fn(o[k]);
44 |
--------------------------------------------------------------------------------
/test/compare/default/for_in_statement-in.js:
--------------------------------------------------------------------------------
1 | for(key in obj){doFoo(obj[key]);}
2 | // we do not remove line breaks! (we assume user knows what he is doing)
3 | for( key
4 | in obj )doFoo(obj[key]);
5 |
6 | for(var k in o){
7 | console.log(k, o[k]);
8 | }
9 |
10 | for(key in obj){
11 | for(prop in obj[key]) {
12 | //indent
13 | console.log(prop)
14 | }
15 | }
16 |
17 | // issue #13 : ForInStatement should not mess with inline object indent
18 | function iss13() {
19 | for (i in {submit : true, change : true, focusin : true}) {
20 | console.log(i);
21 | }
22 | }
23 |
24 | // keep empty statement on one line
25 | var key;
26 | for ( key in obj ) {}
27 |
28 |
29 |
30 |
31 |
32 |
33 | for (key in obj)
34 |
35 | {
36 | // line breaks, weird spaces and multiple empty lines before
37 | doFoo(obj[key]);
38 | }
39 |
40 | // no {}
41 | for ( key in obj ) doFoo(obj[key]);
42 | for ( k in o )
43 | fn(o[k]);
44 |
45 |
--------------------------------------------------------------------------------
/lib/hooks/ClassDeclarationAndExpression.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // this file handles both ClassDeclaration and ClassExpression
4 |
5 | var br = require('rocambole-linebreak');
6 | var tk = require('rocambole-token');
7 | var ws = require('rocambole-whitespace');
8 | var limit = require('../limit');
9 |
10 | exports.format = function ClassDeclarationAndExpression(node) {
11 | var classKeyword = node.startToken;
12 | br.limit(classKeyword, 'ClassKeyword');
13 | ws.limitAfter(classKeyword, 1);
14 |
15 | var opening = node.body.startToken;
16 | var extendsKeyword = tk.findInBetween(classKeyword, opening, 'extends');
17 | if (extendsKeyword) {
18 | br.limit(extendsKeyword, 'ClassExtendsKeyword');
19 | ws.limit(extendsKeyword, 1);
20 | }
21 |
22 | limit.around(opening, 'ClassOpeningBrace');
23 | limit.around(node.body.endToken, 'ClassClosingBrace');
24 | };
25 |
26 | exports.getIndentEdges = function(node) {
27 | return node;
28 | };
29 |
--------------------------------------------------------------------------------
/test/compare/custom/expression_parentheses-in.js:
--------------------------------------------------------------------------------
1 | ;(++n<10);
2 | ; (a==b);
3 | ( c === d );
4 | x = (value / 10);
5 | if (r * (x+1)+(y+2)) {
6 | y = ("123"+"3456");
7 | // parseInt() is the "catch" on this case
8 | z = ((q + w) / (parseInt('abc', 16) * (7) ))
9 | }
10 |
11 |
12 | // edge cases
13 | // ==========
14 |
15 | // not a bynary expression or a ExpressionStatement
16 | // VariableDeclaration > VariableDeclarator > [Identifier + Literal]
17 | var foo = (123);
18 |
19 |
20 | // SequenceExpression
21 | madness = (weird,stuff),(45,56)
22 |
23 | ;(bar());
24 | (function(){})();
25 | (function(){}());
26 |
27 | function returnTest() {
28 | return (x > 1);
29 | }
30 |
31 | function returnTest2() {
32 | return ( y + 1 );
33 | }
34 |
35 | function returnTest3(amount) {
36 | return amount + " result" + (amount > 1 ? "s" : "");
37 | }
38 |
39 | function returnTest4() {
40 | return (a || b < 0) && y();
41 | }
42 |
43 |
44 | fn((1 + 3) + 4);
45 |
--------------------------------------------------------------------------------
/lib/hooks/CatchClause.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _limit = require('../limit');
5 |
6 |
7 | exports.format = function CatchClause(node) {
8 | _limit.around(node.startToken, 'CatchKeyword');
9 |
10 | _limit.before(node.param.startToken, 'CatchParameterList');
11 | _limit.after(node.param.endToken, 'CatchParameterList');
12 |
13 | _limit.around(node.body.startToken, 'CatchOpeningBrace');
14 | _limit.around(node.body.endToken, 'CatchClosingBrace');
15 |
16 | // only remove line breaks if there are no comments inside. Ref #169
17 | if (!node.body.body.length && !containsCommentsInside(node.body)) {
18 | _tk.removeEmptyInBetween(node.body.startToken, node.body.endToken);
19 | }
20 | };
21 |
22 |
23 | function containsCommentsInside(node) {
24 | return !!_tk.findInBetween(node.startToken, node.endToken, _tk.isComment);
25 | }
26 |
27 | exports.getIndentEdges = function(node) {
28 | return node.body;
29 | };
30 |
--------------------------------------------------------------------------------
/test/compare/custom/basic_function_indent-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent" : {
3 | "FunctionDeclaration" : 0
4 | },
5 | "lineBreak" : {
6 | "before" : {
7 | "FunctionDeclarationOpeningBrace" : 0,
8 | "FunctionDeclarationClosingBrace" : 0,
9 | "ReturnStatement" : 0
10 | },
11 | "after" : {
12 | "FunctionDeclarationOpeningBrace" : 0,
13 | "FunctionDeclarationClosingBrace" : ">= 0"
14 | }
15 | },
16 | "whiteSpace" : {
17 | "before" : {
18 | "ParameterComma" : 0,
19 | "ParameterList" : 1,
20 | "FunctionDeclarationOpeningBrace" : 0,
21 | "FunctionDeclarationClosingBrace" : 1
22 | },
23 | "after" : {
24 | "FunctionName" : 1,
25 | "ParameterComma" : 0,
26 | "ParameterList" : 1,
27 | "FunctionDeclarationOpeningBrace" : 1
28 | }
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/test/compare/custom/expression_parentheses-out.js:
--------------------------------------------------------------------------------
1 | ;( ++n < 10 );
2 | ;( a == b );
3 | ( c === d );
4 | x = ( value / 10 );
5 | if (r * ( x + 1 ) + ( y + 2 )) {
6 | y = ( "123" + "3456" );
7 | // parseInt() is the "catch" on this case
8 | z = ( ( q + w ) / ( parseInt('abc', 16) * ( 7 ) ) )
9 | }
10 |
11 |
12 | // edge cases
13 | // ==========
14 |
15 | // not a bynary expression or a ExpressionStatement
16 | // VariableDeclaration > VariableDeclarator > [Identifier + Literal]
17 | var foo = ( 123 );
18 |
19 |
20 | // SequenceExpression
21 | madness = ( weird, stuff ), ( 45, 56 )
22 |
23 | ;( bar() );
24 | (function() {})();
25 | (function() {}());
26 |
27 | function returnTest() {
28 | return ( x > 1 );
29 | }
30 |
31 | function returnTest2() {
32 | return ( y + 1 );
33 | }
34 |
35 | function returnTest3(amount) {
36 | return amount + " result" + ( amount > 1 ? "s" : "" );
37 | }
38 |
39 | function returnTest4() {
40 | return ( a || b < 0 ) && y();
41 | }
42 |
43 |
44 | fn(( 1 + 3 ) + 4);
45 |
--------------------------------------------------------------------------------
/test/compare/custom/object_expression-out.js:
--------------------------------------------------------------------------------
1 | foo.bar.Baz({
2 | method2 : function() {},
3 | prop : 'dolor amet',
4 | prop2 : 123
5 | });
6 |
7 |
8 | function foo(a) {
9 | amet(123, a, {
10 | flag : true
11 | });
12 | }
13 | ipsum({
14 | flag : true
15 | });
16 | ipsum({
17 | flag : true,
18 | other : false
19 | });
20 | ipsum({
21 | flag : true,
22 | other : false
23 | }, 789, 'bar');
24 |
25 |
26 | var obj = {
27 | foo : "bar",
28 | 'lorem' : 123,
29 | dolor : new Date(),
30 | "re" : /\w+/g
31 | };
32 |
33 | // ObjectEpression within CallExpression needs to indent comments
34 | declare({
35 | // comment
36 | create : {}
37 | });
38 |
39 | this.element
40 | .add()
41 | .set({
42 | // line comment
43 | // one more
44 | prop : "value"
45 | });
46 |
47 | define(name, {
48 | _create : function() {
49 | this.element
50 | .add()
51 | .set({
52 | // line comment
53 | // one more
54 | prop : "value"
55 | });
56 | }
57 | });
58 |
--------------------------------------------------------------------------------
/lib/hooks/DoWhileStatement.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _tk = require('rocambole-token');
4 | var _limit = require('../limit');
5 | var _ws = require('rocambole-whitespace');
6 |
7 |
8 | exports.format = function DoWhileStatement(node) {
9 | if (node.body.type === 'BlockStatement') {
10 | _limit.around(node.body.startToken, 'DoWhileStatementOpeningBrace');
11 | _limit.around(node.body.endToken, 'DoWhileStatementClosingBrace');
12 | } else {
13 | _ws.limitAfter(node.startToken, 1);
14 | }
15 | var whileKeyword = _tk.findPrev(node.test.startToken, 'while');
16 | _ws.limit(whileKeyword, 1);
17 | };
18 |
19 |
20 | exports.getIndentEdges = function(node) {
21 | var edges = [
22 | { // do
23 | startToken: node.startToken.next,
24 | endToken: node.body.endToken
25 | },
26 | { // while
27 | startToken: _tk.findNext(node.body.endToken, '('),
28 | endToken: node.endToken.value === ')' ? node.endToken : _tk.findPrev(node.endToken, ')')
29 | }
30 | ];
31 |
32 | return edges;
33 | };
34 |
--------------------------------------------------------------------------------
/test/transform.spec.js:
--------------------------------------------------------------------------------
1 | /*jshint node:true*/
2 | /*global describe:false, it:false*/
3 | "use strict";
4 |
5 | var expect = require('chai').expect;
6 |
7 | var esformatter = require('../lib/esformatter');
8 | var rocambole = require('rocambole');
9 |
10 |
11 | // ---
12 |
13 |
14 | describe('esformatter.transform()', function() {
15 |
16 | it('should transform rocambole AST in place', function() {
17 | var inputAST = rocambole.parse('var foo = 123;');
18 | var outputAST = esformatter.transform(inputAST);
19 | expect(outputAST).to.be.equal(inputAST);
20 | });
21 |
22 |
23 | it('should allow options as second arg', function() {
24 | var inputAST = rocambole.parse('var foo = 123;');
25 | var outputAST = esformatter.transform(inputAST, {
26 | whiteSpace: {
27 | after: {
28 | VariableName: 0
29 | },
30 | before: {
31 | VariableValue: 0
32 | }
33 | }
34 | });
35 | expect(outputAST.toString()).to.be.equal('var foo=123;');
36 | });
37 |
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/lib/hooks/LogicalExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 |
7 |
8 | exports.format = function LogicalExpression(node) {
9 | var operator = _tk.findNext(node.left.endToken, node.operator);
10 | _ws.limit(operator, 'LogicalExpressionOperator');
11 | // revert line breaks since parenthesis might not be part of
12 | // node.startToken and node.endToken
13 | if (node.parent.type === 'ExpressionStatement') {
14 | var prev = _tk.findPrevNonEmpty(node.left.startToken);
15 | if (prev && prev.value === '(') {
16 | _br.limit(prev, 'ExpressionOpeningParentheses');
17 | _ws.limit(prev, 'ExpressionOpeningParentheses');
18 | node.startToken = prev;
19 | }
20 | var next = _tk.findNextNonEmpty(node.right.endToken);
21 | if (next && next.value === ')') {
22 | _br.limit(next, 'ExpressionClosingParentheses');
23 | _ws.limit(next, 'ExpressionClosingParentheses');
24 | node.endToken = next;
25 | }
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/test/compare/custom/if_statement-in.js:
--------------------------------------------------------------------------------
1 | if(true){doStuff()}
2 |
3 | if( foo ||bar ){ if (bar === 'bar'){
4 | // nested
5 | log('nested if'); } else { log('nested else')
6 | } }
7 | else if (baz==null)
8 | {
9 | // else if
10 | log('elseif');
11 | }else{
12 | // else
13 | log('else');
14 | // should keep the 2 empty lines
15 |
16 |
17 | }
18 |
19 | if( singleLine )singleLine();
20 |
21 |
22 | // it's a trap!
23 | if (asi && noBraces)
24 | dolor()
25 | else
26 | amet();
27 |
28 | // another trap!
29 | if (asi && noBraces)
30 | dolor()
31 | else
32 | { amet();}
33 |
34 |
35 |
36 | // issue #34 (break line comment into individual line)
37 | if ( window.DOMParser ) { // Standard
38 | tmp = new DOMParser();
39 | xml = tmp.parseFromString( data , "text/xml" );
40 | } else { // IE
41 | xml = new ActiveXObject( "Microsoft.XMLDOM" );
42 | xml.async = "false";
43 | xml.loadXML( data );
44 | }
45 |
46 |
47 | // issue #196
48 | if (a)
49 | a(); // run a
50 | else if (b)
51 | b(); // run b
52 | else {
53 | c(); // run c
54 | }
55 |
--------------------------------------------------------------------------------
/test/compare/default/arrow_function_expression-out.js:
--------------------------------------------------------------------------------
1 | arr.map(a => a * 2);
2 | arr.map(b => {
3 | return b * 2;
4 | });
5 | arr.map((c, i) => {
6 | return c * i;
7 | });
8 | arr.map(d => {
9 | return d * 2;
10 | });
11 | arr.map((e, f, g) => e * f - g);
12 |
13 | // noop (#487)
14 | const f1 = () => {};
15 | const f2 = () => {};
16 | const f3 = () => {};
17 |
18 | // default params (#285)
19 | let defaultParams = (x, y = 1, z = 2) => {
20 | return x + y + z;
21 | }
22 |
23 | // issue #393
24 | a = () => {
25 | test(() => {
26 | return 1
27 | })
28 | test(() => {
29 | return 1
30 | })
31 | }
32 |
33 | // issue #357
34 | const object = x => ({
35 | x
36 | });
37 |
38 | const retObject = x => {
39 | return {
40 | x
41 | };
42 | }
43 |
44 | const array = x => [
45 | x
46 | ];
47 |
48 | const callWithObject = x => f({
49 | x
50 | });
51 |
52 | // issue #399
53 | const helloWorld = () => (
54 | 'Hello' + ' ' + 'World'
55 | )
56 |
57 | // issue #400
58 | ;
59 | () => process.exit(0);
60 | (example) => process.exit(0);
61 | function example() {
62 | return process.exit(0);
63 | }
64 |
--------------------------------------------------------------------------------
/test/compare/default/conditional_expression-in.js:
--------------------------------------------------------------------------------
1 | a?foo():bar();
2 |
3 | b = (dolor!==amet) ? 'ipsum': 'dolor';
4 |
5 | if(true){
6 | // notice that we don't indent since "consequent" is on same line as "test"
7 | c = !a ?(!foo?d : function(){
8 | return a;
9 | }):b;
10 | }
11 |
12 | // should break lines
13 | foo.a = true; a?foo() : bar()
14 |
15 |
16 | // from jquery
17 | x = function(num) {
18 | return num == null ?
19 |
20 | // Return a 'clean' array
21 | this.toArray() :
22 |
23 | // Return just the object
24 | (object);
25 | }
26 |
27 | function x() {
28 | x.test(y) ?
29 | a :
30 | b;
31 | }
32 |
33 | num == null ?
34 |
35 | // Return a 'clean' array
36 | this.toArray() :
37 |
38 | // Return just the object
39 | ( num < 0 ? this[ this.length + num ] : this[ num ] );
40 |
41 | // issue #253
42 | var format = isSameDate(startDate, endDate) ? this._oneDayLabelFormat :
43 | 'event-multiple-day-duration';
44 |
45 | // issue #380
46 | var foo = lorem ?
47 | ipsum :
48 | {
49 | dolor: 'sit'
50 | };
51 | amet = qwert ?
52 | asd :
53 | {
54 | zxc: 'opi'
55 | };
56 |
--------------------------------------------------------------------------------
/test/compare/default/conditional_expression-out.js:
--------------------------------------------------------------------------------
1 | a ? foo() : bar();
2 |
3 | b = (dolor !== amet) ? 'ipsum' : 'dolor';
4 |
5 | if (true) {
6 | // notice that we don't indent since "consequent" is on same line as "test"
7 | c = !a ? (!foo ? d : function() {
8 | return a;
9 | }) : b;
10 | }
11 |
12 | // should break lines
13 | foo.a = true;
14 | a ? foo() : bar()
15 |
16 |
17 | // from jquery
18 | x = function(num) {
19 | return num == null ?
20 |
21 | // Return a 'clean' array
22 | this.toArray() :
23 |
24 | // Return just the object
25 | (object);
26 | }
27 |
28 | function x() {
29 | x.test(y) ?
30 | a :
31 | b;
32 | }
33 |
34 | num == null ?
35 |
36 | // Return a 'clean' array
37 | this.toArray() :
38 |
39 | // Return just the object
40 | (num < 0 ? this[this.length + num] : this[num]);
41 |
42 | // issue #253
43 | var format = isSameDate(startDate, endDate) ? this._oneDayLabelFormat :
44 | 'event-multiple-day-duration';
45 |
46 | // issue #380
47 | var foo = lorem ?
48 | ipsum :
49 | {
50 | dolor: 'sit'
51 | };
52 | amet = qwert ?
53 | asd :
54 | {
55 | zxc: 'opi'
56 | };
57 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Miller Medeiros
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/test/compare/default/array_expression-in.js:
--------------------------------------------------------------------------------
1 | [
2 |
3 | ];
4 |
5 | [1,2,3];
6 |
7 | [1,2,[3,4,[5,6,[7,8,9]]]];
8 |
9 | function fn(){
10 | return [4,5,[6, 7 , 8 ]];
11 | }
12 |
13 | // issue #12
14 | var tuples = [
15 | // comment test
16 | ["resolve", "done", "bla", "resolved"],
17 | ["reject", "fail", "lorem", "rejected"],
18 | [
19 | ["lorem", "ipsum"]
20 | ],
21 | ["notify", "progress", "ipsum"]
22 | ];
23 |
24 | var x,
25 | y = [
26 | "a",
27 | "b",
28 | "c"
29 | ];
30 |
31 | // rocambole issue with sparse arrays
32 | ;[,3,[,4]];
33 | // sparse arrays indentation is tricky!
34 | ;[
35 | ,
36 | 3,
37 | [,,
38 | ,
39 | 4
40 | ]];
41 | ;[
42 | ,
43 | 3,
44 | [,
45 | 4
46 | ]
47 | ];
48 |
49 | // issue #165 (MemberExpression)
50 | [
51 | "grunt-contrib-concat",
52 | "grunt-contrib-watch",
53 | "grunt-contrib-jshint",
54 | "grunt-contrib-qunit"
55 | ].forEach(function( task ) {
56 | grunt.loadNpmTasks( task );
57 | });
58 |
59 | // issue #224
60 | var fa = [ {
61 | foo: 'bar',
62 | baz: 'yak'
63 | }, {
64 | foo: '1',
65 | baz: '2'
66 | } ];
67 |
68 | // issue #239
69 | var data = [1,
70 | 2];
71 |
--------------------------------------------------------------------------------
/test/compare/custom/if_statement-out.js:
--------------------------------------------------------------------------------
1 | if(true)
2 | {
3 | doStuff()
4 | }
5 |
6 | if(foo || bar)
7 | {
8 | if(bar === 'bar')
9 | {
10 | // nested
11 | log('nested if');
12 | }
13 | else
14 | {
15 | log('nested else')
16 | }
17 | }
18 | else if(baz == null)
19 | {
20 | // else if
21 | log('elseif');
22 | }
23 | else
24 | {
25 | // else
26 | log('else');
27 | // should keep the 2 empty lines
28 |
29 |
30 | }
31 |
32 | if(singleLine) singleLine();
33 |
34 |
35 | // it's a trap!
36 | if(asi && noBraces)
37 | dolor()
38 | else
39 | amet();
40 |
41 | // another trap!
42 | if(asi && noBraces)
43 | dolor()
44 | else
45 | {
46 | amet();
47 | }
48 |
49 |
50 |
51 | // issue #34 (break line comment into individual line)
52 | if(window.DOMParser)
53 | { // Standard
54 | tmp = new DOMParser();
55 | xml = tmp.parseFromString(data, "text/xml");
56 | }
57 | else
58 | { // IE
59 | xml = new ActiveXObject("Microsoft.XMLDOM");
60 | xml.async = "false";
61 | xml.loadXML(data);
62 | }
63 |
64 |
65 | // issue #196
66 | if(a)
67 | a(); // run a
68 | else if(b)
69 | b(); // run b
70 | else
71 | {
72 | c(); // run c
73 | }
74 |
--------------------------------------------------------------------------------
/lib/hooks/ImportDeclaration.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 |
7 | exports.format = function ImportDeclaration(node) {
8 | _br.limitAfter(node.startToken, 0);
9 | _ws.limitAfter(node.startToken, 1);
10 |
11 | // node.specifiers is actually handled by the ImportSpecifier hook!
12 |
13 | if (!node.specifiers.length) return;
14 |
15 | var fromKeyword = _tk.findPrev(node.endToken, 'from');
16 | _br.limit(fromKeyword, 0);
17 | _ws.limit(fromKeyword, 1);
18 | };
19 |
20 | exports.getIndentEdges = function(node) {
21 | // IMPORTANT: getIndentEdges logic is reused by ExportNamedDeclaration
22 | var braceStart;
23 | node.specifiers.some(function(spec) {
24 | var prev = _tk.findPrev(spec.startToken, _tk.isCode);
25 | if (prev.value === '{') {
26 | braceStart = prev;
27 | return true;
28 | }
29 | });
30 | if (!braceStart) {
31 | return;
32 | }
33 |
34 | return {
35 | startToken: braceStart,
36 | endToken: _tk.findNext(node.specifiers[node.specifiers.length - 1].endToken, '}')
37 | };
38 | };
39 |
--------------------------------------------------------------------------------
/test/compare/default/array_expression-out.js:
--------------------------------------------------------------------------------
1 | [];
2 |
3 | [1, 2, 3];
4 |
5 | [1, 2, [3, 4, [5, 6, [7, 8, 9]]]];
6 |
7 | function fn() {
8 | return [4, 5, [6, 7, 8]];
9 | }
10 |
11 | // issue #12
12 | var tuples = [
13 | // comment test
14 | ["resolve", "done", "bla", "resolved"],
15 | ["reject", "fail", "lorem", "rejected"],
16 | [
17 | ["lorem", "ipsum"]
18 | ],
19 | ["notify", "progress", "ipsum"]
20 | ];
21 |
22 | var x,
23 | y = [
24 | "a",
25 | "b",
26 | "c"
27 | ];
28 |
29 | // rocambole issue with sparse arrays
30 | ;[, 3, [, 4]];
31 | // sparse arrays indentation is tricky!
32 | ;[
33 | ,
34 | 3,
35 | [,,
36 | ,
37 | 4
38 | ]];
39 | ;[
40 | ,
41 | 3,
42 | [,
43 | 4
44 | ]
45 | ];
46 |
47 | // issue #165 (MemberExpression)
48 | [
49 | "grunt-contrib-concat",
50 | "grunt-contrib-watch",
51 | "grunt-contrib-jshint",
52 | "grunt-contrib-qunit"
53 | ].forEach(function(task) {
54 | grunt.loadNpmTasks(task);
55 | });
56 |
57 | // issue #224
58 | var fa = [{
59 | foo: 'bar',
60 | baz: 'yak'
61 | }, {
62 | foo: '1',
63 | baz: '2'
64 | }];
65 |
66 | // issue #239
67 | var data = [1,
68 | 2];
69 |
--------------------------------------------------------------------------------
/test/compare/default/arrow_function_expression-in.js:
--------------------------------------------------------------------------------
1 | arr.map(a=>a*2);
2 | arr.map(b => {return b * 2;});
3 | arr.map(( c,i )=>{
4 | return c * i;
5 | });
6 | arr.map(d =>
7 | {return d * 2;});
8 | arr.map( ( e , f , g) => e * f - g );
9 |
10 | // noop (#487)
11 | const f1 = () => {};
12 | const f2 = ( ) => { };
13 | const f3 = ( ) => {
14 |
15 | };
16 |
17 | // default params (#285)
18 | let defaultParams = (x, y = 1, z = 2 ) => {
19 | return x + y + z;
20 | }
21 |
22 | // issue #393
23 | a = () => {
24 | test( () => {
25 | return 1
26 | })
27 | test(() => {
28 | return 1
29 | })
30 | }
31 |
32 | // issue #357
33 | const object = x => ({
34 | x
35 | });
36 |
37 | const retObject = x => {
38 | return {
39 | x
40 | };
41 | }
42 |
43 | const array = x => [
44 | x
45 | ];
46 |
47 | const callWithObject = x => f({
48 | x
49 | });
50 |
51 | // issue #399
52 | const helloWorld = () => (
53 | 'Hello' + ' ' + 'World'
54 | )
55 |
56 | // issue #400
57 | ;
58 | ( ) => process.exit( 0 );
59 | ( example ) => process.exit( 0 );
60 | function example() {
61 | return process.exit( 0 );
62 | }
63 |
--------------------------------------------------------------------------------
/test/compare/custom/array_expression-2-out.js:
--------------------------------------------------------------------------------
1 | [];
2 |
3 | [
4 | 1
5 | ,
6 | 2
7 | ,
8 | 3
9 | ]
10 | ;
11 |
12 | [
13 | 1
14 | ,
15 | 2
16 | ,
17 | [
18 | 3
19 | ,
20 | 4
21 | ,
22 | [
23 | 5
24 | ,
25 | 6
26 | ,
27 | [
28 | 7
29 | ,
30 | 8
31 | ,
32 | 9
33 | ]
34 | ]
35 | ]
36 | ]
37 | ;
38 |
39 | function fn() {
40 | // IMPORTANT: we can't break lines here because of ASI!!!
41 | return [
42 | 4
43 | ,
44 | 5
45 | ,
46 | [
47 | 6
48 | ,
49 | 7
50 | ,
51 | 8
52 | ]
53 | ];
54 | }
55 |
56 | // issue #12
57 | var tuples = [
58 | // comment test
59 | [
60 | "resolve"
61 | ,
62 | "done"
63 | ,
64 | "bla"
65 | ,
66 | "resolved"
67 | ]
68 | ,
69 | [
70 | "reject"
71 | ,
72 | "fail"
73 | ,
74 | "lorem"
75 | ,
76 | "rejected"
77 | ]
78 | ,
79 | [
80 | [
81 | "lorem"
82 | ,
83 | "ipsum"
84 | ]
85 | ]
86 | ,
87 | [
88 | "notify"
89 | ,
90 | "progress"
91 | ,
92 | "ipsum"
93 | ]
94 | ]
95 | ;
96 |
--------------------------------------------------------------------------------
/test/compare/custom/class_declaration-in.js:
--------------------------------------------------------------------------------
1 | // #286
2 | class Foo extends Bar {
3 | constructor (properties, name = 'lorem', ...extra)
4 | {
5 | this.properties = properties;
6 | this.name = name;
7 | this.extra = extra;
8 | }
9 | static
10 | log ( msg , level = 'log' ) {
11 | console[level](msg);
12 | } toObject () { return this.properties; } } class Foo extends Bar {
13 | // empty lines in between the MethodDefinition
14 |
15 | constructor(properties) {
16 | this.properties = properties;
17 | }
18 | get prop() {
19 | return 'getter';
20 | }
21 | set prop(val) {
22 | Foo.log('setting: ', val)
23 | }
24 |
25 |
26 |
27 |
28 | static log(msg, level = 'log') {
29 | console[level]('[Foo]', msg);
30 | }
31 |
32 |
33 |
34 |
35 |
36 | toObject() {
37 | return this.properties;
38 | }
39 |
40 |
41 |
42 |
43 | }
44 |
45 | // Multi line declaration
46 | class
47 | Foo
48 | extends
49 | Bar
50 | {
51 | }
52 | // The value to be extended can be produced by an arbitrary expression.
53 | class Foo extends BarNamespace.Bar{}
54 | class Foo extends BarNamespace['Bar'].Bar["Bar"]('bar').Bar("bar", "bar"){}
55 | class Foo extends(BarNamespace.bar)(){}
56 |
--------------------------------------------------------------------------------
/lib/hooks/AssignmentExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _ws = require('rocambole-whitespace');
5 | var _br = require('rocambole-linebreak');
6 | var helpers = require('../helpers');
7 |
8 |
9 | exports.format = function AssignmentExpression(node) {
10 | // can't use node.right.startToken since it might be surrounded by
11 | // a parenthesis (see #5)
12 | var operator = _tk.findNext(node.left.endToken, node.operator);
13 | _br.limit(operator, 'AssignmentOperator');
14 | _ws.limit(operator, 'AssignmentOperator');
15 | };
16 |
17 |
18 | exports.getIndentEdges = function(node, opts) {
19 | var operator = _tk.findNext(node.left.endToken, node.operator);
20 | if (_tk.findInBetween(operator, node.right.startToken, _tk.isBr) ||
21 | (helpers.shouldIndentChild(node, node.right, opts) &&
22 | _tk.findInBetween(operator, node.right.endToken, _tk.isBr))) {
23 | // we only indent if assignment is on next line
24 | return {
25 | level: opts['AssignmentExpression.' + node.right.type],
26 | startToken: operator,
27 | endToken: node.endToken.type !== 'Punctuator' ?
28 | node.endToken.next : node.endToken
29 | };
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/lib/hooks/MethodDefinition.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var br = require('rocambole-linebreak');
4 | var limit = require('../limit');
5 | var tk = require('rocambole-token');
6 | var ws = require('rocambole-whitespace');
7 |
8 | exports.format = function MethodDefinition(node) {
9 | br.limitAfter(node.startToken, 0);
10 |
11 | // key name
12 | if (node.startToken.value === '[') {
13 | // computed key
14 | limit.around(node.startToken, 'MethodDefinitionComputedOpening');
15 | limit.around(
16 | tk.findNext(node.key.endToken, ']'),
17 | 'MethodDefinitionComputedClosing'
18 | );
19 | } else {
20 | if (node.startToken !== node.key.startToken) {
21 | // limit to one space after get/set/static
22 | ws.limitAfter(node.startToken, 1);
23 | }
24 | ws.limitAfter(node.key.endToken, 'MethodDefinitionName');
25 | }
26 |
27 | // curly braces {}
28 | var opening = node.value.body.startToken;
29 | limit.around(opening, 'MethodDefinitionOpeningBrace');
30 | limit.around(node.endToken, 'MethodDefinitionClosingBrace');
31 | var bodyFirstNonEmpty = tk.findNextNonEmpty(opening);
32 | if (bodyFirstNonEmpty.value === '}') {
33 | // noop
34 | limit.after(opening, 0);
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/lib/diff.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var format = require('./format');
4 | var disparity = require('disparity');
5 |
6 | var hr = '==================================================================' +
7 | '==============';
8 |
9 | // these headers make more sense in this context
10 | disparity.added = 'expected';
11 | disparity.removed = 'actual';
12 |
13 | exports.chars = chars;
14 | function chars(str, opts, fileName) {
15 | var result = disparity.chars(str, format(str, opts));
16 | if (!result) {
17 | return '';
18 | }
19 | // we add a line break at the end because it looks better
20 | return getHeader(fileName) + result + '\n';
21 | }
22 |
23 | function getHeader(fileName) {
24 | return fileName ? cyan(fileName) + '\n' + cyan(hr) + '\n' : '';
25 | }
26 |
27 | function cyan(str) {
28 | return '\u001b[36m' + str + '\u001b[39m';
29 | }
30 |
31 | exports.unified = unified;
32 | function unified(str, opts, fileName) {
33 | return disparity.unified(str, format(str, opts), {
34 | paths: [fileName]
35 | });
36 | }
37 |
38 | exports.unifiedNoColor = unifiedNoColor;
39 | function unifiedNoColor(str, opts, fileName) {
40 | return disparity.unifiedNoColor(str, format(str, opts), {
41 | paths: [fileName]
42 | });
43 | }
44 |
--------------------------------------------------------------------------------
/test/compare/default/comments-out.js:
--------------------------------------------------------------------------------
1 | // line comment, no indent
2 |
3 | /*
4 | * block comment, no indent
5 | */
6 | if (true) {
7 | // line comment, 1 indent
8 | /**
9 | * block comment, 1 indent
10 | */
11 | if (true) {
12 | // line comment, 2 indents
13 | /*
14 | * block comment, 2 indent
15 | */
16 | if (true) {
17 | /* block single line, 3 indents */
18 | /*
19 | BLOCK ASCII
20 | |___________
21 | |___
22 | `----> YEAH
23 | */
24 | bar();
25 | }
26 | }
27 | }
28 |
29 | /* block single line, no indent */
30 |
31 |
32 |
33 | // test PR #57
34 | var obj = { /* test trailing space after multi line comment */
35 | then: function( /* fnDone, fnFail, fnProgress */ ) {
36 | var fns = arguments; // test space before comment
37 | }
38 | };
39 |
40 | function foo() { // single line after token that requires line break
41 | if (false) { /* multi line after token that requires line break */
42 | bar();
43 | }
44 | }
45 |
46 | foo
47 | .bar()
48 |
49 | // surrounded by empty lines and after chained expression
50 |
51 | // issue #139
52 | var pfun = new PFunction(function(hello /*, foo )
53 | ,bar { */ , world) {});
54 |
--------------------------------------------------------------------------------
/lib/hooks/FunctionDeclaration.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _ws = require('rocambole-whitespace');
5 | var _limit = require('../limit');
6 | var _params = require('./Params');
7 |
8 |
9 | exports.format = function FunctionDeclaration(node) {
10 | if (node.id) {
11 | _limit.around(node.id.startToken, 'FunctionName');
12 | }
13 | // babel-eslint reports async functions as generators.
14 | //
15 | // Make sure the generator function is not an async function before removing
16 | // the whitespace.
17 | //
18 | // This will prevent a function such as `async function fun() {}` being
19 | // converted to `asyncfunction fun() {}`.
20 | if (node.async) {
21 | _ws.limitAfter(node.startToken, 1);
22 | } else if (node.generator) {
23 | var genToken = _tk.findNextNonEmpty(node.startToken);
24 | _ws.limitBefore(genToken, 'FunctionGeneratorAsterisk');
25 | }
26 | _params.format(node);
27 | _limit.around(node.body.startToken, 'FunctionDeclarationOpeningBrace');
28 | _limit.around(node.body.endToken, 'FunctionDeclarationClosingBrace');
29 | };
30 |
31 |
32 | exports.getIndentEdges = function(node, opts) {
33 | return [
34 | _params.getIndentEdges(node, opts),
35 | node.body
36 | ];
37 | };
38 |
--------------------------------------------------------------------------------
/lib/hooks/MemberExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _limit = require('../limit');
5 |
6 |
7 | exports.format = function MemberExpression(node) {
8 | var opening = _tk.findPrevNonEmpty(node.property.startToken),
9 | closing = _tk.findNextNonEmpty(node.property.endToken);
10 | if (opening && closing && opening.value === '[' && closing.value === ']') {
11 | _limit.around(opening, 'MemberExpressionOpening');
12 | _limit.around(closing, 'MemberExpressionClosing');
13 | }
14 | if (opening && opening.value === '.') {
15 | _limit.around(opening, 'MemberExpressionPeriod');
16 | }
17 | };
18 |
19 |
20 | exports.getIndentEdges = function(node) {
21 | var edge = {};
22 | edge.startToken = node.object.endToken;
23 |
24 | if (node.object.type !== 'CallExpression') {
25 | edge.startToken = edge.startToken.next;
26 | }
27 |
28 | edge.endToken = node.endToken;
29 | if (node.parent.type === 'CallExpression' &&
30 | node.parent.callee.type === 'MemberExpression') {
31 | edge.endToken = node.parent.endToken;
32 | }
33 |
34 | // only indent if on a different line
35 | if (!_tk.findInBetween(edge.startToken, node.property.startToken, _tk.isBr)) {
36 | return false;
37 | }
38 |
39 | return edge;
40 | };
41 |
42 |
--------------------------------------------------------------------------------
/test/runner.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // we run mocha manually otherwise istanbul coverage won't work
4 | // run `npm test --coverage` to generate coverage report
5 |
6 | var Mocha = require('mocha');
7 |
8 |
9 | // ---
10 |
11 |
12 |
13 | // to set these options run the test script like:
14 | // > BAIL=true GREP=array_expression REPORTER=dot npm test
15 | var opts = {
16 | ui: 'bdd',
17 | bail: !!(process.env.BAIL),
18 | reporter: (process.env.REPORTER || 'spec'),
19 | grep: process.env.GREP
20 | };
21 |
22 | // we use the dot reporter on travis since it works better
23 | if (process.env.TRAVIS) {
24 | opts.reporter = 'dot';
25 | }
26 |
27 | var m = new Mocha(opts);
28 |
29 | if (process.env.INVERT) {
30 | m.invert();
31 | }
32 |
33 |
34 | m.addFile('test/format.spec.js');
35 | m.addFile('test/transform.spec.js');
36 | m.addFile('test/diff.spec.js');
37 | m.addFile('test/api.spec.js');
38 | m.addFile('test/plugins.spec.js');
39 | // run slower tests later for faster feedback cyle
40 | // extremely helpful when running tests with `BAIL=true npm test`
41 | m.addFile('test/cli.spec.js');
42 | m.addFile('test/pipe.spec.js');
43 |
44 | m.run(function(err) {
45 | var exitCode = err ? 1 : 0;
46 | if (err) console.log('failed tests: ' + err);
47 | process.exit(exitCode);
48 | });
49 |
50 |
--------------------------------------------------------------------------------
/test/compare/default/class_declaration-in.js:
--------------------------------------------------------------------------------
1 | // #286
2 | class Foo extends Bar {
3 | constructor (properties, name = 'lorem', ...extra)
4 | {
5 | this.properties = properties;
6 | this.name = name;
7 | this.extra = extra;
8 | }
9 | static
10 | log ( msg , level = 'log' ) {
11 | console[level](msg);
12 | } toObject () { return this.properties; } } class Foo extends Bar {
13 | // empty lines in between the MethodDefinition are valid/kept
14 |
15 | constructor(properties) {
16 | this.properties = properties;
17 | }
18 |
19 | get prop() {
20 | return 'getter';
21 | }
22 |
23 | set prop(val) {
24 | Foo.log('setting: ', val)
25 | }
26 |
27 | static log(msg, level = 'log') {
28 | console[level]('[Foo]', msg);
29 | }
30 |
31 | toObject() {
32 | return this.properties;
33 | }
34 |
35 | }
36 |
37 | // Multi line declaration
38 | class
39 | Foo
40 | extends
41 | Bar
42 | {
43 | }
44 | // The value to be extended can be produced by an arbitrary expression.
45 | class Foo extends BarNamespace.Bar{}
46 | class Foo extends BarNamespace['Bar'].Bar["Bar"]('bar').Bar("bar", "bar"){}
47 | class Foo extends(BarNamespace.bar)(){}
48 |
49 | // #470
50 | const mySym = Symbol('some-symbol');
51 | class Foo {
52 | [ mySym ]() {
53 | return true;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/lib/hooks/ConditionalExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _ws = require('rocambole-whitespace');
5 |
6 |
7 | exports.format = function ConditionalExpression(node) {
8 | // we need to grab the actual punctuators since parenthesis aren't counted
9 | // as part of test/consequent/alternate
10 | var questionMark = _tk.findNext(node.test.endToken, '?');
11 | var colon = _tk.findNext(node.consequent.endToken, ':');
12 |
13 | _ws.limitBefore(questionMark, _ws.expectedAfter('ConditionalExpressionTest'));
14 | _ws.limitAfter(questionMark, _ws.expectedBefore('ConditionalExpressionConsequent'));
15 | _ws.limitBefore(colon, _ws.expectedAfter('ConditionalExpressionConsequent'));
16 | _ws.limitAfter(colon, _ws.expectedBefore('ConditionalExpressionAlternate'));
17 | };
18 |
19 |
20 | exports.getIndentEdges = function(node) {
21 | if (_tk.findInBetween(node.test.endToken, node.consequent.startToken, _tk.isBr)) {
22 | return {
23 | startToken: node.test.endToken.next,
24 | endToken: node.endToken.next
25 | };
26 | }
27 | if (_tk.findInBetween(node.consequent.endToken, node.alternate.startToken, _tk.isBr)) {
28 | return {
29 | startToken: node.consequent.endToken.next,
30 | endToken: node.endToken.next
31 | };
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/test/compare/custom/class_declaration-out.js:
--------------------------------------------------------------------------------
1 | // #286
2 | class Foo extends Bar {
3 |
4 |
5 | constructor (properties, name = 'lorem', ...extra)
6 | {
7 | this.properties = properties;
8 | this.name = name;
9 | this.extra = extra;
10 | }
11 |
12 |
13 | static log (msg, level = 'log')
14 | {
15 | console[level](msg);
16 | }
17 |
18 |
19 | toObject ()
20 | {
21 | return this.properties;
22 | }
23 |
24 |
25 | }
26 | class Foo extends Bar {
27 | // empty lines in between the MethodDefinition
28 |
29 |
30 | constructor (properties)
31 | {
32 | this.properties = properties;
33 | }
34 |
35 |
36 | get prop ()
37 | {
38 | return 'getter';
39 | }
40 |
41 |
42 | set prop (val)
43 | {
44 | Foo.log('setting: ', val)
45 | }
46 |
47 |
48 | static log (msg, level = 'log')
49 | {
50 | console[level]('[Foo]', msg);
51 | }
52 |
53 |
54 | toObject ()
55 | {
56 | return this.properties;
57 | }
58 |
59 |
60 | }
61 |
62 | // Multi line declaration
63 | class Foo extends Bar {
64 | }
65 | // The value to be extended can be produced by an arbitrary expression.
66 | class Foo extends BarNamespace.Bar {
67 | }
68 | class Foo extends BarNamespace['Bar'].Bar["Bar"]('bar').Bar("bar", "bar") {
69 | }
70 | class Foo extends (BarNamespace.bar)() {
71 | }
72 |
--------------------------------------------------------------------------------
/test/compare/default/class_declaration-out.js:
--------------------------------------------------------------------------------
1 | // #286
2 | class Foo extends Bar {
3 | constructor(properties, name = 'lorem', ...extra) {
4 | this.properties = properties;
5 | this.name = name;
6 | this.extra = extra;
7 | }
8 | static log(msg, level = 'log') {
9 | console[level](msg);
10 | }
11 | toObject() {
12 | return this.properties;
13 | }
14 | }
15 | class Foo extends Bar {
16 | // empty lines in between the MethodDefinition are valid/kept
17 |
18 | constructor(properties) {
19 | this.properties = properties;
20 | }
21 |
22 | get prop() {
23 | return 'getter';
24 | }
25 |
26 | set prop(val) {
27 | Foo.log('setting: ', val)
28 | }
29 |
30 | static log(msg, level = 'log') {
31 | console[level]('[Foo]', msg);
32 | }
33 |
34 | toObject() {
35 | return this.properties;
36 | }
37 |
38 | }
39 |
40 | // Multi line declaration
41 | class Foo extends Bar {
42 | }
43 | // The value to be extended can be produced by an arbitrary expression.
44 | class Foo extends BarNamespace.Bar {
45 | }
46 | class Foo extends BarNamespace['Bar'].Bar["Bar"]('bar').Bar("bar", "bar") {
47 | }
48 | class Foo extends (BarNamespace.bar)() {
49 | }
50 |
51 | // #470
52 | const mySym = Symbol('some-symbol');
53 | class Foo {
54 | [mySym]() {
55 | return true;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/test/compare/default/class_expression-in.js:
--------------------------------------------------------------------------------
1 | var foo = class Foo extends Bar {
2 | constructor (properties, name = 'lorem', ...extra)
3 | {
4 | this.properties = properties;
5 | this.name = name;
6 | this.extra = extra;
7 | }
8 | static
9 | log ( msg , level = 'log' ) {
10 | console[level](msg);
11 | } toObject () { return this.properties; } }
12 | let bar = class Foo extends Bar {
13 | // empty lines in between the MethodDefinition are valid/kept
14 |
15 | constructor(properties) {
16 | this.properties = properties;
17 | }
18 |
19 | get prop() {
20 | return 'getter';
21 | }
22 |
23 | set prop(val) {
24 | Foo.log('setting: ', val)
25 | }
26 |
27 | static log(msg, level = 'log') {
28 | console[level]('[Foo]', msg);
29 | }
30 |
31 | toObject() {
32 | return this.properties;
33 | }
34 |
35 | }
36 |
37 | // Multi line declaration
38 | let dolor = class
39 | Foo
40 | extends
41 | Bar
42 | {
43 | }
44 | // The value to be extended can be produced by an arbitrary expression.
45 | var amet = class Foo extends BarNamespace.Bar{}
46 | let ipsum = class Foo extends BarNamespace['Bar'].Bar["Bar"]('bar').Bar("bar", "bar"){}
47 | const ullamcor = class Foo extends(BarNamespace.bar)(){}
48 |
49 |
50 | // issue #358
51 | function makeClass() {
52 | return class MyClass {
53 | method() {}
54 | };
55 | }
56 |
--------------------------------------------------------------------------------
/test/compare/default/class_expression-out.js:
--------------------------------------------------------------------------------
1 | var foo = class Foo extends Bar {
2 | constructor(properties, name = 'lorem', ...extra) {
3 | this.properties = properties;
4 | this.name = name;
5 | this.extra = extra;
6 | }
7 | static log(msg, level = 'log') {
8 | console[level](msg);
9 | }
10 | toObject() {
11 | return this.properties;
12 | }
13 | }
14 | let bar = class Foo extends Bar {
15 | // empty lines in between the MethodDefinition are valid/kept
16 |
17 | constructor(properties) {
18 | this.properties = properties;
19 | }
20 |
21 | get prop() {
22 | return 'getter';
23 | }
24 |
25 | set prop(val) {
26 | Foo.log('setting: ', val)
27 | }
28 |
29 | static log(msg, level = 'log') {
30 | console[level]('[Foo]', msg);
31 | }
32 |
33 | toObject() {
34 | return this.properties;
35 | }
36 |
37 | }
38 |
39 | // Multi line declaration
40 | let dolor = class Foo extends Bar {
41 | }
42 | // The value to be extended can be produced by an arbitrary expression.
43 | var amet = class Foo extends BarNamespace.Bar {
44 | }
45 | let ipsum = class Foo extends BarNamespace['Bar'].Bar["Bar"]('bar').Bar("bar", "bar") {
46 | }
47 | const ullamcor = class Foo extends (BarNamespace.bar)() {
48 | }
49 |
50 |
51 | // issue #358
52 | function makeClass() {
53 | return class MyClass {
54 | method() {}
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/test/compare/custom/try_statement-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "CatchClause": 1,
4 | "TryStatement": 1
5 | },
6 |
7 | "lineBreak": {
8 | "before": {
9 | "CatchOpeningBrace": 1,
10 | "CatchClosingBrace": ">=1",
11 | "CatchKeyword": 1,
12 | "FinallyKeyword": 1,
13 | "FinallyOpeningBrace": 1,
14 | "FinallyClosingBrace": ">=1",
15 | "TryOpeningBrace": 1,
16 | "TryClosingBrace": ">=1"
17 | },
18 |
19 | "after": {
20 | "CatchOpeningBrace": ">=1",
21 | "CatchClosingBrace": ">=0",
22 | "CatchKeyword": 0,
23 | "FinallyOpeningBrace": ">=1",
24 | "FinallyClosingBrace": ">=1",
25 | "TryOpeningBrace": ">=1",
26 | "TryClosingBrace": 1
27 | }
28 | },
29 |
30 | "whiteSpace": {
31 | "before": {
32 | "CatchParameterList": 0,
33 | "CatchOpeningBrace": 1,
34 | "CatchClosingBrace": 1,
35 | "CatchKeyword": 1,
36 | "FinallyOpeningBrace": 1,
37 | "FinallyClosingBrace": 1,
38 | "TryOpeningBrace": 1,
39 | "TryClosingBrace": 1
40 | },
41 |
42 | "after": {
43 | "CatchParameterList": 0,
44 | "CatchOpeningBrace": 1,
45 | "CatchClosingBrace": 1,
46 | "CatchKeyword": 1,
47 | "FinallyOpeningBrace": 1,
48 | "FinallyClosingBrace": 1,
49 | "TryOpeningBrace": 1,
50 | "TryClosingBrace": 1
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/test/compare/default/module-out.js:
--------------------------------------------------------------------------------
1 | // samples borrowed from http://www.2ality.com/2014/09/es6-modules-final.html
2 |
3 | // Default exports and named exports
4 | import theDefault, { named1, named2 } from 'src/mylib';
5 | import theDefault from 'src/mylib';
6 | import { named1, named2 } from 'src/mylib';
7 |
8 | // Renaming: import named1 as myNamed1
9 | import { named1 as myNamed1, named2 } from 'src/mylib';
10 |
11 | // Importing the module as an object
12 | // (with one property per named export)
13 | import * as mylib from 'src/mylib';
14 |
15 | // Only load the module, don’t import anything
16 | import 'src/mylib';
17 |
18 | export var myVar1 = 123;
19 | export let myVar2 = 'foo';
20 | export const MY_CONST = 'BAR';
21 |
22 | export function myFunc() {
23 | return 'myfunc';
24 | }
25 |
26 | export function* myGeneratorFunc() {
27 | return yield someStuff();
28 | }
29 | export class MyClass {
30 | constructor() {
31 | this.name = 'exports test';
32 | }
33 | }
34 |
35 | export default class {
36 | constructor(x, y) {
37 | this.x = x;
38 | this.y = y;
39 | }
40 | }
41 |
42 | // #408
43 | export { lorem, hipstersum, nosemicolon }
44 |
45 | export { FOO_CONST, myOtherFunc };
46 | export { MY_CONST as THE_CONST, myFunc as theFunc };
47 |
48 | export * from 'src/other_module';
49 | export { foo, bar } from 'src/other_module';
50 | export { foo as myFoo, baz } from 'src/other_module';
51 |
--------------------------------------------------------------------------------
/lib/hooks/TryStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _limit = require('../limit');
5 |
6 |
7 | exports.format = function TryStatement(node) {
8 | var finalizer = node.finalizer;
9 | if (finalizer) {
10 | var finallyKeyword = _tk.findPrev(finalizer.startToken, 'finally');
11 | _limit.around(finallyKeyword, 'FinallyKeyword');
12 | _limit.around(finalizer.startToken, 'FinallyOpeningBrace');
13 | _limit.around(finalizer.endToken, 'FinallyClosingBrace');
14 |
15 | if (!finalizer.body.length && !containsCommentsInside(finalizer)) {
16 | // XXX: empty body, so we should remove all white spaces
17 | _tk.removeEmptyInBetween(finalizer.startToken, finalizer.endToken);
18 | }
19 | }
20 |
21 | // CatchClause is handled by its own hook
22 |
23 | _limit.around(node.startToken, 'TryKeyword');
24 | _limit.around(node.block.startToken, 'TryOpeningBrace');
25 | _limit.around(node.block.endToken, 'TryClosingBrace');
26 | };
27 |
28 |
29 | function containsCommentsInside(node) {
30 | return !!_tk.findInBetween(node.startToken, node.endToken, _tk.isComment);
31 | }
32 |
33 |
34 | exports.getIndentEdges = function(node) {
35 | var edges = [node.block];
36 |
37 | if (node.finalizer) {
38 | edges.push(node.finalizer);
39 | }
40 |
41 | // CatchClause is handled by it's own node (automatically)
42 |
43 | return edges;
44 | };
45 |
--------------------------------------------------------------------------------
/test/compare/custom/module-in.js:
--------------------------------------------------------------------------------
1 | // samples borrowed from http://www.2ality.com/2014/09/es6-modules-final.html
2 |
3 | // Default exports and named exports
4 | import theDefault,
5 | {named1,
6 | named2} from 'src/mylib';
7 | import
8 | theDefault from 'src/mylib';
9 | import
10 | { named1, named2 }
11 | from
12 | 'src/mylib';
13 |
14 | // Renaming: import named1 as myNamed1
15 | import { named1 as myNamed1, named2 } from 'src/mylib';
16 |
17 | // Importing the module as an object
18 | // (with one property per named export)
19 | import * as mylib from 'src/mylib';
20 |
21 | // Only load the module, don’t import anything
22 | import 'src/mylib';
23 |
24 | export var myVar1 = 123;
25 | export let myVar2 = 'foo';
26 | export const MY_CONST = 'BAR';
27 |
28 | export
29 | function myFunc() {
30 | return 'myfunc';
31 | }
32 |
33 | export function* myGeneratorFunc() {
34 | return yield someStuff();
35 | }
36 | export class MyClass {
37 | constructor() {
38 | this.name = 'exports test';
39 | }
40 | }
41 |
42 | export default class {
43 | constructor(x, y) {
44 | this.x = x;
45 | this.y = y;
46 | }
47 | }
48 |
49 | export { FOO_CONST, myOtherFunc };
50 | export { MY_CONST as THE_CONST, myFunc as theFunc };
51 |
52 | export * from 'src/other_module';
53 | export { foo , bar }from 'src/other_module';
54 | export {foo as myFoo,baz} from 'src/other_module';
55 |
--------------------------------------------------------------------------------
/lib/hooks/WhileStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _limit = require('../limit');
5 |
6 |
7 | exports.format = function WhileStatement(node) {
8 | var conditionalStart = _tk.findNext(node.startToken, '(');
9 | var conditionalEnd = _tk.findPrev(node.body.startToken, ')');
10 |
11 | _limit.around(conditionalStart, 'WhileStatementConditionalOpening');
12 |
13 | if (node.body.type === 'BlockStatement') {
14 | var bodyStart = node.body.startToken;
15 | var bodyEnd = node.body.endToken;
16 | _limit.around(bodyStart, 'WhileStatementOpeningBrace');
17 | _limit.around(bodyEnd, 'WhileStatementClosingBrace');
18 | _limit.around(conditionalEnd, 'WhileStatementConditionalClosing');
19 | } else {
20 | var next = _tk.findNextNonEmpty(conditionalEnd);
21 | _limit.before(conditionalEnd, 'WhileStatementConditionalClosing');
22 | if (_tk.isSemiColon(next)) {
23 | _limit.after(conditionalEnd, 0);
24 | } else {
25 | _limit.after(conditionalEnd, 'WhileStatementConditionalClosing');
26 | }
27 | }
28 | };
29 |
30 |
31 | exports.getIndentEdges = function(node) {
32 | var edges = [
33 | {
34 | startToken: _tk.findNext(node.startToken, '('),
35 | endToken: _tk.findPrev(node.body.startToken, ')')
36 | }
37 | ];
38 |
39 | if (node.body.type !== 'EmptyStatement') {
40 | edges.push(node.body);
41 | }
42 |
43 | return edges;
44 | };
45 |
--------------------------------------------------------------------------------
/test/compare/default/assignment_expression-in.js:
--------------------------------------------------------------------------------
1 | foo=bar; lorem =123
2 | dolor = "amet"
3 |
4 | // yes, this is valid JS
5 | maecennas
6 |
7 | +=
8 |
9 | "ullamcor"
10 | // end multi-line
11 |
12 |
13 | foo = fn(1);
14 |
15 | bar
16 | = 123;
17 |
18 | // assignment operators
19 |
20 | x+= y
21 | x -= y
22 | x *= y
23 | x /= y
24 | x%= y
25 | x<<= y
26 | x >>= y
27 | x
28 | >>>=
29 | y
30 | x&= y
31 | x^=y
32 | x|=y
33 |
34 |
35 | // multiple same line
36 | this.a=b;this.c=d;this.e=f;this.g=h||0;
37 |
38 | function h(a,b,c,d,e){this._listener=b;this._isOnce=c;this.context=d;this._signal=a;this._priority=e||0}
39 |
40 |
41 | // test for issue #5 (related to parenthesis)
42 | doc=(context&&context.nodeType?context.ownerDocument||context:document);
43 |
44 |
45 | // issue #8 (multiple assignment + OR + indent)
46 | function iss8(){
47 | if (proxy) {
48 | proxy.guid = fn.guid = fn.guid || jQuery.guid++;
49 | }
50 | }
51 |
52 | // issue #306: UnaryExpression
53 | hasNativeRequestAnimationFrame = !!(
54 | window.requestAnimationFrame ||
55 | window.webkitRequestAnimationFrame ||
56 | window.mozRequestAnimationFrame ||
57 | window.msRequestAnimationFrame
58 | );
59 |
60 | // issue #316
61 | export class Foobar extends EventEmitter {
62 | constructor(foo, bar, d = {}) {
63 | super();
64 | var fooBar = { foo, bar };
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/test/compare/default/assignment_expression-out.js:
--------------------------------------------------------------------------------
1 | foo = bar;
2 | lorem = 123
3 | dolor = "amet"
4 |
5 | // yes, this is valid JS
6 | maecennas += "ullamcor"
7 | // end multi-line
8 |
9 |
10 | foo = fn(1);
11 |
12 | bar = 123;
13 |
14 | // assignment operators
15 |
16 | x += y
17 | x -= y
18 | x *= y
19 | x /= y
20 | x %= y
21 | x <<= y
22 | x >>= y
23 | x >>>= y
24 | x &= y
25 | x ^= y
26 | x |= y
27 |
28 |
29 | // multiple same line
30 | this.a = b;
31 | this.c = d;
32 | this.e = f;
33 | this.g = h || 0;
34 |
35 | function h(a, b, c, d, e) {
36 | this._listener = b;
37 | this._isOnce = c;
38 | this.context = d;
39 | this._signal = a;
40 | this._priority = e || 0
41 | }
42 |
43 |
44 | // test for issue #5 (related to parenthesis)
45 | doc = (context && context.nodeType ? context.ownerDocument || context : document);
46 |
47 |
48 | // issue #8 (multiple assignment + OR + indent)
49 | function iss8() {
50 | if (proxy) {
51 | proxy.guid = fn.guid = fn.guid || jQuery.guid++;
52 | }
53 | }
54 |
55 | // issue #306: UnaryExpression
56 | hasNativeRequestAnimationFrame = !!(
57 | window.requestAnimationFrame ||
58 | window.webkitRequestAnimationFrame ||
59 | window.mozRequestAnimationFrame ||
60 | window.msRequestAnimationFrame
61 | );
62 |
63 | // issue #316
64 | export class Foobar extends EventEmitter {
65 | constructor(foo, bar, d = {}) {
66 | super();
67 | var fooBar = {
68 | foo,
69 | bar
70 | };
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/test/pipe.spec.js:
--------------------------------------------------------------------------------
1 | //jshint node:true
2 | /*global describe, it*/
3 | "use strict";
4 |
5 | var expect = require('chai').expect;
6 | var esformatter = require('../lib/esformatter');
7 |
8 | var input = 'var foo = bar;\nfunction bar(dolor, amet) {\n return dolor + amet;\n}';
9 | var output1 = '\n// ---- esformatter-pipe-test-1 ---\n';
10 | var output2 = '\n// ---- esformatter-pipe-test-2 ---\n';
11 |
12 | describe('pipe', function() {
13 |
14 | it('should call piped commands', function() {
15 | var out = esformatter.format(input, {
16 | pipe: {
17 | before: [
18 | 'esformatter-pipe-test-1',
19 | ],
20 | after: [
21 | 'esformatter-pipe-test-2'
22 | ]
23 | }
24 | });
25 | expect(out).to.eql(input + output1 + output2);
26 | });
27 |
28 | it('should call piped commands in order', function() {
29 | var out = esformatter.format(input, {
30 | pipe: {
31 | after: [
32 | 'esformatter-pipe-test-2',
33 | 'esformatter-pipe-test-1'
34 | ]
35 | }
36 | });
37 | expect(out).to.eql(input + output2 + output1);
38 | });
39 |
40 | it('should throw error if command not found', function() {
41 | expect(function() {
42 | esformatter.format(input, {
43 | pipe: {
44 | before: [
45 | 'esformatter-fake-pipe-command'
46 | ]
47 | }
48 | });
49 | }).to.throw();
50 | });
51 |
52 | });
53 |
--------------------------------------------------------------------------------
/lib/hooks/UnaryExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 |
7 |
8 | exports.format = function UnaryExpression(node) {
9 | if (node.operator === 'delete') {
10 | _ws.limitAfter(node.startToken, 1);
11 | _br.limitBefore(node.startToken, 'DeleteOperator');
12 |
13 | var endToken = node.endToken;
14 | if (_tk.isWs(endToken.next)) {
15 | _ws.limitAfter(endToken, 0);
16 | }
17 | if (_tk.isSemiColon(endToken.next)) {
18 | endToken = endToken.next;
19 | }
20 | _br.limitAfter(endToken, 'DeleteOperator');
21 | } else if (node.operator === 'typeof' || node.operator === 'void') {
22 | _ws.limitAfter(node.startToken, 1);
23 | } else {
24 | // multiple consecutive operators like `!!foo` should not have spaces in
25 | // between then (we consider whole block as a single operator)
26 | var operator = node.startToken;
27 | var prev = _tk.findPrev(operator, _tk.isNotEmpty);
28 | if (prev && prev.value === operator.value) {
29 | _ws.limitBefore(operator, 0);
30 | } else {
31 | _ws.limitBefore(operator, 'UnaryExpressionOperator');
32 | }
33 | var next = _tk.findNext(operator, _tk.isNotEmpty);
34 | if (next && next.value === operator.value) {
35 | _ws.limitAfter(operator, 0);
36 | } else {
37 | _ws.limitAfter(operator, 'UnaryExpressionOperator');
38 | }
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/test/compare/default/comments-in.js:
--------------------------------------------------------------------------------
1 | // line comment, no indent
2 |
3 | /*
4 | * block comment, no indent
5 | */
6 | if (true) {
7 | // line comment, 1 indent
8 | /**
9 | * block comment, 1 indent
10 | */
11 | if (true) {
12 | // line comment, 2 indents
13 | /*
14 | * block comment, 2 indent
15 | */
16 | if (true) {
17 | /* block single line, 3 indents */
18 | /*
19 | BLOCK ASCII
20 | |___________
21 | |___
22 | `----> YEAH
23 | */
24 | bar();
25 | }
26 | }
27 | }
28 |
29 | /* block single line, no indent */
30 |
31 |
32 |
33 | // test PR #57
34 | var obj = { /* test trailing space after multi line comment */
35 | then: function( /* fnDone, fnFail, fnProgress */ ) {
36 | var fns = arguments; // test space before comment
37 | }
38 | };
39 |
40 | function foo() { // single line after token that requires line break
41 | if (false) { /* multi line after token that requires line break */
42 | bar();
43 | }
44 | }
45 |
46 | foo
47 | .bar()
48 |
49 | // surrounded by empty lines and after chained expression
50 |
51 | // issue #139
52 | var pfun = new PFunction(function (hello /*, foo )
53 | ,bar { */,world) {});
54 |
--------------------------------------------------------------------------------
/test/compare/default/module-in.js:
--------------------------------------------------------------------------------
1 | // samples borrowed from http://www.2ality.com/2014/09/es6-modules-final.html
2 |
3 | // Default exports and named exports
4 | import theDefault,
5 | {named1,
6 | named2} from 'src/mylib';
7 | import
8 | theDefault from 'src/mylib';
9 | import
10 | { named1, named2 }
11 | from
12 | 'src/mylib';
13 |
14 | // Renaming: import named1 as myNamed1
15 | import { named1 as myNamed1, named2 } from 'src/mylib';
16 |
17 | // Importing the module as an object
18 | // (with one property per named export)
19 | import * as mylib from 'src/mylib';
20 |
21 | // Only load the module, don’t import anything
22 | import 'src/mylib';
23 |
24 | export var myVar1 = 123;
25 | export let myVar2 = 'foo';
26 | export const MY_CONST = 'BAR';
27 |
28 | export
29 | function myFunc() {
30 | return 'myfunc';
31 | }
32 |
33 | export function* myGeneratorFunc() {
34 | return yield someStuff();
35 | }
36 | export class MyClass {
37 | constructor() {
38 | this.name = 'exports test';
39 | }
40 | }
41 |
42 | export default class {
43 | constructor(x, y) {
44 | this.x = x;
45 | this.y = y;
46 | }
47 | }
48 |
49 | // #408
50 | export { lorem, hipstersum, nosemicolon }
51 |
52 | export { FOO_CONST, myOtherFunc };
53 | export { MY_CONST as THE_CONST, myFunc as theFunc };
54 |
55 | export * from 'src/other_module';
56 | export {
57 | foo ,
58 | bar
59 | }from 'src/other_module';
60 | export {foo as myFoo,baz} from 'src/other_module';
61 |
--------------------------------------------------------------------------------
/lib/hooks/ForStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _ws = require('rocambole-whitespace');
5 | var _limit = require('../limit');
6 |
7 |
8 | exports.format = function ForStatement(node) {
9 | var semi_1 = _tk.findNext(node.startToken, ';');
10 | var semi_2 = _tk.findPrev(node.body.startToken, ';');
11 | _ws.limit(semi_1, 'ForStatementSemicolon');
12 | _ws.limit(semi_2, 'ForStatementSemicolon');
13 |
14 | var expressionStart = _tk.findNext(node.startToken, '(');
15 | var expressionEnd = _tk.findPrev(node.body.startToken, ')');
16 | _limit.around(expressionStart, 'ForStatementExpressionOpening');
17 | _limit.around(expressionEnd, 'ForStatementExpressionClosing');
18 |
19 | if (node.body.type === 'BlockStatement') {
20 | var bodyStart = node.body.startToken;
21 | var bodyEnd = node.body.endToken;
22 | _limit.around(bodyStart, 'ForStatementOpeningBrace');
23 | _limit.around(bodyEnd, 'ForStatementClosingBrace');
24 | }
25 | };
26 |
27 |
28 | exports.getIndentEdges = function(node) {
29 | var edges = [];
30 |
31 | var args = {
32 | startToken: _tk.findNext(node.startToken, '('),
33 | endToken: _tk.findPrev(node.body.startToken, ')')
34 | };
35 | edges.push(args);
36 |
37 | if (node.body.type === 'BlockStatement') {
38 | edges.push(node.body);
39 | } else {
40 | edges.push({
41 | startToken: args.endToken,
42 | endToken: node.endToken
43 | });
44 | }
45 |
46 | return edges;
47 | };
48 |
--------------------------------------------------------------------------------
/test/compare/custom/module-out.js:
--------------------------------------------------------------------------------
1 | // samples borrowed from http://www.2ality.com/2014/09/es6-modules-final.html
2 |
3 | // Default exports and named exports
4 | import theDefault, {
5 | named1,
6 | named2
7 | } from 'src/mylib';
8 |
9 | import theDefault from 'src/mylib';
10 |
11 | import {
12 | named1,
13 | named2
14 | } from 'src/mylib';
15 |
16 | // Renaming: import named1 as myNamed1
17 | import {
18 | named1 as myNamed1,
19 | named2
20 | } from 'src/mylib';
21 |
22 | // Importing the module as an object
23 | // (with one property per named export)
24 | import * as mylib from 'src/mylib';
25 |
26 | // Only load the module, don’t import anything
27 | import 'src/mylib';
28 |
29 | export var myVar1 = 123;
30 |
31 | export let myVar2 = 'foo';
32 |
33 | export const MY_CONST = 'BAR';
34 |
35 | export function myFunc() {
36 | return 'myfunc';
37 | }
38 |
39 | export function* myGeneratorFunc() {
40 | return yield someStuff();
41 | }
42 |
43 | export class MyClass {
44 | constructor() {
45 | this.name = 'exports test';
46 | }
47 | }
48 |
49 | export default class {
50 | constructor(x, y) {
51 | this.x = x;
52 | this.y = y;
53 | }
54 | }
55 |
56 | export {
57 | FOO_CONST,
58 | myOtherFunc
59 | };
60 |
61 | export {
62 | MY_CONST as THE_CONST,
63 | myFunc as theFunc
64 | };
65 |
66 | export * from 'src/other_module';
67 |
68 | export {
69 | foo,
70 | bar
71 | } from 'src/other_module';
72 |
73 | export {
74 | foo as myFoo,
75 | baz
76 | } from 'src/other_module';
77 |
78 |
--------------------------------------------------------------------------------
/test/compare/default/switch_statement-out.js:
--------------------------------------------------------------------------------
1 | switch (fruit) {
2 | // case comment
3 | case Fruit.APPLE:
4 | // consequent comment
5 | apple();
6 | break;
7 | case Fruit.BANANA:
8 | banana();
9 | // comment in between content
10 | break;
11 | // case comment
12 | case Fruit.MANGO:
13 | // case comment
14 | case Fruit.PUPAYA:
15 | exotic();
16 | break;
17 | default:
18 | // consequent comment
19 | unknown();
20 | }
21 |
22 | call(function() {
23 | switch (fruit) {
24 | // case comment
25 | case Fruit.APPLE:
26 | // consequent comment
27 | exotic();
28 | break;
29 | default:
30 | unknown();
31 | }
32 | });
33 |
34 |
35 | switch (fruit) {
36 | // case comment
37 | case Fruit.APPLE:
38 | // consequent comment
39 | apple();
40 | break;
41 | }
42 |
43 | // issue #225
44 | switch (item) {
45 | case 'one':
46 | dothis()
47 | break
48 | default:
49 | }
50 |
51 | // issue #290
52 | switch (x) {
53 | case true:
54 | x();
55 | break;
56 | default:
57 | if (x) {
58 | x();
59 | }
60 | }
61 |
62 | // comment alignment (#209)
63 | switch (foo) {
64 | case bar:
65 | baz();
66 | // falls through
67 | // yes, this should be aligned too
68 |
69 | // align with case
70 | case biz:
71 | what();
72 | }
73 |
74 | // Block inside Case (#432)
75 | var f = function(action, state) {
76 | switch (action.type) {
77 | case ADD_GROCERY: {
78 | var foo = 'bar'
79 | }
80 | default:
81 | return state
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/bin/esformatter:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | "use strict";
3 |
4 | // resolve allow us to load the locally installed esformatter instead of using
5 | // the global version
6 | var requireResolve = require('resolve').sync;
7 | var path = require('path');
8 | var dirname = path.dirname;
9 | var pathResolve = path.resolve;
10 |
11 | var argv = process.argv.slice(2);
12 |
13 | // if user sets a config file we use that as the base directory to start the
14 | // search because we assume that some settings aren't backwards compatible
15 | // otherwise we just use the process.cwd()
16 | var opts = require('../lib/cli.js').parse(argv);
17 | var basedir = opts.config ?
18 | pathResolve(dirname(opts.config)) :
19 | process.cwd();
20 |
21 | var cliPath;
22 | try {
23 | cliPath = requireResolve('esformatter', {
24 | basedir: basedir
25 | });
26 | cliPath = pathResolve(dirname(cliPath), './cli.js');
27 | } catch (err) {
28 | // fallback to this version instead
29 | cliPath = '../lib/cli.js';
30 | }
31 |
32 | var cli = require(cliPath);
33 | // until v0.5 the cli module only exposed a single `parse` method, after v0.6
34 | // we expose 2 methods to allow processing the data before executing the
35 | // command (all the logic above)
36 | if ('run' in cli) {
37 | process.on('exit', function(code) {
38 | if (code === 0 && cli.exitCode) {
39 | // if node detected a different error we let it use the standard error
40 | // code: https://nodejs.org/api/process.html#process_exit_codes
41 | // otherwise we make sure it's set to 1 if we had any errors
42 | process.exit(cli.exitCode);
43 | }
44 | });
45 | cli.run(cli.parse(argv));
46 | } else {
47 | cli.parse(argv);
48 | }
49 |
--------------------------------------------------------------------------------
/test/compare/default/switch_statement-in.js:
--------------------------------------------------------------------------------
1 | switch (fruit) {
2 | // case comment
3 | case Fruit.APPLE:
4 | // consequent comment
5 | apple();
6 | break;
7 | case
8 | Fruit.BANANA:
9 | banana();
10 | // comment in between content
11 | break;
12 | // case comment
13 | case Fruit.MANGO:
14 | // case comment
15 | case Fruit.PUPAYA:
16 | exotic();
17 | break;
18 | default:
19 | // consequent comment
20 | unknown();
21 | }
22 |
23 | call(function(){
24 | switch (fruit) {
25 | // case comment
26 | case Fruit.APPLE:
27 | // consequent comment
28 | exotic();
29 | break;
30 | default:
31 | unknown();
32 | }
33 | });
34 |
35 |
36 | switch (fruit)
37 | {
38 | // case comment
39 | case Fruit.APPLE:
40 | // consequent comment
41 | apple();
42 | break; }
43 |
44 | // issue #225
45 | switch (item) {
46 | case 'one':
47 | dothis()
48 | break
49 | default:
50 | }
51 |
52 | // issue #290
53 | switch (x) {
54 | case true:
55 | x();
56 | break;
57 | default:
58 | if (x) {
59 | x();
60 | }
61 | }
62 |
63 | // comment alignment (#209)
64 | switch (foo) {
65 | case bar:
66 | baz();
67 | // falls through
68 | // yes, this should be aligned too
69 |
70 | // align with case
71 | case biz:
72 | what();
73 | }
74 |
75 | // Block inside Case (#432)
76 | var f = function (action, state) {
77 | switch (action.type) {
78 | case ADD_GROCERY: {
79 | var foo = 'bar'
80 | }
81 | default:
82 | return state
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/lib/hooks/ForInStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 |
7 |
8 | exports.format = function ForInStatement(node) {
9 | var expressionStart = _tk.findNext(node.startToken, '(');
10 | var expressionEnd = _tk.findPrev(node.body.startToken, ')');
11 |
12 | _br.limit(expressionStart, 'ForInStatementExpressionOpening');
13 | _ws.limit(expressionStart, 'ForInStatementExpressionOpening');
14 |
15 | _br.limit(expressionEnd, 'ForInStatementExpressionClosing');
16 | _ws.limit(expressionEnd, 'ForInStatementExpressionClosing');
17 |
18 | if (node.body.type === 'BlockStatement' && node.body.body.length) {
19 | var bodyStart = node.body.startToken;
20 | var bodyEnd = node.body.endToken;
21 |
22 | _br.limit(bodyStart, 'ForInStatementOpeningBrace');
23 | _ws.limit(bodyStart, 'ForInStatementOpeningBrace');
24 |
25 | _br.limit(bodyEnd, 'ForInStatementClosingBrace');
26 | _ws.limit(bodyEnd, 'ForInStatementClosingBrace');
27 |
28 | _ws.limitAfter(expressionEnd, 'ForInStatementExpression');
29 | }
30 |
31 | _ws.limitAfter(node.left.endToken, 1);
32 | _ws.limitBefore(node.right.startToken, 1);
33 | };
34 |
35 |
36 | exports.getIndentEdges = function(node) {
37 | var edges = [];
38 |
39 | edges.push({
40 | startToken: node.left.startToken,
41 | endToken: node.right.endToken
42 | });
43 |
44 | if (node.body.type === 'BlockStatement') {
45 | edges.push(node.body);
46 | } else {
47 | edges.push({
48 | startToken: _tk.findNext(node.right.endToken, ')').next,
49 | endToken: node.endToken
50 | });
51 | }
52 |
53 | return edges;
54 | };
55 |
--------------------------------------------------------------------------------
/lib/hooks/ForOfStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 |
7 |
8 | exports.format = function ForOfStatement(node) {
9 | var expressionStart = _tk.findNext(node.startToken, '(');
10 | var expressionEnd = _tk.findPrev(node.body.startToken, ')');
11 |
12 | _br.limit(expressionStart, 'ForOfStatementExpressionOpening');
13 | _ws.limit(expressionStart, 'ForOfStatementExpressionOpening');
14 |
15 | _br.limit(expressionEnd, 'ForOfStatementExpressionClosing');
16 | _ws.limit(expressionEnd, 'ForOfStatementExpressionClosing');
17 |
18 | if (node.body.type === 'BlockStatement' && node.body.body.length) {
19 | var bodyStart = node.body.startToken;
20 | var bodyEnd = node.body.endToken;
21 |
22 | _br.limit(bodyStart, 'ForOfStatementOpeningBrace');
23 | _ws.limit(bodyStart, 'ForOfStatementOpeningBrace');
24 |
25 | _br.limit(bodyEnd, 'ForOfStatementClosingBrace');
26 | _ws.limit(bodyEnd, 'ForOfStatementClosingBrace');
27 |
28 | _ws.limitAfter(expressionEnd, 'ForOfStatementExpression');
29 | }
30 |
31 | _ws.limitAfter(node.left.endToken, 1);
32 | _ws.limitBefore(node.right.startToken, 1);
33 | };
34 |
35 |
36 | exports.getIndentEdges = function(node) {
37 | var edges = [];
38 |
39 | edges.push({
40 | startToken: node.left.startToken,
41 | endToken: node.right.endToken
42 | });
43 |
44 | if (node.body.type === 'BlockStatement') {
45 | edges.push(node.body);
46 | } else {
47 | edges.push({
48 | startToken: _tk.findNext(node.right.endToken, ')').next,
49 | endToken: node.endToken
50 | });
51 | }
52 |
53 | return edges;
54 | };
55 |
--------------------------------------------------------------------------------
/lib/preset/default-indent.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | "indent": {
5 | "ArrayExpression": 1,
6 | "ArrayPattern": 1,
7 | "ArrowFunctionExpression": 1,
8 | "AssignmentExpression": 1,
9 | "AssignmentExpression.BinaryExpression": 1,
10 | "AssignmentExpression.LogicalExpression": 1,
11 | "AssignmentExpression.UnaryExpression": 1,
12 | "BlockStatement": 1,
13 | "CallExpression": 1,
14 | "CallExpression.BinaryExpression": 1,
15 | "CallExpression.LogicalExpression": 1,
16 | "CallExpression.UnaryExpression": 1,
17 | "CatchClause": 1,
18 | "ClassDeclaration": 1,
19 | "ClassExpression": 1,
20 | "CommentInsideEmptyBlock": 1,
21 | "ConditionalExpression": 1,
22 | "DoWhileStatement": 1,
23 | "ExportNamedDeclaration": 1,
24 | "ForInStatement": 1,
25 | "ForOfStatement": 1,
26 | "ForStatement": 1,
27 | "FunctionDeclaration": 1,
28 | "FunctionExpression": 1,
29 | "IfStatement": 1,
30 | "ImportDeclaration": 1,
31 | "MemberExpression": 1,
32 | "MultipleVariableDeclaration": 1,
33 | "NewExpression": 1,
34 | "ObjectExpression": 1,
35 | "ObjectExpression.BinaryExpression": 1,
36 | "ObjectExpression.LogicalExpression": 1,
37 | "ObjectExpression.UnaryExpression": 1,
38 | "ObjectPattern": 1,
39 | "ParameterList": 1,
40 | "ReturnStatement": 1,
41 | "SingleVariableDeclaration": 0,
42 | "SwitchCase": 1,
43 | "SwitchStatement": 1,
44 | "TopLevelFunctionBlock": 1,
45 | "TryStatement": 1,
46 | "VariableDeclaration.BinaryExpression": 1,
47 | "VariableDeclaration.LogicalExpression": 1,
48 | "VariableDeclaration.UnaryExpression": 1,
49 | "WhileStatement": 1
50 | }
51 | };
52 |
--------------------------------------------------------------------------------
/test/helpers.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | //
4 | // helpers used on the specs
5 | //
6 |
7 |
8 | var _fs = require('fs');
9 | var _path = require('path');
10 | var stripJsonComments = require('strip-json-comments');
11 |
12 |
13 | // ---
14 |
15 |
16 | exports.CACHE = {};
17 | exports.COMPARE_FOLDER = _path.join(__dirname, 'compare');
18 |
19 |
20 | // ---
21 |
22 |
23 | exports.readIn = function(id) {
24 | return exports.readFile(_path.join(exports.COMPARE_FOLDER, id + '-in.js'));
25 | };
26 |
27 |
28 | exports.readOut = function(id) {
29 | return exports.readFile(_path.join(exports.COMPARE_FOLDER, id + '-out.js'));
30 | };
31 |
32 |
33 | exports.readConfig = function(id) {
34 | var filePath = _path.join(exports.COMPARE_FOLDER, id + '-config.json');
35 | return JSON.parse(stripJsonComments(exports.readFile(filePath) + '\n'));
36 | };
37 |
38 |
39 | exports.readFile = function(path) {
40 | // we cache the results to avoid redundant I/O
41 | if (!(path in exports.CACHE)) {
42 | exports.CACHE[path] = exports.lineFeed(_fs.readFileSync(path).toString());
43 | }
44 | return exports.CACHE[path];
45 | };
46 |
47 |
48 | exports.purge = function(dir) {
49 | if (!exports.SHOULD_PURGE) return;
50 | _fs.readdirSync(dir).forEach(function(relPath) {
51 | var path = _path.join(dir, relPath);
52 | if (_fs.statSync(path).isDirectory()) {
53 | exports.purge(path);
54 | } else {
55 | _fs.unlinkSync(path);
56 | }
57 | });
58 | _fs.rmdirSync(dir);
59 | };
60 |
61 |
62 | exports.mkdir = function(dir) {
63 | if (!_fs.existsSync(dir)) {
64 | _fs.mkdirSync(dir);
65 | }
66 | };
67 |
68 | exports.lineFeed = function(text) {
69 | return text.replace(/\r\n?|[\n\u2028\u2029]/g, "\n");
70 | };
71 |
--------------------------------------------------------------------------------
/lib/hooks/ImportSpecifier.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // this logic is shared with ExportSpecifier
4 |
5 | var _br = require('rocambole-linebreak');
6 | var _tk = require('rocambole-token');
7 | var _ws = require('rocambole-whitespace');
8 | var limit = require('../limit');
9 |
10 | exports.format = function(node) {
11 | var braceStart = _tk.findPrev(node.startToken, _tk.isCode);
12 | var braceEnd = _tk.findNext(node.endToken, _tk.isCode);
13 |
14 | // handle `import foo, { lorem, ipsum } from 'lib';`
15 | if (braceStart.value === '{') {
16 | limit.around(braceStart, 'ModuleSpecifierOpeningBrace');
17 | } else if (braceStart.value === ',') {
18 | limit.around(braceStart, 'ModuleSpecifierComma');
19 | }
20 |
21 | if (braceEnd.value === ',') {
22 | limit.around(braceEnd, 'ModuleSpecifierComma');
23 | } else if (braceEnd.value === '}') {
24 | limit.before(braceEnd, 'ModuleSpecifierClosingBrace');
25 |
26 | var next = _tk.findNextNonEmpty(braceEnd);
27 | if (next && next.value === ';') {
28 | // handle `export {foo, bar};`
29 | _br.limitAfter(braceEnd, 0);
30 | } else if (node.parent.endToken !== braceEnd) {
31 | // we don't want to limit line break for lines that contains just
32 | // `export {foo, bar}` because that would remove undesired line breaks
33 | limit.after(braceEnd, 'ModuleSpecifierClosingBrace');
34 | }
35 | }
36 |
37 | if (node.startToken.value !== node.endToken.value) {
38 | // handle spaces around "as"
39 | // eg: `import { named1 as myNamed1 } from 'lib'`
40 | // eg: `import * as myLib from 'lib'`
41 | _br.limitAfter(node.startToken, 0);
42 | _br.limitBefore(node.endToken, 0);
43 | _ws.limitAfter(node.startToken, 1);
44 | _ws.limitBefore(node.endToken, 1);
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/lib/hooks/SwitchCase.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _ws = require('rocambole-whitespace');
4 | var _br = require('rocambole-linebreak');
5 | var _tk = require('rocambole-token');
6 | var limit = require('../limit');
7 |
8 |
9 | exports.format = function SwitchCase(node) {
10 | if (node.test) {
11 | // we want case to always be on the same line!
12 | _br.limitBefore(node.test.startToken, 0);
13 | _ws.limitBefore(node.test.startToken, 1);
14 | }
15 | var endToken = node.endToken;
16 |
17 | var colon = _tk.findNext(node.startToken, ':');
18 | limit.before(colon, 'SwitchCaseColon');
19 | limit.after(colon, 'SwitchCaseColon');
20 |
21 | var consequent = node.consequent[0];
22 | if (consequent && consequent.type === 'BlockStatement') {
23 | limit.around(consequent.startToken, 'SwitchCaseBlockStart');
24 | limit.around(consequent.endToken, 'SwitchCaseBlockEnd');
25 | }
26 |
27 | // endToken might be ":" or "break" or ";"
28 | var breakKeyword = _tk.findInBetweenFromEnd(node.startToken, endToken.next, 'break');
29 | if (breakKeyword) {
30 | limit.before(breakKeyword, 'BreakKeyword');
31 | limit.after(endToken, 'BreakKeyword');
32 | }
33 | };
34 |
35 |
36 | exports.getIndentEdges = function(node) {
37 | // we need to get the next token because `default` might end with a `}`
38 | // (ie. IfStatement) we also need to search for next `case` or `}` or
39 | // `break` or `default` to make sure comments are included inside the range
40 | var consequent = node.consequent[0];
41 | var end = consequent && consequent.type === 'BlockStatement' ?
42 | consequent.endToken :
43 | _tk.findNext(node.endToken, ['}', 'case', 'break', 'default']);
44 | return {
45 | startToken: node.startToken,
46 | endToken: end.prev
47 | };
48 | };
49 |
--------------------------------------------------------------------------------
/test/compare/default/function_expression-out.js:
--------------------------------------------------------------------------------
1 | var a = function() {
2 | return 'b';
3 | };
4 |
5 | b = function doB(q, wer, ty) {
6 | var c = function(n) {
7 | return function() {
8 | return q +
9 | wer - ty;
10 | }
11 | }
12 | return c
13 | }
14 |
15 | this.foo = {
16 | bar: function() {
17 | var r = function() {
18 | re(); draw();
19 | return log('foo') + 'bar';
20 | };
21 | },
22 | ipsum: function(amet) {
23 | return function() {
24 | amet()
25 | }
26 | }
27 | };
28 |
29 | var noop = function() {};
30 |
31 |
32 | var add = function(a, b) {
33 | return a + b;
34 | }
35 |
36 | call(function(a) {
37 | b();
38 | });
39 |
40 |
41 | // issue #36
42 | var obj = {
43 | then: function( /* fnDone, fnFail, fnProgress */ ) {
44 | var fns = arguments;
45 | }
46 | };
47 |
48 |
49 | // issue #134
50 | var foo = new MyConstructor(function otherFunction() {});
51 |
52 |
53 |
54 | // issue #143
55 | if (!this._pollReceive) {
56 | this._pollReceive = nn.PollReceiveSocket(this.binding, function(events) {
57 | if (events) this._receive();
58 | }.bind(this));
59 | }
60 |
61 | // issue #283
62 | var foo = function foo() {
63 | bar()
64 | }
65 |
66 | var foo = function() {
67 | bar()
68 | }
69 |
70 | // default params (#285)
71 | var defaultParams = function defaults(z, x = 1, y = 2) {
72 | return z + x + y;
73 | }
74 |
75 | // issue #373
76 | var foo = function(a,
77 | b) {};
78 |
79 | // issue #350
80 | var foo = function*() {
81 | yield '123';
82 | yield '456';
83 | };
84 |
85 | var foo = function*() {
86 | yield '123';
87 | yield '456';
88 | };
89 |
90 | // issue #377
91 | let index = _.findLast(test, function(t) {
92 | return obj && obj[t]
93 | })
94 |
95 | var asyncFunctionExpression = async function() {};
96 |
--------------------------------------------------------------------------------
/test/compare/default/var-out.js:
--------------------------------------------------------------------------------
1 | var foo = true;
2 | var bar = '123';
3 | var lorem = /\w+/;
4 | var parentheses = (123);
5 |
6 | var dolor;
7 |
8 | var bar = ipsum;
9 |
10 | var a,
11 | b = true,
12 | c = 3,
13 | d = false;
14 |
15 | var amet = qwe();
16 | var asi = true
17 |
18 |
19 | // test for issue #4
20 | var
21 | // foo var
22 | foo,
23 | // bar variable
24 | bar = 'dolor amet';
25 |
26 |
27 | // issue #28 : comma first
28 | var x = 33,
29 | y = 12,
30 |
31 |
32 | // comment
33 | w = 45;
34 |
35 |
36 | // issue #31: multiple var declaration + function expression = wrong indent
37 | (function() {
38 | var
39 | // A central reference to the root jQuery(document)
40 | rootjQuery,
41 |
42 | // Define a local copy of jQuery
43 | jQuery = function(selector, context) {
44 | // The jQuery object is actually just the init constructor 'enhanced'
45 | return new jQuery.fn.init(selector, context, rootjQuery);
46 | },
47 |
48 | // literal object
49 | obj = {
50 | num: 123,
51 | str: 'literal'
52 | };
53 | }());
54 |
55 | var lorem = ipsum ||
56 | dolor &&
57 | (sit || amet);
58 |
59 | // issue #306: UnaryExpression
60 | var hasNativeRequestAnimationFrame = !!(
61 | window.requestAnimationFrame ||
62 | window.webkitRequestAnimationFrame ||
63 | window.mozRequestAnimationFrame ||
64 | window.msRequestAnimationFrame
65 | );
66 |
67 | // issue #334
68 | var a = 'foo';
69 | var b = '3';
70 |
71 | // comma-first + asi
72 | var foo = 123,
73 | bar = 456;
74 | [1, 2, 3].forEach(echo)
75 |
76 | // issue #382
77 | function getInverseAnswer() {
78 | var a = 10,
79 | b = 4,
80 | answer,
81 | inverse;
82 | answer = a * b + (a - b - b);
83 | inverse = answer * -1;
84 | return inverse;
85 | }
86 |
87 | // issue #416
88 | var foo = bar + baz +
89 | barbaz;
90 |
--------------------------------------------------------------------------------
/lib/hooks/ArrayExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _limit = require('../limit');
5 |
6 |
7 | exports.format = function ArrayExpression(node) {
8 | if (node.elements.length) {
9 | _limit.around(node.startToken, 'ArrayExpressionOpening');
10 | _limit.around(node.endToken, 'ArrayExpressionClosing');
11 |
12 | node.elements.forEach(function(el) {
13 | // sparse arrays have `null` elements
14 | if (!el) return;
15 |
16 | var prev = _tk.findPrevNonEmpty(el.startToken);
17 | if (prev.value === ',') {
18 | _limit.around(prev, 'ArrayExpressionComma');
19 | }
20 | });
21 | } else {
22 | // empty array should be single line
23 | _limit.after(node.startToken, 0);
24 | }
25 | };
26 |
27 |
28 | exports.getIndentEdges = function(node) {
29 | var start;
30 | var prev = node.startToken;
31 |
32 | // this will grab the start of first element that is on a new line
33 | node.elements.some(function(el, i, els) {
34 | // sparse arrays have `null` elements! which is very weird
35 | if (i) {
36 | var prevEl = els[i - 1];
37 | prev = prevEl ? prevEl.endToken : _tk.findNextNonEmpty(prev);
38 | }
39 | var next = el ? el.startToken : _tk.findNextNonEmpty(prev);
40 |
41 | if (_tk.findInBetween(prev, next, _tk.isBr)) {
42 | start = prev;
43 | return true;
44 | }
45 | });
46 |
47 | var end = node.endToken.prev;
48 |
49 | // if it ends on same line as previous non-empty we need to change the indent
50 | // rule to make sure {}, [] and () are aligned
51 | var sibling = _tk.findPrevNonEmpty(node.endToken);
52 | if (!_tk.findInBetween(sibling, node.endToken, _tk.isBr)) {
53 | end = node.endToken;
54 | }
55 |
56 | return start ? {
57 | startToken: start,
58 | endToken: end
59 | } : false;
60 | };
61 |
62 |
--------------------------------------------------------------------------------
/lib/hooks/ArrowFunctionExpression.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var tk = require('rocambole-token');
4 | var limit = require('../limit');
5 | var _params = require('./Params');
6 |
7 | exports.format = function ArrowFunctionExpression(node) {
8 | var body = node.body;
9 | if (body.type === 'BlockStatement') {
10 | limit.around(body.startToken, 'ArrowFunctionExpressionOpeningBrace');
11 | limit.around(body.endToken, 'ArrowFunctionExpressionClosingBrace');
12 | }
13 |
14 | var arrow = tk.findPrev(body.startToken, '=>');
15 | limit.around(arrow, 'ArrowFunctionExpressionArrow');
16 |
17 | // make sure we handle `(x) => x` and `x => x`
18 | if (shouldHandleParams(node)) {
19 | _params.format(node);
20 | }
21 | };
22 |
23 | exports.getIndentEdges = function(node, opts) {
24 | var edges = [];
25 | if (shouldIndentBody(node, opts)) {
26 | var arrow = tk.findPrev(node.body.startToken, '=>');
27 | edges.push({
28 | startToken: arrow,
29 | endToken: node.endToken
30 | });
31 | }
32 | if (shouldHandleParams(node)) {
33 | edges.push(_params.getIndentEdges(node, opts));
34 | }
35 | return edges;
36 | };
37 |
38 | function shouldHandleParams(node) {
39 | var arrow = tk.findPrev(node.body.startToken, '=>');
40 | // we don't check based on `node.params` because of `node.defaults`
41 | return tk.findPrevNonEmpty(arrow).value === ')';
42 | }
43 |
44 | function shouldIndentBody(node, opts) {
45 | var bodyFirstNonEmpty = tk.findNextNonEmpty(node.body.startToken);
46 |
47 | if (bodyFirstNonEmpty.value === '}') {
48 | // noop
49 | limit.after(node.body.startToken, 0);
50 | return false;
51 | } else {
52 | // we don't want to indent the body twice if ObjectExpression or
53 | // ArrayExpression or CallExpression
54 | return node.body.type === 'BlockStatement' || !opts[node.body.type];
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/test/compare/default/var-in.js:
--------------------------------------------------------------------------------
1 | var foo=true;var bar= '123';
2 | var lorem =
3 | /\w+/;
4 | var parentheses =(123);
5 |
6 | var dolor;
7 |
8 | var bar
9 | = ipsum;
10 |
11 | var a,b= true,
12 | c =3, d=false;
13 |
14 | var
15 |
16 | amet= qwe();
17 | var asi = true
18 |
19 |
20 | // test for issue #4
21 | var
22 | // foo var
23 | foo,
24 | // bar variable
25 | bar = 'dolor amet';
26 |
27 |
28 | // issue #28 : comma first
29 | var x=33
30 | ,y=12
31 |
32 |
33 | // comment
34 | , w = 45;
35 |
36 |
37 | // issue #31: multiple var declaration + function expression = wrong indent
38 | (function(){
39 | var
40 | // A central reference to the root jQuery(document)
41 | rootjQuery,
42 |
43 | // Define a local copy of jQuery
44 | jQuery = function( selector, context ) {
45 | // The jQuery object is actually just the init constructor 'enhanced'
46 | return new jQuery.fn.init( selector, context, rootjQuery );
47 | },
48 |
49 | // literal object
50 | obj = {
51 | num : 123,
52 | str : 'literal'
53 | };
54 | }());
55 |
56 | var lorem = ipsum ||
57 | dolor &&
58 | (sit || amet);
59 |
60 | // issue #306: UnaryExpression
61 | var hasNativeRequestAnimationFrame = !!(
62 | window.requestAnimationFrame ||
63 | window.webkitRequestAnimationFrame ||
64 | window.mozRequestAnimationFrame ||
65 | window.msRequestAnimationFrame
66 | );
67 |
68 | // issue #334
69 | var a = 'foo' ;
70 | var b = '3'
71 | ;
72 |
73 | // comma-first + asi
74 | var foo = 123
75 | , bar = 456
76 | ;[1,2,3].forEach(echo)
77 |
78 | // issue #382
79 | function getInverseAnswer() {
80 | var a = 10, b=4,answer,inverse;
81 | answer = a * b + (a - b - b);
82 | inverse = answer * -1;
83 | return inverse;
84 | }
85 |
86 | // issue #416
87 | var foo = bar + baz +
88 | barbaz;
89 |
--------------------------------------------------------------------------------
/test/compare/default/function_expression-in.js:
--------------------------------------------------------------------------------
1 | var a=function( ){ return 'b';};
2 |
3 | b = function doB(q,wer , ty ) {
4 | var c = function(n) {
5 | return function(){ return q +
6 | wer - ty; }
7 | }
8 | return c}
9 |
10 | this.foo = {
11 | bar : function(){
12 | var r = function(){
13 | re(); draw();
14 | return log('foo') + 'bar';};},
15 | ipsum : function ( amet ) {
16 | return function( ) { amet() }
17 | }
18 | };
19 |
20 | var noop = function ( ) {
21 |
22 | };
23 |
24 |
25 | var add = function(a, b)
26 | {
27 | return a + b;
28 | }
29 |
30 | call( function(a)
31 | {
32 | b();
33 | } );
34 |
35 |
36 | // issue #36
37 | var obj = {
38 | then: function( /* fnDone, fnFail, fnProgress */ ) {
39 | var fns = arguments;
40 | }
41 | };
42 |
43 |
44 | // issue #134
45 | var foo = new MyConstructor(function otherFunction () { });
46 |
47 |
48 |
49 | // issue #143
50 | if (!this._pollReceive) {
51 | this._pollReceive = nn.PollReceiveSocket(this.binding, function (events) {
52 | if (events) this._receive();
53 | }.bind(this));
54 | }
55 |
56 | // issue #283
57 | var foo = function foo () {
58 | bar()
59 | }
60 |
61 | var foo = function () {
62 | bar()
63 | }
64 |
65 | // default params (#285)
66 | var defaultParams = function defaults(z, x= 1, y = 2) {
67 | return z + x + y;
68 | }
69 |
70 | // issue #373
71 | var foo = function(a,
72 | b){};
73 |
74 | // issue #350
75 | var foo = function * () {
76 | yield '123';
77 | yield '456';
78 | };
79 |
80 | var foo = function*() {
81 | yield '123';
82 | yield '456';
83 | };
84 |
85 | // issue #377
86 | let index = _.findLast(test, function (t) {
87 | return obj && obj[t]
88 | })
89 |
90 | var asyncFunctionExpression = async function() {};
91 |
--------------------------------------------------------------------------------
/lib/hooks/ReturnStatement.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _ws = require('rocambole-whitespace');
5 |
6 | var expressionParentheses = require('./expressionParentheses');
7 |
8 |
9 | exports.format = function ReturnStatement(node) {
10 | // need to make sure we only remove line breaks inside the node itself
11 | // because of ASI (see #29)
12 | var nonEmpty = _tk.findInBetween(node.startToken.next, node.endToken, _tk.isNotEmpty);
13 | // XXX: we want to remove line breaks and white spaces inside the node, not
14 | // using _br.limitAfter to avoid changing the program behavior (ASI)
15 | if (nonEmpty) _tk.removeEmptyInBetween(node.startToken, nonEmpty);
16 |
17 | _ws.limitAfter(node.startToken, 1);
18 | if (_tk.isSemiColon(node.endToken)) {
19 | // XXX: we want semicolon to be on same line and no whitespaces for now.
20 | _tk.removeEmptyInBetween(_tk.findPrevNonEmpty(node.endToken), node.endToken);
21 | }
22 |
23 | if (node.argument) {
24 | expressionParentheses.addSpaceInside(node.argument);
25 | }
26 | };
27 |
28 |
29 | exports.getIndentEdges = function(node, opts) {
30 | // we bypass indentation if argument already adds indentation
31 | if (
32 | !node.argument ||
33 | opts[node.argument.type] ||
34 | node.argument.type === 'UnaryExpression'
35 | ) {
36 | return false;
37 | }
38 |
39 | // handle agument wrapped in parenthesis
40 | var argumentStart = _tk.findNextNonEmpty(node.startToken);
41 | if (argumentStart.value === '(') {
42 | return {
43 | startToken: argumentStart,
44 | endToken: node.endToken.value === ')' ?
45 | node.endToken :
46 | _tk.findPrevNonEmpty(_tk.findPrev(node.endToken, ')'))
47 | };
48 | }
49 |
50 | return {
51 | startToken: node.startToken.next,
52 | endToken: _tk.isEmpty(node.endToken) ?
53 | _tk.findPrevNonEmpty(node.endToken) :
54 | node.endToken
55 | };
56 | };
57 |
--------------------------------------------------------------------------------
/doc/presets.md:
--------------------------------------------------------------------------------
1 | # Presets
2 |
3 | Presets are reusable config files that can `require` other presets/plugins and
4 | override configs.
5 |
6 | ## Reusing presets
7 |
8 | On your [esformatter config file](./config.md) you can do;
9 |
10 | ```js
11 | {
12 | // presets are used as "base settings"
13 | "extends": [
14 | "preset:foobar", // load "esformatter-preset-foobar" from "./node_modules"
15 | "./lorem_ipsum.json" // load relative config file
16 | ],
17 |
18 | // you can still override any setting from the preset if needed
19 | "indent": {
20 | "value": " "
21 | }
22 | }
23 | ```
24 |
25 | Note that the `preset:` pseudo-protocol will try to find the module with the
26 | `esformatter-preset-` prefix. That should make it easier to find presets on npm.
27 |
28 |
29 | ## Authoring presets
30 |
31 | List all the preset dependencies on the `package.json`, that way consumers of
32 | your preset only need to list the preset as dependency:
33 |
34 | ```js
35 | {
36 | // use the `esformatter-preset-` prefix on the name
37 | "name": "esformatter-preset-foobar",
38 | // list all the dependencies
39 | "dependencies": {
40 | "esformatter-quotes": "^1.0.3",
41 | "esformatter-preset-dolor": "^1.0.0"
42 | }
43 | }
44 | ```
45 |
46 | And the implementation would be something like:
47 |
48 | ```js
49 | // need to use `require` because dependencies will be listed
50 | // on the preset "package.json"
51 | module.exports = {
52 |
53 | // extend other presets
54 | extends: [
55 | require('esformatter-preset-dolor'),
56 | require('./foo-settings')
57 | ],
58 |
59 | // register plugins
60 | plugins: [
61 | require('esformatter-quotes')
62 | ],
63 |
64 | // this will override any values set by the `esformatter-preset-dolor` and
65 | // `./foo-settings`
66 | indent: {
67 | value: '\t'
68 | }
69 | };
70 | ```
71 |
72 | protip: we use this feature on [lib/preset/default.js](../lib/preset/default.js)
73 | to increase organization.
74 |
--------------------------------------------------------------------------------
/lib/preset/jquery.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | "extends": [
5 | require('./default')
6 | ],
7 |
8 | "indent": {
9 | "value": "\t",
10 | "IfStatementConditional": 2,
11 | "SwitchStatement": 0,
12 | "TopLevelFunctionBlock": 0
13 | },
14 |
15 | "lineBreak": {
16 | "before": {
17 | "ObjectExpressionOpeningBrace": -1,
18 | "ObjectExpressionClosingBrace": -1,
19 | "Property": -1,
20 | "VariableDeclarationWithoutInit": 0
21 | },
22 |
23 | "after": {
24 | "AssignmentOperator": -1,
25 | "ObjectExpressionOpeningBrace": -1,
26 | "ObjectExpressionClosingBrace": -1,
27 | "Property": -1
28 | }
29 | },
30 |
31 | "whiteSpace": {
32 | "before": {
33 | "ArgumentList": 1,
34 | "ArrayExpressionClosing": 1,
35 | "CatchParameterList": 1,
36 | "ExpressionClosingParentheses": 1,
37 | "ForInStatementExpressionClosing": 1,
38 | "ForOfStatementExpressionClosing": 1,
39 | "ForStatementExpressionClosing": 1,
40 | "IfStatementConditionalClosing": 1,
41 | "IIFEClosingParentheses": 1,
42 | "MemberExpressionClosing": 1,
43 | "ObjectExpressionClosingBrace": 1,
44 | "ParameterList": 1,
45 | "SwitchDiscriminantClosing": 1,
46 | "WhileStatementConditionalClosing": 1
47 | },
48 | "after": {
49 | "ArgumentList": 1,
50 | "ArrayExpressionOpening": 1,
51 | "CatchParameterList": 1,
52 | "ExpressionOpeningParentheses": 1,
53 | "ForInStatementExpressionOpening": 1,
54 | "ForOfStatementExpressionOpening": 1,
55 | "ForStatementExpressionOpening": 1,
56 | "IfStatementConditionalOpening": 1,
57 | "IIFEOpeningParentheses": 1,
58 | "MemberExpressionOpening": 1,
59 | "ObjectExpressionOpeningBrace": 1,
60 | "ParameterList": 1,
61 | "PropertyValue": -1,
62 | "SwitchDiscriminantOpening": 1,
63 | "WhileStatementConditionalOpening": 1
64 | }
65 | }
66 | };
67 |
--------------------------------------------------------------------------------
/test/compare/custom/try_statement-in.js:
--------------------------------------------------------------------------------
1 | try{foo()} catch (e){ log(e)
2 | }
3 |
4 | try
5 | {
6 | // foo comment
7 | foo();
8 | }
9 | finally
10 | {
11 | // bar comment
12 | bar();
13 | }
14 |
15 | try{foo()} catch (e){ log(e)
16 | } finally {
17 | bar()
18 | }
19 |
20 | try {
21 | bar( "foo" );
22 | } catch ( e ) {
23 | // Empty Catch comment
24 | }
25 |
26 |
27 | // issue #35: "catch" block indent + empty catch body
28 | jQuery.ready.promise = function( obj ) {
29 | try {
30 | top = window.frameElement == null && document.documentElement;
31 | } catch(e) {}
32 | };
33 |
34 | // "catch" brace indent
35 | function issueNN( obj ) {
36 | try {
37 | x = y;
38 | } catch (e) {
39 | console.log(e);
40 | }
41 | }
42 |
43 | // "finally" brace indent
44 | function foo(obj) {
45 | try {
46 | top = window.frameElement == null && document.documentElement;
47 | } catch (e) {
48 | console.log(e);
49 | } finally {
50 | // finally a comment
51 | top = 0;
52 | // weird
53 | }
54 | }
55 |
56 | jQuery.ready.promise = function( obj ) {
57 | try{
58 | // try 2
59 | top = window.frameElement == null && document.documentElement;
60 | // try after 2
61 | }catch(e){
62 | // catch 2
63 | console.log(e);
64 | // catch after 2
65 | }finally{
66 | // finally a comment 2
67 | top = 0;
68 | // finally after 2
69 | }
70 | };
71 |
72 | // nested try-catch
73 | function nestedTryCatch() {
74 | try{
75 | normalPath();
76 | }catch(e) {
77 | try {
78 | // try
79 | alternatePath();
80 | // just a little bit harder
81 | } catch(e){
82 | // catch
83 | console.log(e);
84 | // if you can
85 | }finally{}
86 | }finally{ shouldBreak = true; } next();
87 | }
88 |
89 | // line break handling (#128)
90 | try {
91 | doStuff()
92 | }
93 | catch
94 | (e)
95 | {
96 | yesThisIsWeird()
97 | }
98 |
--------------------------------------------------------------------------------
/test/compare/default/try_statement-out.js:
--------------------------------------------------------------------------------
1 | try {
2 | foo()
3 | } catch (e) {
4 | log(e)
5 | }
6 |
7 | try {
8 | // foo comment
9 | foo();
10 | } finally {
11 | // bar comment
12 | bar();
13 | }
14 |
15 | try {
16 | foo()
17 | } catch (e) {
18 | log(e)
19 | } finally {
20 | bar()
21 | }
22 |
23 | try {
24 | bar("foo");
25 | } catch (e) {
26 | // Empty Catch comment
27 | }
28 |
29 |
30 | // issue #35: "catch" block indent + empty catch body
31 | jQuery.ready.promise = function(obj) {
32 | try {
33 | top = window.frameElement == null && document.documentElement;
34 | } catch (e) {}
35 | };
36 |
37 | // "catch" brace indent
38 | function issueNN(obj) {
39 | try {
40 | x = y;
41 | } catch (e) {
42 | console.log(e);
43 | }
44 | }
45 |
46 | // "finally" brace indent
47 | function foo(obj) {
48 | try {
49 | top = window.frameElement == null && document.documentElement;
50 | } catch (e) {
51 | console.log(e);
52 | } finally {
53 | // finally a comment
54 | top = 0;
55 | // weird
56 | }
57 | }
58 |
59 | jQuery.ready.promise = function(obj) {
60 | try {
61 | // try 2
62 | top = window.frameElement == null && document.documentElement;
63 | // try after 2
64 | } catch (e) {
65 | // catch 2
66 | console.log(e);
67 | // catch after 2
68 | } finally {
69 | // finally a comment 2
70 | top = 0;
71 | // finally after 2
72 | }
73 | };
74 |
75 | // nested try-catch
76 | function nestedTryCatch() {
77 | try {
78 | normalPath();
79 | } catch (e) {
80 | try {
81 | // try
82 | alternatePath();
83 | // just a little bit harder
84 | } catch (e) {
85 | // catch
86 | console.log(e);
87 | // if you can
88 | } finally {}
89 | } finally {
90 | shouldBreak = true;
91 | }
92 | next();
93 | }
94 |
95 | // line break handling (#128)
96 | try {
97 | doStuff()
98 | } catch (e) {
99 | yesThisIsWeird()
100 | }
101 |
102 | // comment alignment (#270)
103 | try {
104 | bla();
105 | // comment
106 | // too
107 | } catch (e) {
108 | throw e;
109 | }
110 |
--------------------------------------------------------------------------------
/lib/hooks/Params.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // Important: Params is a "virtual" node type, not part of the AST spec.
4 | // this hook is actually called by FunctionDeclaration and FunctionExpression
5 | // hooks. It's mainly a way to share the common logic between both hooks.
6 |
7 | var _ws = require('rocambole-whitespace');
8 | var _tk = require('rocambole-token');
9 | var _limit = require('../limit');
10 |
11 |
12 | exports.format = function Params(node) {
13 | var params = node.params;
14 | var opening = node.startToken.value === '(' ?
15 | node.startToken :
16 | _tk.findNext(node.startToken, '(');
17 | var closing = _tk.findPrev(node.body.startToken, ')');
18 |
19 | if (params.length) {
20 | _ws.limitBefore(_tk.findNextNonEmpty(opening), 'ParameterList');
21 | params.forEach(function(param, i) {
22 | if (i) {
23 | // safer to find based on startToken, because of Flow types
24 | var prev = _tk.findPrevNonEmpty(param.startToken);
25 | if (prev.value === ',') {
26 | _limit.around(prev, 'ParameterComma');
27 | }
28 | }
29 |
30 | // Default parameters are AssignmentExpressions as params
31 | if (param.type === 'AssignmentPattern' && param.right) {
32 | _limit.around(_tk.findPrev(param.right.startToken, '='), 'AssignmentPattern');
33 | }
34 | });
35 | _ws.limitAfter(_tk.findPrevNonEmpty(closing), 'ParameterList');
36 | } else {
37 | _limit.after(opening, 0);
38 | }
39 | };
40 |
41 | exports.getIndentEdges = function(node, opts) {
42 | var params = node.params;
43 | if (params.length && opts.ParameterList) {
44 | // get/set on ObjectEpression affect drastically the FunctionExpression
45 | // structure so we need to handle it differently
46 | var start = node.parent.type === 'Property' ?
47 | node.parent.startToken :
48 | node.startToken;
49 | return {
50 | // we check if start is equal to "(" because of arrow functions
51 | startToken: start.value === '(' ? start : _tk.findNext(start, '('),
52 | endToken: _tk.findPrev(node.body.startToken, ')'),
53 | level: opts.ParameterList
54 | };
55 | }
56 | return null;
57 | };
58 |
--------------------------------------------------------------------------------
/test/compare/jquery/spacing-in.js:
--------------------------------------------------------------------------------
1 | // this file is imcomplete since jquery style guide support is still not
2 | // finished (see #19)
3 |
4 | var i = 0;
5 |
6 | if (condition) { doSomething(); } else if (otherCondition) {
7 | somethingElse();
8 | // comment
9 | } else {
10 | // comment
11 | otherThing();
12 | }
13 |
14 | this.element
15 | .add()
16 | .set({
17 | // line comment
18 | // one more
19 | prop: "value"
20 | });
21 |
22 | while (x) {
23 | y();
24 | }
25 |
26 | for (i = 0; i < length; i++) {
27 | y();
28 | }
29 | for ( ; i < length; i++ ) {
30 | y();
31 | }
32 |
33 | function x() {
34 | return something &&
35 | !somethingElse;
36 | }
37 |
38 | ul.outerWidth( Math.max(
39 | // Firefox wraps long text (possibly a rounding bug)
40 | // so we add 1px to avoid the wrapping (#7513)
41 | ul.width( "" ).outerWidth() + 1,
42 | this.element.outerWidth()
43 | ) );
44 |
45 | function x() {
46 | return this.indeterminate ? false :
47 | Math.min( this.options.max, Math.max( this.min, newValue ) );
48 | }
49 |
50 | if ( event.target !== that.element[ 0 ] &&
51 | event.target !== menuElement &&
52 | !$.contains( menuElement, event.target ) ) {
53 | close();
54 | }
55 |
56 | contents = this.headers.next()
57 | .removeClass("ui-helper-reset ui-widget-content ui-corner-bottom " +
58 | "ui-accordion-content ui-accordion-content-active ui-state-disabled")
59 | .css("display", "")
60 | .removeAttr("role");
61 |
62 | this.buttonElement
63 | .addClass( baseClasses )
64 | .bind( "click" + this.eventNamespace, function( event ) {
65 | if ( options.disabled ) {
66 | event.preventDefault();
67 | }
68 | });
69 |
70 | try {
71 | x();
72 | } catch(error) {
73 | console.log(error);
74 | }
75 |
76 | x({ a: 1 });
77 | y({
78 | a: 1
79 | });
80 | $.each( { div: "#list1", ul: "#navigation", dl: "#accordion-dl" } );
81 |
82 | (function($) {
83 | x;
84 | }(jQuery));
85 |
86 | var x = {foo:{bar: true}};
87 | var y = {a: b, c: d, e:{ f: g}};
88 | x = {
89 | props: {
90 | // comment
91 | x: 1
92 | }
93 | };
94 | x={
95 | b:function b() {
96 | a();
97 | },
98 | a:b
99 | };
100 |
--------------------------------------------------------------------------------
/test/compare/jquery/spacing-out.js:
--------------------------------------------------------------------------------
1 | // this file is imcomplete since jquery style guide support is still not
2 | // finished (see #19)
3 |
4 | var i = 0;
5 |
6 | if ( condition ) {
7 | doSomething();
8 | } else if ( otherCondition ) {
9 | somethingElse();
10 | // comment
11 | } else {
12 | // comment
13 | otherThing();
14 | }
15 |
16 | this.element
17 | .add()
18 | .set( {
19 | // line comment
20 | // one more
21 | prop: "value"
22 | } );
23 |
24 | while ( x ) {
25 | y();
26 | }
27 |
28 | for ( i = 0; i < length; i++ ) {
29 | y();
30 | }
31 | for ( ; i < length; i++ ) {
32 | y();
33 | }
34 |
35 | function x() {
36 | return something &&
37 | !somethingElse;
38 | }
39 |
40 | ul.outerWidth( Math.max(
41 | // Firefox wraps long text (possibly a rounding bug)
42 | // so we add 1px to avoid the wrapping (#7513)
43 | ul.width( "" ).outerWidth() + 1,
44 | this.element.outerWidth()
45 | ) );
46 |
47 | function x() {
48 | return this.indeterminate ? false :
49 | Math.min( this.options.max, Math.max( this.min, newValue ) );
50 | }
51 |
52 | if ( event.target !== that.element[ 0 ] &&
53 | event.target !== menuElement &&
54 | !$.contains( menuElement, event.target ) ) {
55 | close();
56 | }
57 |
58 | contents = this.headers.next()
59 | .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
60 | "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
61 | .css( "display", "" )
62 | .removeAttr( "role" );
63 |
64 | this.buttonElement
65 | .addClass( baseClasses )
66 | .bind( "click" + this.eventNamespace, function( event ) {
67 | if ( options.disabled ) {
68 | event.preventDefault();
69 | }
70 | } );
71 |
72 | try {
73 | x();
74 | } catch ( error ) {
75 | console.log( error );
76 | }
77 |
78 | x( { a: 1 } );
79 | y( {
80 | a: 1
81 | } );
82 | $.each( { div: "#list1", ul: "#navigation", dl: "#accordion-dl" } );
83 |
84 | ( function( $ ) {
85 | x;
86 | }( jQuery ) );
87 |
88 | var x = { foo: { bar: true } };
89 | var y = { a: b, c: d, e: { f: g } };
90 | x = {
91 | props: {
92 | // comment
93 | x: 1
94 | }
95 | };
96 | x = {
97 | b: function b() {
98 | a();
99 | },
100 | a: b
101 | };
102 |
--------------------------------------------------------------------------------
/test/compare/default/try_statement-in.js:
--------------------------------------------------------------------------------
1 | try{foo()} catch (e){ log(e)
2 | }
3 |
4 | try
5 | {
6 | // foo comment
7 | foo();
8 | }
9 | finally
10 | {
11 | // bar comment
12 | bar();
13 | }
14 |
15 | try{foo()} catch (e){ log(e)
16 | } finally {
17 | bar()
18 | }
19 |
20 | try {
21 | bar( "foo" );
22 | } catch ( e ) {
23 | // Empty Catch comment
24 | }
25 |
26 |
27 | // issue #35: "catch" block indent + empty catch body
28 | jQuery.ready.promise = function( obj ) {
29 | try {
30 | top = window.frameElement == null && document.documentElement;
31 | } catch(e) {}
32 | };
33 |
34 | // "catch" brace indent
35 | function issueNN( obj ) {
36 | try {
37 | x = y;
38 | } catch (e) {
39 | console.log(e);
40 | }
41 | }
42 |
43 | // "finally" brace indent
44 | function foo(obj) {
45 | try {
46 | top = window.frameElement == null && document.documentElement;
47 | } catch (e) {
48 | console.log(e);
49 | } finally {
50 | // finally a comment
51 | top = 0;
52 | // weird
53 | }
54 | }
55 |
56 | jQuery.ready.promise = function( obj ) {
57 | try{
58 | // try 2
59 | top = window.frameElement == null && document.documentElement;
60 | // try after 2
61 | }catch(e){
62 | // catch 2
63 | console.log(e);
64 | // catch after 2
65 | }finally{
66 | // finally a comment 2
67 | top = 0;
68 | // finally after 2
69 | }
70 | };
71 |
72 | // nested try-catch
73 | function nestedTryCatch() {
74 | try{
75 | normalPath();
76 | }catch(e) {
77 | try {
78 | // try
79 | alternatePath();
80 | // just a little bit harder
81 | } catch(e){
82 | // catch
83 | console.log(e);
84 | // if you can
85 | }finally{}
86 | }finally{ shouldBreak = true; } next();
87 | }
88 |
89 | // line break handling (#128)
90 | try {
91 | doStuff()
92 | }
93 | catch
94 | (e)
95 | {
96 | yesThisIsWeird()
97 | }
98 |
99 | // comment alignment (#270)
100 | try {
101 | bla();
102 | // comment
103 | // too
104 | } catch(e) {
105 | throw e;
106 | }
107 |
--------------------------------------------------------------------------------
/lib/format.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _options = require('./options');
4 |
5 | var npmRun = require('npm-run');
6 | var parser = require('esformatter-parser');
7 | var plugins = require('./plugins');
8 | var transform = require('./transform');
9 |
10 | exports = module.exports = format;
11 | function format(str, opts) {
12 | // we need to load and register the plugins as soon as possible otherwise
13 | // `stringBefore` won't be called and default settings won't be used
14 | _options.set(opts);
15 |
16 | // remove shebang before pipe because piped commands might not know how
17 | // to handle it
18 | var prefix = getShebang(str);
19 | if (prefix && !_options.get('esformatter.allowShebang')) {
20 | throw new Error(
21 | 'shebang not allowed! Set esformatter.allowShebang to true if you ' +
22 | 'want to support it.'
23 | );
24 | }
25 | str = str.replace(prefix, '');
26 |
27 | var pipeCommands = _options.get('pipe');
28 |
29 | if (pipeCommands) {
30 | str = pipe(pipeCommands.before, str).toString();
31 | }
32 |
33 | str = doFormat(str, opts);
34 |
35 | if (pipeCommands) {
36 | str = pipe(pipeCommands.after, str).toString();
37 | }
38 |
39 | // we only restore bang after pipe because piped commands might not know how
40 | // to handle it
41 | return prefix + str;
42 | }
43 |
44 |
45 | // allows users to override parser if needed
46 | exports.parseFn = function(str, opts) {
47 | return parser.parse(str, opts);
48 | };
49 |
50 |
51 | exports.parseOptions = parser.defaultOptions;
52 |
53 |
54 | function getShebang(str) {
55 | var result = (/^#!.+\n/).exec(str);
56 | return result ? result[0] : '';
57 | }
58 |
59 |
60 | function doFormat(str) {
61 | str = plugins.stringBefore(str);
62 | // allows user to override the parser
63 | var ast = exports.parseFn(str, exports.parseOptions);
64 | transform(ast, transform.BYPASS_OPTIONS);
65 | str = ast.toString();
66 | str = plugins.stringAfter(str);
67 | return str;
68 | }
69 |
70 |
71 | // run cli tools in series passing the stdout of previous tool as stdin of next
72 | // one
73 | function pipe(commands, input) {
74 | if (!commands) {
75 | return input;
76 | }
77 | return commands.reduce(function(input, cmd) {
78 | return npmRun.sync(cmd, {
79 | input: input
80 | });
81 | }, input);
82 | }
83 |
--------------------------------------------------------------------------------
/test/compare/custom/try_statement-out.js:
--------------------------------------------------------------------------------
1 | try
2 | {
3 | foo()
4 | }
5 | catch (e)
6 | {
7 | log(e)
8 | }
9 |
10 | try
11 | {
12 | // foo comment
13 | foo();
14 | }
15 | finally
16 | {
17 | // bar comment
18 | bar();
19 | }
20 |
21 | try
22 | {
23 | foo()
24 | }
25 | catch (e)
26 | {
27 | log(e)
28 | }
29 | finally
30 | {
31 | bar()
32 | }
33 |
34 | try
35 | {
36 | bar("foo");
37 | }
38 | catch (e)
39 | {
40 | // Empty Catch comment
41 | }
42 |
43 |
44 | // issue #35: "catch" block indent + empty catch body
45 | jQuery.ready.promise = function(obj) {
46 | try
47 | {
48 | top = window.frameElement == null && document.documentElement;
49 | }
50 | catch (e)
51 | {}
52 | };
53 |
54 | // "catch" brace indent
55 | function issueNN(obj) {
56 | try
57 | {
58 | x = y;
59 | }
60 | catch (e)
61 | {
62 | console.log(e);
63 | }
64 | }
65 |
66 | // "finally" brace indent
67 | function foo(obj) {
68 | try
69 | {
70 | top = window.frameElement == null && document.documentElement;
71 | }
72 | catch (e)
73 | {
74 | console.log(e);
75 | }
76 | finally
77 | {
78 | // finally a comment
79 | top = 0;
80 | // weird
81 | }
82 | }
83 |
84 | jQuery.ready.promise = function(obj) {
85 | try
86 | {
87 | // try 2
88 | top = window.frameElement == null && document.documentElement;
89 | // try after 2
90 | }
91 | catch (e)
92 | {
93 | // catch 2
94 | console.log(e);
95 | // catch after 2
96 | }
97 | finally
98 | {
99 | // finally a comment 2
100 | top = 0;
101 | // finally after 2
102 | }
103 | };
104 |
105 | // nested try-catch
106 | function nestedTryCatch() {
107 | try
108 | {
109 | normalPath();
110 | }
111 | catch (e)
112 | {
113 | try
114 | {
115 | // try
116 | alternatePath();
117 | // just a little bit harder
118 | }
119 | catch (e)
120 | {
121 | // catch
122 | console.log(e);
123 | // if you can
124 | }
125 | finally
126 | {}
127 | }
128 | finally
129 | {
130 | shouldBreak = true;
131 | }
132 | next();
133 | }
134 |
135 | // line break handling (#128)
136 | try
137 | {
138 | doStuff()
139 | }
140 | catch (e)
141 | {
142 | yesThisIsWeird()
143 | }
144 |
--------------------------------------------------------------------------------
/lib/hooks/FunctionExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _ws = require('rocambole-whitespace');
5 | var _params = require('./Params');
6 | var _limit = require('../limit');
7 |
8 |
9 | exports.format = function FunctionExpression(node) {
10 | _limit.around(node.body.startToken, 'FunctionExpressionOpeningBrace');
11 | _limit.around(node.endToken, 'FunctionExpressionClosingBrace');
12 |
13 | var startToken = node.startToken;
14 | if (node.id) {
15 | _ws.limit(node.id.startToken, 'FunctionName');
16 | } else if (startToken.value === 'function') {
17 | if (node.generator) {
18 | startToken = _tk.findNextNonEmpty(startToken);
19 | _ws.limitBefore(startToken, 'FunctionGeneratorAsterisk');
20 | }
21 |
22 | _ws.limit(startToken, 'FunctionReservedWord');
23 | }
24 |
25 | if (_tk.isWs(node.endToken.next) &&
26 | _tk.isSemiColon(node.endToken.next.next)) {
27 | _tk.remove(node.endToken.next);
28 | }
29 |
30 | if (node.parent.type === 'CallExpression') {
31 | _ws.limitAfter(node.endToken, 0);
32 | }
33 |
34 | var bodyFirstNonEmpty = _tk.findNextNonEmpty(node.body.startToken);
35 | if (bodyFirstNonEmpty.value === '}') {
36 | // noop
37 | _limit.after(node.body.startToken, 0);
38 | }
39 |
40 | _params.format(node);
41 | };
42 |
43 |
44 | exports.getIndentEdges = function(node, opts) {
45 | var params = _params.getIndentEdges(node, opts);
46 | // TODO make this a plugin
47 | if (!opts.TopLevelFunctionBlock && isTopLevelFunctionBlock(node)) {
48 | return params;
49 | }
50 | return [
51 | params,
52 | {
53 | startToken: node.body.startToken,
54 | endToken: _tk.findPrevNonEmpty(node.body.endToken).next
55 | }
56 | ];
57 | };
58 |
59 |
60 | function isTopLevelFunctionBlock(node) {
61 | // exception for UMD blocks
62 | return !(node.params.length === 1 && node.params[0].name === "factory") &&
63 | // regular IFEE
64 | (isOfType(node.parent, 'CallExpression') ||
65 | // module.exports assignment
66 | isOfType(node.parent, 'AssignmentExpression')) &&
67 | !isOfType(node.parent.callee, 'MemberExpression') &&
68 | isOfType(node.parent.parent, 'ExpressionStatement') &&
69 | isOfType(node.parent.parent.parent, 'Program');
70 | }
71 |
72 |
73 | // TODO: extract into rocambole-node
74 | function isOfType(node, type) {
75 | return node && node.type === type;
76 | }
77 |
--------------------------------------------------------------------------------