eslint-plugin-jest 26.4.1 → 26.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -64,7 +64,7 @@ var _default = (0, _utils.createRule)({
64
64
  canonical
65
65
  },
66
66
  node: matcher.node.property,
67
- fix: fixer => [fixer.replaceText(matcher.node.property, canonical)]
67
+ fix: fixer => [(0, _utils.replaceAccessorFixer)(fixer, matcher.node.property, canonical)]
68
68
  });
69
69
  }
70
70
  }
@@ -7,8 +7,6 @@ exports.default = void 0;
7
7
 
8
8
  var _utils = require("@typescript-eslint/utils");
9
9
 
10
- var _detectJestVersion = require("./detectJestVersion");
11
-
12
10
  var _utils2 = require("./utils");
13
11
 
14
12
  const parseJestVersion = rawVersion => {
@@ -40,7 +38,7 @@ var _default = (0, _utils2.createRule)({
40
38
  create(context) {
41
39
  var _context$settings, _context$settings$jes;
42
40
 
43
- const jestVersion = parseJestVersion(((_context$settings = context.settings) === null || _context$settings === void 0 ? void 0 : (_context$settings$jes = _context$settings.jest) === null || _context$settings$jes === void 0 ? void 0 : _context$settings$jes.version) || (0, _detectJestVersion.detectJestVersion)());
41
+ const jestVersion = parseJestVersion(((_context$settings = context.settings) === null || _context$settings === void 0 ? void 0 : (_context$settings$jes = _context$settings.jest) === null || _context$settings$jes === void 0 ? void 0 : _context$settings$jes.version) || (0, _utils2.detectJestVersion)());
44
42
  const deprecations = { ...(jestVersion >= 15 && {
45
43
  'jest.resetModuleRegistry': 'jest.resetModules'
46
44
  }),
@@ -32,13 +32,6 @@ var _default = (0, _utils.createRule)({
32
32
  let suiteDepth = 0;
33
33
  let testDepth = 0;
34
34
  return {
35
- 'CallExpression[callee.name=/^(it|test)$/][arguments.length<2]'(node) {
36
- context.report({
37
- messageId: 'missingFunction',
38
- node
39
- });
40
- },
41
-
42
35
  CallExpression(node) {
43
36
  const jestFnCall = (0, _utils.parseJestFnCall)(node, context.getScope());
44
37
 
@@ -52,6 +45,13 @@ var _default = (0, _utils.createRule)({
52
45
 
53
46
  if (jestFnCall.type === 'test') {
54
47
  testDepth++;
48
+
49
+ if (node.arguments.length < 2) {
50
+ context.report({
51
+ messageId: 'missingFunction',
52
+ node
53
+ });
54
+ }
55
55
  }
56
56
 
57
57
  if ( // the only jest functions that are with "x" are "xdescribe", "xtest", and "xit"
@@ -9,7 +9,7 @@ var _utils = require("@typescript-eslint/utils");
9
9
 
10
10
  var _utils2 = require("./utils");
11
11
 
12
- const testCaseNames = new Set([...Object.keys(_utils2.TestCaseName), 'it.only', 'it.concurrent.only', 'it.skip', 'it.concurrent.skip', 'test.only', 'test.concurrent.only', 'test.skip', 'test.concurrent.skip', 'fit.concurrent']);
12
+ const testCaseNames = new Set([...Object.keys(_utils2.TestCaseName), 'it.only', 'it.only', 'it.skip', 'it.skip', 'test.only', 'test.only', 'test.skip', 'test.skip', 'fit.concurrent']);
13
13
 
14
14
  const isTestFunctionExpression = node => node.parent !== undefined && node.parent.type === _utils.AST_NODE_TYPES.CallExpression && testCaseNames.has((0, _utils2.getNodeName)(node.parent.callee));
15
15
 
@@ -43,7 +43,7 @@ var _default = (0, _utils.createRule)({
43
43
  node: matcher.node.property,
44
44
  suggest: [{
45
45
  messageId: 'suggestReplaceWithStrictEqual',
46
- fix: fixer => [fixer.replaceText(matcher.node.property, _utils.EqualityMatcher.toStrictEqual)]
46
+ fix: fixer => [(0, _utils.replaceAccessorFixer)(fixer, matcher.node.property, _utils.EqualityMatcher.toStrictEqual)]
47
47
  }]
48
48
  });
49
49
  }
@@ -44,7 +44,7 @@ const reportPreferToBe = (context, whatToBe, matcher, modifier) => {
44
44
  fix(fixer) {
45
45
  var _matcher$arguments;
46
46
 
47
- const fixes = [fixer.replaceText(matcher.node.property, `toBe${whatToBe}`)];
47
+ const fixes = [(0, _utils2.replaceAccessorFixer)(fixer, matcher.node.property, `toBe${whatToBe}`)];
48
48
 
49
49
  if ((_matcher$arguments = matcher.arguments) !== null && _matcher$arguments !== void 0 && _matcher$arguments.length && whatToBe !== '') {
50
50
  fixes.push(fixer.remove(matcher.arguments[0]));
@@ -18,13 +18,11 @@ function isEmptyFunction(node) {
18
18
  }
19
19
 
20
20
  function createTodoFixer(jestFnCall, fixer) {
21
- const fixes = [fixer.replaceText(jestFnCall.head.node, `${jestFnCall.head.local}.todo`)];
22
-
23
21
  if (jestFnCall.members.length) {
24
- fixes.unshift(fixer.removeRange([jestFnCall.head.node.range[1], jestFnCall.members[0].range[1]]));
22
+ return (0, _utils2.replaceAccessorFixer)(fixer, jestFnCall.members[0], 'todo');
25
23
  }
26
24
 
27
- return fixes;
25
+ return fixer.replaceText(jestFnCall.head.node, `${jestFnCall.head.local}.todo`);
28
26
  }
29
27
 
30
28
  const isTargetedTestCase = jestFnCall => {
@@ -72,7 +70,7 @@ var _default = (0, _utils2.createRule)({
72
70
  context.report({
73
71
  messageId: 'emptyTest',
74
72
  node,
75
- fix: fixer => [fixer.removeRange([title.range[1], callback.range[1]]), ...createTodoFixer(jestFnCall, fixer)]
73
+ fix: fixer => [fixer.removeRange([title.range[1], callback.range[1]]), createTodoFixer(jestFnCall, fixer)]
76
74
  });
77
75
  }
78
76
 
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isSupportedAccessor = exports.isStringNode = exports.isIdentifier = exports.getStringValue = exports.getAccessorValue = void 0;
7
+
8
+ var _utils = require("@typescript-eslint/utils");
9
+
10
+ /**
11
+ * Checks if the given `node` is a `StringLiteral`.
12
+ *
13
+ * If a `value` is provided & the `node` is a `StringLiteral`,
14
+ * the `value` will be compared to that of the `StringLiteral`.
15
+ *
16
+ * @param {Node} node
17
+ * @param {V} [value]
18
+ *
19
+ * @return {node is StringLiteral<V>}
20
+ *
21
+ * @template V
22
+ */
23
+ const isStringLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.Literal && typeof node.value === 'string' && (value === undefined || node.value === value);
24
+
25
+ /**
26
+ * Checks if the given `node` is a `TemplateLiteral`.
27
+ *
28
+ * Complex `TemplateLiteral`s are not considered specific, and so will return `false`.
29
+ *
30
+ * If a `value` is provided & the `node` is a `TemplateLiteral`,
31
+ * the `value` will be compared to that of the `TemplateLiteral`.
32
+ *
33
+ * @param {Node} node
34
+ * @param {V} [value]
35
+ *
36
+ * @return {node is TemplateLiteral<V>}
37
+ *
38
+ * @template V
39
+ */
40
+ const isTemplateLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.TemplateLiteral && node.quasis.length === 1 && ( // bail out if not simple
41
+ value === undefined || node.quasis[0].value.raw === value);
42
+
43
+ /**
44
+ * Checks if the given `node` is a {@link StringNode}.
45
+ *
46
+ * @param {Node} node
47
+ * @param {V} [specifics]
48
+ *
49
+ * @return {node is StringNode}
50
+ *
51
+ * @template V
52
+ */
53
+ const isStringNode = (node, specifics) => isStringLiteral(node, specifics) || isTemplateLiteral(node, specifics);
54
+ /**
55
+ * Gets the value of the given `StringNode`.
56
+ *
57
+ * If the `node` is a `TemplateLiteral`, the `raw` value is used;
58
+ * otherwise, `value` is returned instead.
59
+ *
60
+ * @param {StringNode<S>} node
61
+ *
62
+ * @return {S}
63
+ *
64
+ * @template S
65
+ */
66
+
67
+
68
+ exports.isStringNode = isStringNode;
69
+
70
+ const getStringValue = node => isTemplateLiteral(node) ? node.quasis[0].value.raw : node.value;
71
+ /**
72
+ * An `Identifier` with a known `name` value - i.e `expect`.
73
+ */
74
+
75
+
76
+ exports.getStringValue = getStringValue;
77
+
78
+ /**
79
+ * Checks if the given `node` is an `Identifier`.
80
+ *
81
+ * If a `name` is provided, & the `node` is an `Identifier`,
82
+ * the `name` will be compared to that of the `identifier`.
83
+ *
84
+ * @param {Node} node
85
+ * @param {V} [name]
86
+ *
87
+ * @return {node is KnownIdentifier<Name>}
88
+ *
89
+ * @template V
90
+ */
91
+ const isIdentifier = (node, name) => node.type === _utils.AST_NODE_TYPES.Identifier && (name === undefined || node.name === name);
92
+ /**
93
+ * Checks if the given `node` is a "supported accessor".
94
+ *
95
+ * This means that it's a node can be used to access properties,
96
+ * and who's "value" can be statically determined.
97
+ *
98
+ * `MemberExpression` nodes most commonly contain accessors,
99
+ * but it's possible for other nodes to contain them.
100
+ *
101
+ * If a `value` is provided & the `node` is an `AccessorNode`,
102
+ * the `value` will be compared to that of the `AccessorNode`.
103
+ *
104
+ * Note that `value` here refers to the normalised value.
105
+ * The property that holds the value is not always called `name`.
106
+ *
107
+ * @param {Node} node
108
+ * @param {V} [value]
109
+ *
110
+ * @return {node is AccessorNode<V>}
111
+ *
112
+ * @template V
113
+ */
114
+
115
+
116
+ exports.isIdentifier = isIdentifier;
117
+
118
+ const isSupportedAccessor = (node, value) => isIdentifier(node, value) || isStringNode(node, value);
119
+ /**
120
+ * Gets the value of the given `AccessorNode`,
121
+ * account for the different node types.
122
+ *
123
+ * @param {AccessorNode<S>} accessor
124
+ *
125
+ * @return {S}
126
+ *
127
+ * @template S
128
+ */
129
+
130
+
131
+ exports.isSupportedAccessor = isSupportedAccessor;
132
+
133
+ const getAccessorValue = accessor => accessor.type === _utils.AST_NODE_TYPES.Identifier ? accessor.name : getStringValue(accessor);
134
+
135
+ exports.getAccessorValue = getAccessorValue;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.followTypeAssertionChain = void 0;
7
+
8
+ var _utils = require("@typescript-eslint/utils");
9
+
10
+ const isTypeCastExpression = node => node.type === _utils.AST_NODE_TYPES.TSAsExpression || node.type === _utils.AST_NODE_TYPES.TSTypeAssertion;
11
+
12
+ const followTypeAssertionChain = expression => isTypeCastExpression(expression) ? followTypeAssertionChain(expression.expression) : expression;
13
+
14
+ exports.followTypeAssertionChain = followTypeAssertionChain;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _accessors = require("./accessors");
8
+
9
+ Object.keys(_accessors).forEach(function (key) {
10
+ if (key === "default" || key === "__esModule") return;
11
+ if (key in exports && exports[key] === _accessors[key]) return;
12
+ Object.defineProperty(exports, key, {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _accessors[key];
16
+ }
17
+ });
18
+ });
19
+
20
+ var _detectJestVersion = require("./detectJestVersion");
21
+
22
+ Object.keys(_detectJestVersion).forEach(function (key) {
23
+ if (key === "default" || key === "__esModule") return;
24
+ if (key in exports && exports[key] === _detectJestVersion[key]) return;
25
+ Object.defineProperty(exports, key, {
26
+ enumerable: true,
27
+ get: function () {
28
+ return _detectJestVersion[key];
29
+ }
30
+ });
31
+ });
32
+
33
+ var _followTypeAssertionChain = require("./followTypeAssertionChain");
34
+
35
+ Object.keys(_followTypeAssertionChain).forEach(function (key) {
36
+ if (key === "default" || key === "__esModule") return;
37
+ if (key in exports && exports[key] === _followTypeAssertionChain[key]) return;
38
+ Object.defineProperty(exports, key, {
39
+ enumerable: true,
40
+ get: function () {
41
+ return _followTypeAssertionChain[key];
42
+ }
43
+ });
44
+ });
45
+
46
+ var _misc = require("./misc");
47
+
48
+ Object.keys(_misc).forEach(function (key) {
49
+ if (key === "default" || key === "__esModule") return;
50
+ if (key in exports && exports[key] === _misc[key]) return;
51
+ Object.defineProperty(exports, key, {
52
+ enumerable: true,
53
+ get: function () {
54
+ return _misc[key];
55
+ }
56
+ });
57
+ });
58
+
59
+ var _parseJestFnCall = require("./parseJestFnCall");
60
+
61
+ Object.keys(_parseJestFnCall).forEach(function (key) {
62
+ if (key === "default" || key === "__esModule") return;
63
+ if (key in exports && exports[key] === _parseJestFnCall[key]) return;
64
+ Object.defineProperty(exports, key, {
65
+ enumerable: true,
66
+ get: function () {
67
+ return _parseJestFnCall[key];
68
+ }
69
+ });
70
+ });
71
+
72
+ var _parseExpectCall = require("./parseExpectCall");
73
+
74
+ Object.keys(_parseExpectCall).forEach(function (key) {
75
+ if (key === "default" || key === "__esModule") return;
76
+ if (key in exports && exports[key] === _parseExpectCall[key]) return;
77
+ Object.defineProperty(exports, key, {
78
+ enumerable: true,
79
+ get: function () {
80
+ return _parseExpectCall[key];
81
+ }
82
+ });
83
+ });
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createRule = exports.TestCaseName = exports.HookName = exports.DescribeAlias = void 0;
7
+ exports.getNodeName = getNodeName;
8
+ exports.replaceAccessorFixer = exports.isFunction = exports.hasOnlyOneArgument = exports.getTestCallExpressionsFromDeclaredVariables = void 0;
9
+
10
+ var _path = require("path");
11
+
12
+ var _utils = require("@typescript-eslint/utils");
13
+
14
+ var _package = require("../../../package.json");
15
+
16
+ var _accessors = require("./accessors");
17
+
18
+ var _parseJestFnCall = require("./parseJestFnCall");
19
+
20
+ const REPO_URL = 'https://github.com/jest-community/eslint-plugin-jest';
21
+
22
+ const createRule = _utils.ESLintUtils.RuleCreator(name => {
23
+ const ruleName = (0, _path.parse)(name).name;
24
+ return `${REPO_URL}/blob/v${_package.version}/docs/rules/${ruleName}.md`;
25
+ });
26
+ /**
27
+ * Represents a `MemberExpression` with a "known" `property`.
28
+ */
29
+
30
+
31
+ exports.createRule = createRule;
32
+
33
+ /**
34
+ * Guards that the given `call` has only one `argument`.
35
+ *
36
+ * @param {CallExpression} call
37
+ *
38
+ * @return {call is CallExpressionWithSingleArgument}
39
+ */
40
+ const hasOnlyOneArgument = call => call.arguments.length === 1;
41
+
42
+ exports.hasOnlyOneArgument = hasOnlyOneArgument;
43
+ let DescribeAlias;
44
+ exports.DescribeAlias = DescribeAlias;
45
+
46
+ (function (DescribeAlias) {
47
+ DescribeAlias["describe"] = "describe";
48
+ DescribeAlias["fdescribe"] = "fdescribe";
49
+ DescribeAlias["xdescribe"] = "xdescribe";
50
+ })(DescribeAlias || (exports.DescribeAlias = DescribeAlias = {}));
51
+
52
+ let TestCaseName;
53
+ exports.TestCaseName = TestCaseName;
54
+
55
+ (function (TestCaseName) {
56
+ TestCaseName["fit"] = "fit";
57
+ TestCaseName["it"] = "it";
58
+ TestCaseName["test"] = "test";
59
+ TestCaseName["xit"] = "xit";
60
+ TestCaseName["xtest"] = "xtest";
61
+ })(TestCaseName || (exports.TestCaseName = TestCaseName = {}));
62
+
63
+ let HookName;
64
+ exports.HookName = HookName;
65
+
66
+ (function (HookName) {
67
+ HookName["beforeAll"] = "beforeAll";
68
+ HookName["beforeEach"] = "beforeEach";
69
+ HookName["afterAll"] = "afterAll";
70
+ HookName["afterEach"] = "afterEach";
71
+ })(HookName || (exports.HookName = HookName = {}));
72
+
73
+ const joinNames = (a, b) => a && b ? `${a}.${b}` : null;
74
+
75
+ function getNodeName(node) {
76
+ if ((0, _accessors.isSupportedAccessor)(node)) {
77
+ return (0, _accessors.getAccessorValue)(node);
78
+ }
79
+
80
+ switch (node.type) {
81
+ case _utils.AST_NODE_TYPES.TaggedTemplateExpression:
82
+ return getNodeName(node.tag);
83
+
84
+ case _utils.AST_NODE_TYPES.MemberExpression:
85
+ return joinNames(getNodeName(node.object), getNodeName(node.property));
86
+
87
+ case _utils.AST_NODE_TYPES.NewExpression:
88
+ case _utils.AST_NODE_TYPES.CallExpression:
89
+ return getNodeName(node.callee);
90
+ }
91
+
92
+ return null;
93
+ }
94
+
95
+ const isFunction = node => node.type === _utils.AST_NODE_TYPES.FunctionExpression || node.type === _utils.AST_NODE_TYPES.ArrowFunctionExpression;
96
+
97
+ exports.isFunction = isFunction;
98
+
99
+ const getTestCallExpressionsFromDeclaredVariables = (declaredVariables, scope) => {
100
+ return declaredVariables.reduce((acc, {
101
+ references
102
+ }) => acc.concat(references.map(({
103
+ identifier
104
+ }) => identifier.parent).filter(node => (node === null || node === void 0 ? void 0 : node.type) === _utils.AST_NODE_TYPES.CallExpression && (0, _parseJestFnCall.isTypeOfJestFnCall)(node, scope, ['test']))), []);
105
+ };
106
+ /**
107
+ * Replaces an accessor node with the given `text`, surrounding it in quotes if required.
108
+ *
109
+ * This ensures that fixes produce valid code when replacing both dot-based and
110
+ * bracket-based property accessors.
111
+ */
112
+
113
+
114
+ exports.getTestCallExpressionsFromDeclaredVariables = getTestCallExpressionsFromDeclaredVariables;
115
+
116
+ const replaceAccessorFixer = (fixer, node, text) => {
117
+ return fixer.replaceText(node, node.type === _utils.AST_NODE_TYPES.Identifier ? text : `'${text}'`);
118
+ };
119
+
120
+ exports.replaceAccessorFixer = replaceAccessorFixer;
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parseExpectCall = exports.isParsedEqualityMatcherCall = exports.isExpectMember = exports.isExpectCall = exports.ModifierName = exports.EqualityMatcher = void 0;
7
+
8
+ var _utils = require("@typescript-eslint/utils");
9
+
10
+ var _utils2 = require("../utils");
11
+
12
+ /**
13
+ * Checks if the given `node` is a valid `ExpectCall`.
14
+ *
15
+ * In order to be an `ExpectCall`, the `node` must:
16
+ * * be a `CallExpression`,
17
+ * * have an accessor named 'expect',
18
+ * * have a `parent`.
19
+ *
20
+ * @param {Node} node
21
+ *
22
+ * @return {node is ExpectCall}
23
+ */
24
+ const isExpectCall = node => node.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isSupportedAccessor)(node.callee, 'expect') && node.parent !== undefined;
25
+
26
+ exports.isExpectCall = isExpectCall;
27
+
28
+ const isExpectMember = (node, name) => node.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.property, name);
29
+ /**
30
+ * Represents all the jest matchers.
31
+ */
32
+
33
+
34
+ exports.isExpectMember = isExpectMember;
35
+ let ModifierName;
36
+ exports.ModifierName = ModifierName;
37
+
38
+ (function (ModifierName) {
39
+ ModifierName["not"] = "not";
40
+ ModifierName["rejects"] = "rejects";
41
+ ModifierName["resolves"] = "resolves";
42
+ })(ModifierName || (exports.ModifierName = ModifierName = {}));
43
+
44
+ let EqualityMatcher;
45
+ exports.EqualityMatcher = EqualityMatcher;
46
+
47
+ (function (EqualityMatcher) {
48
+ EqualityMatcher["toBe"] = "toBe";
49
+ EqualityMatcher["toEqual"] = "toEqual";
50
+ EqualityMatcher["toStrictEqual"] = "toStrictEqual";
51
+ })(EqualityMatcher || (exports.EqualityMatcher = EqualityMatcher = {}));
52
+
53
+ const isParsedEqualityMatcherCall = (matcher, name) => (name ? matcher.name === name : EqualityMatcher.hasOwnProperty(matcher.name)) && matcher.arguments !== null && matcher.arguments.length === 1;
54
+ /**
55
+ * Represents a parsed expect matcher, such as `toBe`, `toContain`, and so on.
56
+ */
57
+
58
+
59
+ exports.isParsedEqualityMatcherCall = isParsedEqualityMatcherCall;
60
+
61
+ const parseExpectMember = expectMember => ({
62
+ name: (0, _utils2.getAccessorValue)(expectMember.property),
63
+ node: expectMember
64
+ });
65
+
66
+ const reparseAsMatcher = parsedMember => ({ ...parsedMember,
67
+
68
+ /**
69
+ * The arguments being passed to this `Matcher`, if any.
70
+ *
71
+ * If this matcher isn't called, this will be `null`.
72
+ */
73
+ arguments: parsedMember.node.parent.type === _utils.AST_NODE_TYPES.CallExpression ? parsedMember.node.parent.arguments : null
74
+ });
75
+ /**
76
+ * Re-parses the given `parsedMember` as a `ParsedExpectModifier`.
77
+ *
78
+ * If the given `parsedMember` does not have a `name` of a valid `Modifier`,
79
+ * an exception will be thrown.
80
+ *
81
+ * @param {ParsedExpectMember<ModifierName>} parsedMember
82
+ *
83
+ * @return {ParsedExpectModifier}
84
+ */
85
+
86
+
87
+ const reparseMemberAsModifier = parsedMember => {
88
+ if (isSpecificMember(parsedMember, ModifierName.not)) {
89
+ return parsedMember;
90
+ }
91
+ /* istanbul ignore if */
92
+
93
+
94
+ if (!isSpecificMember(parsedMember, ModifierName.resolves) && !isSpecificMember(parsedMember, ModifierName.rejects)) {
95
+ // ts doesn't think that the ModifierName.not check is the direct inverse as the above two checks
96
+ // todo: impossible at runtime, but can't be typed w/o negation support
97
+ throw new Error(`modifier name must be either "${ModifierName.resolves}" or "${ModifierName.rejects}" (got "${parsedMember.name}")`);
98
+ }
99
+
100
+ const negation = isExpectMember(parsedMember.node.parent, ModifierName.not) ? parsedMember.node.parent : undefined;
101
+ return { ...parsedMember,
102
+ negation
103
+ };
104
+ };
105
+
106
+ const isSpecificMember = (member, specific) => member.name === specific;
107
+ /**
108
+ * Checks if the given `ParsedExpectMember` should be re-parsed as an `ParsedExpectModifier`.
109
+ *
110
+ * @param {ParsedExpectMember} member
111
+ *
112
+ * @return {member is ParsedExpectMember<ModifierName>}
113
+ */
114
+
115
+
116
+ const shouldBeParsedExpectModifier = member => ModifierName.hasOwnProperty(member.name);
117
+
118
+ const parseExpectCall = expect => {
119
+ const expectation = {
120
+ expect
121
+ };
122
+
123
+ if (!isExpectMember(expect.parent)) {
124
+ return expectation;
125
+ }
126
+
127
+ const parsedMember = parseExpectMember(expect.parent);
128
+
129
+ if (!shouldBeParsedExpectModifier(parsedMember)) {
130
+ expectation.matcher = reparseAsMatcher(parsedMember);
131
+ return expectation;
132
+ }
133
+
134
+ const modifier = expectation.modifier = reparseMemberAsModifier(parsedMember);
135
+ const memberNode = modifier.negation || modifier.node;
136
+
137
+ if (!isExpectMember(memberNode.parent)) {
138
+ return expectation;
139
+ }
140
+
141
+ expectation.matcher = reparseAsMatcher(parseExpectMember(memberNode.parent));
142
+ return expectation;
143
+ };
144
+
145
+ exports.parseExpectCall = parseExpectCall;
@@ -17,6 +17,8 @@ const isTypeOfJestFnCall = (node, scope, types) => {
17
17
 
18
18
  exports.isTypeOfJestFnCall = isTypeOfJestFnCall;
19
19
 
20
+ const joinChains = (a, b) => a && b ? [...a, ...b] : null;
21
+
20
22
  function getNodeChain(node) {
21
23
  if ((0, _utils2.isSupportedAccessor)(node)) {
22
24
  return [node];
@@ -27,14 +29,13 @@ function getNodeChain(node) {
27
29
  return getNodeChain(node.tag);
28
30
 
29
31
  case _utils.AST_NODE_TYPES.MemberExpression:
30
- return [...getNodeChain(node.object), ...getNodeChain(node.property)];
32
+ return joinChains(getNodeChain(node.object), getNodeChain(node.property));
31
33
 
32
- case _utils.AST_NODE_TYPES.NewExpression:
33
34
  case _utils.AST_NODE_TYPES.CallExpression:
34
35
  return getNodeChain(node.callee);
35
36
  }
36
37
 
37
- return [];
38
+ return null;
38
39
  }
39
40
 
40
41
  const determineJestFnType = name => {
@@ -64,8 +65,7 @@ const determineJestFnType = name => {
64
65
  return 'unknown';
65
66
  };
66
67
 
67
- const ValidJestFnCallChains = ['afterAll', 'afterEach', 'beforeAll', 'beforeEach', 'describe', 'describe.each', 'describe.only', 'describe.only.each', 'describe.skip', 'describe.skip.each', 'fdescribe', 'fdescribe.each', 'xdescribe', 'xdescribe.each', 'it', 'it.concurrent', 'it.concurrent.each', 'it.concurrent.only.each', 'it.concurrent.skip.each', 'it.each', 'it.failing', 'it.only', 'it.only.each', 'it.only.failing', 'it.skip', 'it.skip.each', 'it.skip.failing', 'it.todo', 'fit', 'fit.each', 'fit.failing', 'xit', 'xit.each', 'xit.failing', 'test', 'test.concurrent', 'test.concurrent.each', 'test.concurrent.only.each', 'test.concurrent.skip.each', 'test.each', 'test.failing', 'test.only', 'test.only.each', 'test.only.failing', 'test.skip', 'test.skip.each', 'test.skip.failing', 'test.todo', 'xtest', 'xtest.each', 'xtest.failing', // todo: check if actually valid (not in docs)
68
- 'test.concurrent.skip', 'test.concurrent.only', 'it.concurrent.skip', 'it.concurrent.only'];
68
+ const ValidJestFnCallChains = ['afterAll', 'afterEach', 'beforeAll', 'beforeEach', 'describe', 'describe.each', 'describe.only', 'describe.only.each', 'describe.skip', 'describe.skip.each', 'fdescribe', 'fdescribe.each', 'xdescribe', 'xdescribe.each', 'it', 'it.concurrent', 'it.concurrent.each', 'it.concurrent.only.each', 'it.concurrent.skip.each', 'it.each', 'it.failing', 'it.only', 'it.only.each', 'it.only.failing', 'it.skip', 'it.skip.each', 'it.skip.failing', 'it.todo', 'fit', 'fit.each', 'fit.failing', 'xit', 'xit.each', 'xit.failing', 'test', 'test.concurrent', 'test.concurrent.each', 'test.concurrent.only.each', 'test.concurrent.skip.each', 'test.each', 'test.failing', 'test.only', 'test.only.each', 'test.only.failing', 'test.skip', 'test.skip.each', 'test.skip.failing', 'test.todo', 'xtest', 'xtest.each', 'xtest.failing'];
69
69
 
70
70
  const parseJestFnCall = (node, scope) => {
71
71
  var _node$parent, _node$parent2, _resolved$original;
@@ -79,28 +79,32 @@ const parseJestFnCall = (node, scope) => {
79
79
 
80
80
  const chain = getNodeChain(node);
81
81
 
82
- if (chain.length === 0) {
82
+ if (!(chain !== null && chain !== void 0 && chain.length)) {
83
83
  return null;
84
- } // ensure that the only call expression in the chain is at the end
84
+ } // check that every link in the chain except the last is a member expression
85
85
 
86
86
 
87
87
  if (chain.slice(0, chain.length - 1).some(nod => {
88
88
  var _nod$parent;
89
89
 
90
- return ((_nod$parent = nod.parent) === null || _nod$parent === void 0 ? void 0 : _nod$parent.type) === _utils.AST_NODE_TYPES.CallExpression;
90
+ return ((_nod$parent = nod.parent) === null || _nod$parent === void 0 ? void 0 : _nod$parent.type) !== _utils.AST_NODE_TYPES.MemberExpression;
91
91
  })) {
92
92
  return null;
93
93
  }
94
94
 
95
95
  const [first, ...rest] = chain;
96
- const lastNode = chain[chain.length - 1]; // if we're an `each()`, ensure we're the outer CallExpression (i.e `.each()()`)
96
+ const lastLink = (0, _utils2.getAccessorValue)(chain[chain.length - 1]); // if we're an `each()`, ensure we're the outer CallExpression (i.e `.each()()`)
97
97
 
98
- if ((0, _utils2.isSupportedAccessor)(lastNode, 'each')) {
98
+ if (lastLink === 'each') {
99
99
  if (node.callee.type !== _utils.AST_NODE_TYPES.CallExpression && node.callee.type !== _utils.AST_NODE_TYPES.TaggedTemplateExpression) {
100
100
  return null;
101
101
  }
102
102
  }
103
103
 
104
+ if (node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression && lastLink !== 'each') {
105
+ return null;
106
+ }
107
+
104
108
  const resolved = resolveToJestFn(scope, (0, _utils2.getAccessorValue)(first)); // we're not a jest function
105
109
 
106
110
  if (!resolved) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-jest",
3
- "version": "26.4.1",
3
+ "version": "26.4.4",
4
4
  "description": "ESLint rules for Jest",
5
5
  "keywords": [
6
6
  "eslint",
@@ -1,432 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- var _exportNames = {
7
- createRule: true,
8
- followTypeAssertionChain: true,
9
- isStringNode: true,
10
- getStringValue: true,
11
- hasOnlyOneArgument: true,
12
- isIdentifier: true,
13
- isSupportedAccessor: true,
14
- getAccessorValue: true,
15
- isExpectCall: true,
16
- isExpectMember: true,
17
- ModifierName: true,
18
- EqualityMatcher: true,
19
- isParsedEqualityMatcherCall: true,
20
- parseExpectCall: true,
21
- DescribeAlias: true,
22
- TestCaseName: true,
23
- HookName: true,
24
- DescribeProperty: true,
25
- TestCaseProperty: true,
26
- getNodeName: true,
27
- isFunction: true,
28
- getTestCallExpressionsFromDeclaredVariables: true
29
- };
30
- exports.getAccessorValue = exports.followTypeAssertionChain = exports.createRule = exports.TestCaseProperty = exports.TestCaseName = exports.ModifierName = exports.HookName = exports.EqualityMatcher = exports.DescribeProperty = exports.DescribeAlias = void 0;
31
- exports.getNodeName = getNodeName;
32
- exports.parseExpectCall = exports.isSupportedAccessor = exports.isStringNode = exports.isParsedEqualityMatcherCall = exports.isIdentifier = exports.isFunction = exports.isExpectMember = exports.isExpectCall = exports.hasOnlyOneArgument = exports.getTestCallExpressionsFromDeclaredVariables = exports.getStringValue = void 0;
33
-
34
- var _path = require("path");
35
-
36
- var _utils = require("@typescript-eslint/utils");
37
-
38
- var _package = require("../../package.json");
39
-
40
- var _parseJestFnCall = require("./utils/parseJestFnCall");
41
-
42
- Object.keys(_parseJestFnCall).forEach(function (key) {
43
- if (key === "default" || key === "__esModule") return;
44
- if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
45
- if (key in exports && exports[key] === _parseJestFnCall[key]) return;
46
- Object.defineProperty(exports, key, {
47
- enumerable: true,
48
- get: function () {
49
- return _parseJestFnCall[key];
50
- }
51
- });
52
- });
53
- const REPO_URL = 'https://github.com/jest-community/eslint-plugin-jest';
54
-
55
- const createRule = _utils.ESLintUtils.RuleCreator(name => {
56
- const ruleName = (0, _path.parse)(name).name;
57
- return `${REPO_URL}/blob/v${_package.version}/docs/rules/${ruleName}.md`;
58
- });
59
-
60
- exports.createRule = createRule;
61
-
62
- const isTypeCastExpression = node => node.type === _utils.AST_NODE_TYPES.TSAsExpression || node.type === _utils.AST_NODE_TYPES.TSTypeAssertion;
63
-
64
- const followTypeAssertionChain = expression => isTypeCastExpression(expression) ? followTypeAssertionChain(expression.expression) : expression;
65
- /**
66
- * A `Literal` with a `value` of type `string`.
67
- */
68
-
69
-
70
- exports.followTypeAssertionChain = followTypeAssertionChain;
71
-
72
- /**
73
- * Checks if the given `node` is a `StringLiteral`.
74
- *
75
- * If a `value` is provided & the `node` is a `StringLiteral`,
76
- * the `value` will be compared to that of the `StringLiteral`.
77
- *
78
- * @param {Node} node
79
- * @param {V} [value]
80
- *
81
- * @return {node is StringLiteral<V>}
82
- *
83
- * @template V
84
- */
85
- const isStringLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.Literal && typeof node.value === 'string' && (value === undefined || node.value === value);
86
-
87
- /**
88
- * Checks if the given `node` is a `TemplateLiteral`.
89
- *
90
- * Complex `TemplateLiteral`s are not considered specific, and so will return `false`.
91
- *
92
- * If a `value` is provided & the `node` is a `TemplateLiteral`,
93
- * the `value` will be compared to that of the `TemplateLiteral`.
94
- *
95
- * @param {Node} node
96
- * @param {V} [value]
97
- *
98
- * @return {node is TemplateLiteral<V>}
99
- *
100
- * @template V
101
- */
102
- const isTemplateLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.TemplateLiteral && node.quasis.length === 1 && ( // bail out if not simple
103
- value === undefined || node.quasis[0].value.raw === value);
104
-
105
- /**
106
- * Checks if the given `node` is a {@link StringNode}.
107
- *
108
- * @param {Node} node
109
- * @param {V} [specifics]
110
- *
111
- * @return {node is StringNode}
112
- *
113
- * @template V
114
- */
115
- const isStringNode = (node, specifics) => isStringLiteral(node, specifics) || isTemplateLiteral(node, specifics);
116
- /**
117
- * Gets the value of the given `StringNode`.
118
- *
119
- * If the `node` is a `TemplateLiteral`, the `raw` value is used;
120
- * otherwise, `value` is returned instead.
121
- *
122
- * @param {StringNode<S>} node
123
- *
124
- * @return {S}
125
- *
126
- * @template S
127
- */
128
-
129
-
130
- exports.isStringNode = isStringNode;
131
-
132
- const getStringValue = node => isTemplateLiteral(node) ? node.quasis[0].value.raw : node.value;
133
- /**
134
- * Represents a `MemberExpression` with a "known" `property`.
135
- */
136
-
137
-
138
- exports.getStringValue = getStringValue;
139
-
140
- /**
141
- * Guards that the given `call` has only one `argument`.
142
- *
143
- * @param {CallExpression} call
144
- *
145
- * @return {call is CallExpressionWithSingleArgument}
146
- */
147
- const hasOnlyOneArgument = call => call.arguments.length === 1;
148
- /**
149
- * An `Identifier` with a known `name` value - i.e `expect`.
150
- */
151
-
152
-
153
- exports.hasOnlyOneArgument = hasOnlyOneArgument;
154
-
155
- /**
156
- * Checks if the given `node` is an `Identifier`.
157
- *
158
- * If a `name` is provided, & the `node` is an `Identifier`,
159
- * the `name` will be compared to that of the `identifier`.
160
- *
161
- * @param {Node} node
162
- * @param {V} [name]
163
- *
164
- * @return {node is KnownIdentifier<Name>}
165
- *
166
- * @template V
167
- */
168
- const isIdentifier = (node, name) => node.type === _utils.AST_NODE_TYPES.Identifier && (name === undefined || node.name === name);
169
- /**
170
- * Checks if the given `node` is a "supported accessor".
171
- *
172
- * This means that it's a node can be used to access properties,
173
- * and who's "value" can be statically determined.
174
- *
175
- * `MemberExpression` nodes most commonly contain accessors,
176
- * but it's possible for other nodes to contain them.
177
- *
178
- * If a `value` is provided & the `node` is an `AccessorNode`,
179
- * the `value` will be compared to that of the `AccessorNode`.
180
- *
181
- * Note that `value` here refers to the normalised value.
182
- * The property that holds the value is not always called `name`.
183
- *
184
- * @param {Node} node
185
- * @param {V} [value]
186
- *
187
- * @return {node is AccessorNode<V>}
188
- *
189
- * @template V
190
- */
191
-
192
-
193
- exports.isIdentifier = isIdentifier;
194
-
195
- const isSupportedAccessor = (node, value) => isIdentifier(node, value) || isStringNode(node, value);
196
- /**
197
- * Gets the value of the given `AccessorNode`,
198
- * account for the different node types.
199
- *
200
- * @param {AccessorNode<S>} accessor
201
- *
202
- * @return {S}
203
- *
204
- * @template S
205
- */
206
-
207
-
208
- exports.isSupportedAccessor = isSupportedAccessor;
209
-
210
- const getAccessorValue = accessor => accessor.type === _utils.AST_NODE_TYPES.Identifier ? accessor.name : getStringValue(accessor);
211
-
212
- exports.getAccessorValue = getAccessorValue;
213
-
214
- /**
215
- * Checks if the given `node` is a valid `ExpectCall`.
216
- *
217
- * In order to be an `ExpectCall`, the `node` must:
218
- * * be a `CallExpression`,
219
- * * have an accessor named 'expect',
220
- * * have a `parent`.
221
- *
222
- * @param {Node} node
223
- *
224
- * @return {node is ExpectCall}
225
- */
226
- const isExpectCall = node => node.type === _utils.AST_NODE_TYPES.CallExpression && isSupportedAccessor(node.callee, 'expect') && node.parent !== undefined;
227
-
228
- exports.isExpectCall = isExpectCall;
229
-
230
- const isExpectMember = (node, name) => node.type === _utils.AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.property, name);
231
- /**
232
- * Represents all the jest matchers.
233
- */
234
-
235
-
236
- exports.isExpectMember = isExpectMember;
237
- let ModifierName;
238
- exports.ModifierName = ModifierName;
239
-
240
- (function (ModifierName) {
241
- ModifierName["not"] = "not";
242
- ModifierName["rejects"] = "rejects";
243
- ModifierName["resolves"] = "resolves";
244
- })(ModifierName || (exports.ModifierName = ModifierName = {}));
245
-
246
- let EqualityMatcher;
247
- exports.EqualityMatcher = EqualityMatcher;
248
-
249
- (function (EqualityMatcher) {
250
- EqualityMatcher["toBe"] = "toBe";
251
- EqualityMatcher["toEqual"] = "toEqual";
252
- EqualityMatcher["toStrictEqual"] = "toStrictEqual";
253
- })(EqualityMatcher || (exports.EqualityMatcher = EqualityMatcher = {}));
254
-
255
- const isParsedEqualityMatcherCall = (matcher, name) => (name ? matcher.name === name : EqualityMatcher.hasOwnProperty(matcher.name)) && matcher.arguments !== null && matcher.arguments.length === 1;
256
- /**
257
- * Represents a parsed expect matcher, such as `toBe`, `toContain`, and so on.
258
- */
259
-
260
-
261
- exports.isParsedEqualityMatcherCall = isParsedEqualityMatcherCall;
262
-
263
- const parseExpectMember = expectMember => ({
264
- name: getAccessorValue(expectMember.property),
265
- node: expectMember
266
- });
267
-
268
- const reparseAsMatcher = parsedMember => ({ ...parsedMember,
269
-
270
- /**
271
- * The arguments being passed to this `Matcher`, if any.
272
- *
273
- * If this matcher isn't called, this will be `null`.
274
- */
275
- arguments: parsedMember.node.parent.type === _utils.AST_NODE_TYPES.CallExpression ? parsedMember.node.parent.arguments : null
276
- });
277
- /**
278
- * Re-parses the given `parsedMember` as a `ParsedExpectModifier`.
279
- *
280
- * If the given `parsedMember` does not have a `name` of a valid `Modifier`,
281
- * an exception will be thrown.
282
- *
283
- * @param {ParsedExpectMember<ModifierName>} parsedMember
284
- *
285
- * @return {ParsedExpectModifier}
286
- */
287
-
288
-
289
- const reparseMemberAsModifier = parsedMember => {
290
- if (isSpecificMember(parsedMember, ModifierName.not)) {
291
- return parsedMember;
292
- }
293
- /* istanbul ignore if */
294
-
295
-
296
- if (!isSpecificMember(parsedMember, ModifierName.resolves) && !isSpecificMember(parsedMember, ModifierName.rejects)) {
297
- // ts doesn't think that the ModifierName.not check is the direct inverse as the above two checks
298
- // todo: impossible at runtime, but can't be typed w/o negation support
299
- throw new Error(`modifier name must be either "${ModifierName.resolves}" or "${ModifierName.rejects}" (got "${parsedMember.name}")`);
300
- }
301
-
302
- const negation = isExpectMember(parsedMember.node.parent, ModifierName.not) ? parsedMember.node.parent : undefined;
303
- return { ...parsedMember,
304
- negation
305
- };
306
- };
307
-
308
- const isSpecificMember = (member, specific) => member.name === specific;
309
- /**
310
- * Checks if the given `ParsedExpectMember` should be re-parsed as an `ParsedExpectModifier`.
311
- *
312
- * @param {ParsedExpectMember} member
313
- *
314
- * @return {member is ParsedExpectMember<ModifierName>}
315
- */
316
-
317
-
318
- const shouldBeParsedExpectModifier = member => ModifierName.hasOwnProperty(member.name);
319
-
320
- const parseExpectCall = expect => {
321
- const expectation = {
322
- expect
323
- };
324
-
325
- if (!isExpectMember(expect.parent)) {
326
- return expectation;
327
- }
328
-
329
- const parsedMember = parseExpectMember(expect.parent);
330
-
331
- if (!shouldBeParsedExpectModifier(parsedMember)) {
332
- expectation.matcher = reparseAsMatcher(parsedMember);
333
- return expectation;
334
- }
335
-
336
- const modifier = expectation.modifier = reparseMemberAsModifier(parsedMember);
337
- const memberNode = modifier.negation || modifier.node;
338
-
339
- if (!isExpectMember(memberNode.parent)) {
340
- return expectation;
341
- }
342
-
343
- expectation.matcher = reparseAsMatcher(parseExpectMember(memberNode.parent));
344
- return expectation;
345
- };
346
-
347
- exports.parseExpectCall = parseExpectCall;
348
- let DescribeAlias;
349
- exports.DescribeAlias = DescribeAlias;
350
-
351
- (function (DescribeAlias) {
352
- DescribeAlias["describe"] = "describe";
353
- DescribeAlias["fdescribe"] = "fdescribe";
354
- DescribeAlias["xdescribe"] = "xdescribe";
355
- })(DescribeAlias || (exports.DescribeAlias = DescribeAlias = {}));
356
-
357
- let TestCaseName;
358
- exports.TestCaseName = TestCaseName;
359
-
360
- (function (TestCaseName) {
361
- TestCaseName["fit"] = "fit";
362
- TestCaseName["it"] = "it";
363
- TestCaseName["test"] = "test";
364
- TestCaseName["xit"] = "xit";
365
- TestCaseName["xtest"] = "xtest";
366
- })(TestCaseName || (exports.TestCaseName = TestCaseName = {}));
367
-
368
- let HookName;
369
- exports.HookName = HookName;
370
-
371
- (function (HookName) {
372
- HookName["beforeAll"] = "beforeAll";
373
- HookName["beforeEach"] = "beforeEach";
374
- HookName["afterAll"] = "afterAll";
375
- HookName["afterEach"] = "afterEach";
376
- })(HookName || (exports.HookName = HookName = {}));
377
-
378
- let DescribeProperty;
379
- exports.DescribeProperty = DescribeProperty;
380
-
381
- (function (DescribeProperty) {
382
- DescribeProperty["each"] = "each";
383
- DescribeProperty["only"] = "only";
384
- DescribeProperty["skip"] = "skip";
385
- })(DescribeProperty || (exports.DescribeProperty = DescribeProperty = {}));
386
-
387
- let TestCaseProperty;
388
- exports.TestCaseProperty = TestCaseProperty;
389
-
390
- (function (TestCaseProperty) {
391
- TestCaseProperty["each"] = "each";
392
- TestCaseProperty["concurrent"] = "concurrent";
393
- TestCaseProperty["only"] = "only";
394
- TestCaseProperty["skip"] = "skip";
395
- TestCaseProperty["todo"] = "todo";
396
- })(TestCaseProperty || (exports.TestCaseProperty = TestCaseProperty = {}));
397
-
398
- const joinNames = (a, b) => a && b ? `${a}.${b}` : null;
399
-
400
- function getNodeName(node) {
401
- if (isSupportedAccessor(node)) {
402
- return getAccessorValue(node);
403
- }
404
-
405
- switch (node.type) {
406
- case _utils.AST_NODE_TYPES.TaggedTemplateExpression:
407
- return getNodeName(node.tag);
408
-
409
- case _utils.AST_NODE_TYPES.MemberExpression:
410
- return joinNames(getNodeName(node.object), getNodeName(node.property));
411
-
412
- case _utils.AST_NODE_TYPES.NewExpression:
413
- case _utils.AST_NODE_TYPES.CallExpression:
414
- return getNodeName(node.callee);
415
- }
416
-
417
- return null;
418
- }
419
-
420
- const isFunction = node => node.type === _utils.AST_NODE_TYPES.FunctionExpression || node.type === _utils.AST_NODE_TYPES.ArrowFunctionExpression;
421
-
422
- exports.isFunction = isFunction;
423
-
424
- const getTestCallExpressionsFromDeclaredVariables = (declaredVariables, scope) => {
425
- return declaredVariables.reduce((acc, {
426
- references
427
- }) => acc.concat(references.map(({
428
- identifier
429
- }) => identifier.parent).filter(node => !!node && node.type === _utils.AST_NODE_TYPES.CallExpression && (0, _parseJestFnCall.isTypeOfJestFnCall)(node, scope, ['test']))), []);
430
- };
431
-
432
- exports.getTestCallExpressionsFromDeclaredVariables = getTestCallExpressionsFromDeclaredVariables;