fix: mark specs as unreachable when infeasible alongside achieved specs
determineStatuses() was marking specs as 'achievable' based solely on per-specialization upper bounds, ignoring credit sharing with achieved specs. Now performs an LP feasibility check to verify the spec can actually be achieved alongside the current achieved set.
This commit is contained in:
@@ -109,6 +109,37 @@ describe('determineStatuses', () => {
|
||||
// Most specs only have 1 qualifying course in spr1 (2.5 credits < 9)
|
||||
expect(statuses['FIN']).toBe('unreachable');
|
||||
});
|
||||
|
||||
it('marks spec as unreachable when infeasible alongside achieved specs due to credit sharing', () => {
|
||||
// Bug scenario: CRF+STR achieved, LCM has 10 credit upper bound but
|
||||
// shared courses (spr3, fall3) are consumed by CRF/STR
|
||||
const selectedCourses = [
|
||||
'spr1-collaboration', // LCM, MGT
|
||||
'spr2-financial-services', // BNK, CRF, FIN, FIM
|
||||
'spr3-mergers-acquisitions', // CRF, FIN, LCM, STR(S1)
|
||||
'spr4-foundations-entrepreneurship', // ENT, MGT, STR(S1)
|
||||
'spr5-corporate-finance', // CRF, FIN
|
||||
'sum1-global-immersion', // GLB
|
||||
'sum2-business-drivers', // STR(S1)
|
||||
'sum3-valuation', // BNK, CRF, FIN, FIM
|
||||
'fall1-managing-change', // LCM, MGT, STR(S2)
|
||||
'fall2-decision-models', // MGT, MTO
|
||||
'fall3-corporate-governance', // LCM, MGT, SBI, STR(S1)
|
||||
'fall4-game-theory', // MGT, STR(S1)
|
||||
];
|
||||
|
||||
// Baseline: LCM is achievable when no specs are achieved (upper bound alone)
|
||||
const statusesBaseline = determineStatuses(selectedCourses, [], []);
|
||||
expect(statusesBaseline['LCM']).toBe('achievable');
|
||||
|
||||
// Core bug scenario: CRF+STR achieved (without MGT), LCM should still be unreachable
|
||||
const statusesWithoutMgt = determineStatuses(selectedCourses, [], ['CRF', 'STR']);
|
||||
expect(statusesWithoutMgt['LCM']).toBe('unreachable');
|
||||
|
||||
// LCM upper bound is 10 (>= 9) but infeasible alongside CRF+STR+MGT
|
||||
const statusesWithMgt = determineStatuses(selectedCourses, [], ['CRF', 'STR', 'MGT']);
|
||||
expect(statusesWithMgt['LCM']).toBe('unreachable');
|
||||
});
|
||||
});
|
||||
|
||||
describe('optimize (integration)', () => {
|
||||
|
||||
Reference in New Issue
Block a user