From 26635695769fc87156f8d21906fba93af876929e Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Sat, 4 Jun 2016 01:16:36 +0900 Subject: [PATCH] New: `object-curly-newline` (fixes #6072) (#6223) --- conf/eslint.json | 1 + docs/rules/README.md | 1 + docs/rules/object-curly-newline.md | 478 +++++++++++++++++ lib/rules/object-curly-newline.js | 198 +++++++ tests/lib/rules/object-curly-newline.js | 667 ++++++++++++++++++++++++ 5 files changed, 1345 insertions(+) create mode 100644 docs/rules/object-curly-newline.md create mode 100644 lib/rules/object-curly-newline.js create mode 100644 tests/lib/rules/object-curly-newline.js diff --git a/conf/eslint.json b/conf/eslint.json index 612af05c989..c95ba5c65e7 100755 --- a/conf/eslint.json +++ b/conf/eslint.json @@ -175,6 +175,7 @@ "newline-after-var": "off", "newline-before-return": "off", "newline-per-chained-call": "off", + "object-curly-newline": "off", "object-curly-spacing": ["off", "never"], "object-property-newline": "off", "object-shorthand": "off", diff --git a/docs/rules/README.md b/docs/rules/README.md index 7a53d0f424f..34aab98c289 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -201,6 +201,7 @@ These rules relate to style guidelines, and are therefore quite subjective: * [no-underscore-dangle](no-underscore-dangle.md): disallow dangling underscores in identifiers * [no-unneeded-ternary](no-unneeded-ternary.md): disallow ternary operators when simpler alternatives exist * [no-whitespace-before-property](no-whitespace-before-property.md): disallow whitespace before properties (fixable) +* [object-curly-newline](object-curly-newline.md): enforce consistent line breaks inside braces (fixable) * [object-curly-spacing](object-curly-spacing.md): enforce consistent spacing inside braces (fixable) * [object-property-newline](object-property-newline.md): enforce placing object properties on separate lines * [one-var](one-var.md): enforce variables to be declared either together or separately in functions diff --git a/docs/rules/object-curly-newline.md b/docs/rules/object-curly-newline.md new file mode 100644 index 00000000000..a1ee90a0f3b --- /dev/null +++ b/docs/rules/object-curly-newline.md @@ -0,0 +1,478 @@ +# require or disallow line breaks inside braces (object-curly-newline) + +(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fix) automatically fixes problems reported by this rule. + +A number of style guides require or disallow line breaks inside of object braces and other tokens. + +## Rule Details + +This rule enforces consistent line breaks inside braces. +This rule is applied to both object literals and destructuring assignments. + +## Options + +```json +{ + "object-curly-newline": ["error", {"multiline": true}] +} +``` + +This rule has options of 4 kinds: + +* `"always"` - requires line breaks always. +* `"never"` - disallows line breaks. +* `{multiline: true}` (default) - requires line breaks if there are line breaks inside properties or between properties. Otherwise, disallows line breaks. +* `{minProperties: }` - requires line breaks if the number of properties is more than the given integer. Otherwise, disallows line breaks. + +`multiline` and `minProperties` can be combined. + +* `{multiline: true, minProperties: }` - requires line breaks if there are line breaks inside properties or between properties, or if the number of properties is more than the given integer. Otherwise, disallows line breaks. + +Also, we can separate configuration for each object literal and destructuring assignment: + +```json +{ + "object-curly-newline": ["error", { + "ObjectExpression": "always", + "ObjectPattern": {"multiline": true} + }] +} +``` + +* `"ObjectExpression"` - configuration for object literals. +* `"ObjectPattern"` - configuration for object patterns of destructuring assignments. + +### always + +Examples of **incorrect** code for this rule with the `"always"` option: + +```js +/*eslint object-curly-newline: ["error", "always"]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = {foo() { + dosomething(); +}}; + +let {} = obj; +let {f} = obj; +let {g, h} = obj; +let {i, + j} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +Examples of **correct** code for this rule with the `"always"` option: + +```js +/*eslint object-curly-newline: ["error", "always"]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = { + foo: function() { + dosomething(); + } +}; + +let { +} = obj; +let { + f +} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +### never + +Examples of **incorrect** code for this rule with the `"never"` option: + +```js +/*eslint object-curly-newline: ["error", "never"]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = { + foo: function() { + dosomething(); + } +}; + +let { +} = obj; +let { + f +} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +Examples of **correct** code for this rule with the `"never"` option: + +```js +/*eslint object-curly-newline: ["error", "never"]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = {foo: function() { + dosomething(); +}}; + +let {} = obj; +let {f} = obj; +let {g, h} = obj; +let {i, + j} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +### multiline + +Examples of **incorrect** code for this rule with the default `{"multiline": true}` option: + +```js +/*eslint object-curly-newline: ["error", {"multiline": true}]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = { + foo: 1, bar: 2 +}; +let d = {foo: 1, + bar: 2}; +let e = {foo: function() { + dosomething(); +}}; + +let { +} = obj; +let { + f +} = obj; +let { + g, h +} = obj; +let {i, + j} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +Examples of **correct** code for this rule with the default `{"multiline": true}` option: + +```js +/*eslint object-curly-newline: ["error", {"multiline": true}]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = {foo: 1, bar: 2}; +let d = { + foo: 1, + bar: 2 +}; +let e = { + foo: function() { + dosomething(); + } +}; + +let {} = obj; +let {f} = obj; +let {g, h} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +### minProperties + +Examples of **incorrect** code for this rule with the `{"minProperties": 2}` option: + +```js +/*eslint object-curly-newline: ["error", {"minProperties": 2}]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = { + foo: function() { + dosomething(); + } +}; + +let { +} = obj; +let { + f +} = obj; +let {g, h} = obj; +let {i, + j} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +Examples of **correct** code for this rule with the `{"minProperties": 2}` option: + +```js +/*eslint object-curly-newline: ["error", {"minProperties": 2}]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = {foo: function() { + dosomething(); +}}; + +let {} = obj; +let {f} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +### multiline and minProperties + +Examples of **incorrect** code for this rule with the `{"multiline": true, "minProperties": 2}` option: + +```js +/*eslint object-curly-newline: ["error", {"multiline": true, "minProperties": 2}]*/ +/*eslint-env es6*/ + +let a = { +}; +let b = { + foo: 1 +}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = {foo: function() { + dosomething(); +}}; + +let { +} = obj; +let { + f +} = obj; +let {g, h} = obj; +let {i, + j} = obj; +let {k = function() { + dosomething(); +}} = obj; +``` + +Examples of **correct** code for this rule with the `{"multiline": true, "minProperties": 2}` option: + +```js +/*eslint object-curly-newline: ["error", {"multiline": true, "minProperties": 2}]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = { + foo: 1, bar: 2 +}; +let d = { + foo: 1, + bar: 2 +}; +let e = { + foo: function() { + dosomething(); + } +}; + +let {} = obj; +let {f} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +### separating configuration + +Examples of **incorrect** code for this rule with the `{"ObjectExpression": "always", "ObjectPattern": "never"}` option: + +```js +/*eslint object-curly-newline: ["error", {"ObjectExpression": "always", "ObjectPattern": "never"}]*/ +/*eslint-env es6*/ + +let a = {}; +let b = {foo: 1}; +let c = {foo: 1, bar: 2}; +let d = {foo: 1, + bar: 2}; +let e = {foo: function() { + dosomething(); +}}; + +let { +} = obj; +let { + f +} = obj; +let { + g, h +} = obj; +let { + i, + j +} = obj; +let { + k = function() { + dosomething(); + } +} = obj; +``` + +Examples of **correct** code for this rule with the `{"ObjectExpression": "always", "ObjectPattern": "never"}` option: + +```js +/*eslint object-curly-newline: ["error", {"ObjectExpression": "always", "ObjectPattern": "never"}]*/ +/*eslint-env es6*/ + +let a = [ +]; +let b = [ + 1 +]; +let c = [ + 1, 2 +]; +let d = [ + 1, + 2 +]; +let e = [ + function() { + dosomething(); + } +]; + +let [] = obj; +let [f] = obj; +let [g, h] = obj; +let [i, + j] = obj; +let [k = function() { + dosomething(); +}] = obj; +``` + +## Compatibility + +* **JSCS:** `requirePaddingNewLinesInObjects` and `disallowPaddingNewLinesInObjects` + +## When Not To Use It + +If you don't want to enforce consistent line breaks inside braces, then it's safe to disable this rule. + +## Related Rules + +* [comma-spacing](key-spacing.md) +* [key-spacing](key-spacing.md) +* [object-curly-spacing](object-curly-spacing.md) +* [object-property-newline](object-property-newline.md) diff --git a/lib/rules/object-curly-newline.js b/lib/rules/object-curly-newline.js new file mode 100644 index 00000000000..d4a3a85df11 --- /dev/null +++ b/lib/rules/object-curly-newline.js @@ -0,0 +1,198 @@ +/** + * @fileoverview Rule to require or disallow line breaks inside braces. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +var astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +// Schema objects. +var OPTION_VALUE = { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + multiline: { + type: "boolean" + }, + minProperties: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false, + minProperties: 1 + } + ] +}; + +/** + * Normalizes a given option value. + * + * @param {string|object|undefined} value - An option value to parse. + * @returns {{multiline: boolean, minProperties: number}} Normalized option object. + */ +function normalizeOptionValue(value) { + var multiline = false; + var minProperties = Number.POSITIVE_INFINITY; + + if (value) { + if (value === "always") { + minProperties = 0; + } else if (value === "never") { + minProperties = Number.POSITIVE_INFINITY; + } else { + multiline = Boolean(value.multiline); + minProperties = value.minProperties || Number.POSITIVE_INFINITY; + } + } else { + multiline = true; + } + + return {multiline: multiline, minProperties: minProperties}; +} + +/** + * Normalizes a given option value. + * + * @param {string|object|undefined} options - An option value to parse. + * @returns {{ObjectExpression: {multiline: boolean, minProperties: number}, ObjectPattern: {multiline: boolean, minProperties: number}}} Normalized option object. + */ +function normalizeOptions(options) { + if (options && (options.ObjectExpression || options.ObjectPattern)) { + return { + ObjectExpression: normalizeOptionValue(options.ObjectExpression), + ObjectPattern: normalizeOptionValue(options.ObjectPattern) + }; + } + + var value = normalizeOptionValue(options); + + return {ObjectExpression: value, ObjectPattern: value}; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow line breaks inside braces.", + category: "Stylistic Issues", + recommended: false + }, + fixable: "whitespace", + schema: [ + { + oneOf: [ + OPTION_VALUE, + { + type: "object", + properties: { + ObjectExpression: OPTION_VALUE, + ObjectPattern: OPTION_VALUE + }, + additionalProperties: false, + minProperties: 1 + } + ] + } + ] + }, + + create: function(context) { + var sourceCode = context.getSourceCode(); + var normalizedOptions = normalizeOptions(context.options[0]); + + /** + * Reports a given node if it violated this rule. + * + * @param {ASTNode} node - A node to check. This is an ObjectExpression node or an ObjectPattern node. + * @param {{multiline: boolean, minProperties: number}} options - An option object. + * @returns {void} + */ + function check(node) { + var options = normalizedOptions[node.type]; + var openBrace = sourceCode.getFirstToken(node); + var closeBrace = sourceCode.getLastToken(node); + var first = sourceCode.getTokenAfter(openBrace); + var last = sourceCode.getTokenBefore(closeBrace); + var needsLinebreaks = ( + node.properties.length >= options.minProperties || + ( + options.multiline && + node.properties.length > 0 && + first.loc.start.line !== last.loc.end.line + ) + ); + + if (needsLinebreaks) { + if (astUtils.isTokenOnSameLine(openBrace, first)) { + context.report({ + message: "Expected a line break after this open brace.", + node: node, + loc: openBrace.loc.start, + fix: function(fixer) { + return fixer.insertTextAfter(openBrace, "\n"); + } + }); + } + if (astUtils.isTokenOnSameLine(last, closeBrace)) { + context.report({ + message: "Expected a line break before this close brace.", + node: node, + loc: closeBrace.loc.start, + fix: function(fixer) { + return fixer.insertTextBefore(closeBrace, "\n"); + } + }); + } + } else { + if (!astUtils.isTokenOnSameLine(openBrace, first)) { + context.report({ + message: "Unexpected a line break after this open brace.", + node: node, + loc: openBrace.loc.start, + fix: function(fixer) { + return fixer.removeRange([ + openBrace.range[1], + first.range[0] + ]); + } + }); + } + if (!astUtils.isTokenOnSameLine(last, closeBrace)) { + context.report({ + message: "Unexpected a line break before this close brace.", + node: node, + loc: closeBrace.loc.start, + fix: function(fixer) { + return fixer.removeRange([ + last.range[1], + closeBrace.range[0] + ]); + } + }); + } + } + } + + return { + ObjectExpression: check, + ObjectPattern: check + }; + } +}; diff --git a/tests/lib/rules/object-curly-newline.js b/tests/lib/rules/object-curly-newline.js new file mode 100644 index 00000000000..c72431727e8 --- /dev/null +++ b/tests/lib/rules/object-curly-newline.js @@ -0,0 +1,667 @@ +/** + * @fileoverview Tests for object-curly-newline rule. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +var rule = require("../../../lib/rules/object-curly-newline"), + RuleTester = require("../../../lib/testers/rule-tester"); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +var ruleTester = new RuleTester(); + +ruleTester.run("object-curly-newline", rule, { + valid: [ + + // "always" ------------------------------------------------------------ + { + code: [ + "var a = {", + "};" + ].join("\n"), + options: ["always"] + }, + { + code: [ + "var b = {", + " a: 1", + "};" + ].join("\n"), + options: ["always"] + }, + { + code: [ + "var c = {", + " a: 1, b: 2", + "};" + ].join("\n"), + options: ["always"] + }, + { + code: [ + "var d = {", + " a: 1,", + " b: 2", + "};" + ].join("\n"), + options: ["always"] + }, + { + code: [ + "var e = {", + " a: function foo() {", + " dosomething();", + " }", + "};" + ].join("\n"), + options: ["always"] + }, + + // "never" ------------------------------------------------------------- + { + code: [ + "var a = {};" + ].join("\n"), + options: ["never"] + }, + { + code: [ + "var b = {a: 1};" + ].join("\n"), + options: ["never"] + }, + { + code: [ + "var c = {a: 1, b: 2};" + ].join("\n"), + options: ["never"] + }, + { + code: [ + "var d = {a: 1,", + " b: 2};" + ].join("\n"), + options: ["never"] + }, + { + code: [ + "var e = {a: function foo() {", + " dosomething();", + "}};" + ].join("\n"), + options: ["never"] + }, + + // "multiline" --------------------------------------------------------- + { + code: [ + "var a = {};" + ].join("\n"), + options: [{multiline: true}] + }, + { + code: [ + "var b = {a: 1};" + ].join("\n"), + options: [{multiline: true}] + }, + { + code: [ + "var c = {a: 1, b: 2};" + ].join("\n"), + options: [{multiline: true}] + }, + { + code: [ + "var d = {", + " a: 1,", + " b: 2", + "};" + ].join("\n"), + options: [{multiline: true}] + }, + { + code: [ + "var e = {", + " a: function foo() {", + " dosomething();", + " }", + "};" + ].join("\n"), + options: [{multiline: true}] + }, + + // "minProperties" ---------------------------------------------------------- + { + code: [ + "var a = {};" + ].join("\n"), + options: [{minProperties: 2}] + }, + { + code: [ + "var b = {a: 1};" + ].join("\n"), + options: [{minProperties: 2}] + }, + { + code: [ + "var c = {", + " a: 1, b: 2", + "};" + ].join("\n"), + options: [{minProperties: 2}] + }, + { + code: [ + "var d = {", + " a: 1,", + " b: 2", + "};" + ].join("\n"), + options: [{minProperties: 2}] + }, + { + code: [ + "var e = {a: function foo() {", + " dosomething();", + "}};" + ].join("\n"), + options: [{minProperties: 2}] + }, + + // "multiline" and "minProperties" ------------------------------------------ + { + code: [ + "var a = {};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}] + }, + { + code: [ + "var b = {a: 1};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}] + }, + { + code: [ + "var c = {", + " a: 1, b: 2", + "};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}] + }, + { + code: [ + "var d = {", + " a: 1, ", + " b: 2", + "};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}] + }, + { + code: [ + "var e = {", + " a: function foo() {", + " dosomething();", + " }", + "};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}] + }, + + // "ObjectExpression" and "ObjectPattern" --------------------------------------------- + { + code: [ + "let {a, b} = {", + " a: 1, b: 2", + "};" + ].join("\n"), + options: [{ObjectExpression: "always", ObjectPattern: "never"}], + parserOptions: {ecmaVersion: 6} + } + ], + invalid: [ + + // "always" ------------------------------------------------------------ + { + code: [ + "var a = {};" + ].join("\n"), + output: [ + "var a = {", + "};" + ].join("\n"), + options: ["always"], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 1, column: 10, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var b = {a: 1};" + ].join("\n"), + output: [ + "var b = {", + "a: 1", + "};" + ].join("\n"), + options: ["always"], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 1, column: 14, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var c = {a: 1, b: 2};" + ].join("\n"), + output: [ + "var c = {", + "a: 1, b: 2", + "};" + ].join("\n"), + options: ["always"], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 1, column: 20, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var d = {a: 1,", + " b: 2};" + ].join("\n"), + output: [ + "var d = {", + "a: 1,", + " b: 2", + "};" + ].join("\n"), + options: ["always"], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 2, column: 9, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var e = {a: function foo() {", + " dosomething();", + "}};" + ].join("\n"), + output: [ + "var e = {", + "a: function foo() {", + " dosomething();", + "}", + "};" + ].join("\n"), + options: ["always"], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 3, column: 2, message: "Expected a line break before this close brace."} + ] + }, + + // "never" ------------------------------------------------------------ + { + code: [ + "var a = {", + "};" + ].join("\n"), + output: [ + "var a = {};" + ].join("\n"), + options: ["never"], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 2, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var b = {", + " a: 1", + "};" + ].join("\n"), + output: [ + "var b = {a: 1};" + ].join("\n"), + options: ["never"], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 3, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var c = {", + " a: 1, b: 2", + "};" + ].join("\n"), + output: [ + "var c = {a: 1, b: 2};" + ].join("\n"), + options: ["never"], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 3, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var d = {", + " a: 1,", + " b: 2", + "};" + ].join("\n"), + output: [ + "var d = {a: 1,", + " b: 2};" + ].join("\n"), + options: ["never"], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 4, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var e = {", + " a: function foo() {", + " dosomething();", + " }", + "};" + ].join("\n"), + output: [ + "var e = {a: function foo() {", + " dosomething();", + " }};" + ].join("\n"), + options: ["never"], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 5, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + + // "multiline" --------------------------------------------------------- + { + code: [ + "var a = {", + "};" + ].join("\n"), + output: [ + "var a = {};" + ].join("\n"), + options: [{multiline: true}], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 2, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var b = {", + " a: 1", + "};" + ].join("\n"), + output: [ + "var b = {a: 1};" + ].join("\n"), + options: [{multiline: true}], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 3, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var c = {", + " a: 1, b: 2", + "};" + ].join("\n"), + output: [ + "var c = {a: 1, b: 2};" + ].join("\n"), + options: [{multiline: true}], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 3, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var d = {a: 1,", + " b: 2};" + ].join("\n"), + output: [ + "var d = {", + "a: 1,", + " b: 2", + "};" + ].join("\n"), + options: [{multiline: true}], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 2, column: 9, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var e = {a: function foo() {", + " dosomething();", + "}};" + ].join("\n"), + output: [ + "var e = {", + "a: function foo() {", + " dosomething();", + "}", + "};" + ].join("\n"), + options: [{multiline: true}], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 3, column: 2, message: "Expected a line break before this close brace."} + ] + }, + + // "minProperties" ---------------------------------------------------------- + { + code: [ + "var a = {", + "};" + ].join("\n"), + output: [ + "var a = {};" + ].join("\n"), + options: [{minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 2, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var b = {", + " a: 1", + "};" + ].join("\n"), + output: [ + "var b = {a: 1};" + ].join("\n"), + options: [{minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 3, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var c = {a: 1, b: 2};" + ].join("\n"), + output: [ + "var c = {", + "a: 1, b: 2", + "};" + ].join("\n"), + options: [{minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 1, column: 20, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var d = {a: 1,", + " b: 2};" + ].join("\n"), + output: [ + "var d = {", + "a: 1,", + " b: 2", + "};" + ].join("\n"), + options: [{minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 2, column: 9, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var e = {", + " a: function foo() {", + " dosomething();", + " }", + "};" + ].join("\n"), + output: [ + "var e = {a: function foo() {", + " dosomething();", + " }};" + ].join("\n"), + options: [{minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 5, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + + // "multiline" and "minProperties" ------------------------------------------ + { + code: [ + "var a = {", + "};" + ].join("\n"), + output: [ + "var a = {};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 2, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var b = {", + " a: 1", + "};" + ].join("\n"), + output: [ + "var b = {a: 1};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Unexpected a line break after this open brace."}, + {line: 3, column: 1, message: "Unexpected a line break before this close brace."} + ] + }, + { + code: [ + "var c = {a: 1, b: 2};" + ].join("\n"), + output: [ + "var c = {", + "a: 1, b: 2", + "};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 1, column: 20, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var d = {a: 1, ", + " b: 2};" + ].join("\n"), + output: [ + "var d = {", + "a: 1, ", + " b: 2", + "};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 2, column: 9, message: "Expected a line break before this close brace."} + ] + }, + { + code: [ + "var e = {a: function foo() {", + " dosomething();", + "}};" + ].join("\n"), + output: [ + "var e = {", + "a: function foo() {", + " dosomething();", + "}", + "};" + ].join("\n"), + options: [{multiline: true, minProperties: 2}], + errors: [ + {line: 1, column: 9, message: "Expected a line break after this open brace."}, + {line: 3, column: 2, message: "Expected a line break before this close brace."} + ] + }, + + // "ObjectExpression" and "ObjectPattern" --------------------------------------------- + { + code: [ + "let {", + " a, b", + "} = {a: 1, b: 2};" + ].join("\n"), + output: [ + "let {a, b} = {", + "a: 1, b: 2", + "};" + ].join("\n"), + options: [{ObjectExpression: "always", ObjectPattern: "never"}], + parserOptions: {ecmaVersion: 6}, + errors: [ + {line: 1, column: 5, message: "Unexpected a line break after this open brace."}, + {line: 3, column: 1, message: "Unexpected a line break before this close brace."}, + {line: 3, column: 5, message: "Expected a line break after this open brace."}, + {line: 3, column: 16, message: "Expected a line break before this close brace."} + ] + } + ] +});