├── test
├── compare
│ ├── default
│ │ ├── empty_file-in.js
│ │ ├── empty_file-out.js
│ │ ├── inplace-out.js
│ │ ├── array_pattern-out.js
│ │ ├── inplace-in.js
│ │ ├── array_pattern-in.js
│ │ ├── throw_statement-in.js
│ │ ├── object_pattern-out.js
│ │ ├── throw_statement-out.js
│ │ ├── jsx-in.js
│ │ ├── jsx-out.js
│ │ ├── new_expression-in.js
│ │ ├── new_expression-out.js
│ │ ├── object_pattern-in.js
│ │ ├── do_while_statement-in.js
│ │ ├── comma_operator-in.js
│ │ ├── README.md
│ │ ├── comma_operator-out.js
│ │ ├── do_while_statement-out.js
│ │ ├── member_expression-out.js
│ │ ├── member_expression-in.js
│ │ ├── iife-in.js
│ │ ├── flow-in.js
│ │ ├── flow-out.js
│ │ ├── iife-out.js
│ │ ├── while_statement-out.js
│ │ ├── binary_expression-in.js
│ │ ├── binary_expression-out.js
│ │ ├── logical_expression-in.js
│ │ ├── logical_expression-out.js
│ │ ├── while_statement-in.js
│ │ ├── arrow_function_expression-out.js
│ │ ├── for_statement-in.js
│ │ ├── unary_expression-in.js
│ │ ├── unary_expression-out.js
│ │ ├── arrow_function_expression-in.js
│ │ ├── for_statement-out.js
│ │ ├── for_of_statement-out.js
│ │ ├── for_in_statement-out.js
│ │ ├── for_of_statement-in.js
│ │ ├── for_in_statement-in.js
│ │ ├── conditional_expression-in.js
│ │ ├── conditional_expression-out.js
│ │ ├── array_expression-in.js
│ │ ├── array_expression-out.js
│ │ ├── class_declaration-in.js
│ │ ├── class_declaration-out.js
│ │ ├── comments-out.js
│ │ ├── switch_statement-out.js
│ │ ├── class_expression-in.js
│ │ ├── class_expression-out.js
│ │ ├── assignment_expression-in.js
│ │ ├── module-out.js
│ │ ├── assignment_expression-out.js
│ │ ├── switch_statement-in.js
│ │ ├── comments-in.js
│ │ ├── module-in.js
│ │ ├── var-out.js
│ │ ├── var-in.js
│ │ ├── function_expression-out.js
│ │ ├── function_expression-in.js
│ │ ├── function_declaration-in.js
│ │ ├── function_declaration-out.js
│ │ ├── try_statement-out.js
│ │ ├── try_statement-in.js
│ │ ├── call_expression-out.js
│ │ ├── call_expression-in.js
│ │ └── obj_expression-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
│ │ │ ├── package-out.js
│ │ │ ├── nested
│ │ │ │ ├── .esformatter
│ │ │ │ ├── pkg_nested-in.js
│ │ │ │ ├── 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
│ │ ├── class-in.js
│ │ ├── variable_declaration-config.json
│ │ ├── variable_declaration-out.js
│ │ ├── comment_group-config.json
│ │ ├── class-out.js
│ │ ├── multi-indent-in.js
│ │ ├── argumentlist-config.json
│ │ ├── array_bug-config.json
│ │ ├── module-config.json
│ │ ├── negative_indent-config.json
│ │ ├── for_statement-config.json
│ │ ├── iife-in.js
│ │ ├── conditional_expression-out.js
│ │ ├── conditional_expression-in.js
│ │ ├── align_comments-config.json
│ │ ├── iife-out.js
│ │ ├── member_expression-config.json
│ │ ├── expression_parentheses-config.json
│ │ ├── multi-indent-out.js
│ │ ├── iife-config.json
│ │ ├── negative_indent-in.js
│ │ ├── function_expression_bug-config.json
│ │ ├── object_expression-3-in.js
│ │ ├── argumentlist-out.js
│ │ ├── negative_indent-out.js
│ │ ├── object_expression-2-config.json
│ │ ├── if_statement_spacy-config.json
│ │ ├── argumentlist-in.js
│ │ ├── README.md
│ │ ├── class-config.json
│ │ ├── object_expression-3-out.js
│ │ ├── for_in_statement-config.json
│ │ ├── for_of_statement-config.json
│ │ ├── basic_function_indent_2-config.json
│ │ ├── object_pattern-config.json
│ │ ├── align_comments-in.js
│ │ ├── align_comments-out.js
│ │ ├── array_expression-in.js
│ │ ├── array_expression-out.js
│ │ ├── conditional_expression-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
│ │ ├── array_expression-2-config.json
│ │ ├── top-level-indent-exception-out.js
│ │ ├── array_expression-config.json
│ │ ├── object_expression-in.js
│ │ ├── switch_statement-in.js
│ │ ├── if_statement-config.json
│ │ ├── top-level-indent-exception-in.js
│ │ ├── expression_parentheses-in.js
│ │ ├── if_statement-in.js
│ │ ├── expression_parentheses-out.js
│ │ ├── basic_function_indent-config.json
│ │ ├── object_expression-out.js
│ │ ├── if_statement-out.js
│ │ ├── array_expression-2-out.js
│ │ ├── try_statement-config.json
│ │ ├── module-out.js
│ │ ├── module-in.js
│ │ ├── try_statement-in.js
│ │ └── try_statement-out.js
│ ├── .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
│ └── index.js
├── transform.spec.js
├── runner.js
├── pipe.spec.js
├── helpers.js
└── api.spec.js
├── lib
├── hooks
│ ├── ExportSpecifier.js
│ ├── ThrowStatement.js
│ ├── UpdateExpression.js
│ ├── ExportDefaultDeclaration.js
│ ├── SequenceExpression.js
│ ├── MethodDefinition.js
│ ├── ExportAllDeclaration.js
│ ├── ArrayPattern.js
│ ├── ObjectPattern.js
│ ├── ImportDeclaration.js
│ ├── ExportNamedDeclaration.js
│ ├── BinaryExpression.js
│ ├── UnaryExpression.js
│ ├── FunctionDeclaration.js
│ ├── SwitchStatement.js
│ ├── DoWhileStatement.js
│ ├── CatchClause.js
│ ├── ClassDeclarationAndExpression.js
│ ├── LogicalExpression.js
│ ├── AssignmentExpression.js
│ ├── MemberExpression.js
│ ├── ConditionalExpression.js
│ ├── SwitchCase.js
│ ├── TryStatement.js
│ ├── ImportSpecifier.js
│ ├── WhileStatement.js
│ ├── ForStatement.js
│ ├── ArrowFunctionExpression.js
│ ├── ForInStatement.js
│ ├── ForOfStatement.js
│ ├── ReturnStatement.js
│ ├── ArrayExpression.js
│ ├── Params.js
│ ├── FunctionExpression.js
│ ├── VariableDeclaration.js
│ └── expressionParentheses.js
├── helpers.js
├── limit.js
├── esformatter.js
├── diff.js
├── preset
│ └── jquery.json
├── plugins.js
└── hooks.js
├── .gitignore
├── .travis.yml
├── doc
└── cli.txt
├── .editorconfig
├── LICENSE.md
├── bin
└── esformatter
└── package.json
/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/rc/package/rc/nested-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-out.js:
--------------------------------------------------------------------------------
1 | function foo() {
2 | bar();
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/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/rc/package/nested/.esformatter:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "value": "\t"
4 | }
5 | }
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/array_pattern-out.js:
--------------------------------------------------------------------------------
1 | var [lorem, ipsum] = arr;
2 |
3 | var [x, y, z] = position;
4 |
--------------------------------------------------------------------------------
/test/compare/default/inplace-in.js:
--------------------------------------------------------------------------------
1 | var a =
2 |
3 | 40
4 |
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/package/rc/.esformatter:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "indent": {
4 | "value": "\t"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/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/default/array_pattern-in.js:
--------------------------------------------------------------------------------
1 | var [ lorem , ipsum ] = arr;
2 |
3 | var [
4 | x,
5 | y,
6 | z
7 | ] = position;
8 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/test/compare/rc/.esformatter:
--------------------------------------------------------------------------------
1 | {
2 | "indent": {
3 | "value": " "
4 | },
5 | "whiteSpace": {
6 | "before": {
7 | "FunctionDeclarationOpeningBrace" : 0
8 | }
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/module-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace": {
3 | "before": {
4 | "ModuleSpecifierClosingBrace": 3
5 | },
6 | "after": {
7 | "ModuleSpecifierOpeningBrace": 3
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/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/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/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/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/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/expression_parentheses-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "whiteSpace" : {
3 | "before" : {
4 | "ExpressionClosingParentheses" : 1
5 | },
6 | "after" : {
7 | "ExpressionOpeningParentheses" : 1
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/hooks/UpdateExpression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 |
5 | exports.format = function UpdateExpression(node) {
6 | // XXX: should never have spaces or line breaks before/after "++" and "--"!
7 | _tk.removeEmptyInBetween(node.startToken, node.endToken);
8 | };
9 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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": "index.js",
7 | "author": "Miller Medeiros",
8 | "license": "ISC"
9 | }
10 |
--------------------------------------------------------------------------------
/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/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/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 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.12"
4 | script:
5 | - "npm test --coverage"
6 | - "npm run-script lint"
7 | branches:
8 | only:
9 | - master
10 | notifications:
11 | irc:
12 | channels:
13 | - "irc.freenode.org#esformatter"
14 | on_success: change
15 | use_notice: true
16 | skip_join: true
17 |
--------------------------------------------------------------------------------
/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 | };
21 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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/default/do_while_statement-in.js:
--------------------------------------------------------------------------------
1 | do{console.log(i++)}while(i<100); do{i--}while(i);
2 |
3 | do n--; while(n&&foo());
4 |
5 | do n--; while(n&&foo());do++i;while(amet(i));
6 |
7 | // issue #256
8 | function main() {
9 | do if (true) return 1; while (true);
10 | }
11 |
12 | function main() {
13 | do
14 | if (true) return 1;
15 | while (true);
16 | }
17 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 | };
21 |
--------------------------------------------------------------------------------
/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 n--; while (n && foo());
9 |
10 | do n--; while (n && foo());
11 | do ++i; while (amet(i));
12 |
13 | // issue #256
14 | function main() {
15 | do
16 | if (true) return 1;
17 | while (true);
18 | }
19 |
20 | function main() {
21 | do
22 | if (true) return 1;
23 | while (true);
24 | }
25 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/hooks/MethodDefinition.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var ws = require('rocambole-whitespace');
4 | var br = require('rocambole-linebreak');
5 |
6 | exports.format = function MethodDefinition(node) {
7 | br.limitAfter(node.startToken, 0);
8 | // limit to one space after get/set/static
9 | if (node.startToken !== node.key) {
10 | ws.limitAfter(node.startToken, 1);
11 | }
12 | ws.limitAfter(node.key.endToken, 'MethodDefinitionName');
13 | };
14 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 | node.elements.forEach(function(el) {
11 | var comma = tk.findNext(el.endToken, [',', ']']);
12 | if (comma.value === ',') {
13 | limit.around(comma, 'ArrayPatternComma');
14 | }
15 | });
16 | };
17 |
--------------------------------------------------------------------------------
/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/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 left/right of a BinaryExpression, LogicalExpression or
7 | // UnaryExpression
8 | if (!child || !opts[parent.type + '.' + child.type]) {
9 | return false;
10 | }
11 |
12 | var left = child.left;
13 | var right = child.right;
14 | return !right || (!opts[right.type] && !opts[left.type]);
15 | }
16 |
--------------------------------------------------------------------------------
/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/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/plugin/index.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | "ObjectExpressionOpeningBrace": 1,
22 | "PropertyValue": -1
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 | exports.format = function ExportNamedDeclaration(node) {
8 | _br.limitAfter(node.startToken, 0);
9 | _ws.limitAfter(node.startToken, 1);
10 |
11 | // node.specifiers is actually handled by the ExportSpecifier hook!
12 |
13 | if (!node.specifiers.length) return;
14 |
15 | var fromKeyword = _tk.findPrev(node.endToken, 'from');
16 | if (fromKeyword) {
17 | // safeguard against `export { foo, bar };` (no "from")
18 | _br.limit(fromKeyword, 0);
19 | _ws.limit(fromKeyword, 1);
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | // default params (#285)
14 | let defaultParams = (x, y = 1, z = 2) => {
15 | return x + y + z;
16 | }
17 |
18 | // issue #393
19 | a = () => {
20 | test(() => {
21 | return 1
22 | })
23 | test(() => {
24 | return 1
25 | })
26 | }
27 |
28 | // issue #357
29 | const object = x => ({
30 | x
31 | });
32 |
33 | const retObject = x => {
34 | return {
35 | x
36 | };
37 | }
38 |
39 | const array = x => [
40 | x
41 | ];
42 |
43 | const callWithObject = x => f({
44 | x
45 | });
46 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 | // default params (#285)
11 | let defaultParams = (x, y = 1, z = 2 ) => {
12 | return x + y + z;
13 | }
14 |
15 | // issue #393
16 | a = () => {
17 | test( () => {
18 | return 1
19 | })
20 | test(() => {
21 | return 1
22 | })
23 | }
24 |
25 | // issue #357
26 | const object = x => ({
27 | x
28 | });
29 |
30 | const retObject = x => {
31 | return {
32 | x
33 | };
34 | }
35 |
36 | const array = x => [
37 | x
38 | ];
39 |
40 | const callWithObject = x => f({
41 | x
42 | });
43 |
--------------------------------------------------------------------------------
/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/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/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 | _ws.limit(node.startToken, 'UnaryExpressionOperator');
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/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 | if (node.generator) {
14 | var genToken = _tk.findNextNonEmpty(node.startToken);
15 | _ws.limitBefore(genToken, 'FunctionGeneratorAsterisk');
16 | }
17 | _params.format(node);
18 | _limit.around(node.body.startToken, 'FunctionDeclarationOpeningBrace');
19 | _limit.around(node.body.endToken, 'FunctionDeclarationClosingBrace');
20 | };
21 |
22 |
23 | exports.getIndentEdges = function(node, opts) {
24 | return [
25 | _params.getIndentEdges(node, opts),
26 | node.body
27 | ];
28 | };
29 |
--------------------------------------------------------------------------------
/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/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 | return [
22 | { // do
23 | startToken: node.startToken.next,
24 | endToken: node.body.endToken
25 | },
26 | { // while
27 | startToken: _tk.findNext(node.body.endToken, '('),
28 | endToken: _tk.findPrev(node.endToken, ')')
29 | }
30 | ];
31 | };
32 |
--------------------------------------------------------------------------------
/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/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 |
29 |
30 | // issue #34 (break line comment into individual line)
31 | if ( window.DOMParser ) { // Standard
32 | tmp = new DOMParser();
33 | xml = tmp.parseFromString( data , "text/xml" );
34 | } else { // IE
35 | xml = new ActiveXObject( "Microsoft.XMLDOM" );
36 | xml.async = "false";
37 | xml.loadXML( data );
38 | }
39 |
40 |
41 | // issue #196
42 | if (a)
43 | a(); // run a
44 | else if (b)
45 | b(); // run b
46 | else {
47 | c(); // run c
48 | }
49 |
--------------------------------------------------------------------------------
/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/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 | "ParameterList" : 1,
19 | "ParameterComma" : 0,
20 | "ParameterList" : 1,
21 | "FunctionDeclarationOpeningBrace" : 0,
22 | "FunctionDeclarationClosingBrace" : 1
23 | },
24 | "after" : {
25 | "FunctionName" : 1,
26 | "ParameterComma" : 0,
27 | "ParameterList" : 1,
28 | "FunctionDeclarationOpeningBrace" : 1
29 | }
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/ClassDeclarationAndExpression.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // this file handles both ClassDeclaration and ClassExpression
4 |
5 | var tk = require('rocambole-token');
6 | var ws = require('rocambole-whitespace');
7 | var limit = require('../limit');
8 |
9 | exports.format = function ClassDeclarationAndExpression(node) {
10 | var classKeyword = node.startToken;
11 | var opening = tk.findNext(node.startToken, '{');
12 | var closing = node.endToken;
13 | // yes, we remove all the line breaks and limit to a single whitespace in
14 | // between the words since line breaks here would increase complexity
15 | tk.removeInBetween(classKeyword, opening, tk.isBr);
16 | ws.limitAfter(classKeyword, 1);
17 | var extendsKeyword = tk.findInBetween(classKeyword, opening, 'extends');
18 | if (extendsKeyword) {
19 | ws.limit(extendsKeyword, 1);
20 | }
21 |
22 | limit.around(opening, 'ClassOpeningBrace');
23 | limit.around(closing, 'ClassClosingBrace');
24 | };
25 |
26 | exports.getIndentEdges = function(node) {
27 | return node;
28 | };
29 |
--------------------------------------------------------------------------------
/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 |
42 |
43 | // issue #34 (break line comment into individual line)
44 | if(window.DOMParser)
45 | { // Standard
46 | tmp = new DOMParser();
47 | xml = tmp.parseFromString(data, "text/xml");
48 | }
49 | else
50 | { // IE
51 | xml = new ActiveXObject("Microsoft.XMLDOM");
52 | xml.async = "false";
53 | xml.loadXML(data);
54 | }
55 |
56 |
57 | // issue #196
58 | if(a)
59 | a(); // run a
60 | else if(b)
61 | b(); // run b
62 | else
63 | {
64 | c(); // run c
65 | }
66 |
--------------------------------------------------------------------------------
/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/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/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/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 |
--------------------------------------------------------------------------------
/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/cli.spec.js');
38 | m.addFile('test/api.spec.js');
39 | m.addFile('test/plugins.spec.js');
40 | m.addFile('test/pipe.spec.js');
41 |
42 | m.run(function(err) {
43 | var exitCode = err ? 1 : 0;
44 | if (err) console.log('failed tests: ' + err);
45 | process.exit(exitCode);
46 | });
47 |
48 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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/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/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | // endToken might be ":" or "break" or ";"
22 | var breakKeyword = _tk.findInBetweenFromEnd(node.startToken, endToken.next, 'break');
23 | if (breakKeyword) {
24 | limit.before(breakKeyword, 'BreakKeyword');
25 | limit.after(endToken, 'BreakKeyword');
26 | }
27 | };
28 |
29 |
30 | exports.getIndentEdges = function(node) {
31 | return {
32 | startToken: node.startToken,
33 | // we need to get the next token because `default` might end with a `}`
34 | // (ie. IfStatement) we also need to search for next `case` or `}` or
35 | // `break` or `default` to make sure comments are included inside the range
36 | endToken: _tk.findNext(node.endToken, ['}', 'case', 'break', 'default']).prev
37 | };
38 | };
39 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
9 | exports.format = function(node) {
10 | var braceStart = _tk.findPrev(node.startToken, _tk.isCode);
11 | var braceEnd = _tk.findNext(node.endToken, _tk.isCode);
12 |
13 | // handle `import foo, { lorem, ipsum } from 'lib';`
14 | if (braceStart.value === '{' || braceStart.value === ',') {
15 | _br.limit(braceStart, 0);
16 | _ws.limitBefore(braceStart, braceStart.value === '{' ? 1 : 0);
17 | _ws.limitAfter(braceStart, braceStart.value === '{' ? 'ModuleSpecifierOpeningBrace' : 1);
18 | }
19 |
20 | if (braceEnd.value === '}' || braceEnd.value === ',') {
21 | _br.limit(braceEnd, 0);
22 | var next = _tk.findNextNonEmpty(braceEnd);
23 | _ws.limitAfter(braceEnd, next.value === ';' ? 0 : 1);
24 | _ws.limitBefore(braceEnd, braceEnd.value === '}' ? 'ModuleSpecifierClosingBrace' : 0);
25 | }
26 |
27 | _br.limit(node.startToken, 0);
28 | _br.limit(node.endToken, 0);
29 |
30 | if (node.startToken !== node.endToken) {
31 | // handle spaces around "as"
32 | // eg: `import { named1 as myNamed1 } from 'lib'`
33 | // eg: `import * as myLib from 'lib'`
34 | _ws.limitAfter(node.startToken, 1);
35 | _ws.limitBefore(node.endToken, 1);
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/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 |
16 | // assignment operators
17 |
18 | x+= y
19 | x -= y
20 | x *= y
21 | x /= y
22 | x%= y
23 | x<<= y
24 | x >>= y
25 | x
26 | >>>=
27 | y
28 | x&= y
29 | x^=y
30 | x|=y
31 |
32 |
33 | // multiple same line
34 | this.a=b;this.c=d;this.e=f;this.g=h||0;
35 |
36 | function h(a,b,c,d,e){this._listener=b;this._isOnce=c;this.context=d;this._signal=a;this._priority=e||0}
37 |
38 |
39 | // test for issue #5 (related to parenthesis)
40 | doc=(context&&context.nodeType?context.ownerDocument||context:document);
41 |
42 |
43 | // issue #8 (multiple assignment + OR + indent)
44 | function iss8(){
45 | if (proxy) {
46 | proxy.guid = fn.guid = fn.guid || jQuery.guid++;
47 | }
48 | }
49 |
50 | // issue #306: UnaryExpression
51 | hasNativeRequestAnimationFrame = !!(
52 | window.requestAnimationFrame ||
53 | window.webkitRequestAnimationFrame ||
54 | window.mozRequestAnimationFrame ||
55 | window.msRequestAnimationFrame
56 | );
57 |
58 | // issue #316
59 | export class Foobar extends EventEmitter {
60 | constructor(foo, bar, d = {}) {
61 | super();
62 | var fooBar = { foo, bar };
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/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 123;
36 | export default function (x) {
37 | return x
38 | }
39 | export default x => x;
40 | export default class {
41 | constructor(x, y) {
42 | this.x = x;
43 | this.y = y;
44 | }
45 | }
46 |
47 | export { MY_CONST, myFunc };
48 | export { MY_CONST as THE_CONST, myFunc as theFunc };
49 |
50 | export * from 'src/other_module';
51 | export { foo, bar } from 'src/other_module';
52 | export { foo as myFoo, bar } from 'src/other_module';
53 |
--------------------------------------------------------------------------------
/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 |
13 | // assignment operators
14 |
15 | x += y
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 |
27 |
28 | // multiple same line
29 | this.a = b;
30 | this.c = d;
31 | this.e = f;
32 | this.g = h || 0;
33 |
34 | function h(a, b, c, d, e) {
35 | this._listener = b;
36 | this._isOnce = c;
37 | this.context = d;
38 | this._signal = a;
39 | this._priority = e || 0
40 | }
41 |
42 |
43 | // test for issue #5 (related to parenthesis)
44 | doc = (context && context.nodeType ? context.ownerDocument || context : document);
45 |
46 |
47 | // issue #8 (multiple assignment + OR + indent)
48 | function iss8() {
49 | if (proxy) {
50 | proxy.guid = fn.guid = fn.guid || jQuery.guid++;
51 | }
52 | }
53 |
54 | // issue #306: UnaryExpression
55 | hasNativeRequestAnimationFrame = !!(
56 | window.requestAnimationFrame ||
57 | window.webkitRequestAnimationFrame ||
58 | window.mozRequestAnimationFrame ||
59 | window.msRequestAnimationFrame
60 | );
61 |
62 | // issue #316
63 | export class Foobar extends EventEmitter {
64 | constructor(foo, bar, d = {}) {
65 | super();
66 | var fooBar = {
67 | foo,
68 | bar
69 | };
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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, { 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 123;
36 | export default function (x) {
37 | return x
38 | }
39 | export default x => x;
40 | export default class {
41 | constructor(x, y) {
42 | this.x = x;
43 | this.y = y;
44 | }
45 | }
46 |
47 | export { MY_CONST, myFunc };
48 | export { MY_CONST as THE_CONST, myFunc as theFunc };
49 |
50 | export * from 'src/other_module';
51 | export { foo, bar } from 'src/other_module';
52 | export { foo as myFoo, bar } from 'src/other_module';
53 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | edges.push(node.body);
27 | }
28 | if (shouldHandleParams(node)) {
29 | edges.push(_params.getIndentEdges(node, opts));
30 | }
31 | return edges;
32 | };
33 |
34 | function shouldHandleParams(node) {
35 | var arrow = tk.findPrev(node.body.startToken, '=>');
36 | // we don't check based on `node.params` because of `node.defaults`
37 | return tk.findPrevNonEmpty(arrow).value === ')';
38 | }
39 |
40 | function shouldIndentBody(node, opts) {
41 | // we don't want to indent the body twice if ObjectExpression or
42 | // ArrayExpression or CallExpression
43 | return node.body.type === 'BlockStatement' || !opts[node.body.type];
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
43 | default 123;
44 | export default function (x) {
45 | return x
46 | }
47 | export default x => x;
48 | export default class {
49 | constructor(x, y) {
50 | this.x = x;
51 | this.y = y;
52 | }
53 | }
54 |
55 | export { MY_CONST, myFunc };
56 | export { MY_CONST as THE_CONST, myFunc as theFunc };
57 |
58 | export * from 'src/other_module';
59 | export { foo , bar }from 'src/other_module';
60 | export {foo as myFoo,bar} from 'src/other_module';
61 |
--------------------------------------------------------------------------------
/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
43 | default 123;
44 | export default function (x) {
45 | return x
46 | }
47 | export default x => x;
48 | export default class {
49 | constructor(x, y) {
50 | this.x = x;
51 | this.y = y;
52 | }
53 | }
54 |
55 | export { MY_CONST, myFunc };
56 | export { MY_CONST as THE_CONST, myFunc as theFunc };
57 |
58 | export * from 'src/other_module';
59 | export { foo , bar }from 'src/other_module';
60 | export {foo as myFoo,bar} from 'src/other_module';
61 |
--------------------------------------------------------------------------------
/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 a,
9 | b = true,
10 | c = 3,
11 | d = false;
12 |
13 | var amet = qwe();
14 | var asi = true
15 |
16 |
17 | // test for issue #4
18 | var
19 | // foo var
20 | foo,
21 | // bar variable
22 | bar = 'dolor amet';
23 |
24 |
25 | // issue #28 : comma first
26 | var x = 33,
27 | y = 12,
28 |
29 |
30 | // comment
31 | w = 45;
32 |
33 |
34 | // issue #31: multiple var declaration + function expression = wrong indent
35 | (function() {
36 | var
37 | // A central reference to the root jQuery(document)
38 | rootjQuery,
39 |
40 | // Define a local copy of jQuery
41 | jQuery = function(selector, context) {
42 | // The jQuery object is actually just the init constructor 'enhanced'
43 | return new jQuery.fn.init(selector, context, rootjQuery);
44 | },
45 |
46 | // literal object
47 | obj = {
48 | num: 123,
49 | str: 'literal'
50 | };
51 | }());
52 |
53 | var lorem = ipsum ||
54 | dolor &&
55 | (sit || amet);
56 |
57 | // issue #306: UnaryExpression
58 | var hasNativeRequestAnimationFrame = !!(
59 | window.requestAnimationFrame ||
60 | window.webkitRequestAnimationFrame ||
61 | window.mozRequestAnimationFrame ||
62 | window.msRequestAnimationFrame
63 | );
64 |
65 | // issue #334
66 | var a = 'foo';
67 | var b = '3';
68 |
69 | // comma-first + asi
70 | var foo = 123,
71 | bar = 456;
72 | [1, 2, 3].forEach(echo)
73 |
--------------------------------------------------------------------------------
/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 a,b= true,
9 | c =3, d=false;
10 |
11 | var
12 |
13 | amet= qwe();
14 | var asi = true
15 |
16 |
17 | // test for issue #4
18 | var
19 | // foo var
20 | foo,
21 | // bar variable
22 | bar = 'dolor amet';
23 |
24 |
25 | // issue #28 : comma first
26 | var x=33
27 | ,y=12
28 |
29 |
30 | // comment
31 | , w = 45;
32 |
33 |
34 | // issue #31: multiple var declaration + function expression = wrong indent
35 | (function(){
36 | var
37 | // A central reference to the root jQuery(document)
38 | rootjQuery,
39 |
40 | // Define a local copy of jQuery
41 | jQuery = function( selector, context ) {
42 | // The jQuery object is actually just the init constructor 'enhanced'
43 | return new jQuery.fn.init( selector, context, rootjQuery );
44 | },
45 |
46 | // literal object
47 | obj = {
48 | num : 123,
49 | str : 'literal'
50 | };
51 | }());
52 |
53 | var lorem = ipsum ||
54 | dolor &&
55 | (sit || amet);
56 |
57 | // issue #306: UnaryExpression
58 | var hasNativeRequestAnimationFrame = !!(
59 | window.requestAnimationFrame ||
60 | window.webkitRequestAnimationFrame ||
61 | window.mozRequestAnimationFrame ||
62 | window.msRequestAnimationFrame
63 | );
64 |
65 | // issue #334
66 | var a = 'foo' ;
67 | var b = '3'
68 | ;
69 |
70 | // comma-first + asi
71 | var foo = 123
72 | , bar = 456
73 | ;[1,2,3].forEach(echo)
74 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | var _specialArguments = {
30 | 'BinaryExpression': true
31 | };
32 |
33 |
34 | exports.getIndentEdges = function(node, opts) {
35 | // we bypass indentation if argument already adds indentation
36 | if (!node.argument ||
37 | (opts[node.argument.type] && !_specialArguments[node.argument.type])) {
38 | return false;
39 | }
40 |
41 | var parentheses = expressionParentheses.getParentheses(node.argument);
42 | return parentheses ?
43 | {
44 | startToken: parentheses.opening,
45 | endToken: parentheses.closing
46 | } :
47 | {
48 | startToken: node.startToken.next,
49 | endToken: _tk.isEmpty(node.endToken) ?
50 | _tk.findPrevNonEmpty(node.endToken) :
51 | node.endToken
52 | };
53 | };
54 |
--------------------------------------------------------------------------------
/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/preset/jquery.json:
--------------------------------------------------------------------------------
1 | {
2 | "preset" : "default",
3 |
4 | "indent" : {
5 | "value" : "\t",
6 | "IfStatementConditional": 2,
7 | "SwitchStatement" : 0,
8 | "TopLevelFunctionBlock" : 0
9 | },
10 |
11 | "lineBreak" : {
12 | "before" : {
13 | "ObjectExpressionOpeningBrace": -1,
14 | "ObjectExpressionClosingBrace": -1,
15 | "Property": -1,
16 | "VariableDeclarationWithoutInit" : 0
17 | },
18 |
19 | "after": {
20 | "AssignmentOperator": -1,
21 | "ObjectExpressionOpeningBrace": -1,
22 | "ObjectExpressionClosingBrace": -1,
23 | "Property": -1
24 | }
25 | },
26 |
27 | "whiteSpace" : {
28 | "before" : {
29 | "ArgumentList" : 1,
30 | "ArrayExpressionClosing" : 1,
31 | "CatchParameterList": 1,
32 | "ExpressionClosingParentheses" : 1,
33 | "ForInStatementExpressionClosing" : 1,
34 | "ForOfStatementExpressionClosing" : 1,
35 | "ForStatementExpressionClosing" : 1,
36 | "IfStatementConditionalClosing" : 1,
37 | "IIFEClosingParentheses": 1,
38 | "MemberExpressionClosing" : 1,
39 | "ObjectExpressionClosingBrace": 1,
40 | "ParameterList" : 1,
41 | "SwitchDiscriminantClosing" : 1,
42 | "WhileStatementConditionalClosing" : 1
43 | },
44 | "after" : {
45 | "ArgumentList" : 1,
46 | "ArrayExpressionOpening" : 1,
47 | "CatchParameterList": 1,
48 | "ExpressionOpeningParentheses" : 1,
49 | "ForInStatementExpressionOpening" : 1,
50 | "ForOfStatementExpressionOpening" : 1,
51 | "ForStatementExpressionOpening" : 1,
52 | "IfStatementConditionalOpening" : 1,
53 | "IIFEOpeningParentheses": 1,
54 | "MemberExpressionOpening" : 1,
55 | "ObjectExpressionOpeningBrace": 1,
56 | "ParameterList" : 1,
57 | "PropertyValue": -1,
58 | "SwitchDiscriminantOpening" : 1,
59 | "WhileStatementConditionalOpening" : 1
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/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/function_declaration-in.js:
--------------------------------------------------------------------------------
1 | function simple(x,y){return x+y;}
2 |
3 | function simple_2(a,b,c)
4 | {
5 | return a+b + c ;
6 | }
7 |
8 | // indent, spaces
9 | function foo( x ){ return x; }
10 |
11 | // test space on params
12 | function bar(a,b,c){
13 | // test indentation
14 | return 'baz'; // test comment
15 | }
16 |
17 | // test nested fn
18 | function dolor(){
19 | // trailing white space
20 | // missing semicolon
21 | function fn(){ function deep() {
22 | // moar
23 | function moar() {
24 | // nested comment
25 | return "inner";
26 | }
27 | return moar( ) ;
28 | }
29 | // test invocation
30 | setTimeout(fn,100);
31 | }
32 | }
33 |
34 | // invocation
35 | dolor();
36 |
37 |
38 | // start test keepEmptyLines
39 |
40 |
41 |
42 | // end test keepEmptyLines
43 |
44 | // test a bug related with indentation and multiple consecutive functions
45 | function outter(){ function a1(){return true}function a2(val){return (val*2)} }
46 |
47 |
48 | // issue #29 : return + line break + ternary
49 | function iss29(a){
50 | return
51 | a<5?23:12;
52 | }
53 |
54 | function multiLineReturn() {
55 | return a&&
56 | b||
57 | c;
58 | }
59 |
60 | function expressionReturn() {
61 | return (
62 | a &&
63 | b+
64 | c
65 | );
66 | }
67 |
68 | // issue #283
69 | function foo () {
70 | bar()
71 | }
72 |
73 | // issue #140
74 | function chainedReturn() {
75 | return deferred.promise
76 | .then(console.log)
77 | }
78 |
79 | // issue #231
80 | function multiLineParams(
81 | foo,
82 | bar
83 | ) {
84 | }
85 |
86 | // issue #285
87 | function defaultParams(z, x = 1, y=2) {
88 | return x + y + z;
89 | }
90 |
91 | // issue #350
92 | function * gen() {
93 | yield '123';
94 | yield '456';
95 | }
96 | function* gen() {
97 | yield '123';
98 | yield '456';
99 | }
100 | function*gen() {
101 | yield '123';
102 | yield '456';
103 | }
104 |
--------------------------------------------------------------------------------
/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 only one param or last one there are no commas to look for
23 | if (i < params.length - 1) {
24 | _limit.around(_tk.findNext(param.startToken, ','), 'ParameterComma');
25 | }
26 |
27 | // Default parameters are AssignmentExpressions as params
28 | if (param.type === 'AssignmentPattern' && param.right) {
29 | _limit.around(_tk.findPrev(param.right.startToken, '='), 'AssignmentPattern');
30 | }
31 | });
32 | _ws.limitAfter(_tk.findPrevNonEmpty(closing), 'ParameterList');
33 | } else {
34 | _limit.after(opening, 0);
35 | }
36 | };
37 |
38 | exports.getIndentEdges = function(node, opts) {
39 | var params = node.params;
40 | if (params.length && opts.ParameterList) {
41 | // get/set on ObjectEpression affect drastically the FunctionExpression
42 | // structure so we need to handle it differently
43 | var start = node.parent.type === 'Property' ?
44 | node.parent.startToken :
45 | node.startToken;
46 | return {
47 | // we check if start is equal to "(" because of arrow functions
48 | startToken: start.value === '(' ? start : _tk.findNext(start, '('),
49 | endToken: _tk.findPrev(node.body.startToken, ')'),
50 | level: opts.ParameterList
51 | };
52 | }
53 | return null;
54 | };
55 |
--------------------------------------------------------------------------------
/test/compare/default/function_declaration-out.js:
--------------------------------------------------------------------------------
1 | function simple(x, y) {
2 | return x + y;
3 | }
4 |
5 | function simple_2(a, b, c) {
6 | return a + b + c;
7 | }
8 |
9 | // indent, spaces
10 | function foo(x) {
11 | return x;
12 | }
13 |
14 | // test space on params
15 | function bar(a, b, c) {
16 | // test indentation
17 | return 'baz'; // test comment
18 | }
19 |
20 | // test nested fn
21 | function dolor() {
22 | // trailing white space
23 | // missing semicolon
24 | function fn() {
25 | function deep() {
26 | // moar
27 | function moar() {
28 | // nested comment
29 | return "inner";
30 | }
31 | return moar();
32 | }
33 | // test invocation
34 | setTimeout(fn, 100);
35 | }
36 | }
37 |
38 | // invocation
39 | dolor();
40 |
41 |
42 | // start test keepEmptyLines
43 |
44 |
45 |
46 | // end test keepEmptyLines
47 |
48 | // test a bug related with indentation and multiple consecutive functions
49 | function outter() {
50 | function a1() {
51 | return true
52 | }
53 | function a2(val) {
54 | return (val * 2)
55 | }
56 | }
57 |
58 |
59 | // issue #29 : return + line break + ternary
60 | function iss29(a) {
61 | return
62 | a < 5 ? 23 : 12;
63 | }
64 |
65 | function multiLineReturn() {
66 | return a &&
67 | b ||
68 | c;
69 | }
70 |
71 | function expressionReturn() {
72 | return (
73 | a &&
74 | b +
75 | c
76 | );
77 | }
78 |
79 | // issue #283
80 | function foo() {
81 | bar()
82 | }
83 |
84 | // issue #140
85 | function chainedReturn() {
86 | return deferred.promise
87 | .then(console.log)
88 | }
89 |
90 | // issue #231
91 | function multiLineParams(
92 | foo,
93 | bar
94 | ) {
95 | }
96 |
97 | // issue #285
98 | function defaultParams(z, x = 1, y = 2) {
99 | return x + y + z;
100 | }
101 |
102 | // issue #350
103 | function* gen() {
104 | yield '123';
105 | yield '456';
106 | }
107 | function* gen() {
108 | yield '123';
109 | yield '456';
110 | }
111 | function* gen() {
112 | yield '123';
113 | yield '456';
114 | }
115 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "esformatter",
3 | "version": "0.9.0",
4 | "description": "ECMAScript code beautifier/formatter",
5 | "main": "lib/esformatter.js",
6 | "bin": {
7 | "esformatter": "./bin/esformatter"
8 | },
9 | "scripts": {
10 | "test": "node test/runner.js",
11 | "lint": "jshint lib/*.js lib/**/*.js test/*.js",
12 | "format": "esformatter -i 'lib/**/*.js'"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/millermedeiros/esformatter.git"
17 | },
18 | "bugs": {
19 | "url": "https://github.com/millermedeiros/esformatter/issues"
20 | },
21 | "directories": {
22 | "doc": "./doc",
23 | "bin": "./bin",
24 | "lib": "./lib"
25 | },
26 | "keywords": [
27 | "babel",
28 | "beautifier",
29 | "beautify",
30 | "ecmascript",
31 | "esprima",
32 | "format",
33 | "formatter",
34 | "javascript",
35 | "jscs",
36 | "source",
37 | "style",
38 | "syntax"
39 | ],
40 | "author": {
41 | "name": "Miller Medeiros",
42 | "url": "http://blog.millermedeiros.com/"
43 | },
44 | "devDependencies": {
45 | "chai": "1.4",
46 | "esformatter-pipe-test": "file:test/pipe",
47 | "esformatter-test-plugin": "file:test/plugin",
48 | "jshint": "~2.3.0",
49 | "mocha": "https://github.com/millermedeiros/mocha/tarball/latest",
50 | "mockery": "^1.4.0"
51 | },
52 | "dependencies": {
53 | "acorn-to-esprima": "^2.0.6",
54 | "babel-traverse": "^6.4.5",
55 | "babylon": "^6.4.5",
56 | "debug": "^0.7.4",
57 | "disparity": "^2.0.0",
58 | "glob": "^5.0.3",
59 | "minimist": "^1.1.1",
60 | "mout": ">=0.9 <2.0",
61 | "npm-run": "^2.0.0",
62 | "resolve": "^1.1.5",
63 | "rocambole": ">=0.7 <2.0",
64 | "rocambole-indent": "^2.0.4",
65 | "rocambole-linebreak": "^1.0.0",
66 | "rocambole-node": "~1.0",
67 | "rocambole-token": "^1.1.2",
68 | "rocambole-whitespace": "^1.0.0",
69 | "stdin": "*",
70 | "strip-json-comments": "~0.1.1",
71 | "supports-color": "^1.3.1",
72 | "user-home": "^2.0.0"
73 | },
74 | "esformatter": {
75 | "root": true
76 | },
77 | "license": "MIT"
78 | }
79 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/plugins.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var partial = require('mout/function/partial');
4 | var remove = require('mout/array/remove');
5 |
6 | var _plugins = [];
7 |
8 |
9 | exports.register = register;
10 | function register(plugin) {
11 | if (_plugins.indexOf(plugin) === -1) {
12 | _plugins.push(plugin);
13 | }
14 | }
15 |
16 |
17 | exports.unregister = partial(remove, _plugins);
18 |
19 |
20 | exports.unregisterAll = unregisterAll;
21 | function unregisterAll() {
22 | _plugins = [];
23 | }
24 |
25 |
26 | exports.setOptions = function(opts) {
27 | loadAndRegister(opts && opts.plugins);
28 | // esformatter ends up being a circular dependency,
29 | // but this was the quickest way of doing it :P
30 | // needed specially because of issue #348
31 | exec('setOptions', opts, require('./esformatter'));
32 | };
33 |
34 |
35 | exports.loadAndRegister = loadAndRegister;
36 | function loadAndRegister(ids) {
37 | ids = ids || [];
38 | ids.forEach(function(id) {
39 | var module;
40 | try {
41 | module = require(id);
42 | } catch (e) {
43 | throw new Error(
44 | 'Error: Cannot find plugin \'' + id + '\'.' + ' Make sure ' +
45 | 'you used the correct name on the config file or run `npm install ' +
46 | '--save-dev ' + id + '` to add it as a project dependency.'
47 | );
48 | }
49 | register(module);
50 | });
51 | }
52 |
53 |
54 | exportMethods([
55 | 'tokenBefore',
56 | 'tokenAfter',
57 | 'nodeBefore',
58 | 'nodeAfter',
59 | // "transform" is an alias to "transformAfter" but we do not recommend using
60 | // it going forward. it might be deprecated in the future.
61 | 'transform',
62 | 'transformAfter',
63 | 'transformBefore'
64 | ], exec);
65 |
66 | exportMethods([
67 | 'stringBefore',
68 | 'stringAfter'
69 | ], pipe);
70 |
71 |
72 | function exportMethods(arr, fn) {
73 | arr.forEach(function(methodName) {
74 | exports[methodName] = partial(fn, methodName);
75 | });
76 | }
77 |
78 |
79 | function exec(methodName) {
80 | var args = Array.prototype.slice.call(arguments, 1);
81 | _plugins.forEach(function(plugin) {
82 | if (methodName in plugin) {
83 | plugin[methodName].apply(plugin, args);
84 | }
85 | });
86 | }
87 |
88 |
89 | function pipe(methodName, input) {
90 | return _plugins.reduce(function(output, plugin) {
91 | return methodName in plugin ? plugin[methodName](output) : output;
92 | }, input);
93 | }
94 |
--------------------------------------------------------------------------------
/test/compare/default/call_expression-out.js:
--------------------------------------------------------------------------------
1 | foo();
2 | baz();
3 |
4 | bar(1, 'dolor');
5 | ipsum(3, {
6 | amet: true
7 | }, 'foo');
8 |
9 | dolor = foo(2)
10 |
11 | // should not remove line breaks
12 | foo(a, b,
13 | c, d)
14 |
15 | tricky((123));
16 | tricky2((123), ((456)));
17 |
18 | // it should indent chained calls if there is a line break between each call
19 | foo.bar()
20 | // comment
21 | .ipsum()
22 | .dolor();
23 |
24 | function foo() {
25 | dolor
26 | // comment
27 | .amet()
28 | .maecennas();
29 | }
30 |
31 | contents = this.headers.next()
32 | .removeClass("ui-helper-reset ui-widget-content ui-corner-bottom " +
33 | "ui-accordion-content ui-accordion-content-active ui-state-disabled")
34 | .css("display", "")
35 | .removeAttr("role");
36 |
37 | returned.promise().done(foo)
38 | // comment
39 | .done(newDefer.resolve)
40 | .fail(newDefer.reject)
41 | // comment
42 | .progress(newDefer.notify);
43 |
44 | filter(function() {
45 | // comment
46 | x;
47 | }).map(function() {
48 | // comment
49 | y;
50 | });
51 |
52 | var contents;
53 | contents = this.headers.next()
54 | .removeClass("ui-state-disabled")
55 | .css("display", "");
56 |
57 | gulp.task('lint', function() {
58 | return gulp.src('**.js')
59 | .pipe(jshint())
60 | .pipe(jshint.reporter(stylish));
61 | });
62 |
63 | // issue #68
64 | define(function() {
65 | // line comment
66 | x;
67 | });
68 |
69 |
70 | noArgs();
71 |
72 | noArgs2();
73 | noArgs3();
74 | noArgs4(
75 | // not passing any args for some reason
76 | );
77 |
78 |
79 | // only indent if there is a line break before/between arguments
80 | indent(
81 | 'foo'
82 | );
83 |
84 | indent2({
85 | dolor: 123
86 | }, [
87 | 1, 2, 3
88 | ]);
89 |
90 | // this is a weird style but makes sense to indent args if you think about it
91 | indent3('lorem',
92 | {
93 | ipsum: 'dolor'
94 | },
95 | [
96 | 1,
97 | 2,
98 | 3
99 | ]);
100 |
101 | indent4({
102 | a: b
103 | });
104 | indent5(
105 | {
106 | a: b
107 | },
108 | [1, 2, 3]
109 | );
110 | indent6(
111 | {
112 | a: b
113 | }, [
114 | 1, 2, 3
115 | ]
116 | );
117 |
118 |
119 | // issue #200
120 | require([
121 | "foo",
122 | "bar"
123 | ], function(foo, bar) {
124 | foo(bar);
125 | });
126 |
127 |
128 | // issue #202
129 | app
130 | .directive('testDirective', ['param',
131 | function(param) {
132 | alert();
133 | }
134 | ])
135 |
136 | // issue #240
137 | equal(
138 | y
139 | .find()
140 | .length,
141 | expected
142 | );
143 |
144 | // issue #252
145 | promise().then(function(foo) {
146 | return x;
147 | }, function(bar) {
148 | return y;
149 | });
150 |
151 | // issue #267
152 | require('something');
153 | var Sidebar = Backbone.Model.extend({
154 | //...
155 | lorem: 'ipsum'
156 | });
157 |
158 | // issue #306
159 | foo(!!(lorem ||
160 | ipsum || dolor));
161 |
--------------------------------------------------------------------------------
/test/compare/default/call_expression-in.js:
--------------------------------------------------------------------------------
1 | foo();
2 | baz();
3 |
4 | bar(1,'dolor');
5 | ipsum(3,{amet:true},'foo');
6 |
7 | dolor=foo(2)
8 |
9 | // should not remove line breaks
10 | foo(a,b,
11 | c,d)
12 |
13 | tricky( (123) );
14 | tricky2( (123) , ((456)) );
15 |
16 | // it should indent chained calls if there is a line break between each call
17 | foo.bar()
18 | // comment
19 | .ipsum()
20 | .dolor();
21 |
22 | function foo() {
23 | dolor
24 | // comment
25 | .amet()
26 | .maecennas();
27 | }
28 |
29 | contents = this.headers.next()
30 | .removeClass("ui-helper-reset ui-widget-content ui-corner-bottom " +
31 | "ui-accordion-content ui-accordion-content-active ui-state-disabled")
32 | .css("display", "")
33 | .removeAttr("role");
34 |
35 | returned.promise().done(foo)
36 | // comment
37 | .done(newDefer.resolve)
38 | .fail(newDefer.reject)
39 | // comment
40 | .progress(newDefer.notify);
41 |
42 | filter(function() {
43 | // comment
44 | x;
45 | }).map(function() {
46 | // comment
47 | y;
48 | });
49 |
50 | var contents;
51 | contents = this.headers.next()
52 | .removeClass("ui-state-disabled")
53 | .css("display", "");
54 |
55 | gulp.task('lint', function() {
56 | return gulp.src('**.js')
57 | .pipe(jshint())
58 | .pipe(jshint.reporter(stylish));
59 | });
60 |
61 | // issue #68
62 | define(function() {
63 | // line comment
64 | x;
65 | });
66 |
67 |
68 | noArgs(
69 | );
70 |
71 | noArgs2( );
72 | noArgs3();
73 | noArgs4(
74 | // not passing any args for some reason
75 | );
76 |
77 |
78 | // only indent if there is a line break before/between arguments
79 | indent(
80 | 'foo'
81 | );
82 |
83 | indent2({
84 | dolor: 123
85 | }, [
86 | 1, 2, 3
87 | ]);
88 |
89 | // this is a weird style but makes sense to indent args if you think about it
90 | indent3('lorem',
91 | {
92 | ipsum: 'dolor'
93 | },
94 | [
95 | 1,
96 | 2,
97 | 3
98 | ]);
99 |
100 | indent4({
101 | a: b
102 | });
103 | indent5(
104 | {
105 | a: b
106 | },
107 | [1, 2, 3]
108 | );
109 | indent6(
110 | {
111 | a: b
112 | }, [
113 | 1, 2, 3
114 | ]
115 | );
116 |
117 |
118 | // issue #200
119 | require([
120 | "foo",
121 | "bar"
122 | ], function (foo, bar) {
123 | foo(bar);
124 | });
125 |
126 |
127 | // issue #202
128 | app
129 | .directive( 'testDirective', [ 'param',
130 | function( param ) {
131 | alert();
132 | }
133 | ])
134 |
135 | // issue #240
136 | equal(
137 | y
138 | .find()
139 | .length,
140 | expected
141 | );
142 |
143 | // issue #252
144 | promise().then(function(foo) {
145 | return x;
146 | }, function(bar) {
147 | return y;
148 | });
149 |
150 | // issue #267
151 | require ('something');
152 | var Sidebar = Backbone.Model.extend
153 | ({
154 | //...
155 | lorem: 'ipsum'
156 | });
157 |
158 | // issue #306
159 | foo(!!(lorem ||
160 | ipsum || dolor));
161 |
--------------------------------------------------------------------------------
/lib/hooks.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | // Hooks for each node.type that should be processed individually
5 | // ---
6 | // using an object to store each transform method to avoid a long switch
7 | // statement, will be more organized in the long run and also allow
8 | // monkey-patching/spies/mock/stub.
9 |
10 |
11 | // we are not using something like https://npmjs.org/package/require-all
12 | // because we want esformatter to be able to run in the browser in the future
13 |
14 | exports.ArrayExpression = require('./hooks/ArrayExpression');
15 | exports.ArrayPattern = require('./hooks/ArrayPattern');
16 | exports.ArrowFunctionExpression = require('./hooks/ArrowFunctionExpression');
17 | exports.AssignmentExpression = require('./hooks/AssignmentExpression');
18 | exports.BinaryExpression = require('./hooks/BinaryExpression');
19 | exports.CallExpression = exports.NewExpression = require('./hooks/CallExpression');
20 | exports.CatchClause = require('./hooks/CatchClause');
21 | exports.ClassDeclaration = exports.ClassExpression = require('./hooks/ClassDeclarationAndExpression');
22 | exports.ConditionalExpression = require('./hooks/ConditionalExpression');
23 | exports.DoWhileStatement = require('./hooks/DoWhileStatement');
24 | exports.ExportAllDeclaration = require('./hooks/ExportAllDeclaration');
25 | exports.ExportDefaultDeclaration = require('./hooks/ExportDefaultDeclaration');
26 | exports.ExportNamedDeclaration = require('./hooks/ExportNamedDeclaration');
27 | exports.ExportSpecifier = require('./hooks/ExportSpecifier');
28 | exports.ForInStatement = require('./hooks/ForInStatement');
29 | exports.ForOfStatement = require('./hooks/ForOfStatement');
30 | exports.ForStatement = require('./hooks/ForStatement');
31 | exports.FunctionDeclaration = require('./hooks/FunctionDeclaration');
32 | exports.FunctionExpression = require('./hooks/FunctionExpression');
33 | exports.IfStatement = require('./hooks/IfStatement');
34 | exports.ImportDeclaration = require('./hooks/ImportDeclaration');
35 | exports.ImportSpecifier = require('./hooks/ImportSpecifier');
36 | exports.LogicalExpression = require('./hooks/LogicalExpression');
37 | exports.MemberExpression = require('./hooks/MemberExpression');
38 | exports.MethodDefinition = require('./hooks/MethodDefinition');
39 | exports.ObjectExpression = require('./hooks/ObjectExpression');
40 | exports.ObjectPattern = require('./hooks/ObjectPattern');
41 | exports.ReturnStatement = require('./hooks/ReturnStatement');
42 | exports.SequenceExpression = require('./hooks/SequenceExpression');
43 | exports.SwitchStatement = require('./hooks/SwitchStatement');
44 | exports.SwitchCase = require('./hooks/SwitchCase');
45 | exports.ThrowStatement = require('./hooks/ThrowStatement');
46 | exports.TryStatement = require('./hooks/TryStatement');
47 | exports.UnaryExpression = require('./hooks/UnaryExpression');
48 | exports.UpdateExpression = require('./hooks/UpdateExpression');
49 | exports.VariableDeclaration = require('./hooks/VariableDeclaration');
50 | exports.WhileStatement = require('./hooks/WhileStatement');
51 |
--------------------------------------------------------------------------------
/lib/hooks/VariableDeclaration.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _br = require('rocambole-linebreak');
4 | var _tk = require('rocambole-token');
5 | var _ws = require('rocambole-whitespace');
6 | var helpers = require('../helpers');
7 |
8 |
9 | exports.format = function VariableDeclaration(node) {
10 | var insideFor = node.parent.type === 'ForStatement';
11 |
12 | node.declarations.forEach(function(declarator, i) {
13 | var idStartToken = declarator.id.startToken;
14 |
15 | // need to swap comma-first line break
16 | var prevNonEmpty = _tk.findPrevNonEmpty(idStartToken);
17 | if (i && prevNonEmpty.value === ',') {
18 | if (_tk.isBr(prevNonEmpty.prev) || _tk.isBr(prevNonEmpty.prev.prev)) {
19 | var beforeComma = _tk.findPrev(prevNonEmpty, function(t) {
20 | return !_tk.isEmpty(t) && !_tk.isComment(t);
21 | });
22 | _ws.limit(prevNonEmpty, 0);
23 | _tk.remove(prevNonEmpty);
24 | _tk.after(beforeComma, prevNonEmpty);
25 | }
26 | }
27 |
28 | if (!i && !_tk.isComment(_tk.findPrevNonEmpty(idStartToken))) {
29 | // XXX: we don't allow line breaks or multiple spaces after "var"
30 | // keyword for now (might change in the future)
31 | _tk.removeEmptyAdjacentBefore(idStartToken);
32 | } else if (!insideFor && declarator.init) {
33 | _br.limit(idStartToken, 'VariableName');
34 | }
35 | _ws.limitBefore(idStartToken, 'VariableName');
36 |
37 | if (declarator.init) {
38 | _ws.limitAfter(declarator.id.endToken, 'VariableName');
39 | var equalSign = _tk.findNext(declarator.id.endToken, '=');
40 | var valueStart = _tk.findNextNonEmpty(equalSign);
41 | _br.limitBefore(valueStart, 'VariableValue');
42 | _ws.limitBefore(valueStart, 'VariableValue');
43 | _br.limitAfter(declarator.endToken, 'VariableValue');
44 | _ws.limitAfter(declarator.endToken, 'VariableValue');
45 | }
46 | });
47 |
48 | // always add a space after the "var" keyword
49 | _ws.limitAfter(node.startToken, 1);
50 |
51 | if (_tk.isSemiColon(node.endToken)) {
52 | _br.limit(node.endToken, 'VariableDeclarationSemiColon');
53 | _ws.limit(node.endToken, 'VariableDeclarationSemiColon');
54 | }
55 | };
56 |
57 |
58 | exports.getIndentEdges = function(node, opts) {
59 | var edges = [];
60 |
61 | var isMulti = node.declarations.length > 1;
62 |
63 | if ((opts.MultipleVariableDeclaration && isMulti) ||
64 | (opts.SingleVariableDeclaration && !isMulti)
65 | ) {
66 | edges.push(node);
67 | }
68 |
69 | node.declarations.forEach(function(declaration) {
70 | var init = declaration.init;
71 | if (helpers.shouldIndentChild(node, init, opts)) {
72 | var end = init.endToken.value === ')' ?
73 | _tk.findPrevNonEmpty(init.endToken) :
74 | init.endToken.next;
75 | edges.push({
76 | level: opts['VariableDeclaration.' + init.type],
77 | startToken: init.startToken,
78 | endToken: end
79 | });
80 | }
81 | });
82 |
83 | return edges;
84 | };
85 |
--------------------------------------------------------------------------------
/lib/hooks/expressionParentheses.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _tk = require('rocambole-token');
4 | var _ws = require('rocambole-whitespace');
5 | var debug = require('debug')('esformatter:parentheses');
6 |
7 |
8 | exports.addSpaceInside = addSpaceInsideExpressionParentheses;
9 | function addSpaceInsideExpressionParentheses(node) {
10 | var parentheses = getParentheses(node);
11 | if (parentheses) {
12 | _ws.limitAfter(parentheses.opening, 'ExpressionOpeningParentheses');
13 | _ws.limitBefore(parentheses.closing, 'ExpressionClosingParentheses');
14 | }
15 | }
16 |
17 |
18 | exports.getParentheses = getParentheses;
19 | function getParentheses(node) {
20 | if (!isValidExpression(node)) {
21 | debug('not valid expression: %s', node.type);
22 | return;
23 | }
24 |
25 | var opening = node.startToken;
26 | if (/^(?:Binary|Logical)Expression$/.test(node.type) || opening.value !== '(') {
27 | opening = _tk.findPrevNonEmpty(opening);
28 | }
29 |
30 | if (!opening || opening.value !== '(') {
31 | // "safe" to assume it is not inside parentheses
32 | debug(
33 | 'opening is not a parentheses; type: %s, opening: "%s"',
34 | node.type,
35 | opening && opening.value
36 | );
37 | return;
38 | }
39 |
40 | var token = opening;
41 | var count = 0;
42 | var closing;
43 |
44 | while (token) {
45 | if (token.value === '(') {
46 | count += 1;
47 | } else if (token.value === ')') {
48 | count -= 1;
49 | }
50 | if (count === 0) {
51 | closing = token;
52 | break;
53 | }
54 | token = token.next;
55 | }
56 |
57 | if (!closing) {
58 | debug('not inside parentheses', count);
59 | return;
60 | }
61 |
62 | debug(
63 | 'found parentheses; type: %s, opening: "%s", closing: "%s"',
64 | node.type,
65 | opening && opening.value,
66 | closing && closing.value
67 | );
68 |
69 | return {
70 | opening: opening,
71 | closing: closing
72 | };
73 | }
74 |
75 | // Literal when inside BinaryExpression might be surrounded by parenthesis
76 | // CallExpression and ArrayExpression don't need spaces
77 | var needExpressionParenthesesSpaces = {
78 | Literal: true,
79 | CallExpression: false,
80 | FunctionExpression: false,
81 | ArrayExpression: false,
82 | ObjectExpression: false,
83 | // Special is used when we need to override default behavior
84 | Special: true
85 | };
86 |
87 |
88 | function isValidExpression(node) {
89 | var needSpaces = needExpressionParenthesesSpaces[node.type];
90 |
91 | if (needSpaces) {
92 | return true;
93 | }
94 |
95 | if (needSpaces == null && node.type.indexOf('Expression') !== -1) {
96 | if (node.type === 'ExpressionStatement' &&
97 | (node.expression.callee && node.expression.callee.type === 'FunctionExpression')) {
98 | // bypass IIFE
99 | return false;
100 | }
101 | return true;
102 | }
103 |
104 | return false;
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/test/compare/default/obj_expression-in.js:
--------------------------------------------------------------------------------
1 | foo.bar.Baz( {
2 | method2: function () {}, prop : 'dolor amet'
3 | , prop2 : 123
4 | });
5 |
6 | // issue #142
7 | var foo = [{
8 | bar: 42
9 | }];
10 |
11 | function foo(a){ amet(123, a, {flag:true}); }
12 | ipsum({flag:true});
13 | ipsum({flag:true,other:false});
14 | ipsum({flag:true,other:false},789,'bar');
15 |
16 |
17 | var obj = {foo:"bar", 'lorem' : 123,
18 | dolor :new Date()
19 | , "re": /\w+/g} ;
20 |
21 | // ObjectEpression within CallExpression needs to indent comments
22 | declare({
23 | // comment
24 | create: {}
25 | });
26 |
27 | this.element
28 | .add()
29 | .set({
30 | // line comment
31 | // one more
32 | prop: "value"
33 | });
34 |
35 | define( name, {
36 | _create: function() {
37 | this.element
38 | .add()
39 | .set({
40 | // line comment
41 | // one more
42 | prop: "value"
43 | });
44 | }
45 | });
46 |
47 | x = {
48 | props: {
49 | // comment
50 | x: 1
51 | }
52 | };
53 |
54 | var x = {
55 | data: x ?
56 | x() :
57 | // comment
58 | function() {}
59 | };
60 |
61 | // edge case
62 | for (key in {
63 | foo:'bar',
64 | lorem:'ipsum'
65 | }) {
66 | doStuff(key);
67 | }
68 |
69 | // issues #47 and #166
70 | Ext.define('VMS.model.User', {
71 | extend: 'Ext.data.Model',
72 | idProperty: 'UserID',
73 | fields: [
74 | {
75 | // foo
76 | name: 'UserID',
77 | type: 'int' // bar
78 | },
79 | // dolor
80 | // amet
81 | {
82 | name: 'FirstName',
83 | type: 'string'
84 | },
85 | {
86 | name: 'LastName',
87 | type: 'string'
88 | // align with previous line because of line break
89 |
90 | // align with "}"
91 | // dolor sit amet
92 | // maecennas ullamcor
93 | }
94 | ]
95 | });
96 |
97 |
98 | // issue #175
99 | var ItemsSchema = new Schema({
100 | name: String // comments
101 | ,dds: ""
102 | });
103 |
104 |
105 | this
106 | .foo({
107 | bar: 'baz'
108 | });
109 |
110 |
111 | // issue #193
112 | foo = function() {
113 | var a,
114 | b,
115 | c;
116 | var bar = this.baz({});
117 | };
118 |
119 | // issue #226
120 | var o = {
121 | a: 0,
122 | get b(){},
123 | set c (x){},
124 | method1(foo) {},
125 | method2 ( bar )
126 | {}
127 | };
128 |
129 | o = {
130 | get b(){return 'test'; },
131 | set c(x){}
132 | };
133 |
134 | x = {
135 | at: "left" +
136 | "top"
137 | };
138 | x = {
139 | at: a &&
140 | b
141 | };
142 |
143 | // ES6 Object Literal Property Value Shorthand
144 | x = { w, y, z }
145 |
146 | // issue #295
147 | o = {
148 | foo: (
149 | lorem &&
150 | ipsum
151 | ),
152 | bar: (
153 | dolor ||
154 | amet
155 | )
156 | };
157 |
158 | // issue #306
159 | unary = {
160 | a: !!(dolor ||
161 | amet && ipsum
162 | )
163 | };
164 |
165 | // issue ##287
166 | var i = 0;
167 | var obj = {
168 | ["foo" + ++i]: i,
169 | [ "foo" + ++i ] : i,
170 | ["foo" + ++i]
171 | :
172 | 1
173 | };
174 |
--------------------------------------------------------------------------------
/test/api.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 |
9 | describe('API', function() {
10 |
11 | describe('exposed API', function() {
12 | // plugins might need to access some internal methods from esformatter
13 | // so we check if these methods are really available
14 | var limit = require('../lib/limit');
15 | var options = require('../lib/options');
16 |
17 | it('shoud expose useful methods to plugin authors', function() {
18 | // we don't need to check implementation here since these methods are
19 | // used internally
20 | expect(limit.before).to.be.a('function');
21 | expect(limit.after).to.be.a('function');
22 | expect(limit.around).to.be.a('function');
23 | expect(options.set).to.be.a('function');
24 | expect(options.get).to.be.a('function');
25 | expect(options.getRc).to.be.a('function');
26 | expect(options.loadAndParseConfig).to.be.a('function');
27 | expect(esformatter.rc).to.be.a('function');
28 | });
29 | });
30 |
31 | describe('esformatter.rc', function() {
32 | // PS: CLI is already testing this method indirectly, we are only checking
33 | // for edge cases for now
34 |
35 | it('should return custom options if root == true', function() {
36 | expect(
37 | esformatter.rc(null, {root:true})
38 | ).to.be.eql({root:true});
39 | });
40 |
41 | it('should return custom options if preset', function() {
42 | expect(
43 | esformatter.rc(null, {preset:'default'})
44 | ).to.be.eql({preset:'default'});
45 | });
46 |
47 | it('should merge the custom option', function() {
48 | var customOpts = {
49 | whiteSpace: {
50 | before: {
51 | "ArrayExpressionClosing" : 1
52 | },
53 | after: {
54 | "ArrayExpressionOpening" : 1
55 | }
56 | }
57 | };
58 | var result = esformatter.rc('test/compare/rc/top-in.js', customOpts);
59 | expect(result.whiteSpace.before.FunctionDeclarationOpeningBrace).to.be.eql(0);
60 | expect(result.whiteSpace.before.ArrayExpressionClosing).to.be.eql(1);
61 | expect(result.whiteSpace.after.ArrayExpressionOpening).to.be.eql(1);
62 | });
63 |
64 | it('should merge rcs from parent folder', function() {
65 | var result = esformatter.rc('test/compare/rc/nested/nested-in.js');
66 | expect(result.indent.value).to.be.eql('\t');
67 | expect(result.whiteSpace.before.FunctionDeclarationOpeningBrace).to.be.eql(0);
68 | });
69 |
70 | it('should merge .esformatter and package.json files', function() {
71 | var result = esformatter.rc('test/compare/rc/package/nested/pkg_nested-in.js');
72 | expect(result.indent.value).to.be.eql('\t');
73 | expect(result.lineBreak.before.FunctionDeclarationOpeningBrace).to.be.eql(1);
74 | expect(result.lineBreak.before.FunctionDeclarationClosingBrace).to.be.eql(0);
75 | });
76 | });
77 | });
78 |
--------------------------------------------------------------------------------