mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-28 00:58:11 +08:00
finish tests for world (#340)
* Create Release_Validation_Recipe.md * nameCreators test and better error handling * add test for createObsDimensionMap * add last set of tests for world module
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Test cases for nameCreators.js.
|
||||
*/
|
||||
import {
|
||||
layoutDimensionName,
|
||||
obsAnnoDimensionName,
|
||||
diffexpDimensionName,
|
||||
userDefinedDimensionName,
|
||||
makeContinuousDimensionName
|
||||
} from "../../src/util/nameCreators";
|
||||
|
||||
describe("nameCreators", () => {
|
||||
const nameCreators = [
|
||||
layoutDimensionName,
|
||||
obsAnnoDimensionName,
|
||||
diffexpDimensionName,
|
||||
userDefinedDimensionName
|
||||
];
|
||||
|
||||
test("check for namespace isolation", () => {
|
||||
const foo = "foo";
|
||||
nameCreators.forEach(fn => expect(fn(foo)).not.toBe(foo));
|
||||
|
||||
const bar = "bar";
|
||||
nameCreators.forEach(fn => expect(fn(foo)).not.toBe(fn(bar)));
|
||||
|
||||
nameCreators.forEach(fn => {
|
||||
const allOtherFn = nameCreators.filter(elmnt => elmnt !== fn);
|
||||
allOtherFn.forEach(otherFn => expect(fn(foo)).not.toBe(otherFn(foo)));
|
||||
});
|
||||
});
|
||||
|
||||
test("check for legal keys", () => {
|
||||
/* need namespace creators to return strings only */
|
||||
nameCreators.forEach(fn => expect(fn("X")).toMatch(/X/));
|
||||
});
|
||||
});
|
||||
|
||||
describe("makeContinuousDimensionName", () => {
|
||||
test("namespaces", () => {
|
||||
expect(makeContinuousDimensionName({ isObs: true }, "OK")).toMatch(/OK/);
|
||||
expect(makeContinuousDimensionName({ isDiffExp: true }, "OK")).toMatch(
|
||||
/OK/
|
||||
);
|
||||
expect(makeContinuousDimensionName({ isUserDefined: true }, "OK")).toMatch(
|
||||
/OK/
|
||||
);
|
||||
});
|
||||
|
||||
test("error handling", () => {
|
||||
expect(() => makeContinuousDimensionName({}, "oops")).toThrow();
|
||||
expect(() =>
|
||||
makeContinuousDimensionName(
|
||||
{ isObs: false, isDiffExp: false, isUserDefined: false },
|
||||
"oops"
|
||||
)
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
makeContinuousDimensionName({ isObs: true }, "OK")
|
||||
).not.toThrow();
|
||||
expect(() =>
|
||||
makeContinuousDimensionName({ isDiffExp: true }, "OK")
|
||||
).not.toThrow();
|
||||
expect(() =>
|
||||
makeContinuousDimensionName({ isUserDefined: true }, "OK")
|
||||
).not.toThrow();
|
||||
});
|
||||
});
|
||||
@@ -3,15 +3,40 @@ import * as Universe from "../../../src/util/stateManager/universe";
|
||||
import * as World from "../../../src/util/stateManager/world";
|
||||
import Crossfilter from "../../../src/util/typedCrossfilter";
|
||||
import * as REST from "./sampleResponses";
|
||||
import { obsAnnoDimensionName } from "../../../src/util/nameCreators";
|
||||
import {
|
||||
obsAnnoDimensionName,
|
||||
layoutDimensionName
|
||||
} from "../../../src/util/nameCreators";
|
||||
import * as kvCache from "../../../src/util/stateManager/keyvalcache";
|
||||
|
||||
/*
|
||||
TODO: endpoints to test:
|
||||
|
||||
createObsDimensionMap(crossfilter, world)
|
||||
subsetVarData(world, universe, varData)
|
||||
|
||||
Helper - creates universe, world, corssfilter and dimensionMap from
|
||||
the default REST test response.
|
||||
*/
|
||||
const defaultBigBang = () => {
|
||||
/* create unverse, world, crossfilter and dimensionMap */
|
||||
/* create universe */
|
||||
const universe = Universe.createUniverseFromRestV02Response(
|
||||
REST.config,
|
||||
REST.schema,
|
||||
REST.annotationsObs,
|
||||
REST.annotationsVar,
|
||||
REST.layoutObs
|
||||
);
|
||||
/* create world */
|
||||
const world = World.createWorldFromEntireUniverse(universe);
|
||||
/* create crossfilter */
|
||||
const crossfilter = Crossfilter(world.obsAnnotations);
|
||||
/* create dimension map */
|
||||
const dimensionMap = World.createObsDimensionMap(crossfilter, world);
|
||||
|
||||
return {
|
||||
universe,
|
||||
world,
|
||||
crossfilter,
|
||||
dimensionMap
|
||||
};
|
||||
};
|
||||
|
||||
describe("createWorldFromEntireUniverse", () => {
|
||||
test("create from REST sample", () => {
|
||||
@@ -55,24 +80,14 @@ describe("createWorldFromEntireUniverse", () => {
|
||||
|
||||
describe("createWorldFromCurrentSelection", () => {
|
||||
test("create from REST sample", () => {
|
||||
/* create universe */
|
||||
const universe = Universe.createUniverseFromRestV02Response(
|
||||
REST.config,
|
||||
REST.schema,
|
||||
REST.annotationsObs,
|
||||
REST.annotationsVar,
|
||||
REST.layoutObs
|
||||
);
|
||||
/* create world */
|
||||
const originalWorld = World.createWorldFromEntireUniverse(universe);
|
||||
/* create crossfilter */
|
||||
const crossfilter = Crossfilter(originalWorld.obsAnnotations);
|
||||
|
||||
/* fake a selection */
|
||||
const dimensionMap = World.createObsDimensionMap(
|
||||
const {
|
||||
universe,
|
||||
world: originalWorld,
|
||||
crossfilter,
|
||||
originalWorld
|
||||
);
|
||||
dimensionMap
|
||||
} = defaultBigBang();
|
||||
|
||||
/* mock a selection */
|
||||
dimensionMap[obsAnnoDimensionName("field1")].filterRange([0, 5]);
|
||||
dimensionMap[obsAnnoDimensionName("field3")].filterExact(false);
|
||||
|
||||
@@ -128,3 +143,87 @@ describe("createWorldFromCurrentSelection", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("createObsDimensionMap", () => {
|
||||
test("when universe eq world", () => {
|
||||
/*
|
||||
check for:
|
||||
- creates a dimension for all obsAnnotations, PLUS X/Y layout
|
||||
- check that dimension typing is sane
|
||||
*/
|
||||
|
||||
const { dimensionMap } = defaultBigBang();
|
||||
|
||||
const schemaByObsName = _.keyBy(REST.schema.schema.annotations.obs, "name");
|
||||
expect(dimensionMap).toBeDefined();
|
||||
REST.annotationsObs.names.forEach(name => {
|
||||
const dim = dimensionMap[obsAnnoDimensionName(name)];
|
||||
const { type } = schemaByObsName[name];
|
||||
if (type === "string" || type === "boolean" || type === "categorical") {
|
||||
expect(dim).toBeInstanceOf(Crossfilter.EnumDimension);
|
||||
} else {
|
||||
expect(dim).toBeInstanceOf(Crossfilter.ScalarDimension);
|
||||
}
|
||||
});
|
||||
expect(dimensionMap[layoutDimensionName("X")]).toBeInstanceOf(
|
||||
Crossfilter.ScalarDimension
|
||||
);
|
||||
expect(dimensionMap[layoutDimensionName("Y")]).toBeInstanceOf(
|
||||
Crossfilter.ScalarDimension
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("subsetVarData", () => {
|
||||
test("when world eq universe", () => {
|
||||
const { universe, world } = defaultBigBang();
|
||||
/* create a mock varData array for subsetting */
|
||||
const sourceVarData = new Float32Array(universe.nObs);
|
||||
|
||||
/* expect literally the same object back */
|
||||
const result = World.subsetVarData(world, universe, sourceVarData);
|
||||
expect(result).toBe(sourceVarData);
|
||||
});
|
||||
|
||||
test("when world neq universe", () => {
|
||||
const { universe, world, crossfilter, dimensionMap } = defaultBigBang();
|
||||
/* create a mock varData array for subsetting */
|
||||
const sourceVarData = Float32Array.from(_.range(universe.nObs));
|
||||
|
||||
/* mock a selection */
|
||||
dimensionMap[obsAnnoDimensionName("field1")].filterRange([0, 5]);
|
||||
dimensionMap[obsAnnoDimensionName("field3")].filterExact(false);
|
||||
|
||||
/* create the world from the selection */
|
||||
const newWorld = World.createWorldFromCurrentSelection(
|
||||
universe,
|
||||
world,
|
||||
crossfilter
|
||||
);
|
||||
|
||||
/* expect a subset */
|
||||
const result = World.subsetVarData(newWorld, universe, sourceVarData);
|
||||
expect(result).not.toBe(sourceVarData);
|
||||
expect(result).toHaveLength(newWorld.nObs);
|
||||
/* check that we have expected source var content */
|
||||
expect(result).toMatchObject(new Float32Array([0, 2]));
|
||||
});
|
||||
});
|
||||
|
||||
describe("createVarDimension", () => {
|
||||
/* create default universe */
|
||||
const { world, crossfilter } = defaultBigBang();
|
||||
/* create a mock var data cache */
|
||||
const varDataCache = kvCache.set(
|
||||
kvCache.create(),
|
||||
"GENE",
|
||||
Float32Array.from(_.range(world.nObs))
|
||||
);
|
||||
const result = World.createVarDimension(
|
||||
world,
|
||||
varDataCache,
|
||||
crossfilter,
|
||||
"GENE"
|
||||
);
|
||||
expect(result).toBeInstanceOf(Crossfilter.ScalarDimension);
|
||||
});
|
||||
|
||||
@@ -37,6 +37,8 @@ export const makeContinuousDimensionName = (continuousNamespace, key) => {
|
||||
name = diffexpDimensionName(key);
|
||||
} else if (continuousNamespace.isUserDefined) {
|
||||
name = userDefinedDimensionName(key);
|
||||
} else {
|
||||
throw new Error("unknown continuous dimension");
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
Reference in New Issue
Block a user