Repository: ember-cli/eslint-plugin-ember
Pull request #571 (2019-11-06 20:38:31)

Update `avoid-leaking-state-in-ember-objects` rule to handle ternary expressions
Our app uses a pattern like this quite a bit:

```javascript
const Whatever = EmberObject.extend({
  host: config.sentry ? config.sentry.host : ''
});
```

This isn't allowed by the `avoid-leaking-state-in-ember-object` rule, even though it should be, in a case where either option in a ternary expression would be considered "safe".

This tweak allows  a ternary expression to be accepted as long as both the consequent and alternate would be allowed if that value was used directly.


Patch:
diff --git a/lib/rules/avoid-leaking-state-in-ember-objects.js b/lib/rules/avoid-leaking-state-in-ember-objects.js
index c4e8aa4d..e72ed955 100644
--- a/lib/rules/avoid-leaking-state-in-ember-objects.js
+++ b/lib/rules/avoid-leaking-state-in-ember-objects.js
@@ -15,8 +15,15 @@ const DEFAULT_IGNORED_PROPERTIES = [
   'attrs',
 ];
 
-const isAllowed = function(property) {
-  const value = property.value;
+function isAllowedTernary(value) {
+  return (
+    types.isConditionalExpression(value) &&
+    isAllowed(value.consequent) &&
+    isAllowed(value.alternate)
+  );
+}
+
+function isAllowed(value) {
   return (
     ember.isFunctionExpression(value) ||
     types.isLiteral(value) ||
@@ -26,9 +33,10 @@ const isAllowed = function(property) {
     types.isTemplateLiteral(value) ||
     types.isTaggedTemplateExpression(value) ||
     types.isMemberExpression(value) ||
-    types.isUnaryExpression(value)
+    types.isUnaryExpression(value) ||
+    isAllowedTernary(value)
   );
-};
+}
 
 //------------------------------------------------------------------------------
 // Ember object rule - Avoid leaking state
@@ -75,7 +83,7 @@ module.exports = {
         properties
           .filter(property => property.key && ignoredProperties.indexOf(property.key.name) === -1)
           .forEach(property => {
-            if (!isAllowed(property)) {
+            if (!isAllowed(property.value)) {
               report(property);
             }
           });


Test patch:
diff --git a/tests/lib/rules/avoid-leaking-state-in-ember-objects.js b/tests/lib/rules/avoid-leaking-state-in-ember-objects.js
index e87730d0..6afa0b58 100644
--- a/tests/lib/rules/avoid-leaking-state-in-ember-objects.js
+++ b/tests/lib/rules/avoid-leaking-state-in-ember-objects.js
@@ -63,6 +63,7 @@ eslintTester.run('avoid-leaking-state-in-ember-objects', rule, {
     'export default Foo.extend({ foo: abc.something() });',
     'export default Foo.extend({ foo: !true });',
     'export default Foo.extend({ ...props });',
+    'export default Foo.extend({ foo: condition ? "foo" : "bar" });',
   ],
   invalid: [
     {
@@ -166,5 +167,25 @@ eslintTester.run('avoid-leaking-state-in-ember-objects', rule, {
         },
       ],
     },
+    {
+      code: 'export default Foo.extend({ foo: condition ? {} : false });',
+      output: null,
+      errors: [
+        {
+          message:
+            'Only string, number, symbol, boolean, null, undefined, and function are allowed as default properties',
+        },
+      ],
+    },
+    {
+      code: 'export default Foo.extend({ foo: condition ? false : {} });',
+      output: null,
+      errors: [
+        {
+          message:
+            'Only string, number, symbol, boolean, null, undefined, and function are allowed as default properties',
+        },
+      ],
+    },
   ],
 });