diff --git a/tools/hermes-parser/js/hermes-eslint/__test_utils__/verifyHasScopes.js b/tools/hermes-parser/js/hermes-eslint/__test_utils__/verifyHasScopes.js index 5b81512512a..49ac780cbda 100644 --- a/tools/hermes-parser/js/hermes-eslint/__test_utils__/verifyHasScopes.js +++ b/tools/hermes-parser/js/hermes-eslint/__test_utils__/verifyHasScopes.js @@ -31,7 +31,7 @@ export function verifyHasScopes( type: ScopeTypeType, variables: $ReadOnlyArray<{ name: string, - type: ?DefinitionTypeType, + type: ?DefinitionTypeType | $ReadOnlyArray, referenceCount: ?number, eslintUsed?: boolean, }>, @@ -40,56 +40,94 @@ export function verifyHasScopes( ) { const {scopeManager} = parseForESLint(code, parserOptions); - // report as an array so that it's easier to debug the tests - // otherwise you get a cryptic failure that just says "expected 1 but received 2" - expect(scopeManager.scopes.map(s => s.type)).toEqual([ - // Global scope (at index 0 of actual scopes) is not passed as an expected scope - 'global', - ...expectedScopes.map(s => s.type), - ]); + it('should have the correct scopes', () => { + // report as an array so that it's easier to debug the tests + // otherwise you get a cryptic failure that just says "expected 1 but received 2" + expect(scopeManager.scopes.map(s => s.type)).toEqual([ + // Global scope (at index 0 of actual scopes) is not passed as an expected scope + 'global', + ...expectedScopes.map(s => s.type), + ]); + }); for (let i = 0; i < expectedScopes.length; i++) { const actualScope = scopeManager.scopes[i + 1]; const expectedScope = expectedScopes[i]; - expect(actualScope.type).toEqual(expectedScope.type); - // report as an object so that it's easier to debug the tests - expect({ - type: actualScope.type, - variables: actualScope.variables.map(v => v.name), - }).toEqual({ - type: actualScope.type, - variables: expectedScope.variables.map(v => v.name), - }); - - for (let j = 0; j < expectedScope.variables.length; j++) { - const expectedVariable = expectedScope.variables[j]; - const actualVariable = actualScope.variables[j]; - - expect(actualVariable.name).toEqual(expectedVariable.name); + describe(`${i}th scope - ${expectedScope.type}`, () => { + it('has the correct type', () => { + expect(actualScope.type).toEqual(expectedScope.type); + }); - if (expectedVariable.referenceCount != null) { - const cnt = expectedVariable.referenceCount; + it('has the expected variable names', () => { // report as an object so that it's easier to debug the tests expect({ - type: expectedVariable.type, - name: actualVariable.name, - refCount: actualVariable.references.length, + type: actualScope.type, + variables: actualScope.variables.map(v => v.name), }).toEqual({ - type: expectedVariable.type, - name: actualVariable.name, - refCount: cnt, + type: actualScope.type, + variables: expectedScope.variables.map(v => v.name), }); - } + }); - if (expectedVariable.type != null) { - expect(actualVariable.defs).toHaveLength(1); - expect(actualVariable.defs[0].type).toEqual(expectedVariable.type); - } + describe('variables', () => { + for (let j = 0; j < expectedScope.variables.length; j++) { + const expectedVariable = expectedScope.variables[j]; + const actualVariable = actualScope.variables[j]; + describe(`${j}th variable - ${expectedVariable.name}`, () => { + it('has the expected name', () => { + expect(actualVariable.name).toEqual(expectedVariable.name); + }); - if (expectedVariable.eslintUsed != null) { - expect(actualVariable.eslintUsed).toBe(expectedVariable.eslintUsed); - } - } + if (expectedVariable.referenceCount != null) { + it('has the expected reference count', () => { + const cnt = expectedVariable.referenceCount; + // report as an object so that it's easier to debug the tests + expect({ + type: expectedVariable.type, + name: actualVariable.name, + refCount: actualVariable.references.length, + }).toEqual({ + type: expectedVariable.type, + name: actualVariable.name, + refCount: cnt, + }); + }); + } else { + it.skip('has the expected reference count', () => {}); + } + + if (expectedVariable.type != null) { + it('has the expected definition type(s)', () => { + if (Array.isArray(expectedVariable.type)) { + expect(actualVariable.defs.map(d => d.type)).toEqual( + expectedVariable.type, + ); + } else { + expect(actualVariable.defs).toHaveLength(1); + expect(actualVariable.defs[0].type).toEqual( + expectedVariable.type, + ); + } + }); + } else { + it('has no definitions', () => { + expect(actualVariable.defs).toHaveLength(0); + }); + } + + if (expectedVariable.eslintUsed != null) { + it('has the expected eslintUsed value', () => { + expect(actualVariable.eslintUsed).toBe( + expectedVariable.eslintUsed, + ); + }); + } else { + it.skip('has the expected eslintUsed value', () => {}); + } + }); + } + }); + }); } } diff --git a/tools/hermes-parser/js/hermes-eslint/__tests__/HermesScopeManager-test.js b/tools/hermes-parser/js/hermes-eslint/__tests__/HermesScopeManager-test.js index d53b510a277..6f3a7677bce 100644 --- a/tools/hermes-parser/js/hermes-eslint/__tests__/HermesScopeManager-test.js +++ b/tools/hermes-parser/js/hermes-eslint/__tests__/HermesScopeManager-test.js @@ -50,7 +50,7 @@ describe('Type and value references', () => { name: string, definitionType: 'ClassName' | 'Enum', ) { - it(code, () => { + test(code, () => { const {scopeManager} = parseForESLint(code); // Verify that scope contains a single variable @@ -118,7 +118,7 @@ describe('Type definitions', () => { expect(variable.defs[0].type).toEqual(DefinitionType.Type); } - test('TypeAlias', () => { + describe('TypeAlias', () => { const {scopeManager} = parseForESLint(` type T = number; (1: T); @@ -126,7 +126,7 @@ describe('Type definitions', () => { verifyTypeDefinition(scopeManager); }); - test('OpaqueType', () => { + describe('OpaqueType', () => { const {scopeManager} = parseForESLint(` opaque type T = number; (1: T); @@ -134,7 +134,7 @@ describe('Type definitions', () => { verifyTypeDefinition(scopeManager); }); - test('InterfaceDeclaration', () => { + describe('InterfaceDeclaration', () => { const {scopeManager} = parseForESLint(` interface T {} (1: T); @@ -240,7 +240,7 @@ describe('Identifiers not mistakenly treated as references', () => { } } - test('Enum body', () => { + describe('Enum body', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -255,7 +255,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('QualifiedTypeIdentifier', () => { + describe('QualifiedTypeIdentifier', () => { verifyHasReferences( ` import * as Foo from 'Foo'; @@ -272,7 +272,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('ObjectTypeProperty', () => { + describe('ObjectTypeProperty', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -286,7 +286,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('ObjectTypeIndexer', () => { + describe('ObjectTypeIndexer', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -300,7 +300,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('ObjectTypeInternalSlot', () => { + describe('ObjectTypeInternalSlot', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -314,7 +314,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('FunctionTypeParam', () => { + describe('FunctionTypeParam', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -328,7 +328,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('MemberExpression', () => { + describe('MemberExpression', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -342,7 +342,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('OptionalMemberExpression', () => { + describe('OptionalMemberExpression', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -356,7 +356,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('CallExpression', () => { + describe('CallExpression', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -374,7 +374,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('OptionalCallExpression', () => { + describe('OptionalCallExpression', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -392,7 +392,7 @@ describe('Identifiers not mistakenly treated as references', () => { ); }); - test('PropertyDefinition', () => { + describe('PropertyDefinition', () => { verifyHasReferences( ` import Foo from 'Foo'; @@ -443,7 +443,7 @@ describe('Type parameters', () => { expect(scopeManager.scopes[1].type).toEqual(ScopeType.Module); }); - test('TypeAlias', () => { + describe('TypeAlias', () => { // Type alias contains type parameter in Type scope verifyHasScopes(`type Foo = T;`, [ { @@ -469,7 +469,7 @@ describe('Type parameters', () => { ]); }); - test('OpaqueType', () => { + describe('OpaqueType', () => { // Opaque type contains type parameter in Type scope verifyHasScopes(`opaque type Foo = T;`, [ { @@ -495,7 +495,7 @@ describe('Type parameters', () => { ]); }); - test('InterfaceDeclaration', () => { + describe('InterfaceDeclaration', () => { // Interface declaration contains type parameter in Type scope verifyHasScopes(`interface Foo { prop: T }`, [ { @@ -521,7 +521,7 @@ describe('Type parameters', () => { ]); }); - test('FunctionTypeAnnotation', () => { + describe('FunctionTypeAnnotation', () => { // FunctionTypeAnnotation contains type parameter in Type scope verifyHasScopes(`(1: (T) => void);`, [ { @@ -541,7 +541,7 @@ describe('Type parameters', () => { ]); }); - test('DeclareClass', () => { + describe('DeclareClass', () => { // DeclareClass contains type parameter in Type scope verifyHasScopes(`declare class C { prop: T }`, [ { @@ -567,7 +567,7 @@ describe('Type parameters', () => { ]); }); - test('FunctionDeclaration', () => { + describe('FunctionDeclaration', () => { // Function contains type parameter in Function scope alongside value parameter verifyHasScopes( ` @@ -610,7 +610,7 @@ describe('Type parameters', () => { ); }); - test('FunctionExpression', () => { + describe('FunctionExpression', () => { verifyHasScopes( ` (function foo(x) { @@ -656,7 +656,7 @@ describe('Type parameters', () => { ); }); - test('Class', () => { + describe('Class', () => { // Class contains type parameter in Class scope verifyHasScopes( ` @@ -696,7 +696,7 @@ describe('Type parameters', () => { }); describe('Flow type nodes in Patterns', () => { - test('Identifier', () => { + describe('Identifier', () => { verifyHasScopes( ` type T = string; @@ -734,7 +734,7 @@ describe('Flow type nodes in Patterns', () => { ); }); - test('ArrayPattern', () => { + describe('ArrayPattern', () => { verifyHasScopes( ` type T = string; @@ -772,7 +772,7 @@ describe('Flow type nodes in Patterns', () => { ); }); - test('ObjectPattern', () => { + describe('ObjectPattern', () => { verifyHasScopes( ` type T = string; @@ -810,7 +810,7 @@ describe('Flow type nodes in Patterns', () => { ); }); - test('RestElement', () => { + describe('RestElement', () => { verifyHasScopes( ` type T = string; @@ -842,7 +842,7 @@ describe('Flow type nodes in Patterns', () => { ); }); - test('Nested patterns', () => { + describe('Nested patterns', () => { verifyHasScopes( ` type T = string; @@ -881,7 +881,7 @@ describe('Flow type nodes in Patterns', () => { }); describe('Declare statements', () => { - test('DeclareTypeAlias', () => { + describe('DeclareTypeAlias', () => { verifyHasScopes( ` declare type T = number; @@ -902,7 +902,7 @@ describe('Declare statements', () => { ); }); - test('DeclareOpaqueType', () => { + describe('DeclareOpaqueType', () => { verifyHasScopes( ` declare opaque type T: number; @@ -923,7 +923,7 @@ describe('Declare statements', () => { ); }); - test('DeclareInterface', () => { + describe('DeclareInterface', () => { verifyHasScopes( ` declare interface I {}; @@ -944,7 +944,7 @@ describe('Declare statements', () => { ); }); - test('DeclareVariable', () => { + describe('DeclareVariable', () => { verifyHasScopes(`declare var Foo: typeof Foo;`, [ { type: ScopeType.Module, @@ -959,7 +959,7 @@ describe('Declare statements', () => { ]); }); - test('DeclareFunction', () => { + describe('DeclareFunction', () => { verifyHasScopes( ` declare function Foo(): void; @@ -980,7 +980,7 @@ describe('Declare statements', () => { ); }); - test('DeclareClass', () => { + describe('DeclareClass', () => { verifyHasScopes( ` declare class C {} @@ -1001,7 +1001,7 @@ describe('Declare statements', () => { ); }); - test('DeclareModuleExports', () => { + describe('DeclareModuleExports', () => { verifyHasScopes( ` import type {Foo} from 'foo'; @@ -1022,7 +1022,7 @@ describe('Declare statements', () => { ); }); - test('DeclareModule', () => { + describe('DeclareModule', () => { verifyHasScopes( ` declare module Foo { @@ -1090,7 +1090,7 @@ describe('Declare statements', () => { expect(references[1].resolved).toBe(null); }); - test('DeclareModule DeclareModuleExports', () => { + describe('DeclareModule DeclareModuleExports', () => { verifyHasScopes( ` import {module, exports} from 'Foo'; @@ -1129,7 +1129,7 @@ describe('Declare statements', () => { ); }); - test('DeclareModule DeclareExportDeclaration', () => { + describe('DeclareModule DeclareExportDeclaration', () => { // Verify that all declare export nodes introduce a definition, with a single // additional reference in the declare module body. verifyHasScopes( @@ -1192,7 +1192,7 @@ describe('Declare statements', () => { }); describe('Flow specific properties visited on non-Flow nodes', () => { - test('Function', () => { + describe('Function', () => { // Return type is visited, but predicate is NOT visited verifyHasScopes( ` @@ -1235,7 +1235,7 @@ describe('Flow specific properties visited on non-Flow nodes', () => { ); }); - test('Class', () => { + describe('Class', () => { // Supertype parameters and implements are visited verifyHasScopes( ` @@ -1290,7 +1290,7 @@ describe('Flow specific properties visited on non-Flow nodes', () => { }); describe('PropertyDefinition', () => { - it('PropertyDefinition', () => { + describe('PropertyDefinition', () => { verifyHasScopes( ` import Foo from 'Foo'; @@ -1346,7 +1346,7 @@ describe('PropertyDefinition', () => { }); describe('FunctionExpression', () => { - test('Function name not referenced in return type', () => { + describe('Function name not referenced in return type', () => { verifyHasScopes(`(function foo(): foo {});`, [ { type: ScopeType.Module, @@ -1439,7 +1439,7 @@ describe('FunctionExpression', () => { }); describe('This type annotation', () => { - test('Is not treated as a parameter', () => { + describe('Is not treated as a parameter', () => { verifyHasScopes( ` function foo(this: string, param: number) { @@ -1476,7 +1476,7 @@ describe('This type annotation', () => { ); }); - test('Type annotation is still visited', () => { + describe('Type annotation is still visited', () => { verifyHasScopes( ` type T = string; @@ -1513,7 +1513,7 @@ describe('This type annotation', () => { }); describe('this annotation can reference generics', () => { - test('function decl', () => { + describe('function decl', () => { verifyHasScopes( ` function foo(this: This) {} @@ -1547,7 +1547,7 @@ describe('This type annotation', () => { ], ); }); - test('function expr', () => { + describe('function expr', () => { verifyHasScopes( ` const foo = function (this: This) {}; @@ -1581,7 +1581,7 @@ describe('This type annotation', () => { ], ); }); - test('function type1', () => { + describe('function type1', () => { verifyHasScopes( ` type foo = (this: This) => void; @@ -1610,7 +1610,7 @@ describe('This type annotation', () => { ], ); }); - test('function type2', () => { + describe('function type2', () => { verifyHasScopes( ` type foo = (this: This) => void; @@ -1644,7 +1644,7 @@ describe('This type annotation', () => { describe('Imports', () => { describe('default', () => { - it('import type', () => { + describe('import type', () => { verifyHasScopes( ` import type RefValue from 'foo'; @@ -1682,7 +1682,7 @@ describe('Imports', () => { ); }); - it('import typeof', () => { + describe('import typeof', () => { verifyHasScopes( ` import typeof RefValue from 'foo'; @@ -1720,7 +1720,7 @@ describe('Imports', () => { ); }); - it('import value', () => { + describe('import value', () => { verifyHasScopes( ` import RefValue from 'foo'; @@ -1761,7 +1761,7 @@ describe('Imports', () => { describe('named', () => { describe('top-level', () => { - it('import type', () => { + describe('import type', () => { verifyHasScopes( ` import type {RefValue} from 'foo'; @@ -1799,7 +1799,7 @@ describe('Imports', () => { ); }); - it('import typeof', () => { + describe('import typeof', () => { verifyHasScopes( ` import typeof {RefValue} from 'foo'; @@ -1837,7 +1837,7 @@ describe('Imports', () => { ); }); - it('import value', () => { + describe('import value', () => { verifyHasScopes( ` import {RefValue} from 'foo'; @@ -1877,7 +1877,7 @@ describe('Imports', () => { }); describe('inline', () => { - it('import type', () => { + describe('import type', () => { verifyHasScopes( ` import {type RefValue} from 'foo'; @@ -1915,7 +1915,7 @@ describe('Imports', () => { ); }); - it('import typeof', () => { + describe('import typeof', () => { verifyHasScopes( ` import {typeof RefValue} from 'foo'; @@ -1955,7 +1955,7 @@ describe('Imports', () => { }); }); - it('namespace', () => { + describe('namespace', () => { verifyHasScopes( ` import * as RefValue from 'foo'; diff --git a/tools/hermes-parser/js/hermes-eslint/__tests__/hermes-scope/declare-export-test.js b/tools/hermes-parser/js/hermes-eslint/__tests__/hermes-scope/declare-export-test.js index f76dca24dfd..de28b368320 100644 --- a/tools/hermes-parser/js/hermes-eslint/__tests__/hermes-scope/declare-export-test.js +++ b/tools/hermes-parser/js/hermes-eslint/__tests__/hermes-scope/declare-export-test.js @@ -14,7 +14,7 @@ import {DefinitionType, ScopeType} from '../../src'; import {verifyHasScopes} from '../../__test_utils__/verifyHasScopes'; describe('declare export', () => { - it('variable', () => { + describe('variable', () => { verifyHasScopes( ` declare export var foo: string; @@ -34,7 +34,7 @@ describe('declare export', () => { ], ); }); - it('function', () => { + describe('function', () => { verifyHasScopes( ` declare export function foo(): void; @@ -54,7 +54,7 @@ describe('declare export', () => { ], ); }); - it('type', () => { + describe('type', () => { // you can only declare export types within a module verifyHasScopes( ` @@ -82,7 +82,7 @@ describe('declare export', () => { ], ); }); - it('opaque type', () => { + describe('opaque type', () => { verifyHasScopes( ` declare export opaque type foo: 1; @@ -102,7 +102,7 @@ describe('declare export', () => { ], ); }); - it('interface', () => { + describe('interface', () => { verifyHasScopes( ` declare export interface foo {}; diff --git a/tools/hermes-parser/js/hermes-eslint/__tests__/hermes-scope/jsx-test.js b/tools/hermes-parser/js/hermes-eslint/__tests__/hermes-scope/jsx-test.js index f024dcaddda..7f9ff28f954 100644 --- a/tools/hermes-parser/js/hermes-eslint/__tests__/hermes-scope/jsx-test.js +++ b/tools/hermes-parser/js/hermes-eslint/__tests__/hermes-scope/jsx-test.js @@ -24,7 +24,7 @@ describe('jsx', () => { const parserOptions = {jsxPragma: 'CustomReact'}; const pragmaComment = `\x40jsx PragmaReact.foo`; - test('Defaults', () => { + describe('Defaults', () => { verifyHasScopes( ` /** @@ -55,7 +55,7 @@ describe('jsx', () => { ], ); }); - test('Explicit Option', () => { + describe('Explicit Option', () => { verifyHasScopes( ` /** @@ -87,7 +87,7 @@ describe('jsx', () => { parserOptions, ); }); - test('Comment pragma overrides defaults', () => { + describe('Comment pragma overrides defaults', () => { verifyHasScopes( ` /** @@ -119,7 +119,7 @@ describe('jsx', () => { ], ); }); - test('Comment pragma overrides explicit option', () => { + describe('Comment pragma overrides explicit option', () => { verifyHasScopes( ` /** @@ -171,7 +171,7 @@ describe('jsx', () => { * \x40jsxFrag PragmaFragment.bar `; - test('Defaults', () => { + describe('Defaults', () => { verifyHasScopes( ` /** @@ -212,7 +212,7 @@ describe('jsx', () => { ], ); }); - test('Explicit Option', () => { + describe('Explicit Option', () => { verifyHasScopes( ` /** @@ -254,7 +254,7 @@ describe('jsx', () => { parserOptions, ); }); - test('Comment pragma overrides defaults', () => { + describe('Comment pragma overrides defaults', () => { verifyHasScopes( ` /** @@ -296,7 +296,7 @@ describe('jsx', () => { ], ); }); - test('Comment pragma overrides explicit option', () => { + describe('Comment pragma overrides explicit option', () => { verifyHasScopes( ` /** @@ -343,7 +343,7 @@ describe('jsx', () => { describe('fbt', () => { describe('with option', () => { - test('identifier', () => { + describe('identifier', () => { verifyHasScopes( ` import React from 'react'; @@ -372,7 +372,7 @@ describe('jsx', () => { }, ); }); - test('identifier - fbs', () => { + describe('identifier - fbs', () => { verifyHasScopes( ` import React from 'react'; @@ -401,7 +401,7 @@ describe('jsx', () => { }, ); }); - test('namespace', () => { + describe('namespace', () => { verifyHasScopes( ` import React from 'react'; @@ -430,7 +430,7 @@ describe('jsx', () => { }, ); }); - test('member expr', () => { + describe('member expr', () => { verifyHasScopes( ` import React from 'react'; @@ -461,7 +461,7 @@ describe('jsx', () => { }); }); describe('without option', () => { - test('identifier', () => { + describe('identifier', () => { verifyHasScopes( ` import React from 'react'; @@ -490,7 +490,7 @@ describe('jsx', () => { }, ); }); - test('namespace', () => { + describe('namespace', () => { verifyHasScopes( ` import React from 'react'; @@ -521,7 +521,7 @@ describe('jsx', () => { }, ); }); - test('member expr', () => { + describe('member expr', () => { verifyHasScopes( ` import React from 'react'; @@ -556,7 +556,7 @@ describe('jsx', () => { }); describe('Component name references', () => { - test('Upper-case references name', () => { + describe('Upper-case references name', () => { verifyHasScopes( ` import React from 'react'; @@ -583,7 +583,7 @@ describe('jsx', () => { ); }); - test('Lower-case does not reference name', () => { + describe('Lower-case does not reference name', () => { verifyHasScopes( ` import React from 'react'; @@ -610,7 +610,7 @@ describe('jsx', () => { ); }); - test('Member expressions are referenced regardless of casing', () => { + describe('Member expressions are referenced regardless of casing', () => { verifyHasScopes( ` import React from 'react';