-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# Pull Request ## 🤨 Rationale Create `parameterizeSuite` function within `jasmine-parameterize` package. Resolves #1827 ## 👩💻 Implementation - Refactored the existing internal `parameterize` function within `jasmine-parameterize` so that it can be called for specs and suites - Create `parameterizeSuite` function within `jasmine-parameterize` package - Leverage the new `parameterizeSuite` function in one place within `nimble-components` ## 🧪 Testing - Extended the testing of `parameterize` to cover both spec and suite usages - Copied the `parameterizeSpec` tests and adapted for testing `parameterizeSuite` - Made sure the `parameterizeSuite` function worked as expected by using it within the `nimble-select` tests ## ✅ Checklist <!--- Review the list and put an x in the boxes that apply or ~~strike through~~ around items that don't (along with an explanation). --> - [ ] I have updated the project documentation to reflect my changes or determined no changes are needed. --------- Co-authored-by: Milan Raj <rajsite@users.noreply.github.com>
- Loading branch information
1 parent
1412ad5
commit 116f0bc
Showing
15 changed files
with
662 additions
and
251 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
change/@ni-jasmine-parameterized-544a8033-fa3b-4201-872c-b6f070a48513.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "minor", | ||
"comment": "Create `parameterizeSuite` function", | ||
"packageName": "@ni/jasmine-parameterized", | ||
"email": "20542556+mollykreis@users.noreply.github.com", | ||
"dependentChangeType": "patch" | ||
} |
7 changes: 7 additions & 0 deletions
7
change/@ni-nimble-components-d6494d37-cc3a-4756-9bb7-c4a8ea4d89c7.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "none", | ||
"comment": "Update tests to use `parameterizeSuite`", | ||
"packageName": "@ni/nimble-components", | ||
"email": "20542556+mollykreis@users.noreply.github.com", | ||
"dependentChangeType": "none" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export { parameterizeSpec } from './parameterized.js'; | ||
export { parameterizeSpec } from './parameterize-spec.js'; | ||
export { parameterizeSuite } from './parameterize-suite.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { parameterize } from './parameterize.js'; | ||
import { ObjectFromNamedList, Spec, SpecOverride } from './types.js'; | ||
|
||
/** | ||
* Used to create a parameterized test using an array of tests with names. | ||
* In the following example: | ||
* - the test named `cats-and-dogs` is focused for debugging | ||
* - the test named `frogs` is configured to always be disabled | ||
* - the test named `men` will run normally as it has no override | ||
* @example | ||
* const rainTests = [ | ||
* { name: 'cats-and-dogs', type: 'idiom' }, | ||
* { name: 'frogs' type: 'idiom'}, | ||
* { name: 'men', type: 'lyrics'} | ||
* ] as const; | ||
* describe('Different rains', () => { | ||
* parameterizeSpec(rainTests, (spec, name, value) => { | ||
* spec(`of type ${name} exist`, () => { | ||
* expect(value.type).toBeDefined(); | ||
* }); | ||
* }, { | ||
* 'cats-and-dogs': fit, | ||
* frogs: xit | ||
* }); | ||
* }); | ||
*/ | ||
export const parameterizeSpec = <T extends readonly { name: string }[]>( | ||
list: T, | ||
test: ( | ||
spec: Spec, | ||
name: keyof ObjectFromNamedList<T>, | ||
value: T[number] | ||
) => void, | ||
specOverrides?: { | ||
[P in keyof ObjectFromNamedList<T>]?: SpecOverride; | ||
} | ||
): void => { | ||
const testCases = list.reduce<{ [key: string]: { name: string } }>( | ||
(result, entry) => { | ||
if (result[entry.name]) { | ||
throw new Error( | ||
`Duplicate name found in test case list: ${entry.name}. Make sure all test names are unique.` | ||
); | ||
} | ||
result[entry.name] = entry; | ||
return result; | ||
}, | ||
{} | ||
) as ObjectFromNamedList<T>; | ||
parameterize<ObjectFromNamedList<T>>('spec', testCases, test, specOverrides); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { parameterize } from './parameterize.js'; | ||
import { ObjectFromNamedList, Suite, SuiteOverride } from './types.js'; | ||
|
||
/** | ||
* Used to create a parameterized suite using an array of test scenarios with names. | ||
* In the following example: | ||
* - the suite named `cats-and-dogs` is focused for debugging | ||
* - the suite named `frogs` is configured to always be disabled | ||
* - the suite named `men` will run normally as it has no override | ||
* @example | ||
* const rainTests = [ | ||
* { name: 'cats-and-dogs', type: 'idiom' }, | ||
* { name: 'frogs' type: 'idiom'}, | ||
* { name: 'men', type: 'lyrics'} | ||
* ] as const; | ||
* parameterizeSuite(rainTests, (suite, name, value) => { | ||
* suite(`with ${name}`, () => { | ||
* it('expect type to be defined', () => { | ||
* expect(value.type).toBeDefined(); | ||
* }); | ||
* | ||
* it('expect type to have a non-zero length', () => { | ||
* const length = value.type.length; | ||
* expect(length).toBeGreaterThan(0); | ||
* }); | ||
* }); | ||
* }, { | ||
* 'cats-and-dogs': fdescribe, | ||
* frogs: xdescribe | ||
* }); | ||
*/ | ||
export const parameterizeSuite = <T extends readonly { name: string }[]>( | ||
list: T, | ||
test: ( | ||
suite: Suite, | ||
name: keyof ObjectFromNamedList<T>, | ||
value: T[number] | ||
) => void, | ||
specOverrides?: { | ||
[P in keyof ObjectFromNamedList<T>]?: SuiteOverride; | ||
} | ||
): void => { | ||
const testCases = list.reduce<{ [key: string]: { name: string } }>( | ||
(result, entry) => { | ||
if (result[entry.name]) { | ||
throw new Error( | ||
`Duplicate name found in test suite list: ${entry.name}. Make sure all test suite names are unique.` | ||
); | ||
} | ||
result[entry.name] = entry; | ||
return result; | ||
}, | ||
{} | ||
) as ObjectFromNamedList<T>; | ||
parameterize<ObjectFromNamedList<T>>('suite', testCases, test, specOverrides); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { Spec, SpecOverride, Suite, SuiteOverride } from './types.js'; | ||
|
||
/** | ||
* Used to create a parameterized test or suite using an object of names and arbitrary test values. | ||
* In the following example: | ||
* - the test named `catsAndDogs` is focused for debugging | ||
* - the test named `frogs` is configured to always be disabled | ||
* - the test named `men` will run normally as it has no override | ||
* @example | ||
* const rainTests = { | ||
* catsAndDogs: 'idiom', | ||
* frogs: 'idiom', | ||
* men: 'lyrics' | ||
* } as const; | ||
* describe('Different rains', () => { | ||
* parameterize('spec', rainTests, (spec, name, value) => { | ||
* spec(`of type ${name} exist`, () => { | ||
* expect(value).toBeDefined(); | ||
* }); | ||
* }, { | ||
* catsAndDogs: fit, | ||
* frogs: xit | ||
* }); | ||
* }); | ||
*/ | ||
export function parameterize<T extends object>( | ||
testType: 'spec', | ||
testCases: T, | ||
test: (spec: Spec, name: keyof T, value: T[keyof T]) => void, | ||
overrides?: { | ||
[P in keyof T]?: SpecOverride; | ||
} | ||
): void; | ||
export function parameterize<T extends object>( | ||
testType: 'suite', | ||
testCases: T, | ||
test: (spec: Suite, name: keyof T, value: T[keyof T]) => void, | ||
overrides?: { | ||
[P in keyof T]?: SuiteOverride; | ||
} | ||
): void; | ||
export function parameterize<T extends object, U = Spec | Suite>( | ||
testType: 'spec' | 'suite', | ||
testCases: T, | ||
test: (spec: U, name: keyof T, value: T[keyof T]) => void, | ||
overrides?: { | ||
[P in keyof T]?: U extends Spec ? SpecOverride : SuiteOverride; | ||
} | ||
): void { | ||
const testCaseNames = Object.keys(testCases) as (keyof T)[]; | ||
if (overrides) { | ||
const overrideNames = Object.keys( | ||
overrides | ||
) as (keyof typeof overrides)[]; | ||
if ( | ||
!overrideNames.every(overrideName => testCaseNames.includes(overrideName)) | ||
) { | ||
throw new Error( | ||
'Parameterized test override names must match test case name' | ||
); | ||
} | ||
if ( | ||
testType === 'spec' | ||
// eslint-disable-next-line no-restricted-globals | ||
&& !overrideNames.every(overrideName => [fit, xit].includes(overrides[overrideName] as Spec)) | ||
) { | ||
throw new Error('Must configure override with one of the jasmine spec functions: fit or xit'); | ||
} | ||
if ( | ||
testType === 'suite' | ||
// eslint-disable-next-line no-restricted-globals | ||
&& !overrideNames.every(overrideName => [fdescribe, xdescribe].includes(overrides[overrideName] as Suite)) | ||
) { | ||
throw new Error( | ||
'Must configure override with one of the jasmine suite functions: fdescribe or xdescribe' | ||
); | ||
} | ||
} | ||
testCaseNames.forEach(testCaseName => { | ||
const defaultTest = testType === 'spec' ? it : describe; | ||
const spec = overrides?.[testCaseName] ?? defaultTest; | ||
test(spec as U, testCaseName, testCases[testCaseName]); | ||
}); | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.