一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
54 行
2.3 KiB
TypeScript
54 行
2.3 KiB
TypeScript
import { flipNthCheckbox } from './useCheckboxToggle';
|
|
|
|
// Joplin's renderer only converts `- [ ]` / `- [x]` items inside bullet lists
|
|
// into clickable checkboxes — `*`, `+`, and numbered list markers are ignored.
|
|
// `flipNthCheckbox` must count exactly the same subset so the Nth rendered
|
|
// checkbox maps to the Nth source-text checkbox.
|
|
|
|
describe('useCheckboxToggle', () => {
|
|
test('flips an unchecked box to checked', () => {
|
|
expect(flipNthCheckbox('- [ ] todo', 0)).toBe('- [x] todo');
|
|
});
|
|
|
|
test('flips a checked box back to unchecked', () => {
|
|
expect(flipNthCheckbox('- [x] done', 0)).toBe('- [ ] done');
|
|
expect(flipNthCheckbox('- [X] done', 0)).toBe('- [ ] done');
|
|
});
|
|
|
|
test('targets the Nth checkbox by zero-based index', () => {
|
|
const body = '- [ ] one\n- [ ] two\n- [ ] three';
|
|
expect(flipNthCheckbox(body, 0)).toBe('- [x] one\n- [ ] two\n- [ ] three');
|
|
expect(flipNthCheckbox(body, 1)).toBe('- [ ] one\n- [x] two\n- [ ] three');
|
|
expect(flipNthCheckbox(body, 2)).toBe('- [ ] one\n- [ ] two\n- [x] three');
|
|
});
|
|
|
|
test('returns null when index is out of range', () => {
|
|
expect(flipNthCheckbox('- [ ] only one', 1)).toBeNull();
|
|
expect(flipNthCheckbox('no checkboxes here', 0)).toBeNull();
|
|
expect(flipNthCheckbox('', 0)).toBeNull();
|
|
});
|
|
|
|
test('ignores list markers other than `-` to match the renderer', () => {
|
|
// `*`, `+`, and numbered markers are not turned into checkboxes by
|
|
// Joplin's renderer, so they must not affect the index either.
|
|
const body = '* [ ] starred\n+ [ ] plused\n1. [ ] numbered\n- [ ] real';
|
|
// The only "real" checkbox is index 0 — it's the dash-prefixed one.
|
|
expect(flipNthCheckbox(body, 0)).toBe('* [ ] starred\n+ [ ] plused\n1. [ ] numbered\n- [x] real');
|
|
expect(flipNthCheckbox(body, 1)).toBeNull();
|
|
});
|
|
|
|
test('ignores `[ ]` not preceded by a list marker', () => {
|
|
expect(flipNthCheckbox('Standalone [ ] not a checkbox', 0)).toBeNull();
|
|
});
|
|
|
|
test('handles Windows line endings', () => {
|
|
const body = '- [ ] one\r\n- [ ] two';
|
|
expect(flipNthCheckbox(body, 1)).toBe('- [ ] one\r\n- [x] two');
|
|
});
|
|
|
|
test('preserves indentation and the surrounding text', () => {
|
|
const body = 'Intro paragraph.\n\n - [ ] indented\n - [x] also indented\n\nOutro.';
|
|
expect(flipNthCheckbox(body, 1)).toBe('Intro paragraph.\n\n - [ ] indented\n - [ ] also indented\n\nOutro.');
|
|
});
|
|
});
|