mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
181 lines
5 KiB
JavaScript
181 lines
5 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const { __test, getAndroidVersionInfo } = require('./release-notes');
|
|
|
|
const parse = (subject) => __test.parseCommitSubject(subject);
|
|
|
|
test('calculates stable and pre-release Android version codes', () => {
|
|
assert.deepEqual(getAndroidVersionInfo('18.5.0'), {
|
|
baseVersion: '18.5.0',
|
|
isPreRelease: false,
|
|
versionCode: 1805009000,
|
|
versionCodeWithUnderscores: '18_05_00_9000',
|
|
});
|
|
|
|
assert.deepEqual(getAndroidVersionInfo('18.6.0-RC.2'), {
|
|
baseVersion: '18.6.0',
|
|
isPreRelease: true,
|
|
versionCode: 1806000002,
|
|
versionCodeWithUnderscores: '18_06_00_0002',
|
|
});
|
|
});
|
|
|
|
test('parses conventional and plain commit subjects', () => {
|
|
assert.deepEqual(parse('fix(sync): keep Dropbox refresh token'), {
|
|
type: 'fix',
|
|
scope: 'sync',
|
|
description: 'keep Dropbox refresh token',
|
|
raw: 'fix(sync): keep Dropbox refresh token',
|
|
});
|
|
|
|
assert.deepEqual(parse('plain release note'), {
|
|
type: null,
|
|
scope: null,
|
|
description: 'plain release note',
|
|
raw: 'plain release note',
|
|
});
|
|
});
|
|
|
|
test('keeps first duplicate release-note description only', () => {
|
|
const commits = [
|
|
parse('fix(sync): Avoid duplicate task import'),
|
|
parse('fix(tasks): avoid duplicate task import'),
|
|
parse('feat(theme): add blur slider'),
|
|
];
|
|
|
|
assert.deepEqual(
|
|
__test.uniqueByDescription(commits).map((commit) => commit.raw),
|
|
['fix(sync): Avoid duplicate task import', 'feat(theme): add blur slider'],
|
|
);
|
|
});
|
|
|
|
test('filters to user-facing commits and falls back when only internal commits exist', () => {
|
|
const mixedCommits = [
|
|
parse('test(sync): stabilize flaky test'),
|
|
parse('build(release): add automated release notes'),
|
|
parse('fix(sync): repair archive hydration'),
|
|
parse('docs: update wiki'),
|
|
];
|
|
assert.deepEqual(
|
|
__test.getUserFacingCommits(mixedCommits).map((commit) => commit.raw),
|
|
['fix(sync): repair archive hydration'],
|
|
);
|
|
|
|
const internalCommits = [
|
|
parse('test(sync): stabilize flaky test'),
|
|
parse('build(release): add automated release notes'),
|
|
parse('docs: update wiki'),
|
|
];
|
|
assert.deepEqual(
|
|
__test.getUserFacingCommits(internalCommits).map((commit) => commit.raw),
|
|
[
|
|
'test(sync): stabilize flaky test',
|
|
'build(release): add automated release notes',
|
|
'docs: update wiki',
|
|
],
|
|
);
|
|
});
|
|
|
|
test('groups GitHub markdown by semantic commit type', () => {
|
|
const markdown = __test.toGroupedGithubMarkdown([
|
|
parse('feat(theme): add blur slider'),
|
|
parse('fix(sync): repair archive hydration'),
|
|
parse('perf(android): prewarm WebView'),
|
|
parse('docs: update wiki'),
|
|
]);
|
|
|
|
assert.match(markdown, /### Features\n\n- \*\*theme:\*\* add blur slider/);
|
|
assert.match(markdown, /### Fixes\n\n- \*\*sync:\*\* repair archive hydration/);
|
|
assert.match(markdown, /### Performance\n\n- \*\*android:\*\* prewarm WebView/);
|
|
assert.match(markdown, /### Other Changes\n\n- update wiki/);
|
|
});
|
|
|
|
test('normalizes Play Store text and enforces the character limit', () => {
|
|
const normalized = __test.normalizePlayStoreText(
|
|
`- Fixed [sync](https://example.com) issues\r\n${'x'.repeat(600)}`,
|
|
);
|
|
|
|
assert.equal(normalized, '- Fixed sync issues');
|
|
assert.ok(normalized.length <= 500);
|
|
});
|
|
|
|
test('parses fenced AI JSON and constrains Play Store output', () => {
|
|
const response = `\`\`\`json
|
|
${JSON.stringify({
|
|
githubMarkdown: '### Fixes\n\n- Fixed sync',
|
|
playStore: `- Fixed [sync](https://example.com)\n${'x'.repeat(600)}`,
|
|
})}
|
|
\`\`\``;
|
|
|
|
const parsed = __test.parseAiResponse(response);
|
|
|
|
assert.equal(parsed.githubMarkdown, '### Fixes\n\n- Fixed sync');
|
|
assert.equal(parsed.playStore, '- Fixed sync');
|
|
assert.ok(parsed.playStore.length <= 500);
|
|
});
|
|
|
|
test('resolves explicit AI provider environment values', () => {
|
|
assert.equal(
|
|
__test.resolveAiProvider({
|
|
env: { SP_RELEASE_NOTES_AI: 'claude' },
|
|
isInteractive: false,
|
|
}),
|
|
'claude',
|
|
);
|
|
assert.equal(
|
|
__test.resolveAiProvider({
|
|
env: { SP_RELEASE_NOTES_AI: 'false' },
|
|
isInteractive: true,
|
|
lifecycleEvent: 'version',
|
|
prompt: () => '',
|
|
}),
|
|
null,
|
|
);
|
|
assert.equal(
|
|
__test.resolveAiProvider({
|
|
env: { SP_RELEASE_NOTES_AI: '1', SP_RELEASE_NOTES_AI_PROVIDER: 'claude' },
|
|
isInteractive: false,
|
|
}),
|
|
'claude',
|
|
);
|
|
});
|
|
|
|
test('prompts during npm version only and defaults to AI on enter', () => {
|
|
assert.equal(
|
|
__test.resolveAiProvider({
|
|
env: {},
|
|
isInteractive: true,
|
|
lifecycleEvent: 'version',
|
|
prompt: () => '',
|
|
}),
|
|
'codex',
|
|
);
|
|
assert.equal(
|
|
__test.resolveAiProvider({
|
|
env: {},
|
|
isInteractive: true,
|
|
lifecycleEvent: 'version',
|
|
prompt: () => 'n',
|
|
}),
|
|
null,
|
|
);
|
|
assert.equal(
|
|
__test.resolveAiProvider({
|
|
env: {},
|
|
isInteractive: true,
|
|
lifecycleEvent: 'release-notes:generate',
|
|
prompt: () => '',
|
|
}),
|
|
null,
|
|
);
|
|
assert.equal(
|
|
__test.resolveAiProvider({
|
|
env: {},
|
|
isInteractive: false,
|
|
lifecycleEvent: 'version',
|
|
prompt: () => '',
|
|
}),
|
|
null,
|
|
);
|
|
});
|