Skip to content

Commit

Permalink
Finish e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
tansongchen committed Jan 15, 2024
1 parent 63fc6f7 commit fb21373
Show file tree
Hide file tree
Showing 15 changed files with 128 additions and 116 deletions.
5 changes: 1 addition & 4 deletions spec/degenerator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ import _degenerate, {
} from "~/lib/degenerator";
import { describe, it, expect } from "vitest";
import { create, all } from "mathjs";
import type { SVGGlyph } from "~/lib/data";
import { computedGlyphs, rendered } from "./mock";
import { computedGlyphs2 as computedGlyphs } from "./mock";
import { RenderedGlyph } from "~/lib/topology";
import { defaultKeyboard } from "~/lib/templates";
import { computeComponent } from "~/lib/component";

const { randomInt } = create(all, {
randomSeed: "a",
Expand Down
14 changes: 9 additions & 5 deletions spec/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import type {
import { determine } from "~/lib/repertoire";
import { computeComponent } from "~/lib/component";

export const repertoire: PrimitiveRepertoire = listToObject(rawrepertoire);
export const rendered = determine(repertoire);
export const repertoire = determine(listToObject(rawrepertoire));
export const computedGlyphs = Object.fromEntries(
Object.entries(rendered)
.filter(([k, v]) => v.glyph?.type === "component")
Object.entries(repertoire)
.filter(([k, v]) => v.glyph?.type === "basic_component")
.map(([k, v]) => {
const glyph = (v.glyph as BasicComponent).strokes;
return [k, computeComponent(k, glyph).glyph];
return [k, computeComponent(k, glyph)];
}),
);
export const computedGlyphs2 = Object.fromEntries(
Object.entries(computedGlyphs).map(([k, v]) => {
return [k, v.glyph];
}),
);
14 changes: 11 additions & 3 deletions spec/selector.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,20 @@ import {
Scheme,
} from "~/lib/selector";
import select from "~/lib/selector";
import { rendered } from "./mock";
import { computedGlyphs, repertoire } from "./mock";
import { defaultKeyboard } from "~/lib/templates";
import { Config } from "~/lib/config";

const config = defaultKeyboard;
const config: Config = {
source: null,
form: defaultKeyboard,
encoder: {
sources: {},
conditions: {},
},
};

const {} = rendered;
const {} = computedGlyphs;

const rootMap = new Map<number, string>();

Expand Down
2 changes: 1 addition & 1 deletion spec/topology.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { StrokeRelation } from "~/lib/topology";
import findTopology, { curveRelation, renderSVGGlyph } from "~/lib/topology";
import { CubicCurve, LinearCurve, area, render } from "~/lib/bezier";
import type { Draw, Point } from "~/lib/data";
import { computedGlyphs } from "./mock";
import { computedGlyphs2 as computedGlyphs } from "./mock";
import { getIntervalPosition, makeCurve } from "~/lib/bezier";

describe("interval position", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/CharacterQuery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export default function ({ setFilter }: StrokeSearchProps) {
const tags = useAtomValue(tagsAtom);
return (
<QueryFilter<CharacterFilter>
onValuesChange={async (values) => setFilter(values)}
onValuesChange={async (_, values) => setFilter(values)}
labelWidth="auto"
submitter={false}
style={{ maxWidth: 1080 }}
Expand Down
24 changes: 19 additions & 5 deletions src/lib/affine.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { add } from "mathjs";
import { Draw, Operator, Point, SVGGlyph, SVGStroke } from "./data";
import { Compound, Draw, Operator, Point, SVGGlyph, SVGStroke } from "./data";
import { deepcopy } from "./utils";

class Affine {
Expand Down Expand Up @@ -79,10 +79,24 @@ const affineMap: Record<Operator, Affine[]> = {
"⿻": [id, id],
};

export function affineMerge(operator: Operator, glyphList: SVGGlyph[]) {
const result: SVGGlyph[] = [];
export function affineMerge(compound: Compound, glyphList: SVGGlyph[]) {
const { operator, order } = compound;
const transformedGlyphs: SVGGlyph[] = [];
for (const [index, affine] of affineMap[operator].entries()) {
result.push(affine.transformSVGGlyph(glyphList[index]!));
const transformed = affine.transformSVGGlyph(glyphList[index]!);
transformedGlyphs.push(transformed);
}
return result.flat();
if (order === undefined) return transformedGlyphs.flat();
const result: SVGGlyph = [];
for (const { index, strokes } of order) {
const glyph = transformedGlyphs[index];
if (glyph === undefined) continue;
if (strokes === 0) {
result.push(...glyph);
} else {
result.push(...glyph.slice(0, strokes));
transformedGlyphs[index] = glyph.slice(strokes);
}
}
return result;
}
28 changes: 16 additions & 12 deletions src/lib/component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { KeyboardConfig, SieveName } from "./config";
import type { Config, KeyboardConfig, SieveName } from "./config";
import type {
DerivedComponent,
Compound,
Expand All @@ -15,7 +15,6 @@ import type { RenderedGlyph, Topology } from "./topology";
import findTopology, { renderSVGGlyph } from "./topology";
import type { Classifier } from "./classifier";
import { isValidCJKChar, isValidChar } from "./utils";
import defaultClassifier from "./classifier";
import { affineMerge } from "./affine";

class InvalidGlyphError extends Error {}
Expand Down Expand Up @@ -54,10 +53,10 @@ export class MultipleSchemeError extends Error {}
const getComponentScheme = function (
component: ComputedComponent,
rootData: ComputedComponent[],
config: KeyboardConfig,
config: Config,
classifier: Classifier,
): ComponentResult | NoSchemeError | MultipleSchemeError {
const { mapping } = config;
const { mapping } = config.form;
if (mapping[component.name])
return {
sequence: [component.name],
Expand Down Expand Up @@ -176,7 +175,7 @@ export const recursiveRenderCompound = function (
glyphCache.set(char, rendered);
}
}
return affineMerge(compound.operator, glyphs);
return affineMerge(compound, glyphs);
};

export const computeComponent = (name: string, glyph: SVGGlyph) => {
Expand All @@ -190,25 +189,30 @@ export const computeComponent = (name: string, glyph: SVGGlyph) => {
return cache;
};

export const renderRootList = (data: Repertoire, config: KeyboardConfig) => {
const { mapping, grouping } = config;
const glyphCache = new Map<string, SVGGlyph>();
export const renderRootList = (repertoire: Repertoire, config: Config) => {
const { mapping, grouping } = config.form;
const roots = [...Object.keys(mapping), ...Object.keys(grouping)].filter(
(x) => data[x] !== undefined,
(x) => repertoire[x] !== undefined,
);
const rootList: ComputedComponent[] = [];
for (const root of roots) {
const glyph = data[root]?.glyph;
if (glyph?.type === "basic_component") {
const glyph = repertoire[root]?.glyph;
if (glyph === undefined) continue;
if (glyph.type === "basic_component") {
rootList.push(computeComponent(root, glyph.strokes));
} else {
const rendered = recursiveRenderCompound(glyph, repertoire);
if (rendered instanceof Error) continue;
const cache = computeComponent(root, rendered);
rootList.push(cache);
}
}
return rootList;
};

export const disassembleComponents = function (
data: Repertoire,
config: KeyboardConfig,
config: Config,
classifier: Classifier,
): [ComponentCache, string[]] {
const rootList = renderRootList(data, config);
Expand Down
2 changes: 0 additions & 2 deletions src/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ export type SieveName =

export type Selector = SieveName[];

export type PartialClassifier = Partial<Classifier>;

export type Element = string;

export type Key = string | { element: string; index: number };
Expand Down
5 changes: 3 additions & 2 deletions src/lib/degenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
isCollinear,
sortTwoNumbers,
} from "./bezier";
import { Degenerator, FormConfig } from "./config";
import { Config, Degenerator, KeyboardConfig } from "./config";
import { Feature } from "./classifier";
import { ComputedComponent } from "./component";

Expand All @@ -26,6 +26,7 @@ export const binaryToIndices = (n: number) => (binary: number) => {

export const defaultDegenerator: Degenerator = {
feature: {
: "横",
: "点",
} as Record<Feature, Feature>,
no_cross: false,
Expand Down Expand Up @@ -89,7 +90,7 @@ const verifySpecialRoots = (
};

export const generateSliceBinaries = (
config: FormConfig,
config: Config,
component: ComputedComponent,
root: ComputedComponent,
) => {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Config, Rule } from "./config";
import type { TotalResult } from "./encoder";

export interface Extra {
rootSequence: Record<string, number[]>;
rootSequence: Map<string, number[]>;
}

interface Base {
Expand Down Expand Up @@ -214,7 +214,7 @@ export const findElement = (
case "二笔": {
root = getindex(sequence, object.rootIndex);
if (root === undefined) return undefined;
strokes = extra.rootSequence[root];
strokes = extra.rootSequence.get(root);
if (strokes === undefined) {
if (Math.abs(object.strokeIndex) === 1) return root;
return undefined;
Expand Down
36 changes: 20 additions & 16 deletions src/lib/repertoire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ComponentResult,
disassembleComponents,
recursiveRenderComponent,
recursiveRenderCompound,
} from "./component";
import { disassembleCompounds } from "./compound";
import { Config, CustomGlyph, KeyboardConfig } from "./config";
Expand Down Expand Up @@ -63,7 +64,7 @@ export const determine = (
export const getAnalysisCore = (data: Repertoire, config: Config) => {
const [componentCache, componentError] = disassembleComponents(
data,
config.form,
config,
mergeClassifier(config.analysis?.classifier),
);
const customizations: ComponentCache = new Map(
Expand All @@ -90,27 +91,30 @@ export const getAnalysisCore = (data: Repertoire, config: Config) => {
};
};

const getExtra = function (data: Repertoire, config: Config): Extra {
const getExtra = function (repertoire: Repertoire, config: Config): Extra {
const { mapping, grouping } = config.form;
const roots = Object.keys(mapping).concat(Object.keys(grouping));
const classifier = mergeClassifier(config.analysis?.classifier);
const findSequence = (x: string) => {
if (data[x] === undefined) {
// 单笔画
return [Number(x)];
if (x.match(/[0-9]+/)) {
return [...x].map(Number);
}
try {
const sequence = [1];
if (sequence instanceof Error) {
return [];
}
return sequence;
} catch {
const glyph = repertoire[x]?.glyph;
if (glyph === undefined) {
return [];
}
if (glyph.type === "basic_component") {
return glyph.strokes.map((s) => classifier[s.feature]);
} else {
const sequence = recursiveRenderCompound(glyph, repertoire);
if (sequence instanceof Error) return [];
return sequence.map((s) => classifier[s.feature]);
}
};
const rootSequence = Object.fromEntries(
roots.map((x) => [x, findSequence(x)]),
);
const rootSequence = new Map<string, number[]>();
const roots = Object.keys(mapping).concat(Object.keys(grouping));
for (const root of roots) {
rootSequence.set(root, findSequence(root));
}
return {
rootSequence,
};
Expand Down
11 changes: 5 additions & 6 deletions src/lib/selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import {
type ComputedComponent,
NoSchemeError,
} from "./component";
import type { FormConfig, SieveName } from "./config";
import type { Config, SieveName } from "./config";
import { binaryToIndices } from "./degenerator";
import { type CurveRelation } from "./topology";
import { isEqual } from "lodash-es";
import { sortTwoNumbers } from "./bezier";

export const defaultSelector: SieveName[] = [
"结构完整",
"根少优先",
"能连不交",
"能散不连",
Expand All @@ -26,7 +27,7 @@ interface Sieve<T extends Comparable> {
key: (
scheme: Scheme,
component: ComputedComponent,
config: FormConfig,
config: Config,
rootMap: Map<number, string>,
) => T;
display?: (data: T) => string;
Expand Down Expand Up @@ -121,7 +122,7 @@ export const similar: Sieve<number> = {
title: "非形近根",
key: (scheme, _, config, rootMap) => {
const roots = scheme.map((x) => rootMap.get(x)!);
return roots.filter((x) => config.grouping[x] !== undefined).length;
return roots.filter((x) => config.form.grouping[x] !== undefined).length;
},
};

Expand Down Expand Up @@ -267,10 +268,8 @@ export const sieveMap = new Map<SieveName, Sieve<number> | Sieve<number[]>>(
].map((x) => [x.title, x]),
);

type Evaluation = Map<SieveName, number | number[]>;

const select = (
config: FormConfig,
config: Config,
component: ComputedComponent,
schemeList: Scheme[],
rootMap: Map<number, string>,
Expand Down
16 changes: 8 additions & 8 deletions src/lib/templates.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import type {
Analysis,
Config,
KeyboardConfig,
PartialClassifier,
} from "./config";
import { Classifier } from "./classifier";
import type { Analysis, Config, KeyboardConfig } from "./config";
import { defaultDegenerator } from "./degenerator";
import { examples } from "./example";
import { defaultSelector } from "./selector";
Expand All @@ -23,8 +19,8 @@ export const classifierTypes = [
"郑码七分类",
] as const;
export type ClassifierType = (typeof classifierTypes)[number];
const classifierMap: Record<ClassifierType, PartialClassifier> = {
国标五分类: {},
const classifierMap: Record<ClassifierType, Classifier> = {
国标五分类: {} as Classifier,
表形码六分类: examples.mswb.analysis!.classifier!,
郑码七分类: examples.zhengma.analysis!.classifier!,
};
Expand Down Expand Up @@ -72,6 +68,10 @@ export const createConfig = function (starter: StarterType): Config {
version: APP_VERSION,
source: null,
info: getInfo(starter.name),
analysis: {
...defaultAnalysis,
classifier: classifierMap[starter.data]!,
},
form: keyboardMap[starter.keyboard],
encoder: encoderMap[starter.encoder],
};
Expand Down
Loading

0 comments on commit fb21373

Please sign in to comment.