2021-04-17 08:38:45 +02:00
|
|
|
// Copyright: Ankitects Pty Ltd and contributors
|
|
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
|
|
|
|
import * as pb from "anki/backend_proto";
|
|
|
|
import { DeckConfigState } from "./lib";
|
2021-04-17 13:00:10 +02:00
|
|
|
import { get } from "svelte/store";
|
2021-04-17 08:38:45 +02:00
|
|
|
|
|
|
|
const exampleData = {
|
|
|
|
allConfig: [
|
|
|
|
{
|
|
|
|
config: {
|
|
|
|
id: "1",
|
|
|
|
name: "Default",
|
|
|
|
mtimeSecs: "1618570764",
|
|
|
|
usn: -1,
|
|
|
|
config: {
|
|
|
|
learnSteps: [1, 10],
|
|
|
|
relearnSteps: [10],
|
2021-04-17 13:00:10 +02:00
|
|
|
newPerDay: 10,
|
2021-04-17 08:38:45 +02:00
|
|
|
reviewsPerDay: 200,
|
|
|
|
initialEase: 2.5,
|
|
|
|
easyMultiplier: 1.2999999523162842,
|
|
|
|
hardMultiplier: 1.2000000476837158,
|
|
|
|
intervalMultiplier: 1,
|
|
|
|
maximumReviewInterval: 36500,
|
|
|
|
minimumLapseInterval: 1,
|
|
|
|
graduatingIntervalGood: 1,
|
|
|
|
graduatingIntervalEasy: 4,
|
|
|
|
leechAction: "LEECH_ACTION_TAG_ONLY",
|
|
|
|
leechThreshold: 8,
|
|
|
|
capAnswerTimeToSecs: 60,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
useCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
config: {
|
|
|
|
id: "1618570764780",
|
|
|
|
name: "another one",
|
|
|
|
mtimeSecs: "1618570781",
|
|
|
|
usn: -1,
|
|
|
|
config: {
|
|
|
|
learnSteps: [1, 10, 20, 30],
|
|
|
|
relearnSteps: [10],
|
|
|
|
newPerDay: 40,
|
|
|
|
reviewsPerDay: 200,
|
|
|
|
initialEase: 2.5,
|
|
|
|
easyMultiplier: 1.2999999523162842,
|
|
|
|
hardMultiplier: 1.2000000476837158,
|
|
|
|
intervalMultiplier: 1,
|
|
|
|
maximumReviewInterval: 36500,
|
|
|
|
minimumLapseInterval: 1,
|
|
|
|
graduatingIntervalGood: 1,
|
|
|
|
graduatingIntervalEasy: 4,
|
|
|
|
leechAction: "LEECH_ACTION_TAG_ONLY",
|
|
|
|
leechThreshold: 8,
|
|
|
|
capAnswerTimeToSecs: 60,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
useCount: 1,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
currentDeck: {
|
|
|
|
name: "Default::child",
|
|
|
|
configId: "1618570764780",
|
|
|
|
parentConfigIds: [1],
|
|
|
|
},
|
|
|
|
defaults: {
|
|
|
|
config: {
|
|
|
|
learnSteps: [1, 10],
|
|
|
|
relearnSteps: [10],
|
|
|
|
newPerDay: 20,
|
|
|
|
reviewsPerDay: 200,
|
|
|
|
initialEase: 2.5,
|
|
|
|
easyMultiplier: 1.2999999523162842,
|
|
|
|
hardMultiplier: 1.2000000476837158,
|
|
|
|
intervalMultiplier: 1,
|
|
|
|
maximumReviewInterval: 36500,
|
|
|
|
minimumLapseInterval: 1,
|
|
|
|
graduatingIntervalGood: 1,
|
|
|
|
graduatingIntervalEasy: 4,
|
|
|
|
leechAction: "LEECH_ACTION_TAG_ONLY",
|
|
|
|
leechThreshold: 8,
|
|
|
|
capAnswerTimeToSecs: 60,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-04-17 13:00:10 +02:00
|
|
|
function startingState(): DeckConfigState {
|
|
|
|
return new DeckConfigState(
|
|
|
|
pb.BackendProto.DeckConfigForUpdate.fromObject(exampleData)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
test("start", () => {
|
|
|
|
const state = startingState();
|
2021-04-17 08:38:45 +02:00
|
|
|
expect(state.currentDeck.name).toBe("Default::child");
|
|
|
|
});
|
2021-04-17 13:00:10 +02:00
|
|
|
|
|
|
|
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 });
|
|
|
|
});
|