Skip to content

Commit 527beba

Browse files
committed
tests for :excess and :missing
1 parent 0b20b26 commit 527beba

1 file changed

Lines changed: 134 additions & 0 deletions

File tree

‎src/test/cljs/cljs/destructuring_test.cljs‎

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,140 @@
424424
(is (= 1 (let [{:keys [a & 'b]} {:a 1}] a)))
425425
(is (= 1 (let [{:keys! [a & 'b "c"]} {:a 1, 'b 2, "c" 3}] a)))))))
426426

427+
(deftest excess
428+
(let [sample-map {:a 1, :b 2, :c {:aa 10},
429+
'd 4 'e 5 'f {'dd 40 'ee 50},
430+
"g" 6 "h" 7 "i" {"gg" 60 "hh" 70}}]
431+
(testing "happy path"
432+
(let [{:keys [a] :excess exa} (select-keys sample-map [:a :b :c])
433+
{:keys [a b c] :excess exnil} (select-keys sample-map [:a :b :c])
434+
{{:excess exnest} :c} sample-map
435+
{:keys [a c] :excess exkws} (select-keys sample-map [:a :b :c])
436+
{:syms [d f] :excess exsyms} (select-keys sample-map '[d e f])
437+
{:strs [g i] :excess exstrs} (select-keys sample-map ["g" "h" "i"])]
438+
(is (= {:b 2 :c {:aa 10}} exa))
439+
(is (= {:aa 10} exnest))
440+
(is (= {:b 2} exkws))
441+
(is (= '{e 5} exsyms))
442+
(is (= {"h" 7} exstrs))
443+
444+
(testing ":excess predicative use"
445+
(is (nil? exnil))
446+
(is (nil? (let [{:excess ex} {}] ex)))
447+
(is (nil? (let [{:keys [a] :excess ex} nil] ex)))
448+
449+
(let [{:keys [a] :excess ex-some} (select-keys sample-map [:a :b :c])
450+
{:keys [a b c] :excess ex-none} (assoc (select-keys sample-map [:a :b :c]) :b nil)]
451+
(is (some-vals ex-some))
452+
(is (not (some-vals ex-none)))))))
453+
454+
(testing ":excess retains nil values"
455+
(let [{:keys [a] :excess ex-nil1} (assoc (select-keys sample-map [:a :b :c]) :b nil)
456+
{{:keys [aa] :excess ex-nil2} :c} (assoc-in sample-map [:c :bb] nil)]
457+
(is (= {:b nil :c {:aa 10}} ex-nil1))
458+
(is (= {:bb nil} ex-nil2))))
459+
460+
(testing ":excess and :or to ensure that defaults do not show up"
461+
(let [{:keys [a z] :or {z 99} :excess exor} (select-keys sample-map [:a :b :c])]
462+
(is (= {:b 2 :c {:aa 10}} exor))))
463+
464+
(testing "nested :excess, also with &"
465+
(let [{:keys [a] {:keys [aa] :excess exc} :c} sample-map
466+
{:keys! [a & :b :c]
467+
:syms! [& 'd 'e 'f]
468+
:strs! [& "g" "h" "i"]
469+
{:keys [zz] :or {:zz 999} :excess exinner1} :c
470+
{:syms [yy] :or {'yy 999} :excess exinner2} 'f
471+
{:strs [xx] :or {"xx" 999} :excess exinner3} "i"
472+
:excess exouter} sample-map]
473+
(is (nil? exc))
474+
(is (= {:aa 10} exinner1))
475+
(is (= {'dd 40 'ee 50} exinner2))
476+
(is (= {"gg" 60 "hh" 70} exinner3))
477+
(is (= '{:c {:aa 10}, f {dd 40, ee 50}, "i" {"gg" 60, "hh" 70}} exouter))))
478+
479+
(testing ":excess with namespace-qualification"
480+
(let [nsmap {:foo/x 1000, :foo/y 2000, ::z 3000}
481+
{:foo/keys [x] :excess exfoo} nsmap
482+
{::keys [z] :excess exauto} nsmap
483+
{:foo/keys [x] ::keys [z] :excess exmix} nsmap
484+
{:foo/keys [x y] ::keys [z] :excess exall} nsmap]
485+
(is (= {:foo/y 2000 ::z 3000} exfoo))
486+
(is (= {:foo/x 1000 :foo/y 2000} exauto))
487+
(is (= {:foo/y 2000} exmix))
488+
(is (nil? exall))))))
489+
490+
(deftest missing-directive
491+
(let [keys-map {:a 1 :b 2 :nest {:aa 10}}
492+
{:keys! [a b], :missing mkeys-nil} keys-map
493+
{:keys! [a b c], :missing mkeys-c} keys-map
494+
{:keys! [a b & :c], :missing mkeys-c&} keys-map
495+
496+
syms-map '{a 1 b 2 nest {aa 10}}
497+
{:syms! [a b], :missing msyms-nil} syms-map
498+
{:syms! [a b c], :missing msyms-c} syms-map
499+
{:syms! [a b & 'c], :missing msyms-c&} syms-map
500+
501+
strs-map {"a" 1 "b" 2 "nest" {"aa" 10}}
502+
{:strs! [a b], :missing mstrs-nil} strs-map
503+
{:strs! [a b c], :missing mstrs-c} strs-map
504+
{:strs! [a b & "c"], :missing mstrs-c&} strs-map
505+
506+
q-map {:foo/a 1 :b 2 :foo/c 3 ::d 4}
507+
{:keys! [foo/a :foo/c] :missing mq-nil} q-map
508+
{:keys! [b & :foo/d] :missing mq-d} q-map
509+
{:keys! [foo/a & :foo/d] :missing mq-d&} q-map
510+
{:foo/keys! [a c] :missing q-nil} q-map
511+
{:foo/keys! [a & :foo/d] :missing q-d} q-map
512+
{:foo/keys! [a & :foo/d] :missing q-d&} q-map
513+
{::keys! [d] :missing aq-nil} q-map]
514+
515+
(testing "1-level :missing keys for keys/qkeys/syms/strs"
516+
(is (nil? mkeys-nil))
517+
(is (= mkeys-c {:c nil}))
518+
(is (= mkeys-c& {:c nil}))
519+
520+
(is (nil? msyms-nil))
521+
(is (= msyms-c '{c nil}))
522+
(is (= msyms-c& '{c nil}))
523+
524+
(is (nil? mstrs-nil))
525+
(is (= mstrs-c {"c" nil}))
526+
(is (= mstrs-c& {"c" nil}))
527+
528+
(is (nil? mq-nil))
529+
(is (= mq-d #:foo{:d nil}))
530+
(is (= mq-d& #:foo{:d nil}))
531+
(is (nil? q-nil))
532+
(is (= q-d #:foo{:d nil}))
533+
(is (= q-d& #:foo{:d nil}))
534+
(is (nil? aq-nil)))
535+
536+
(testing "required nested map that also has required keys, covering the following cases:
537+
- :nest is missing
538+
- :nest is nil
539+
- :nest is a map missing :x and/or :y
540+
- :nest is a map having everything that's required"
541+
(let [sample-nest {:a 0 :b 0}]
542+
(are [input-map expected] (= expected
543+
(let [{:keys! [a b & :nest]
544+
{:keys! [x y]} :nest
545+
:missing mkeys-missing}
546+
input-map]
547+
mkeys-missing))
548+
549+
sample-nest {:nest {:x nil, :y nil}}
550+
551+
(assoc sample-nest :nest nil) {:nest {:x nil, :y nil}}
552+
553+
(assoc sample-nest :nest {:x 1}) {:nest {:y nil}}
554+
555+
(assoc sample-nest :nest {:x 1 :y 2}) nil)))
556+
557+
(testing "that a nested map required keys is captured with the outer :missing"
558+
(let [{:keys! [a b], {:keys! [bb]} :nest :missing mkeys-outer} keys-map]
559+
(is (= mkeys-outer {:nest {:bb nil}}))))))
560+
427561
(comment
428562

429563
(cljs.test/run-tests)

0 commit comments

Comments
 (0)