add some unit tests to deckconfig

This commit is contained in:
Damien Elmes 2021-04-17 21:00:10 +10:00
parent ac46d40db3
commit 633e93904a
3 changed files with 157 additions and 11 deletions

View file

@ -131,5 +131,6 @@ jest_test(
":lib", ":lib",
"//ts/lib:backend_proto", "//ts/lib:backend_proto",
"@npm//protobufjs", "@npm//protobufjs",
"@npm//svelte",
], ],
) )

View file

@ -3,6 +3,7 @@
import * as pb from "anki/backend_proto"; import * as pb from "anki/backend_proto";
import { DeckConfigState } from "./lib"; import { DeckConfigState } from "./lib";
import { get } from "svelte/store";
const exampleData = { const exampleData = {
allConfig: [ allConfig: [
@ -15,7 +16,7 @@ const exampleData = {
config: { config: {
learnSteps: [1, 10], learnSteps: [1, 10],
relearnSteps: [10], relearnSteps: [10],
newPerDay: 20, newPerDay: 10,
reviewsPerDay: 200, reviewsPerDay: 200,
initialEase: 2.5, initialEase: 2.5,
easyMultiplier: 1.2999999523162842, easyMultiplier: 1.2999999523162842,
@ -85,9 +86,149 @@ const exampleData = {
}, },
}; };
test("create", () => { function startingState(): DeckConfigState {
const empty = pb.BackendProto.DeckConfigForUpdate.fromObject(exampleData); return new DeckConfigState(
console.log(empty); pb.BackendProto.DeckConfigForUpdate.fromObject(exampleData)
const state = new DeckConfigState(empty); );
}
test("start", () => {
const state = startingState();
expect(state.currentDeck.name).toBe("Default::child"); expect(state.currentDeck.name).toBe("Default::child");
}); });
test("deck list", () => {
const state = startingState();
expect(get(state.configList)).toStrictEqual([
{
current: true,
idx: 1,
name: "another one",
useCount: 1,
},
{
current: false,
idx: 0,
name: "Default",
useCount: 1,
},
]);
expect(get(state.currentConfig).newPerDay).toBe(40);
// rename
state.setCurrentName("zzz");
expect(get(state.configList)).toStrictEqual([
{
current: false,
idx: 0,
name: "Default",
useCount: 1,
},
{
current: true,
idx: 1,
name: "zzz",
useCount: 1,
},
]);
// add
state.addConfig("hello");
expect(get(state.configList)).toStrictEqual([
{
current: false,
idx: 0,
name: "Default",
useCount: 1,
},
{
current: true,
idx: 2,
name: "hello",
useCount: 1,
},
{
current: false,
idx: 1,
name: "zzz",
useCount: 0,
},
]);
expect(get(state.currentConfig).newPerDay).toBe(20);
// change current
state.setCurrentIndex(0);
expect(get(state.configList)).toStrictEqual([
{
current: true,
idx: 0,
name: "Default",
useCount: 2,
},
{
current: false,
idx: 2,
name: "hello",
useCount: 0,
},
{
current: false,
idx: 1,
name: "zzz",
useCount: 0,
},
]);
expect(get(state.currentConfig).newPerDay).toBe(10);
// can't delete default
expect(() => state.removeCurrentConfig()).toThrow();
// deleting old deck should work
state.setCurrentIndex(1);
state.removeCurrentConfig();
expect(get(state.currentConfig).newPerDay).toBe(10);
// as should newly added one
state.setCurrentIndex(1);
state.removeCurrentConfig();
expect(get(state.currentConfig).newPerDay).toBe(10);
// only the pre-existing deck should be listed for removal
expect((state as any).removedConfigs).toStrictEqual([1618570764780]);
});
test("duplicate name", () => {
const state = startingState();
// duplicate will get renamed
state.addConfig("another one");
expect(get(state.configList).find((e) => e.current)?.name).toMatch(/another.*\d+$/);
// should handle renames too
state.setCurrentName("Default");
expect(get(state.configList).find((e) => e.current)?.name).toMatch(/Default\d+$/);
});
test("parent counts", () => {
const state = startingState();
expect(get(state.parentLimits)).toStrictEqual({ newCards: 10, reviews: 200 });
// adjusting the current deck config won't alter parent
state.currentConfig.update((c) => {
c.newPerDay = 123;
return c;
});
expect(get(state.parentLimits)).toStrictEqual({ newCards: 10, reviews: 200 });
// but adjusting the default config will, since the parent deck uses it
state.setCurrentIndex(0);
state.currentConfig.update((c) => {
c.newPerDay = 123;
return c;
});
// fixme: we should do this automatically when currentConfig is updated, or the
// parent count will become stale
state.saveCurrentConfig();
expect(get(state.parentLimits)).toStrictEqual({ newCards: 123, reviews: 200 });
});

View file

@ -49,8 +49,8 @@ export class DeckConfigState {
private configs: ConfigWithCount[]; private configs: ConfigWithCount[];
private selectedIdx: number; private selectedIdx: number;
private configListSetter?: (val: ConfigListEntry[]) => void; private configListSetter!: (val: ConfigListEntry[]) => void;
private parentLimitsSetter?: (val: ParentLimits) => void; private parentLimitsSetter!: (val: ParentLimits) => void;
private removedConfigs: DeckConfigId[] = []; private removedConfigs: DeckConfigId[] = [];
constructor(data: pb.BackendProto.DeckConfigForUpdate) { constructor(data: pb.BackendProto.DeckConfigForUpdate) {
@ -79,6 +79,11 @@ export class DeckConfigState {
this.parentLimitsSetter = set; this.parentLimitsSetter = set;
return; return;
}); });
// create a temporary subscription to force our setters to be set, so unit
// tests don't get stale results
get(this.configList);
get(this.parentLimits);
} }
setCurrentIndex(index: number): void { setCurrentIndex(index: number): void {
@ -93,12 +98,10 @@ export class DeckConfigState {
saveCurrentConfig(): void { saveCurrentConfig(): void {
const config = get(this.currentConfig); const config = get(this.currentConfig);
if (!isEqual(config, this.configs[this.selectedIdx].config.config)) { if (!isEqual(config, this.configs[this.selectedIdx].config.config)) {
console.log("save");
this.configs[this.selectedIdx].config.config = config; this.configs[this.selectedIdx].config.config = config;
this.configs[this.selectedIdx].config.mtimeSecs = 0; this.configs[this.selectedIdx].config.mtimeSecs = 0;
} else {
console.log("no changes");
} }
this.parentLimitsSetter?.(this.getParentLimits());
} }
getCurrentName(): string { getCurrentName(): string {
@ -148,7 +151,8 @@ export class DeckConfigState {
} }
private ensureNewNameUnique(name: string): string { private ensureNewNameUnique(name: string): string {
if (this.configs.find((e) => e.config.name === name) !== undefined) { const idx = this.configs.findIndex((e) => e.config.name === name);
if (idx !== -1) {
return name + (new Date().getTime() / 1000).toFixed(0); return name + (new Date().getTime() / 1000).toFixed(0);
} else { } else {
return name; return name;