-
Notifications
You must be signed in to change notification settings - Fork 14
New unit tests for singleCellCellType & singleCellGeneExpression tws #4300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,102 @@ | ||||||
| import tape from 'tape' | ||||||
| import { SingleCellCellTypeBase } from '../singleCellCellType.ts' | ||||||
| import { TermTypes } from '#shared/terms.js' | ||||||
|
|
||||||
| /************************* | ||||||
| reusable helper functions | ||||||
| **************************/ | ||||||
|
|
||||||
| function getValidRawTerm(overrides: any = {}) { | ||||||
| return { | ||||||
| type: TermTypes.SINGLECELL_CELL_TYPE, | ||||||
|
||||||
| type: TermTypes.SINGLECELL_CELL_TYPE, | |
| type: TermTypes.SINGLECELL_CELLTYPE, |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| import tape from 'tape' | ||
| import { SingleCellGeneExpressionBase, getSCGEunit } from '../singleCellGeneExpression.ts' | ||
| import { TermTypes } from '#shared/terms.js' | ||
|
|
||
| /************************* | ||
| reusable helper functions | ||
| **************************/ | ||
|
|
||
| const mockVocabApi = { | ||
| termdbConfig: { | ||
| queries: { | ||
| singleCell: { | ||
| geneExpression: { unit: 'log2 CPM' } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| const mockVocabApiNoUnit = { | ||
| termdbConfig: { | ||
| queries: { | ||
| singleCell: { | ||
| geneExpression: {} | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| function getValidRawTerm(overrides: any = {}) { | ||
| return { | ||
| type: TermTypes.SINGLECELL_GENE_EXPRESSION, | ||
| gene: 'TP53', | ||
| sample: 'Tumor cells', | ||
| ...overrides | ||
| } | ||
| } | ||
|
|
||
| /************** | ||
| test sections | ||
| ***************/ | ||
|
|
||
| tape('\n', function (test) { | ||
| test.comment('-***- tw/singleCellGeneExpression -***-') | ||
| test.end() | ||
| }) | ||
|
|
||
| tape('getSCGEunit() should return configured unit and fallback default unit', test => { | ||
| test.equal(getSCGEunit(mockVocabApi as any), 'log2 CPM', 'Should return configured unit from termdbConfig') | ||
| test.equal(getSCGEunit(mockVocabApiNoUnit as any), 'Gene Expression', 'Should fallback to default unit') | ||
| test.end() | ||
| }) | ||
|
|
||
| tape('validate() should throw on invalid terms', test => { | ||
| test.throws( | ||
| () => SingleCellGeneExpressionBase.validate(null as any), | ||
| /term is not an object/, | ||
| 'Should throw when term is not an object' | ||
| ) | ||
|
|
||
| test.throws( | ||
| () => SingleCellGeneExpressionBase.validate({ type: TermTypes.GENE_EXPRESSION } as any), | ||
| /incorrect term.type='geneExpression'/, | ||
| 'Should throw when term.type is incorrect' | ||
| ) | ||
|
|
||
| test.throws( | ||
| () => | ||
| SingleCellGeneExpressionBase.validate({ | ||
| type: TermTypes.SINGLECELL_GENE_EXPRESSION, | ||
| sample: 'Tumor cells' | ||
| } as any), | ||
| /no gene or name present/, | ||
| 'Should throw when both gene and name are missing' | ||
| ) | ||
|
|
||
| test.throws( | ||
| () => | ||
| SingleCellGeneExpressionBase.validate({ | ||
| type: TermTypes.SINGLECELL_GENE_EXPRESSION, | ||
| gene: 123, | ||
| name: 'Bad gene', | ||
| sample: 'Tumor cells' | ||
| } as any), | ||
| /singleCellGeneExpression term.gene must be non-empty string/, | ||
| 'Should throw when gene is not a non-empty string' | ||
| ) | ||
|
|
||
| test.throws( | ||
| () => | ||
| SingleCellGeneExpressionBase.validate({ | ||
| type: TermTypes.SINGLECELL_GENE_EXPRESSION, | ||
| gene: 'TP53' | ||
| } as any), | ||
| /missing sample name/, | ||
| 'Should throw when sample is missing' | ||
| ) | ||
|
|
||
| test.end() | ||
| }) | ||
|
|
||
| tape('fill() should populate missing name and unit', test => { | ||
| const term = getValidRawTerm({ name: undefined, unit: undefined }) | ||
| SingleCellGeneExpressionBase.fill(term as any, { vocabApi: mockVocabApi as any } as any) | ||
|
|
||
| test.equal(term.unit, 'log2 CPM', 'Should set unit from vocabApi') | ||
| test.equal(term.name, 'TP53 log2 CPM', 'Should set generated name from gene and unit') | ||
| test.end() | ||
| }) | ||
|
|
||
| tape('fill() should not overwrite existing name', test => { | ||
| const term = getValidRawTerm({ name: 'Custom label', unit: undefined }) | ||
| SingleCellGeneExpressionBase.fill(term as any, { vocabApi: mockVocabApi as any } as any) | ||
|
|
||
| test.equal(term.name, 'Custom label', 'Should preserve existing name') | ||
| test.equal(term.unit, undefined, 'Should not force unit when name already exists') | ||
| test.end() | ||
| }) | ||
|
|
||
| tape('fill() should no-op for class instances', test => { | ||
| const instance = new SingleCellGeneExpressionBase(getValidRawTerm(), { vocabApi: mockVocabApi as any } as any) | ||
| test.doesNotThrow( | ||
| () => SingleCellGeneExpressionBase.fill(instance as any, { vocabApi: mockVocabApi as any } as any), | ||
| 'Should not throw when fill is called on instance' | ||
| ) | ||
| test.end() | ||
| }) | ||
|
|
||
| tape('constructor should set fields and use configured unit', test => { | ||
| const term = getValidRawTerm({ unit: undefined }) | ||
| const x = new SingleCellGeneExpressionBase(term as any, { vocabApi: mockVocabApi as any } as any) | ||
|
|
||
| test.equal(x.type, TermTypes.SINGLECELL_GENE_EXPRESSION, 'Should set type') | ||
| test.equal(x.gene, 'TP53', 'Should set gene') | ||
| test.equal(x.sample, 'Tumor cells', 'Should set sample') | ||
| test.equal(x.unit, 'log2 CPM', 'Should set configured unit when term.unit is missing') | ||
| test.end() | ||
| }) | ||
|
|
||
| tape('constructor should use default unit when config unit is missing', test => { | ||
| const term = getValidRawTerm({ unit: undefined }) | ||
| const x = new SingleCellGeneExpressionBase(term as any, { vocabApi: mockVocabApiNoUnit as any } as any) | ||
|
|
||
| test.equal(x.unit, 'Gene Expression', 'Should fallback to default unit') | ||
| test.end() | ||
| }) | ||
|
|
||
| tape('constructor should preserve explicit term.unit', test => { | ||
| const term = getValidRawTerm({ unit: 'Custom Unit' }) | ||
| const x = new SingleCellGeneExpressionBase(term as any, { vocabApi: mockVocabApi as any } as any) | ||
|
|
||
| test.equal(x.unit, 'Custom Unit', 'Should preserve explicit term.unit') | ||
| test.end() | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,2 @@ | ||
| Features | ||
| - Expanded integration tests for TermTypeSearch. New unit tests available for the recently added Single-Cell Cell Type and Single-Cell Gene Expression handlers as well as previously implemented Gene Expression, SNP, ssGSEA, and Term Collection handlers. | ||
|
|
||
| Fixes | ||
| - Simplified logic for custom termType2terms vocabulary. Resolved issue with elements from other handlers lingering on tab change and the pills for the singleCellCellType not appearing after clicking away from the Single-Cell Cell Type tab. | ||
|
|
||
| - New unit tests for recently created termwrappers, singleCellCellType and singleCellGeneExpression. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TermTypesdoes not defineSINGLECELL_CELL_TYPE(the existing constant isTermTypes.SINGLECELL_CELLTYPE: 'singleCellCellType'). As written,termTypewill beundefined, which breaks validation/type checks and can let invalid terms pass silently. Update this to use the correctTermTypeskey sotermTyperesolves to'singleCellCellType'.