import { test } from 'brittle'
import { layout } from '../lib/layout.js'
// An explicit rank: which COLUMN an item belongs in, when the caller already
// knows. Layering derives columns from edges, which is right when that is the
// only information there is — but a relation view knows each node's hop distance
// and side exactly, and re-deriving it from edges loses that.
test('layout: an explicit rank decides the column', (t) => {
// Ranks deliberately DISAGREE with the edges: b supplies a, so layering would
// put b left of a. The rank says otherwise and must win.
const out = layout({
nodes: [
{ id: 'a', container: null, w: 100, h: 40, rank: 0 },
{ id: 'b', container: null, w: 100, h: 40, rank: 1 },
{ id: 'c', container: null, w: 100, h: 40, rank: 2 }
],
links: [{ from: 'b', to: 'a' }],
containers: []
})
const x = new Map(out.nodes.map(n => [n.id, n.x]))
t.ok(x.get('a') < x.get('b'), 'a is left of b, as ranked')
t.ok(x.get('b') < x.get('c'), 'b is left of c')
})
test('layout: ranks and edges are not mixed within one group', (t) => {
// Half-ranked columns would be a silent guess about what the caller meant.
// If anything in a group is ranked, ranks decide the whole group and an
// unranked sibling sits at 0.
const out = layout({
nodes: [
{ id: 'a', container: null, w: 100, h: 40, rank: 3 },
{ id: 'b', container: null, w: 100, h: 40 },
{ id: 'c', container: null, w: 100, h: 40 }
],
links: [{ from: 'b', to: 'c' }],
containers: []
})
const x = new Map(out.nodes.map(n => [n.id, n.x]))
t.is(x.get('b'), x.get('c'), 'b and c are both unranked, so both at column 0')
t.ok(x.get('a') > x.get('b'), 'the ranked item still lands right of them')
})
test('layout: a container can be ranked too', (t) => {
const out = layout({
nodes: [
{ id: 'a', container: 'far', w: 100, h: 40 },
{ id: 'b', container: 'near', w: 100, h: 40 }
],
links: [],
containers: [
{ id: 'near', parent: null, label: 'near', rank: 0 },
{ id: 'far', parent: null, label: 'far', rank: 1 }
]
})
const x = new Map(out.containers.map(c => [c.id, c.x]))
t.ok(x.get('near') < x.get('far'), 'near is left of far, with no edges at all')
})
test('layout: unranked input is unaffected', (t) => {
const input = {
nodes: [
{ id: 'a', container: null, w: 100, h: 40 },
{ id: 'b', container: null, w: 100, h: 40 }
],
links: [{ from: 'a', to: 'b' }],
containers: []
}
const out = layout(input)
const x = new Map(out.nodes.map(n => [n.id, n.x]))
t.ok(x.get('a') < x.get('b'), 'layering still decides when nothing is ranked')
})