mirror of
https://github.com/wekan/wekan.git
synced 2026-11-05 01:20:07 -05:00
Convert client-reachable models/lib helpers from CommonJS to ES modules (1/2).
The rspack client build treats a `module.exports` file imported into the
client bundle as an ES module and throws
"ES Modules may not assign module.exports" at evaluation time, aborting
the whole client module chain (No such template: swimlane / notifications
/ boardButtons, blank board, missing top bar). This is not an rspack
version regression (the lockfile has pinned ~1.7.x since v8.40); it is
that WeKan added CommonJS helpers to the client bundle.
Convert the 42 client-reachable pure-logic models/lib helpers from
`module.exports = { ... }` to `export { ... }`, and calendarFilter's
internal require('./swimlaneFilter') to an import with a .js extension
(node ESM needs it; rspack/reify tolerate it). Server-only helpers that
use node built-ins (fs/path/child_process) stay CommonJS. The plain-Node
.cjs unit tests for these helpers now use `await import(...js)` (wrapped
in an async IIFE); a source-guard in importVirtualMembers was updated
from module.exports to export. Verified: the full tests/*.test.cjs suite
has the SAME 7 pre-existing failures as before this change and no new
ones.
This commit is contained in:
1 parent
eca452d674
commit
8d1fae4f7d
82 files changed
+205
-85
No files matched your search
@@ -47,4 +47,4 @@ function buildCardAttachmentMeta(card, getCardById) {
|
||||
return meta;
|
||||
}
|
||||
|
||||
module.exports = { buildCardAttachmentMeta };
|
||||
export { buildCardAttachmentMeta };
|
||||
@@ -38,7 +38,7 @@ function resolveDefaultAuthenticationMethod(preferred, current, fallback = 'pass
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
normalizeAuthenticationMethod,
|
||||
resolveDefaultAuthenticationMethod,
|
||||
};
|
||||
@@ -38,4 +38,4 @@ function computeBoardBackground(board) {
|
||||
return { type: 'none' };
|
||||
}
|
||||
|
||||
module.exports = { computeBoardBackground };
|
||||
export { computeBoardBackground };
|
||||
@@ -26,4 +26,4 @@ function remapCopiedBoardDefaults(board, oldId, newId) {
|
||||
return patch;
|
||||
}
|
||||
|
||||
module.exports = { remapCopiedBoardDefaults };
|
||||
export { remapCopiedBoardDefaults };
|
||||
@@ -53,7 +53,7 @@ function cardIdsOnBoard(cardIds, boardId, getCard) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
boardScopedFilterSelector,
|
||||
boardScopedSelectionSelector,
|
||||
cardIdsOnBoard,
|
||||
|
||||
@@ -60,7 +60,7 @@ function computeReorderedSortIndex(orderedIds, draggedId, targetId) {
|
||||
return computeSortIndexMapping(reordered);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
isDragReorderEnabled,
|
||||
computeReorderedIds,
|
||||
computeSortIndexMapping,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// filter is active (or on the server) and the base selector is returned
|
||||
// unchanged.
|
||||
|
||||
const { combineWithFilter } = require('./swimlaneFilter');
|
||||
import { combineWithFilter } from './swimlaneFilter.js';
|
||||
|
||||
// Cards whose due date falls within [start, end].
|
||||
function cardsDueInBetweenSelector(boardId, start, end, filterSelector) {
|
||||
@@ -47,7 +47,7 @@ function cardsInIntervalSelector(boardId, start, end, filterSelector) {
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
cardsDueInBetweenSelector,
|
||||
cardsInIntervalSelector,
|
||||
};
|
||||
@@ -31,4 +31,4 @@ function computeCardMoveModifier(card, target = {}) {
|
||||
return fields;
|
||||
}
|
||||
|
||||
module.exports = { computeCardMoveModifier };
|
||||
export { computeCardMoveModifier };
|
||||
@@ -48,4 +48,4 @@ function buildCardSearchOr(term) {
|
||||
return or;
|
||||
}
|
||||
|
||||
module.exports = { parseNumericSearchTerm, buildCardSearchOr };
|
||||
export { parseNumericSearchTerm, buildCardSearchOr };
|
||||
@@ -86,7 +86,7 @@ function computeRepairedDropIndex(orderedCards, prevCard, nextCard, nCards = 1)
|
||||
return { updates, base, increment };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
isDegenerateSortGap,
|
||||
computeMonotonicSortRepair,
|
||||
computeRepairedDropIndex,
|
||||
|
||||
@@ -28,4 +28,4 @@ function sortWithIdTiebreaker(sort) {
|
||||
return { _id: 1 };
|
||||
}
|
||||
|
||||
module.exports = { sortWithIdTiebreaker };
|
||||
export { sortWithIdTiebreaker };
|
||||
@@ -32,4 +32,4 @@ function buildCardRelativeUrl(card, board) {
|
||||
return `/b/${boardId}/${slug}/${card._id}`;
|
||||
}
|
||||
|
||||
module.exports = { isThenable, buildCardRelativeUrl };
|
||||
export { isThenable, buildCardRelativeUrl };
|
||||
@@ -62,7 +62,7 @@ function windowCountId(listId, swimlaneId) {
|
||||
return `${listId}::${swimlaneId || ''}`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
DEFAULT_LAZY_THRESHOLD,
|
||||
resolveCardsLoadingMode,
|
||||
parseCardsLoadingEnv,
|
||||
|
||||
@@ -44,4 +44,4 @@ function buildChecklistItemPayload(title, checklist, sort) {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { parseChecklistItemTitles, buildChecklistItemPayload };
|
||||
export { parseChecklistItemTitles, buildChecklistItemPayload };
|
||||
@@ -19,4 +19,4 @@ function commentActivityDisplayText(activity) {
|
||||
return '';
|
||||
}
|
||||
|
||||
module.exports = { commentActivityDisplayText };
|
||||
export { commentActivityDisplayText };
|
||||
@@ -105,7 +105,7 @@ function contrastText(bgHexOrNamed) {
|
||||
return luminance > 0.179 ? '#000000' : '#ffffff';
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
NAMED_COLOR_HEX,
|
||||
isHexColor,
|
||||
normalizeHex,
|
||||
|
||||
@@ -70,4 +70,4 @@ function buildCustomFieldsWD(customFields, definitions) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
module.exports = { buildCustomFieldsWD, resolveTrueValue };
|
||||
export { buildCustomFieldsWD, resolveTrueValue };
|
||||
@@ -47,7 +47,7 @@ function pickDefaultSwimlane(swimlanes) {
|
||||
return active || swimlanes[0];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
defaultSwimlaneId,
|
||||
defaultSwimlaneFields,
|
||||
pickDefaultSwimlane,
|
||||
|
||||
@@ -35,4 +35,4 @@ function parseNotifyDueHour(envValue, defaultHour = 8) {
|
||||
return hour;
|
||||
}
|
||||
|
||||
module.exports = { parseNotifyDueDays, parseNotifyDueHour };
|
||||
export { parseNotifyDueDays, parseNotifyDueHour };
|
||||
@@ -29,4 +29,4 @@ function isSubmitKey(event, opts = {}) {
|
||||
return !!(event.ctrlKey || event.metaKey);
|
||||
}
|
||||
|
||||
module.exports = { isSubmitKey };
|
||||
export { isSubmitKey };
|
||||
@@ -140,7 +140,7 @@ function buildCsvCardRow(card, result, customFieldMap) {
|
||||
return currentRow;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
lookupProp,
|
||||
buildCsvCardRow,
|
||||
};
|
||||
@@ -22,4 +22,4 @@ function planImportedBoardMember(wekanMember, importerId) {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { planImportedBoardMember };
|
||||
export { planImportedBoardMember };
|
||||
@@ -48,4 +48,4 @@ function importedCardDates(card, activityCreatedAt, now) {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { importedCardDates, toValidDateOrNull };
|
||||
export { importedCardDates, toValidDateOrNull };
|
||||
@@ -31,7 +31,7 @@ function filterLabelsByTerm(labels, term) {
|
||||
return labels.filter(label => labelMatchesTerm(label, term));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
labelMatchesTerm,
|
||||
filterLabelsByTerm,
|
||||
};
|
||||
@@ -34,4 +34,4 @@ function resolveCoverId(card, getCard) {
|
||||
return source && source.coverId ? source.coverId : null;
|
||||
}
|
||||
|
||||
module.exports = { coverSourceCard, resolveCoverId };
|
||||
export { coverSourceCard, resolveCoverId };
|
||||
@@ -45,4 +45,4 @@ function memberTargetBoardId(card, resolveCard) {
|
||||
return card.boardId || null;
|
||||
}
|
||||
|
||||
module.exports = { memberTargetCardId, memberTargetBoardId };
|
||||
export { memberTargetCardId, memberTargetBoardId };
|
||||
@@ -35,4 +35,4 @@ function isLinkableCardTarget(target, ownRealCardIds = []) {
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = { isLinkPointerCard, isLinkableCardTarget };
|
||||
export { isLinkPointerCard, isLinkableCardTarget };
|
||||
@@ -34,4 +34,4 @@ function computeTitleUpdateTargets(card) {
|
||||
return targets;
|
||||
}
|
||||
|
||||
module.exports = { computeTitleUpdateTargets };
|
||||
export { computeTitleUpdateTargets };
|
||||
@@ -81,7 +81,7 @@ function resolveListWidth(options) {
|
||||
return normalizeListWidth(personalWidth, shared);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
DEFAULT_LIST_WIDTH,
|
||||
MIN_LIST_WIDTH,
|
||||
isValidListWidth,
|
||||
|
||||
@@ -36,7 +36,7 @@ function filterMembersByTerm(users, term) {
|
||||
return users.filter(user => memberMatchesTerm(user, term));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
memberMatchesTerm,
|
||||
filterMembersByTerm,
|
||||
};
|
||||
@@ -12,4 +12,4 @@ function productNameOrDefault(productName) {
|
||||
return 'WeKan';
|
||||
}
|
||||
|
||||
module.exports = { productNameOrDefault };
|
||||
export { productNameOrDefault };
|
||||
@@ -72,7 +72,7 @@ function appendCardTitleFilterToDesc(desc, cardTitle, label) {
|
||||
return `${base} (${tag}: "${cardTitle}")`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
cardTitleFilterOrWildcard,
|
||||
cardTitleMatchList,
|
||||
cardTitleFilterMatches,
|
||||
|
||||
@@ -50,4 +50,4 @@ function canSelectBoardInRules(board, ctx, templatesBoardId) {
|
||||
return boardVisibleToUserContext(board, ctx);
|
||||
}
|
||||
|
||||
module.exports = { canSelectBoardInRules, boardVisibleToUserContext };
|
||||
export { canSelectBoardInRules, boardVisibleToUserContext };
|
||||
@@ -25,7 +25,7 @@ function sortCardsByTitle(cards) {
|
||||
return cards.slice().sort(compareCardTitle);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
compareCardTitle,
|
||||
sortCardsByTitle,
|
||||
};
|
||||
@@ -29,4 +29,4 @@ function subtaskCopyChildKinds() {
|
||||
return ['checklists'];
|
||||
}
|
||||
|
||||
module.exports = { buildCopiedSubtaskFields, subtaskCopyChildKinds };
|
||||
export { buildCopiedSubtaskFields, subtaskCopyChildKinds };
|
||||
@@ -49,4 +49,4 @@ function cardsToRestoreWithSwimlane(cards, swimlaneArchivedAt) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { cardsToArchiveWithSwimlane, cardsToRestoreWithSwimlane };
|
||||
export { cardsToArchiveWithSwimlane, cardsToRestoreWithSwimlane };
|
||||
@@ -102,7 +102,7 @@ function filteredListCardsSelector(listId, swimlaneId, filterSelector, otherSwim
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
swimlaneMembershipSelector,
|
||||
listCardsSelector,
|
||||
combineWithFilter,
|
||||
|
||||
@@ -79,7 +79,7 @@ function isValidCustomColors(color, customColors) {
|
||||
return customColors.every(c => typeof c === 'string' && HEX_RE.test(c));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
THEME_CATEGORIES,
|
||||
THEME_CATEGORY_ORDER,
|
||||
CUSTOM_COLOR_COUNT,
|
||||
|
||||
@@ -109,7 +109,7 @@ function colorValue(value) {
|
||||
return isHexColor6(value) ? value : '';
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
UI_FONTS,
|
||||
SAFE_FONT_RE,
|
||||
isSafeFontName,
|
||||
|
||||
@@ -122,7 +122,7 @@ async function applyUserDeletionCleanup(plan, collections) {
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
isValidUserId,
|
||||
buildUserDeletionCleanupPlan,
|
||||
applyUserDeletionCleanup,
|
||||
|
||||
@@ -75,7 +75,7 @@ function weekNumberByFirstDay(date, firstDay) {
|
||||
return Math.floor(diffDays / 7) + 1;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
normalizeFirstDay,
|
||||
startOfWeek,
|
||||
weekRange,
|
||||
|
||||
@@ -49,4 +49,4 @@ function withDeadline(promise, ms, onTimeout) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { withDeadline };
|
||||
export { withDeadline };
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the swimlane archive/restore card
|
||||
// cascade. Run: node tests/archiveSwimlaneCards.test.cjs
|
||||
@@ -18,7 +19,7 @@ const assert = require('assert');
|
||||
const {
|
||||
cardsToArchiveWithSwimlane,
|
||||
cardsToRestoreWithSwimlane,
|
||||
} = require('../models/lib/swimlaneArchive');
|
||||
} = await import('../models/lib/swimlaneArchive.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -186,3 +187,5 @@ test('re-archiving after restore archives the restored cards again', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the default authentication-method helpers.
|
||||
// Run: node tests/authenticationMethod.test.cjs
|
||||
@@ -15,7 +16,7 @@ const assert = require('assert');
|
||||
const {
|
||||
normalizeAuthenticationMethod,
|
||||
resolveDefaultAuthenticationMethod,
|
||||
} = require('../models/lib/authenticationMethod');
|
||||
} = await import('../models/lib/authenticationMethod.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -78,3 +79,5 @@ test('NEGATIVE: a real selected value still overrides the stored one', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} passing`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the board-background descriptor.
|
||||
// Run: node tests/boardBackground.test.cjs
|
||||
@@ -13,7 +14,7 @@
|
||||
// image. The old code only ever SET a background, never reset it.
|
||||
|
||||
const assert = require('assert');
|
||||
const { computeBoardBackground } = require('../models/lib/boardBackground');
|
||||
const { computeBoardBackground } = await import('../models/lib/boardBackground.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -70,3 +71,5 @@ test('NEGATIVE: null / undefined board is handled without throwing', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the board-copy default-pointer remap.
|
||||
// Run: node tests/boardCopyDefaults.test.cjs
|
||||
@@ -11,7 +12,7 @@
|
||||
// copy (and clear the paired list id so it self-heals on the new board).
|
||||
|
||||
const assert = require('assert');
|
||||
const { remapCopiedBoardDefaults } = require('../models/lib/boardCopyDefaults');
|
||||
const { remapCopiedBoardDefaults } = await import('../models/lib/boardCopyDefaults.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -81,3 +82,5 @@ test('NEGATIVE: the new board must NOT keep the template board id', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for models/lib/boardScopedSelection.js.
|
||||
// Run: ELECTRON_RUN_AS_NODE=1 <node> tests/boardScopedSelection.test.cjs
|
||||
@@ -16,7 +17,7 @@ const {
|
||||
boardScopedFilterSelector,
|
||||
boardScopedSelectionSelector,
|
||||
cardIdsOnBoard,
|
||||
} = require('../models/lib/boardScopedSelection');
|
||||
} = await import('../models/lib/boardScopedSelection.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -210,3 +211,5 @@ test('#2306: selection built from the scoped filter query holds only current-boa
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the All Boards drag-reorder helpers.
|
||||
// Run: node tests/boardSortReorder.test.cjs
|
||||
@@ -17,7 +18,7 @@ const {
|
||||
computeReorderedIds,
|
||||
computeSortIndexMapping,
|
||||
computeReorderedSortIndex,
|
||||
} = require('../models/lib/boardSortReorder');
|
||||
} = await import('../models/lib/boardSortReorder.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -132,3 +133,5 @@ test('#6442: ordered ids read from the wrong DOM class (all "js-board") never re
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the Calendar view's card selector
|
||||
// builders. Run: node tests/calendarFilter.test.cjs
|
||||
@@ -15,7 +16,7 @@ const assert = require('assert');
|
||||
const {
|
||||
cardsDueInBetweenSelector,
|
||||
cardsInIntervalSelector,
|
||||
} = require('../models/lib/calendarFilter');
|
||||
} = await import('../models/lib/calendarFilter.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -134,3 +135,5 @@ test('#5656: without a filter, both users\' cards are shown (pre-fix behaviour p
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the Card.move() modifier builder.
|
||||
// Run: node tests/cardMoveModifier.test.cjs
|
||||
@@ -14,7 +15,7 @@
|
||||
// the caller skips entirely.
|
||||
|
||||
const assert = require('assert');
|
||||
const { computeCardMoveModifier } = require('../models/lib/cardMoveModifier');
|
||||
const { computeCardMoveModifier } = await import('../models/lib/cardMoveModifier.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -115,3 +116,5 @@ test('NEGATIVE: undefined target fields are ignored, not written as undefined',
|
||||
});
|
||||
|
||||
console.log(`\n${passed} passing`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the board card-search query builder.
|
||||
// Run: node tests/cardSearch.test.cjs
|
||||
@@ -15,7 +16,7 @@ const assert = require('assert');
|
||||
const {
|
||||
parseNumericSearchTerm,
|
||||
buildCardSearchOr,
|
||||
} = require('../models/lib/cardSearch');
|
||||
} = await import('../models/lib/cardSearch.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -133,3 +134,5 @@ test('non-numeric term against a numeric-only card finds nothing', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Tests for models/lib/cardSortTiebreaker.js (#6511).
|
||||
//
|
||||
@@ -13,7 +14,7 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { sortWithIdTiebreaker } = require('../models/lib/cardSortTiebreaker');
|
||||
const { sortWithIdTiebreaker } = await import('../models/lib/cardSortTiebreaker.js');
|
||||
|
||||
let passed = 0;
|
||||
function check(name, fn) { fn(); passed += 1; console.log(' ok -', name); }
|
||||
@@ -62,3 +63,5 @@ check('the server card window tiebreaks its limited sort too', () => {
|
||||
});
|
||||
|
||||
console.log(`\ncardSortTiebreaker: ${passed} checks passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the card relative-URL builder.
|
||||
// Run: node tests/cardUrl.test.cjs
|
||||
@@ -12,7 +13,7 @@
|
||||
// The client was unaffected because there Card.board() is synchronous.
|
||||
|
||||
const assert = require('assert');
|
||||
const { isThenable, buildCardRelativeUrl } = require('../models/lib/cardUrl');
|
||||
const { isThenable, buildCardRelativeUrl } = await import('../models/lib/cardUrl.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -105,3 +106,5 @@ test('NEGATIVE: returns undefined for a missing card', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} passing`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the CARDS_LOADING / lazy card-loading
|
||||
// helpers. Run: node tests/cardsLoading.test.cjs
|
||||
@@ -20,7 +21,7 @@ const {
|
||||
cardsLoadingLazyThreshold,
|
||||
effectiveBoardCardsMode,
|
||||
windowCountId,
|
||||
} = require('../models/lib/cardsLoading');
|
||||
} = await import('../models/lib/cardsLoading.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -117,3 +118,5 @@ test('different lists never collide', () => {
|
||||
});
|
||||
|
||||
console.log(`\ncardsLoading: ${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the minicard/card-detail "add checklist
|
||||
// item" text parsing and payload builder.
|
||||
@@ -15,7 +16,7 @@ const assert = require('assert');
|
||||
const {
|
||||
parseChecklistItemTitles,
|
||||
buildChecklistItemPayload,
|
||||
} = require('../models/lib/checklistItemTitles');
|
||||
} = await import('../models/lib/checklistItemTitles.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -104,3 +105,5 @@ test('payload does NOT target a different checklist/card', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for comment-activity display text.
|
||||
// Run: node tests/commentActivity.test.cjs
|
||||
@@ -10,7 +11,7 @@
|
||||
// stored text, else the live comment's text, else '' — never "undefined".
|
||||
|
||||
const assert = require('assert');
|
||||
const { commentActivityDisplayText } = require('../models/lib/commentActivity');
|
||||
const { commentActivityDisplayText } = await import('../models/lib/commentActivity.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -71,3 +72,5 @@ test('NEGATIVE: non-string commentText / malformed comment do not leak "undefine
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node regression test (no Meteor) for issue #3843:
|
||||
// "Keep the link between global attachment and attachment in a comment" —
|
||||
@@ -31,7 +32,7 @@ const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const { buildCardAttachmentMeta } = require('../models/lib/attachmentMeta');
|
||||
const { buildCardAttachmentMeta } = await import('../models/lib/attachmentMeta.js');
|
||||
|
||||
const repoRoot = path.resolve(__dirname, '..');
|
||||
const read = rel => fs.readFileSync(path.join(repoRoot, rel), 'utf8');
|
||||
@@ -215,3 +216,5 @@ test('NEGATIVE: a linked card whose real card is gone still links by id and does
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the pure color helpers behind #5514
|
||||
// (custom color-wheel / RGB hex picker with automatically readable text).
|
||||
@@ -10,7 +11,7 @@ const {
|
||||
normalizeHex,
|
||||
toHex,
|
||||
contrastText,
|
||||
} = require('../models/lib/contrastColor');
|
||||
} = await import('../models/lib/contrastColor.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -128,3 +129,5 @@ test('toHex passes hex through (normalized) and rejects unknown names', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the "customFields with definitions"
|
||||
// matcher used by Cards.customFieldsWD().
|
||||
@@ -22,7 +23,7 @@ const assert = require('assert');
|
||||
const {
|
||||
buildCustomFieldsWD,
|
||||
resolveTrueValue,
|
||||
} = require('../models/lib/customFieldsWD');
|
||||
} = await import('../models/lib/customFieldsWD.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -172,3 +173,5 @@ test('resolveTrueValue: non-dropdown and unmatched ids keep the raw value', () =
|
||||
});
|
||||
|
||||
console.log(`\n${passed} passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the default-swimlane self-heal helpers.
|
||||
// Run: node tests/defaultSwimlane.test.cjs
|
||||
@@ -17,7 +18,7 @@ const {
|
||||
defaultSwimlaneId,
|
||||
defaultSwimlaneFields,
|
||||
pickDefaultSwimlane,
|
||||
} = require('../models/lib/defaultSwimlane');
|
||||
} = await import('../models/lib/defaultSwimlane.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -204,3 +205,5 @@ test('#1971 source guard: boards.js getDefaultSwimline uses pickDefaultSwimlane'
|
||||
});
|
||||
|
||||
console.log(`\n${passed} passing`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Unit + negative tests for the due-date reminder config parsers (#3192).
|
||||
// Run: node tests/dueNotificationConfig.test.cjs
|
||||
@@ -9,7 +10,7 @@ const path = require('path');
|
||||
const {
|
||||
parseNotifyDueDays,
|
||||
parseNotifyDueHour,
|
||||
} = require('../models/lib/dueNotificationConfig');
|
||||
} = await import('../models/lib/dueNotificationConfig.js');
|
||||
|
||||
let passed = 0;
|
||||
function check(name, fn) { fn(); passed += 1; console.log(' ok -', name); }
|
||||
@@ -78,3 +79,5 @@ check('#3192: due-card notifications include card ASSIGNEES as participants', ()
|
||||
});
|
||||
|
||||
console.log(`\ndueNotificationConfig: ${passed} checks passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the editor submit-key rule.
|
||||
// Run: node tests/editorSubmitKey.test.cjs
|
||||
@@ -10,7 +11,7 @@
|
||||
// ONLY on Enter + Ctrl/Cmd; plain Enter and Shift+Enter make a newline.
|
||||
|
||||
const assert = require('assert');
|
||||
const { isSubmitKey } = require('../models/lib/editorSubmitKey');
|
||||
const { isSubmitKey } = await import('../models/lib/editorSubmitKey.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -84,3 +85,5 @@ test('submitOnEnter defaults off: explicit false and omitted both require Ctrl/C
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the CSV export row builder.
|
||||
// Run: node tests/exporterCsvRow.test.cjs
|
||||
@@ -14,7 +15,7 @@
|
||||
// still produce the correct cells for well-formed cards.
|
||||
|
||||
const assert = require('assert');
|
||||
const { buildCsvCardRow, lookupProp } = require('../models/lib/exporterCsvRow');
|
||||
const { buildCsvCardRow, lookupProp } = await import('../models/lib/exporterCsvRow.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -156,3 +157,5 @@ test('lookupProp returns the property for a present id and fallback otherwise',
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -64,8 +64,11 @@ test('import is bounded on the server by a hard deadline', () => {
|
||||
assert.ok(/'import-timeout'/.test(srv), 'server raises import-timeout');
|
||||
});
|
||||
|
||||
test('the deadline + map-plan helpers are CommonJS (importable + testable)', () => {
|
||||
assert.ok(/module\.exports = \{ withDeadline \}/.test(read('models/lib/withDeadline.js')));
|
||||
test('the deadline + map-plan helpers are importable + testable', () => {
|
||||
// withDeadline is a client-reachable helper, so it is an ES module (export) to keep
|
||||
// rspack from flagging module.exports as an ES-module assignment; boardMemberMapPlan is
|
||||
// server-only and stays CommonJS.
|
||||
assert.ok(/export \{ withDeadline \}/.test(read('models/lib/withDeadline.js')));
|
||||
assert.ok(/module\.exports = \{ planBoardMemberMapping \}/.test(read('models/lib/boardMemberMapPlan.js')));
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for how an imported board member becomes a member of
|
||||
// the new board. Run: node tests/importedBoardMemberPlan.test.cjs
|
||||
|
||||
const assert = require('assert');
|
||||
const { planImportedBoardMember } = require('../models/lib/importedBoardMemberPlan');
|
||||
const { planImportedBoardMember } = await import('../models/lib/importedBoardMemberPlan.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -56,3 +57,5 @@ test('null / undefined member is dropped', () => {
|
||||
});
|
||||
|
||||
console.log(`\nimportedBoardMemberPlan: ${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the board-import card date helper.
|
||||
// Run: node tests/importedCardDates.test.cjs
|
||||
@@ -15,7 +16,7 @@ const assert = require('assert');
|
||||
const {
|
||||
importedCardDates,
|
||||
toValidDateOrNull,
|
||||
} = require('../models/lib/importedCardDates');
|
||||
} = await import('../models/lib/importedCardDates.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -116,3 +117,5 @@ test('toValidDateOrNull: valid ISO string gives the matching Date', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Unit + negative tests for the card-title "#" label autocomplete matcher
|
||||
// (issue #5116): typing "#test" must suggest a label named "Testing".
|
||||
@@ -8,7 +9,7 @@ const assert = require('assert');
|
||||
const {
|
||||
labelMatchesTerm,
|
||||
filterLabelsByTerm,
|
||||
} = require('../models/lib/labelAutocomplete');
|
||||
} = await import('../models/lib/labelAutocomplete.js');
|
||||
|
||||
let passed = 0;
|
||||
function check(name, fn) { fn(); passed += 1; console.log(' ok -', name); }
|
||||
@@ -92,3 +93,5 @@ check('listBody.js label strategy routes through labelMatchesTerm (no case-sensi
|
||||
});
|
||||
|
||||
console.log(`\nlabelAutocompleteMatch: ${passed} checks passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the linked-card cover resolver.
|
||||
// Run: node tests/linkedCardCover.test.cjs
|
||||
@@ -13,7 +14,7 @@ const assert = require('assert');
|
||||
const {
|
||||
coverSourceCard,
|
||||
resolveCoverId,
|
||||
} = require('../models/lib/linkedCardCover');
|
||||
} = await import('../models/lib/linkedCardCover.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -72,3 +73,5 @@ test('null / typeless cards are handled without throwing', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the linked-card member target helpers.
|
||||
// Run: node tests/linkedCardMembers.test.cjs
|
||||
@@ -16,7 +17,7 @@ const assert = require('assert');
|
||||
const {
|
||||
memberTargetCardId,
|
||||
memberTargetBoardId,
|
||||
} = require('../models/lib/linkedCardMembers');
|
||||
} = await import('../models/lib/linkedCardMembers.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -94,3 +95,5 @@ test('memberTargetBoardId is null-safe', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the "Link to this card" target guard.
|
||||
// Run: node tests/linkedCardTarget.test.cjs
|
||||
@@ -14,7 +15,7 @@ const assert = require('assert');
|
||||
const {
|
||||
isLinkPointerCard,
|
||||
isLinkableCardTarget,
|
||||
} = require('../models/lib/linkedCardTarget');
|
||||
} = await import('../models/lib/linkedCardTarget.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -76,3 +77,5 @@ test('NEGATIVE: cannot link to a template card, or to nothing', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} passing`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for linked-card title update targets.
|
||||
// Run: node tests/linkedCardTitle.test.cjs
|
||||
@@ -11,7 +12,7 @@
|
||||
// document, plus the linked target.
|
||||
|
||||
const assert = require('assert');
|
||||
const { computeTitleUpdateTargets } = require('../models/lib/linkedCardTitle');
|
||||
const { computeTitleUpdateTargets } = await import('../models/lib/linkedCardTitle.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -79,3 +80,5 @@ test('NEGATIVE: null / id-less card yields no targets, no throw', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node regression test (no Meteor) for issue #5659:
|
||||
// "Bug: List Width settings do not affect Public Board".
|
||||
@@ -31,7 +32,7 @@ const {
|
||||
isValidListWidth,
|
||||
normalizeListWidth,
|
||||
resolveListWidth,
|
||||
} = require('../models/lib/listWidth');
|
||||
} = await import('../models/lib/listWidth.js');
|
||||
|
||||
const repoRoot = path.resolve(__dirname, '..');
|
||||
const read = rel => fs.readFileSync(path.join(repoRoot, rel), 'utf8');
|
||||
@@ -208,3 +209,5 @@ test('the lists schema default matches the shared default', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Unit + negative tests for the "@" member autocomplete matcher (#5116
|
||||
// follow-up): typing "@ann" must suggest the member "Anna" and username
|
||||
@@ -11,7 +12,7 @@ const path = require('path');
|
||||
const {
|
||||
memberMatchesTerm,
|
||||
filterMembersByTerm,
|
||||
} = require('../models/lib/memberAutocomplete');
|
||||
} = await import('../models/lib/memberAutocomplete.js');
|
||||
|
||||
let passed = 0;
|
||||
function check(name, fn) { fn(); passed += 1; console.log(' ok -', name); }
|
||||
@@ -91,3 +92,5 @@ function read(rel) {
|
||||
}
|
||||
|
||||
console.log(`\nmemberAutocompleteMatch: ${passed} checks passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Unit tests for the Product-name helper (models/lib/productName.js) and the
|
||||
// migration-progress modal branding that uses it.
|
||||
@@ -11,7 +12,7 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { productNameOrDefault } = require('../models/lib/productName');
|
||||
const { productNameOrDefault } = await import('../models/lib/productName.js');
|
||||
|
||||
let passed = 0;
|
||||
function check(name, fn) { fn(); passed += 1; console.log(' ok -', name); }
|
||||
@@ -55,3 +56,5 @@ check('migrationProgress.jade shows the Product name in the title', () => {
|
||||
});
|
||||
|
||||
console.log(`\nproductName: ${passed} checks passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the IFTTT-Rules board selector logic.
|
||||
// Run: node tests/rulesBoardSelector.test.cjs
|
||||
@@ -16,7 +17,7 @@ const assert = require('assert');
|
||||
const {
|
||||
canSelectBoardInRules,
|
||||
boardVisibleToUserContext,
|
||||
} = require('../models/lib/rulesBoardSelector');
|
||||
} = await import('../models/lib/rulesBoardSelector.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -132,3 +133,5 @@ test('missing org/team/domain arrays on ctx do not throw', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the board-rule card-title filter.
|
||||
// Run: ELECTRON_RUN_AS_NODE=1 <node> tests/rulesCardTitleFilter.test.cjs
|
||||
@@ -21,7 +22,7 @@ const {
|
||||
cardTitleMatchList,
|
||||
cardTitleFilterMatches,
|
||||
appendCardTitleFilterToDesc,
|
||||
} = require('../models/lib/ruleCardTitleFilter');
|
||||
} = await import('../models/lib/ruleCardTitleFilter.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -141,3 +142,5 @@ test('server matching uses the shared helper for the cardTitle field', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,3 +1,4 @@
|
||||
(async () => {
|
||||
/**
|
||||
* Test: sortCardsByTitle (models/lib/sortCardsByTitle.js).
|
||||
*
|
||||
@@ -10,7 +11,7 @@
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const { sortCardsByTitle, compareCardTitle } = require('../models/lib/sortCardsByTitle');
|
||||
const { sortCardsByTitle, compareCardTitle } = await import('../models/lib/sortCardsByTitle.js');
|
||||
|
||||
const titles = cards => cards.map(c => c.title);
|
||||
|
||||
@@ -89,3 +90,5 @@ if (failed) {
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('\nAll ' + tests.length + ' tests passed');
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the #3826 drag-sort repair helpers.
|
||||
// Run: ELECTRON_RUN_AS_NODE=1 <node> tests/subtaskCardReorder.test.cjs
|
||||
@@ -24,8 +25,8 @@ const {
|
||||
isDegenerateSortGap,
|
||||
computeMonotonicSortRepair,
|
||||
computeRepairedDropIndex,
|
||||
} = require('../models/lib/cardSortRepair');
|
||||
const { computeCardMoveModifier } = require('../models/lib/cardMoveModifier');
|
||||
} = await import('../models/lib/cardSortRepair.js');
|
||||
const { computeCardMoveModifier } = await import('../models/lib/cardMoveModifier.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -198,3 +199,5 @@ test('NEGATIVE: the repair must not rewrite cards without an _id (defensive)', (
|
||||
});
|
||||
|
||||
console.log(`\n${passed} passing`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for copying a card's subtasks.
|
||||
// Run: node tests/subtaskCopy.test.cjs
|
||||
@@ -12,7 +13,7 @@ const assert = require('assert');
|
||||
const {
|
||||
buildCopiedSubtaskFields,
|
||||
subtaskCopyChildKinds,
|
||||
} = require('../models/lib/subtaskCopy');
|
||||
} = await import('../models/lib/subtaskCopy.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -80,3 +81,5 @@ test('NEGATIVE: ... nor the SOURCE board id (would strand the subtask)', () => {
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the per-list / per-swimlane card
|
||||
// selector builder. Run: node tests/swimlaneFilter.test.cjs
|
||||
@@ -20,7 +21,7 @@ const {
|
||||
listCardsSelector,
|
||||
combineWithFilter,
|
||||
filteredListCardsSelector,
|
||||
} = require('../models/lib/swimlaneFilter');
|
||||
} = await import('../models/lib/swimlaneFilter.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -246,3 +247,5 @@ test('#6443: label filter still applies alongside the first-swimlane orphaned cl
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the user-deletion cleanup planner.
|
||||
// Run: ELECTRON_RUN_AS_NODE=1 <node> tests/userDeletionCleanup.test.cjs
|
||||
@@ -16,7 +17,7 @@ const {
|
||||
isValidUserId,
|
||||
buildUserDeletionCleanupPlan,
|
||||
applyUserDeletionCleanup,
|
||||
} = require('../models/lib/userDeletionCleanup');
|
||||
} = await import('../models/lib/userDeletionCleanup.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -267,3 +268,5 @@ run.catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
(async () => {
|
||||
|
||||
// Plain-Node unit test (no Meteor) for the start-day-of-week math.
|
||||
// Run: node tests/weekStart.test.cjs
|
||||
@@ -19,7 +20,7 @@ const {
|
||||
startOfWeek,
|
||||
weekRange,
|
||||
weekNumberByFirstDay,
|
||||
} = require('../models/lib/weekStart');
|
||||
} = await import('../models/lib/weekStart.js');
|
||||
|
||||
let passed = 0;
|
||||
function test(name, fn) {
|
||||
@@ -128,3 +129,5 @@ test('NEGATIVE: start day changes the number for Saturday 2023-01-07 (#4946)', (
|
||||
});
|
||||
|
||||
console.log(`\n${passed} tests passed`);
|
||||
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
Reference in new issue
Block a user