121 lines
4.1 KiB
TypeScript
Executable File
121 lines
4.1 KiB
TypeScript
Executable File
import ist from "ist"
|
|
import {EditorState, EditorSelection, Facet, Extension, Precedence} from "@codemirror/next/state"
|
|
|
|
function mk(...extensions: Extension[]) {
|
|
return EditorState.create({extensions})
|
|
}
|
|
|
|
let num = Facet.define<number>(), str = Facet.define<string>()
|
|
|
|
describe("EditorState facets", () => {
|
|
it("allows querying of facets", () => {
|
|
let st = mk(num.of(10), num.of(20), str.of("x"), str.of("y"))
|
|
ist(st.facet(num).join(), "10,20")
|
|
ist(st.facet(str).join(), "x,y")
|
|
})
|
|
|
|
it("includes sub-extenders", () => {
|
|
let e = (s: string) => [num.of(s.length), num.of(+s)]
|
|
let st = mk(num.of(5), e("20"), num.of(40), e("100"))
|
|
ist(st.facet(num).join(), "5,2,20,40,3,100")
|
|
})
|
|
|
|
it("only includes duplicated extensions once", () => {
|
|
let e = num.of(50)
|
|
let st = mk(num.of(1), e, num.of(4), e)
|
|
ist(st.facet(num).join(), "1,50,4")
|
|
})
|
|
|
|
it("returns an empty array for absent facet", () => {
|
|
let st = mk()
|
|
ist(JSON.stringify(st.facet(num)), "[]")
|
|
})
|
|
|
|
it("sorts extensions by priority", () => {
|
|
let st = mk(str.of("a"), str.of("b"), Precedence.Extend.set(str.of("c")),
|
|
Precedence.Override.set(str.of("d")),
|
|
Precedence.Fallback.set(str.of("e")),
|
|
Precedence.Extend.set(str.of("f")), str.of("g"))
|
|
ist(st.facet(str).join(), "d,c,f,a,b,g,e")
|
|
})
|
|
|
|
it("lets sub-extensions inherit their parent's priority", () => {
|
|
let e = (n: number) => num.of(n)
|
|
let st = mk(num.of(1), Precedence.Override.set(e(2)), e(4))
|
|
ist(st.facet(num).join(), "2,1,4")
|
|
})
|
|
|
|
it("supports dynamic facet", () => {
|
|
let st = mk(num.of(1), num.compute([], () => 88))
|
|
ist(st.facet(num).join(), "1,88")
|
|
})
|
|
|
|
it("only recomputes a facet value when necessary", () => {
|
|
let st = mk(num.of(1), num.compute([str], s => s.facet(str).join().length), str.of("hello"))
|
|
let array = st.facet(num)
|
|
ist(array.join(), "1,5")
|
|
ist(st.t().apply().facet(num), array)
|
|
})
|
|
|
|
it("can specify a dependency on the document", () => {
|
|
let count = 0
|
|
let st = mk(num.compute(["doc"], s => count++))
|
|
ist(st.facet(num).join(), "0")
|
|
st = st.t().replace(0, 0, "hello").apply()
|
|
ist(st.facet(num).join(), "1")
|
|
st = st.t().apply()
|
|
ist(st.facet(num).join(), "1")
|
|
})
|
|
|
|
it("can specify a dependency on the selection", () => {
|
|
let count = 0
|
|
let st = mk(num.compute(["selection"], s => count++))
|
|
ist(st.facet(num).join(), "0")
|
|
st = st.t().replace(0, 0, "hello").apply()
|
|
ist(st.facet(num).join(), "1")
|
|
st = st.t().setSelection(EditorSelection.single(2)).apply()
|
|
ist(st.facet(num).join(), "2")
|
|
st = st.t().apply()
|
|
ist(st.facet(num).join(), "2")
|
|
})
|
|
|
|
it("can provide multiple values at once", () => {
|
|
let st = mk(num.computeN(["doc"], s => s.doc.length % 2 ? [100, 10] : []), num.of(1))
|
|
ist(st.facet(num).join(), "1")
|
|
st = st.t().replace(0, 0, "hello").apply()
|
|
ist(st.facet(num).join(), "100,10,1")
|
|
})
|
|
|
|
it("works with a static combined facet", () => {
|
|
let f = Facet.define<number, number>({combine: ns => ns.reduce((a, b) => a + b, 0)})
|
|
let st = mk(f.of(1), f.of(2), f.of(3))
|
|
ist(st.facet(f), 6)
|
|
})
|
|
|
|
it("works with a dynamic combined facet", () => {
|
|
let f = Facet.define<number, number>({combine: ns => ns.reduce((a, b) => a + b, 0)})
|
|
let st = mk(f.of(1), f.compute(["doc"], s => s.doc.length), f.of(3))
|
|
ist(st.facet(f), 4)
|
|
st = st.t().replace(0, 0, "hello").apply()
|
|
ist(st.facet(f), 9)
|
|
})
|
|
|
|
it("survives reconfiguration", () => {
|
|
let st = mk(num.compute(["doc"], s => s.doc.length), num.of(2), str.of("3"))
|
|
let st2 = st.t().reconfigure([num.compute(["doc"], s => s.doc.length), num.of(2)]).apply()
|
|
ist(st.facet(num), st2.facet(num))
|
|
ist(st2.facet(str).length, 0)
|
|
})
|
|
|
|
it("preserves static facets across reconfiguration", () => {
|
|
let st = mk(num.of(1), num.of(2), str.of("3"))
|
|
let st2 = st.t().reconfigure([num.of(1), num.of(2)]).apply()
|
|
ist(st.facet(num), st2.facet(num))
|
|
})
|
|
|
|
it("errors on cyclic dependencies", () => {
|
|
ist.throws(() => mk(num.compute([str], s => s.facet(str).length), str.compute([num], s => s.facet(num).join())),
|
|
/cyclic/i)
|
|
})
|
|
})
|