mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-01 18:08:11 +08:00
TS Revert (1) (#2402)
* revert all commits to before Typescript migration * update compat workflow to match latest deps (#2335) * update compat workflow to match latest deps * attempt to debug * attempt to debug * remove debugging code * typo * update deps to match desktop (#2340) * fix: don't run lint with `--fix` on push tests (#2273) * fix: don't run lint with `--fix` on push tests * npx Co-authored-by: maniarathi <mani.arathi@gmail.com> Co-authored-by: Madison Dunitz <madison.dunitz@chanzuckerberg.com> * rename X_approx_distribution to X_approximate_distribution (#2337) * Correctly handle non-finite numbers in heuristic determination of X distribution (#2342) * handle non-finites explicitly * improve and test edge case handling for distribution estimation * revert debugging changes * code readability * clean up type inferencing (#2332) * unit tests for 64 bit conversion * clean up type handling * type inference tests * more type inference fixes * use schema to determine user intent for data typing * stop using deprecated API * fbs type encoding test * add missing test * add more tests * correctly infer X type for CXG adaptor * lint * fix typo * ts migration * cleanup from PR review * lint * PR review changes * remove unused packages from client (#2359) * remove unused packages from client * add missing peer dep * fix: disable FE auth testing on compatibility tests (#2377) * update: release process (#2277) Co-authored-by: maniarathi <mani.arathi@gmail.com> * fix: remove spaces in param setup (#2380) * delete deploy workflow (#2396) * undo reformatting which now does not pass lint * fix snapshots which changed due to npm dep changes * add missing quoting to snapshot * another snapshot typo fix * TS Revert (2) - replay PR #2347 and #2354 (#2403) * replay edits from PR 2347 * TS Revert (3) - replay edits in PR #2327 (#2404) * replay edits in PR 2327 * TS Revert (4) - replay PR #2355 (#2405) * replay edits in PR 2355 * add additional babel config * reformat with new prettier config Co-authored-by: Severiano Badajoz <sbadajoz@chanzuckerberg.com> Co-authored-by: maniarathi <mani.arathi@gmail.com> Co-authored-by: Madison Dunitz <madison.dunitz@chanzuckerberg.com>
This commit is contained in:
co-authored by
maniarathi
Madison Dunitz
Severiano Badajoz
parent
295590a7c6
commit
eaae6df5e3
@@ -0,0 +1,322 @@
|
||||
// these TWO statements MUST be first in the file, before any other imports
|
||||
import { enableFetchMocks } from "jest-fetch-mock";
|
||||
import * as serverMocks from "./serverMocks";
|
||||
// OK, continue on!
|
||||
|
||||
import {
|
||||
AnnoMatrixLoader,
|
||||
clip,
|
||||
isubset,
|
||||
isubsetMask,
|
||||
} from "../../../src/annoMatrix";
|
||||
import { Dataframe } from "../../../src/util/dataframe";
|
||||
|
||||
enableFetchMocks();
|
||||
|
||||
describe("AnnoMatrix", () => {
|
||||
let annoMatrix;
|
||||
|
||||
beforeEach(async () => {
|
||||
fetch.resetMocks(); // reset all fetch mocking state
|
||||
annoMatrix = new AnnoMatrixLoader(
|
||||
serverMocks.baseDataURL,
|
||||
serverMocks.schema.schema
|
||||
);
|
||||
});
|
||||
|
||||
describe("basics", () => {
|
||||
test("annomatrix static checks", () => {
|
||||
expect(annoMatrix).toBeDefined();
|
||||
expect(annoMatrix.schema).toMatchObject(serverMocks.schema.schema);
|
||||
expect(annoMatrix.nObs).toEqual(serverMocks.schema.schema.dataframe.nObs);
|
||||
expect(annoMatrix.nVar).toEqual(serverMocks.schema.schema.dataframe.nVar);
|
||||
expect(annoMatrix.isView).toBeFalsy();
|
||||
expect(annoMatrix.viewOf).toBeUndefined();
|
||||
expect(annoMatrix.rowIndex).toBeDefined();
|
||||
});
|
||||
|
||||
test("simple single column fetch", async () => {
|
||||
fetch.once(serverMocks.annotationsObs(["name_0"]));
|
||||
|
||||
const df = await annoMatrix.fetch("obs", "name_0");
|
||||
expect(df).toBeInstanceOf(Dataframe);
|
||||
expect(df.colIndex.labels()).toEqual(["name_0"]);
|
||||
expect(df.dims).toEqual([annoMatrix.nObs, 1]);
|
||||
});
|
||||
|
||||
test("simple multi column fetch", async () => {
|
||||
fetch
|
||||
.once(serverMocks.annotationsObs(["name_0"]))
|
||||
.once(serverMocks.annotationsObs(["n_genes"]));
|
||||
|
||||
await expect(
|
||||
annoMatrix.fetch("obs", ["name_0", "n_genes"])
|
||||
).resolves.toBeInstanceOf(Dataframe);
|
||||
});
|
||||
|
||||
describe("fetch from field", () => {
|
||||
const getLastTwo = async (field) => {
|
||||
const columnNames = annoMatrix.getMatrixColumns(field).slice(-2);
|
||||
fetch.mockResponses(...columnNames.map(() => serverMocks.responder));
|
||||
await expect(
|
||||
annoMatrix.fetch(field, columnNames)
|
||||
).resolves.toBeInstanceOf(Dataframe);
|
||||
};
|
||||
|
||||
test("obs", async () => getLastTwo("obs"));
|
||||
test("var", async () => getLastTwo("var"));
|
||||
test("emb", async () => getLastTwo("emb"));
|
||||
});
|
||||
|
||||
test("fetch - test all query forms", async () => {
|
||||
// single string is a column name
|
||||
fetch.once(serverMocks.annotationsObs(["n_genes"]));
|
||||
await expect(annoMatrix.fetch("obs", "n_genes")).resolves.toBeInstanceOf(
|
||||
Dataframe
|
||||
);
|
||||
|
||||
// array of column names, expecting n_genes to be cached.
|
||||
fetch.once(serverMocks.annotationsObs(["percent_mito"]));
|
||||
await expect(
|
||||
annoMatrix.fetch("obs", ["n_genes", "percent_mito"])
|
||||
).resolves.toBeInstanceOf(Dataframe);
|
||||
|
||||
// more complex value filter query, enumerated
|
||||
fetch.once(serverMocks.responder);
|
||||
await expect(
|
||||
annoMatrix.fetch("X", {
|
||||
where: {
|
||||
field: "var",
|
||||
column: annoMatrix.schema.annotations.var.index,
|
||||
value: "TYMP",
|
||||
},
|
||||
})
|
||||
).resolves.toBeInstanceOf(Dataframe);
|
||||
|
||||
// more complex value filter query, range
|
||||
const varIndex = annoMatrix.schema.annotations.var.index;
|
||||
fetch
|
||||
.once(
|
||||
serverMocks.withExpected("/data/var", [[`var:${varIndex}`, "SUMO3"]])
|
||||
)
|
||||
.once(
|
||||
serverMocks.withExpected("/data/var", [[`var:${varIndex}`, "TYMP"]])
|
||||
);
|
||||
await expect(
|
||||
annoMatrix.fetch("X", [
|
||||
{
|
||||
where: {
|
||||
field: "var",
|
||||
column: varIndex,
|
||||
value: "SUMO3",
|
||||
},
|
||||
},
|
||||
{
|
||||
where: {
|
||||
field: "var",
|
||||
column: varIndex,
|
||||
value: "TYMP",
|
||||
},
|
||||
},
|
||||
])
|
||||
).resolves.toBeInstanceOf(Dataframe);
|
||||
// XXX inspect the wherecache?
|
||||
});
|
||||
|
||||
test("push and pop views", async () => {
|
||||
const am1 = clip(annoMatrix, 0.1, 0.9);
|
||||
expect(am1.viewOf).toBe(annoMatrix);
|
||||
expect(am1.nObs).toEqual(annoMatrix.nObs);
|
||||
expect(am1.nVar).toEqual(annoMatrix.nVar);
|
||||
expect(am1.rowIndex).toBe(annoMatrix.rowIndex);
|
||||
|
||||
const am2 = clip(annoMatrix, 0.1, 0.9);
|
||||
expect(am2.viewOf).toBe(annoMatrix);
|
||||
expect(am2).not.toBe(am1);
|
||||
expect(am2.rowIndex).toBe(annoMatrix.rowIndex);
|
||||
});
|
||||
|
||||
test("schema accessors", () => {
|
||||
expect(annoMatrix.getMatrixFields()).toEqual(
|
||||
expect.arrayContaining(["X", "obs", "emb", "var"])
|
||||
);
|
||||
expect(annoMatrix.getMatrixColumns("obs")).toEqual(
|
||||
expect.arrayContaining(["name_0", "n_genes", "louvain"])
|
||||
);
|
||||
expect(annoMatrix.getColumnSchema("emb", "umap")).toEqual({
|
||||
name: "umap",
|
||||
dims: ["umap_0", "umap_1"],
|
||||
type: "float32",
|
||||
});
|
||||
expect(annoMatrix.getColumnDimensions("emb", "umap")).toEqual([
|
||||
"umap_0",
|
||||
"umap_1",
|
||||
]);
|
||||
});
|
||||
|
||||
/*
|
||||
test the mask & label access to subset via isubset and isubsetMask
|
||||
*/
|
||||
test("isubset", async () => {
|
||||
const rowList = [0, 10];
|
||||
const rowMask = new Uint8Array(annoMatrix.nObs);
|
||||
for (let i = 0; i < rowList.length; i += 1) {
|
||||
rowMask[rowList[i]] = 1;
|
||||
}
|
||||
|
||||
const am1 = isubset(annoMatrix, rowList);
|
||||
const am2 = isubsetMask(annoMatrix, rowMask);
|
||||
expect(am1).not.toBe(am2);
|
||||
expect(am1.nObs).toEqual(2);
|
||||
expect(am1.nObs).toEqual(am2.nObs);
|
||||
expect(am1.nVar).toEqual(am2.nVar);
|
||||
|
||||
fetch
|
||||
.once(serverMocks.annotationsObs(["n_genes"]))
|
||||
.once(serverMocks.annotationsObs(["n_genes"]));
|
||||
const ng1 = await am1.fetch("obs", "n_genes");
|
||||
const ng2 = await am2.fetch("obs", "n_genes");
|
||||
expect(ng1).toHaveLength(ng2.length);
|
||||
expect(ng1.colIndex.labels()).toEqual(ng2.colIndex.labels());
|
||||
expect(ng1.col("n_genes").asArray()).toEqual(
|
||||
ng2.col("n_genes").asArray()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("add/drop column", () => {
|
||||
async function addDrop(base) {
|
||||
expect(base.getMatrixColumns("obs")).not.toContain("foo");
|
||||
fetch.mockRejectOnce(new Error("unknown column name"));
|
||||
await expect(base.fetch("obs", "foo")).rejects.toThrow(
|
||||
"unknown column name"
|
||||
);
|
||||
|
||||
/* add */
|
||||
const am1 = base.addObsColumn(
|
||||
{ name: "foo", type: "float32", writable: true },
|
||||
Float32Array,
|
||||
0
|
||||
);
|
||||
expect(base.getMatrixColumns("obs")).not.toContain("foo");
|
||||
expect(am1.getMatrixColumns("obs")).toContain("foo");
|
||||
const foo = await am1.fetch("obs", "foo");
|
||||
expect(foo).toBeDefined();
|
||||
expect(foo).toBeInstanceOf(Dataframe);
|
||||
expect(foo).toHaveLength(am1.nObs);
|
||||
expect(foo.col("foo").asArray()).toEqual(
|
||||
new Float32Array(am1.nObs).fill(0)
|
||||
);
|
||||
|
||||
/* drop */
|
||||
const am2 = am1.dropObsColumn("foo");
|
||||
expect(base.getMatrixColumns("obs")).not.toContain("foo");
|
||||
expect(am2.getMatrixColumns("obs")).not.toContain("foo");
|
||||
fetch.mockRejectOnce(new Error("unknown column name"));
|
||||
await expect(am2.fetch("obs", "foo")).rejects.toThrow(
|
||||
"unknown column name"
|
||||
);
|
||||
}
|
||||
|
||||
test("add/drop column, without view", async () => {
|
||||
await addDrop(annoMatrix);
|
||||
});
|
||||
|
||||
test("add/drop column, with view", async () => {
|
||||
const am1 = clip(annoMatrix, 0.1, 0.9);
|
||||
await addDrop(am1);
|
||||
|
||||
const am2 = isubset(am1, [0, 1, 2, 20, 30, 400]);
|
||||
await addDrop(am2);
|
||||
|
||||
const am3 = isubset(annoMatrix, [10, 0, 7, 3]);
|
||||
await addDrop(am3);
|
||||
|
||||
const am4 = clip(am3, 0, 1);
|
||||
await addDrop(am4);
|
||||
|
||||
fetch.mockResponse(serverMocks.responder);
|
||||
|
||||
await am1.fetch("obs", am1.getMatrixColumns("obs"));
|
||||
await am2.fetch("obs", am2.getMatrixColumns("obs"));
|
||||
await am3.fetch("obs", am3.getMatrixColumns("obs"));
|
||||
await am4.fetch("obs", am4.getMatrixColumns("obs"));
|
||||
|
||||
fetch.resetMocks();
|
||||
|
||||
await addDrop(am1);
|
||||
await addDrop(am2);
|
||||
await addDrop(am3);
|
||||
await addDrop(am4);
|
||||
});
|
||||
});
|
||||
|
||||
describe("setObsColumnValues", () => {
|
||||
async function addSetDrop(base) {
|
||||
/* add column */
|
||||
let am = base.addObsColumn(
|
||||
{
|
||||
name: "test",
|
||||
type: "categorical",
|
||||
categories: ["unassigned", "red", "green"],
|
||||
writable: true,
|
||||
},
|
||||
Array,
|
||||
"unassigned"
|
||||
);
|
||||
|
||||
const testVal = await am.fetch("obs", "test");
|
||||
expect(testVal.col("test").asArray()).toEqual(
|
||||
new Array(am.nObs).fill("unassigned")
|
||||
);
|
||||
|
||||
/* set values in column */
|
||||
const whichRows = [1, 2, 10];
|
||||
const am1 = await am.setObsColumnValues("test", whichRows, "yo");
|
||||
const testVal1 = await am1.fetch("obs", "test");
|
||||
const expt = new Array(am1.nObs).fill("unassigned");
|
||||
for (let i = 0; i < whichRows.length; i += 1) {
|
||||
const offset = am1.rowIndex.getOffset(whichRows[i]);
|
||||
expt[offset] = "yo";
|
||||
}
|
||||
expect(testVal1).not.toBe(testVal);
|
||||
expect(testVal1.col("test").asArray()).toEqual(expt);
|
||||
expect(am1.getColumnSchema("obs", "test").type).toBe("categorical");
|
||||
expect(am1.getColumnSchema("obs", "test").categories).toEqual(
|
||||
expect.arrayContaining(["unassigned", "red", "green", "yo"])
|
||||
);
|
||||
|
||||
/* drop column */
|
||||
fetch.mockRejectOnce(new Error("unknown column name"));
|
||||
am = am1.dropObsColumn("test");
|
||||
await expect(am.fetch("obs", "test")).rejects.toThrow(
|
||||
"unknown column name"
|
||||
);
|
||||
}
|
||||
|
||||
test("set, without a view", async () => {
|
||||
await addSetDrop(annoMatrix);
|
||||
});
|
||||
|
||||
test("set, with a view", async () => {
|
||||
const am1 = clip(annoMatrix, 0.1, 0.9);
|
||||
await addSetDrop(am1);
|
||||
|
||||
const am2 = isubset(am1, [0, 1, 2, 10, 20, 30, 400]);
|
||||
await addSetDrop(am2);
|
||||
|
||||
const am3 = isubset(annoMatrix, [10, 1, 0, 30, 2]);
|
||||
await addSetDrop(am3);
|
||||
|
||||
fetch.mockResponse(serverMocks.responder);
|
||||
|
||||
await am1.fetch("obs", am1.getMatrixColumns("obs"));
|
||||
await am2.fetch("obs", am2.getMatrixColumns("obs"));
|
||||
await am3.fetch("obs", am3.getMatrixColumns("obs"));
|
||||
|
||||
await addSetDrop(am1);
|
||||
await addSetDrop(am2);
|
||||
await addSetDrop(am3);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user