tests/bundle-compatibility.unit.test.ts
Rama main · réplica de lectura del repositorio original.
import type { NativePackage } from '../src/services/bundleCompatibility'
import { describe, expect, it } from 'vitest'
import { comparePackages, hasPlatformChecksumMetadataDrift, summarizeCompatibility } from '../src/services/bundleCompatibility'
function pkg(name: string, version: string, extra: Partial<NativePackage> = {}): NativePackage {
return { name, version, ...extra }
}
function byName(name: string, comparisons: ReturnType<typeof comparePackages>) {
const found = comparisons.find(entry => entry.name === name)
if (!found)
throw new Error(`missing comparison for ${name}`)
return found
}
describe('comparePackages', () => {
it.concurrent('marks a package present in both with the same version as unchanged + compatible', () => {
const result = comparePackages([pkg('a', '1.0.0')], [pkg('a', '1.0.0')])
const a = byName('a', result)
expect(a.status).toBe('unchanged')
expect(a.compatible).toBe(true)
expect(a.reasons).toEqual([])
expect(a.candidateVersion).toBe('1.0.0')
expect(a.baselineVersion).toBe('1.0.0')
})
it.concurrent('stays unchanged when version and both checksums match', () => {
const result = comparePackages(
[pkg('a', '1.0.0', { ios_checksum: 'i', android_checksum: 'd' })],
[pkg('a', '1.0.0', { ios_checksum: 'i', android_checksum: 'd' })],
)
const a = byName('a', result)
expect(a.status).toBe('unchanged')
expect(a.compatible).toBe(true)
})
it.concurrent('marks a newly added package as added + incompatible (new_plugin)', () => {
const result = comparePackages([pkg('a', '1.0.0')], [])
const a = byName('a', result)
expect(a.status).toBe('added')
expect(a.compatible).toBe(false)
expect(a.reasons).toEqual(['new_plugin'])
expect(a.baselineVersion).toBeUndefined()
})
it.concurrent('marks a removed package as removed + compatible (OTA-safe)', () => {
const result = comparePackages([], [pkg('a', '1.0.0')])
const a = byName('a', result)
expect(a.status).toBe('removed')
expect(a.compatible).toBe(true)
expect(a.reasons).toEqual([])
expect(a.candidateVersion).toBeUndefined()
})
it.concurrent('flags a non-intersecting version change as changed + version_mismatch', () => {
const result = comparePackages([pkg('a', '2.0.0')], [pkg('a', '1.0.0')])
const a = byName('a', result)
expect(a.status).toBe('changed')
expect(a.compatible).toBe(false)
expect(a.reasons).toEqual(['version_mismatch'])
})
it.concurrent('treats an intersecting version range as compatible (no version_mismatch)', () => {
// Caret range on baseline intersects the concrete candidate version.
const result = comparePackages([pkg('a', '1.2.0')], [pkg('a', '^1.0.0')])
const a = byName('a', result)
expect(a.reasons).not.toContain('version_mismatch')
expect(a.compatible).toBe(true)
})
it.concurrent('flags a same-version package whose iOS native checksum changed', () => {
const result = comparePackages(
[pkg('a', '1.0.0', { ios_checksum: 'new' })],
[pkg('a', '1.0.0', { ios_checksum: 'old' })],
)
const a = byName('a', result)
// Same version string but native code differs => status must be 'changed'
// (not 'unchanged') so it stays consistent with the incompatible verdict.
expect(a.status).toBe('changed')
expect(a.compatible).toBe(false)
expect(a.reasons).toEqual(['ios_code_changed'])
})
it.concurrent('flags a same-version package whose Android native checksum changed', () => {
const result = comparePackages(
[pkg('a', '1.0.0', { android_checksum: 'new' })],
[pkg('a', '1.0.0', { android_checksum: 'old' })],
)
const a = byName('a', result)
expect(a.status).toBe('changed')
expect(a.compatible).toBe(false)
expect(a.reasons).toEqual(['android_code_changed'])
})
it.concurrent('flags both platforms when both checksums changed', () => {
const result = comparePackages(
[pkg('a', '1.0.0', { ios_checksum: 'i2', android_checksum: 'a2' })],
[pkg('a', '1.0.0', { ios_checksum: 'i1', android_checksum: 'a1' })],
)
expect(byName('a', result).reasons).toEqual(['both_platforms_changed'])
})
it.concurrent('emits multiple reasons when version and native code both change', () => {
const result = comparePackages(
[pkg('a', '2.0.0', { ios_checksum: 'i2' })],
[pkg('a', '1.0.0', { ios_checksum: 'i1' })],
)
const a = byName('a', result)
expect(a.status).toBe('changed')
expect(a.compatible).toBe(false)
expect(a.reasons).toEqual(['version_mismatch', 'ios_code_changed'])
})
it.concurrent('flags one-sided checksum as incompatible metadata change (possible CLI false alarm)', () => {
const result = comparePackages(
[pkg('a', '1.0.0', { ios_checksum: 'i2' })],
[pkg('a', '1.0.0')],
)
const a = byName('a', result)
expect(a.status).toBe('changed')
expect(a.compatible).toBe(false)
expect(a.platformChecksumMetadataChanged).toBe(true)
expect(a.reasons).toEqual(['platform_checksum_metadata_changed'])
})
it.concurrent('treats empty checksum strings as absent and still flags metadata change', () => {
const result = comparePackages(
[pkg('a', '1.0.0', { ios_checksum: 'real', android_checksum: 'd' })],
[pkg('a', '1.0.0', { ios_checksum: '', android_checksum: ' ' })],
)
const a = byName('a', result)
expect(a.compatible).toBe(false)
expect(a.reasons).toEqual(['platform_checksum_metadata_changed'])
expect(a.platformChecksumMetadataChanged).toBe(true)
})
it.concurrent('flags when both iOS and Android checksums newly appear', () => {
const result = comparePackages(
[pkg('a', '1.0.0', { ios_checksum: 'i', android_checksum: 'd' })],
[pkg('a', '1.0.0')],
)
const a = byName('a', result)
expect(a.compatible).toBe(false)
expect(a.platformChecksumMetadataChanged).toBe(true)
expect(a.reasons).toEqual(['platform_checksum_metadata_changed'])
expect(hasPlatformChecksumMetadataDrift(result)).toBe(true)
})
it.concurrent('keeps version mismatch when CLI checksum metadata also appears', () => {
const result = comparePackages(
[pkg('a', '2.0.0', { ios_checksum: 'i', android_checksum: 'd' })],
[pkg('a', '1.0.0')],
)
const a = byName('a', result)
expect(a.compatible).toBe(false)
expect(a.reasons).toEqual(['version_mismatch', 'platform_checksum_metadata_changed'])
})
it.concurrent('does not flag metadata drift when checksums match on both sides', () => {
const result = comparePackages(
[pkg('a', '1.0.0', { ios_checksum: 'i', android_checksum: 'd' })],
[pkg('a', '1.0.0', { ios_checksum: 'i', android_checksum: 'd' })],
)
expect(byName('a', result).platformChecksumMetadataChanged).toBe(false)
expect(hasPlatformChecksumMetadataDrift(result)).toBe(false)
})
it.concurrent('orders changes first, then added, removed, unchanged, then by name', () => {
const result = comparePackages(
[pkg('keep', '1.0.0'), pkg('added', '1.0.0'), pkg('changed', '2.0.0')],
[pkg('keep', '1.0.0'), pkg('removed', '1.0.0'), pkg('changed', '1.0.0')],
)
expect(result.map(entry => entry.status)).toEqual(['changed', 'added', 'removed', 'unchanged'])
})
})
describe('summarizeCompatibility', () => {
it.concurrent('is compatible when every package is compatible', () => {
const result = comparePackages([pkg('a', '1.0.0')], [pkg('a', '1.0.0')])
expect(summarizeCompatibility(result)).toEqual({ compatible: true, incompatibleCount: 0, offenders: [] })
})
it.concurrent('reports offenders and count when any package is incompatible', () => {
const result = comparePackages(
[pkg('newplug', '1.0.0'), pkg('bump', '2.0.0'), pkg('same', '1.0.0')],
[pkg('bump', '1.0.0'), pkg('same', '1.0.0')],
)
const summary = summarizeCompatibility(result)
expect(summary.compatible).toBe(false)
expect(summary.incompatibleCount).toBe(2)
expect(summary.offenders.sort()).toEqual(['bump', 'newplug'])
})
it.concurrent('stays compatible when the only difference is a removed package', () => {
const result = comparePackages([], [pkg('gone', '1.0.0')])
expect(summarizeCompatibility(result).compatible).toBe(true)
})
})