mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-01 06:22:44 -08:00
Add fallback enqueue when addNote no
This commit is contained in:
@@ -230,6 +230,36 @@ test('proxy ignores addNote when upstream response reports error', async () => {
|
|||||||
assert.deepEqual(processed, []);
|
assert.deepEqual(processed, []);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('proxy falls back to latest added note when addNote returns no IDs', async () => {
|
||||||
|
const processed: number[] = [];
|
||||||
|
const findNotesQueries: string[] = [];
|
||||||
|
const proxy = new AnkiConnectProxyServer({
|
||||||
|
shouldAutoUpdateNewCards: () => true,
|
||||||
|
processNewCard: async (noteId) => {
|
||||||
|
processed.push(noteId);
|
||||||
|
},
|
||||||
|
getDeck: () => 'My "Japanese" Deck',
|
||||||
|
findNotes: async (query) => {
|
||||||
|
findNotesQueries.push(query);
|
||||||
|
return [500, 501];
|
||||||
|
},
|
||||||
|
logInfo: () => undefined,
|
||||||
|
logWarn: () => undefined,
|
||||||
|
logError: () => undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
(proxy as unknown as {
|
||||||
|
maybeEnqueueFromRequest: (request: Record<string, unknown>, responseBody: Buffer) => void;
|
||||||
|
}).maybeEnqueueFromRequest(
|
||||||
|
{ action: 'addNote' },
|
||||||
|
Buffer.from(JSON.stringify({ result: [], error: null }), 'utf8'),
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForCondition(() => processed.length === 1);
|
||||||
|
assert.deepEqual(findNotesQueries, ['"deck:My \\"Japanese\\" Deck" added:1']);
|
||||||
|
assert.deepEqual(processed, [501]);
|
||||||
|
});
|
||||||
|
|
||||||
test('proxy does not fallback-enqueue latest note for multi requests without add actions', async () => {
|
test('proxy does not fallback-enqueue latest note for multi requests without add actions', async () => {
|
||||||
const processed: number[] = [];
|
const processed: number[] = [];
|
||||||
const findNotesQueries: string[] = [];
|
const findNotesQueries: string[] = [];
|
||||||
|
|||||||
@@ -233,7 +233,8 @@ export class AnkiConnectProxyServer {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const deck = this.deps.getDeck ? this.deps.getDeck() : undefined;
|
const deck = this.deps.getDeck ? this.deps.getDeck() : undefined;
|
||||||
const query = deck ? `"deck:${deck}" added:1` : 'added:1';
|
const escapedDeck = deck ? deck.replace(/"/g, '\\"') : null;
|
||||||
|
const query = escapedDeck ? `"deck:${escapedDeck}" added:1` : 'added:1';
|
||||||
const noteIds = await findNotes(query, { maxRetries: 0 });
|
const noteIds = await findNotes(query, { maxRetries: 0 });
|
||||||
if (!noteIds || noteIds.length === 0) {
|
if (!noteIds || noteIds.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ function applyFrequencyMarking(
|
|||||||
return { ...token, frequencyRank: undefined };
|
return { ...token, frequencyRank: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Existing Yomitan frequency ranks take precedence over the local lookup.
|
||||||
|
// Keep this early return to preserve explicitly-supplied values.
|
||||||
if (typeof token.frequencyRank === 'number' && Number.isFinite(token.frequencyRank)) {
|
if (typeof token.frequencyRank === 'number' && Number.isFinite(token.frequencyRank)) {
|
||||||
const rank = Math.max(1, Math.floor(token.frequencyRank));
|
const rank = Math.max(1, Math.floor(token.frequencyRank));
|
||||||
return { ...token, frequencyRank: rank };
|
return { ...token, frequencyRank: rank };
|
||||||
|
|||||||
65
src/token-merger.test.ts
Normal file
65
src/token-merger.test.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import { MergedToken, PartOfSpeech } from './types';
|
||||||
|
import { markNPlusOneTargets } from './token-merger';
|
||||||
|
|
||||||
|
function makeToken(overrides: Partial<MergedToken> = {}): MergedToken {
|
||||||
|
return {
|
||||||
|
surface: '猫',
|
||||||
|
reading: 'ネコ',
|
||||||
|
headword: '猫',
|
||||||
|
startPos: 0,
|
||||||
|
endPos: 1,
|
||||||
|
partOfSpeech: PartOfSpeech.noun,
|
||||||
|
isMerged: false,
|
||||||
|
isKnown: false,
|
||||||
|
isNPlusOneTarget: false,
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
test('markNPlusOneTargets counts only eligible tokens toward minSentenceWords', () => {
|
||||||
|
const tokens = [
|
||||||
|
makeToken({
|
||||||
|
surface: 'は',
|
||||||
|
headword: 'は',
|
||||||
|
reading: 'ハ',
|
||||||
|
partOfSpeech: PartOfSpeech.particle,
|
||||||
|
pos1: '助詞',
|
||||||
|
startPos: 0,
|
||||||
|
endPos: 1,
|
||||||
|
}),
|
||||||
|
makeToken({
|
||||||
|
surface: 'に',
|
||||||
|
headword: 'に',
|
||||||
|
reading: 'ニ',
|
||||||
|
partOfSpeech: PartOfSpeech.particle,
|
||||||
|
pos1: '助詞',
|
||||||
|
startPos: 1,
|
||||||
|
endPos: 2,
|
||||||
|
}),
|
||||||
|
makeToken({
|
||||||
|
surface: 'を',
|
||||||
|
headword: 'を',
|
||||||
|
reading: 'ヲ',
|
||||||
|
partOfSpeech: PartOfSpeech.particle,
|
||||||
|
pos1: '助詞',
|
||||||
|
startPos: 2,
|
||||||
|
endPos: 3,
|
||||||
|
}),
|
||||||
|
makeToken({
|
||||||
|
surface: '猫',
|
||||||
|
headword: '猫',
|
||||||
|
partOfSpeech: PartOfSpeech.noun,
|
||||||
|
startPos: 3,
|
||||||
|
endPos: 4,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
const result = markNPlusOneTargets(tokens, 3);
|
||||||
|
|
||||||
|
assert.equal(result[0]?.isNPlusOneTarget, false);
|
||||||
|
assert.equal(result[1]?.isNPlusOneTarget, false);
|
||||||
|
assert.equal(result[2]?.isNPlusOneTarget, false);
|
||||||
|
assert.equal(result[3]?.isNPlusOneTarget, false);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user