397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
46 lines
2.0 KiB
JavaScript
46 lines
2.0 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { buildNodeGraph } from './node-graph.mjs';
|
|
import { missingContracts, emptyCards, unresolvedConflicts, asymmetricConflicts } from './card-coverage.mjs';
|
|
|
|
const reg = (nodes) => ({ nodes, chains: {} });
|
|
|
|
describe('card-coverage — покрытие узел↔карточка', () => {
|
|
it('missingContracts: узел без карточки (skill≠slug) попадает в список', () => {
|
|
const nodes = [{ id: '#1', slug: 'a' }, { id: '#2', slug: 'b' }];
|
|
const contracts = [{ skill: 'a' }];
|
|
expect(missingContracts(nodes, contracts)).toEqual(['#2']);
|
|
});
|
|
it('emptyCards: needs[] и produces[] пусты → карточка пустая', () => {
|
|
const contracts = [
|
|
{ skill: 'a', needs: [], produces: [] },
|
|
{ skill: 'b', needs: ['x'], produces: [] },
|
|
{ skill: 'c', needs: [], produces: ['y'] },
|
|
];
|
|
expect(emptyCards(contracts)).toEqual(['a']);
|
|
});
|
|
});
|
|
|
|
describe('card-coverage — конфликт-рёбра', () => {
|
|
it('unresolvedConflicts: ссылка в никуда ловится', () => {
|
|
const g = buildNodeGraph(reg([
|
|
{ id: '#1', slug: 'a', attributes: { conflicts_with: ['nope'] } },
|
|
]));
|
|
expect(unresolvedConflicts(g)).toEqual([{ from: '#1', ref: 'nope' }]);
|
|
});
|
|
it('asymmetricConflicts: A→B без B→A ловится', () => {
|
|
const g = buildNodeGraph(reg([
|
|
{ id: '#1', slug: 'a', attributes: { conflicts_with: ['b'] } },
|
|
{ id: '#2', slug: 'b', attributes: { conflicts_with: [] } },
|
|
]));
|
|
expect(asymmetricConflicts(g)).toEqual([{ from: '#1', to: '#2' }]);
|
|
});
|
|
it('симметричная пара A↔B → ни unresolved, ни asymmetric', () => {
|
|
const g = buildNodeGraph(reg([
|
|
{ id: '#1', slug: 'a', attributes: { conflicts_with: ['b'] } },
|
|
{ id: '#2', slug: 'b', attributes: { conflicts_with: ['a'] } },
|
|
]));
|
|
expect(unresolvedConflicts(g)).toEqual([]);
|
|
expect(asymmetricConflicts(g)).toEqual([]);
|
|
});
|
|
});
|