fASTQuery_spec.lua
1 dofile('init.lua') 2 local Q, describe, it = fASTQuery, describe, it 3 describe("wrapper", function () 4 it("wraps and references make unwrapping not needed", function () 5 local dom = { type = "box", color = "#FFFFFF" } 6 Q(dom).color = "#000000" 7 assert.same(dom, { type = "box", color = "#000000" }, "color was changed") 8 end) 9 it("works with multiple nodes too!", function () 10 local dom = { 11 type = "container", 12 { type = "box", color = "#FFFFFF" }, 13 { type = "label", label = "asdf" }, 14 { type = "box", color = "#aFFFFF" } 15 } 16 Q(dom):all{ type = "box" }.color = "#000000" 17 assert.same(dom, { 18 type = "container", 19 { type = "box", color = "#000000" }, 20 { type = "label", label = "asdf" }, 21 { type = "box", color = "#000000" } 22 }, "modified only the colors") 23 end) 24 it("supports getting children, and children are also wrapped", function () 25 local dom = { type = "container", { type = "box", color = "#FFFFFF" } } 26 local wrapped_child = Q(dom)[1] 27 assert.truthy(wrapped_child, "child found") 28 assert.equal(wrapped_child.type, dom[1].type, "child type is the same") 29 assert.equal(wrapped_child.color, dom[1].color, "child color is the same") 30 assert.truthy(wrapped_child.all, "child is wrapped") 31 wrapped_child.color = "#000000" 32 assert.equal(wrapped_child.color, dom[1].color, "child color is still the same") 33 assert.same(dom, { type = "container", { type = "box", color = "#000000" } }, "child was modified") 34 end) 35 it("supports getting number of children for first match using #", function () 36 local dom = { 37 type = "container", 38 { type = "box", color = "#FFFFFF"}, 39 { type = "box", color = "#FFFFFF"}, 40 { type = "box", color = "#FFFFFF"} 41 } 42 assert.equal(#Q(dom), 3) 43 end) 44 end) 45 describe("navigation", function () 46 describe("all", function () 47 it("can search by table", function () 48 local dom = { type = "container", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } } 49 Q(dom):all{ type = "box" }.color = "#000000" 50 assert.same(dom, { type = "container", { type = "box", color = "#000000" }, { type = "box", color = "#000000" } }) 51 end) 52 it("returns all if no args provided", function () 53 local dom = { type = "container", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } } 54 Q(dom):all().k = "v" 55 assert.same({ 56 type = "container", 57 k = "v", 58 { type = "box", color = "#FFFFFF", k = "v" }, 59 { type = "box", color = "#aFFFFF", k = "v" } 60 }, dom) 61 end) 62 it("can accept a function as the key", function () 63 local dom = { type = "container", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } } 64 Q(dom):all(function (elm) 65 return elm.type == "box" 66 end).color = "#000000" 67 assert.same(dom, { type = "container", { type = "box", color = "#000000" }, { type = "box", color = "#000000" } }) 68 end) 69 end) 70 describe("first", function () 71 it("only finds one element", function () 72 local dom = { type = "container", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } } 73 Q(dom):first{ type = "box" }.color = "#000000" 74 assert.same(dom, { type = "container", { type = "box", color = "#000000" }, { type = "box", color = "#aFFFFF" } }) 75 end) 76 it("gives the first element when no args", function () 77 local dom = { type = "container", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } } 78 -- Remember, all is slow. This is bad. Don't do this, just do :first(pattern). Reduce first, then pattern 79 Q(dom):all{ type = "box" }:first().color = "#000000" 80 assert.same(dom, { type = "container", { type = "box", color = "#000000" }, { type = "box", color = "#aFFFFF" } }) 81 end) 82 it("provides a way to tell if none were found", function () 83 local dom = { type = "container", { type = "label", label = "lol" } } 84 assert.equal(Q(dom):first{ type = "box" }:count(), 0, "none should be found") 85 end) 86 it("can accept a function", function () 87 local dom = { type = "container", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } } 88 Q(dom):first(function (elm) 89 return elm.type == "box" 90 end).color = "#000000" 91 assert.same(dom, { type = "container", { type = "box", color = "#000000" }, { type = "box", color = "#aFFFFF" } }) 92 end) 93 end) 94 describe("children", function () 95 it("finds all children of all selected elements", function () 96 local dom = { 97 type = "container", 98 { type = "container", findMe = "pls", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } }, 99 { type = "box", color = "#bFFFFF" }, 100 { type = "container", findMe = "pls", { type = "box", color = "#cFFFFF" }, { type = "box", color = "#dFFFFF" } } 101 } 102 Q(dom):all{ findMe = "pls" }:children().color = "#000000" 103 assert.same(dom, { 104 type = "container", 105 { type = "container", findMe = "pls", { type = "box", color = "#000000" }, { type = "box", color = "#000000" } }, 106 { type = "box", color = "#bFFFFF" }, 107 { type = "container", findMe = "pls", { type = "box", color = "#000000" }, { type = "box", color = "#000000" } } 108 }) 109 end) 110 end) 111 describe("include", function () 112 it("adds elements found in a different search into this search", function () 113 local dom = { 114 type = "container", 115 { type = "box", color = "#FFFFFF" }, 116 { type = "box", color = "#cFFFFF" }, 117 { type = "container", { type = "box", color = "#aFFFFF" }, { type = "box", color = "#bFFFFF" } } 118 } 119 local first = Q(dom):first{ type = "box" } 120 Q(dom)[3]:all{ type = "box" }:include(first).color = "#000000" 121 assert.same(dom, { 122 type = "container", 123 { type = "box", color = "#000000" }, 124 { type = "box", color = "#cFFFFF" }, 125 { type = "container", { type = "box", color = "#000000" }, { type = "box", color = "#000000" } } 126 }) 127 end) 128 end) 129 describe("count", function () 130 it("counts the number of matches made", function () 131 local dom = { 132 type = "container", 133 { type = "box", color = "#FFFFFF" }, 134 { type = "label", label = "hi"}, 135 { type = "box", color = "#FFFFFF" }, 136 { type = "box", color = "#FFFFFF" } 137 } 138 local container = Q(dom) 139 assert.equal(container:all{ type = "box" }:count(), 3, "there are three matches") 140 assert.equal(container:first{ type = "box" }:count(), 1, "first found only just the one") 141 end) 142 end) 143 describe("each", function () 144 it("is an iterator returning wrapped elements", function () 145 local dom = { 146 type = "container", 147 { type = "container", findMe = "pls", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } }, 148 { type = "box", color = "#bFFFFF" }, 149 { type = "container", findMe = "pls", { type = "box", color = "#cFFFFF" }, { type = "box", color = "#dFFFFF" } } 150 } 151 for elm in Q(dom):all{ findMe = "pls" }:children():each() do 152 elm.color = "#000000" 153 assert.is.truthy(elm.each, "is wrapped") 154 end 155 assert.same(dom, { 156 type = "container", 157 { type = "container", findMe = "pls", { type = "box", color = "#000000" }, { type = "box", color = "#000000" } }, 158 { type = "box", color = "#bFFFFF" }, 159 { type = "container", findMe = "pls", { type = "box", color = "#000000" }, { type = "box", color = "#000000" } } 160 }) 161 end) 162 end) 163 describe("parents", function () 164 it("returns the parents of each element", function () 165 local dom = { 166 type = "container", 167 { type = "container", { type = "box", color = "#FFFFFF" } }, 168 { type = "container", { type = "box", color = "#FFFFFF" } } 169 } 170 Q(dom):all{ type = "box" }:parents().type = "vbox" 171 assert.same(dom, { 172 type = "container", 173 { type = "vbox", { type = "box", color = "#FFFFFF" } }, 174 { type = "vbox", { type = "box", color = "#FFFFFF" } } 175 }) 176 end) 177 it("does not match duplicates", function () 178 local dom = { 179 type = "container", 180 { type = "container", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#FFFFFF" } } 181 } 182 local count = 0 183 for _ in Q(dom):all{ type = "box" }:parents():each() do 184 count = count + 1 185 end 186 assert.equal(1, count) 187 end) 188 end) 189 --TODO slice (or something that performs subsets on _path, by a good name) 190 end) 191 describe("manipulation", function () 192 describe("getKey", function () 193 it("gets a key, regardless of if that key is shadowed by this api", function () 194 local dom = { type = "box", getKey = 3 } 195 assert.equal(Q(dom):getKey("getKey"), 3) 196 end) 197 it("only returns the first key", function() 198 local dom = { 199 type = "container", 200 { type = "box", color = "#FFFFFF" }, 201 { type = "box", color = "#aFFFFF" } 202 } 203 assert.equal(Q(dom):children():getKey("color"), "#FFFFFF") 204 end) 205 it("is an unalias for just getting the key conventionally", function () 206 local dom = { type = "container", { type = "box", color = "#FFFFFF" }, { type = "box", color = "#aFFFFF" } } 207 assert.equal(Q(dom):children().color, "#FFFFFF") 208 end) 209 end) 210 describe("append", function () 211 it("inserts a new DOM element at the end", function () 212 local dom = { type = "container", { type = "label", label = "hi" } } 213 Q(dom):append{ type = "box", color = "#FFFFFF" } 214 assert.same(dom, { 215 type = "container", 216 { type = "label", label = "hi" }, 217 { type = "box", color = "#FFFFFF" } 218 }) 219 end) 220 end) 221 -- insert (take the last two [or one] arguments from table.insert) 222 describe("insert", function () 223 it("inserts a new DOM element at a given location", function () 224 local dom = { 225 type = "container", 226 { type = "label", label = "hi" }, 227 { type = "label", label = "hi1" } 228 } 229 Q(dom):insert(2, { type = "box", color = "#FFFFFF" }) 230 assert.same(dom, { 231 type = "container", 232 { type = "label", label = "hi" }, 233 { type = "box", color = "#FFFFFF" }, 234 { type = "label", label = "hi1" } 235 }) 236 end) 237 it("falls back to append() if no index", function () 238 local dom = { type = "container", { type = "label", label = "hi" } } 239 Q(dom):insert{ type = "box", color = "#FFFFFF" } 240 assert.same({ 241 type = "container", 242 { type = "label", label = "hi" }, 243 { type = "box", color = "#FFFFFF" } 244 }, dom) 245 end) 246 end) 247 -- TODO remove 248 -- TODO replaceWith 249 -- TODO wrap 250 -- TODO unwrap 251 -- TODO before 252 -- TODO after 253 end)