summaryrefslogtreecommitdiff
path: root/test/unheard/strudel/mini_notation_compiler_test.clj
blob: 38ae8bed297bbca97e196e722cc3279e2b91ee28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
(ns unheard.strudel.mini-notation-compiler-test
  (:refer-clojure :exclude [compile])
  (:require [clojure.test :refer [deftest is testing]]
            [unheard.strudel.mini-notation-compiler :refer [compile]]))

(deftest compile-tests
  (testing "single atom" (is (= :c (compile "c" keyword))))
  (testing "rest literal" (is (= :r (compile "~" keyword))))
  (testing "simple sequence - space separated"
    (is (= '(l :c :e :g) (compile "c e g" keyword))))
  (testing "sequence with rest"
    (is (= '(l :c :r :g) (compile "c ~ g" keyword))))
  (testing "subdivision with brackets"
    (is (= '(l :c (l :e :g) :b) (compile "c [e g] b" keyword))))
  (testing "nested brackets"
    (is (= '(l :a (l :b (l :c :d))) (compile "a [b [c d]]" keyword))))
  (testing "angle brackets - alternation"
    (is (= '(f :c :e :g :b) (compile "<c e g b>" keyword))))
  (testing "parallel with commas"
    (is (= '(p :c :e :g) (compile "c,e,g" keyword))))
  (testing "parallel in sequence"
    (is (= '(l (p :c :e :g) (p :d :f :a)) (compile "[c,e,g] [d,f,a]" keyword))))
  (testing "rate modifier - multiplication"
    (is (= '(rate 2 :c) (compile "c*2" keyword))))
  (testing "rate modifier - division"
    (is (= '(rate (/ 1 2) :c) (compile "c/2" keyword))))
  (testing "rate on group"
    (is (= '(rate 2 (l :e :g)) (compile "[e g]*2" keyword))))
  (testing "rate on alternation"
    (is (= '(rate 2 (f :c :e :g :b)) (compile "<c e g b>*2" keyword))))
  (testing "elongate modifier"
    (is (= '(elongate 3 :c) (compile "c@3" keyword))))
  (testing "elongate in sequence"
    (is (= '(l (elongate 2 :a) :b :c) (compile "a@2 b c" keyword))))
  (testing "replication modifier" (is (= '(rep 3 :c) (compile "c!3" keyword))))
  (testing "replication in sequence"
    (is (= '(l (rep 2 :x) :y) (compile "x!2 y" keyword))))
  (testing "multiple modifiers"
    (is (= '(rate 2 (elongate 3 :c)) (compile "c@3*2" keyword))))
  (testing "complex nested structure"
    (is (= '(l :c (f :e :g) :b :d) (compile "c <e g> b d" keyword))))
  (testing "subdivision with parallel"
    (is (= '(l :x (p :y :z) :w) (compile "x [y,z] w" keyword))))
  (testing "strudel example from docs"
    (is (= '(l :e5 (l :b4 :c5) :d5 (l :c5 :b4))
           (compile "e5 [b4 c5] d5 [c5 b4]" keyword))))
  (testing "chord sequence"
    (is (= '(rate 2 (f (p :g3 :b3 :e4) (p :a3 :c3 :e4)))
           (compile "<[g3,b3,e4] [a3,c3,e4]>*2" keyword))))
  (testing "elongated chord"
    (is (= '(rate 2 (f (elongate 2 (p :g3 :b3 :e4)) (p :a3 :c3 :e4)))
           (compile "<[g3,b3,e4]@2 [a3,c3,e4]>*2" keyword))))
  (testing "replicated chord"
    (is (= '(rate 2 (f (rep 2 (p :g3 :b3 :e4)) (p :a3 :c3 :e4)))
           (compile "<[g3,b3,e4]!2 [a3,c3,e4]>*2" keyword))))
  (testing "rest in subdivision"
    (is (= '(l :b4 (l :r :c5) :d5 :e5) (compile "b4 [~ c5] d5 e5" keyword))))
  (testing "numbers as values" (is (= '(l 1 2 3) (compile "1 2 3" keyword))))
  (testing "rational number rate"
    (is (= '(rate 3/2 :c) (compile "c*3/2" keyword))))
  (testing "whitespace handling"
    (is (= '(l :a :b :c) (compile "  a   b   c  " keyword))))
  (testing "complex real-world pattern"
    (is (= '(l (rate 2 (f :bd :sd)) (p :hat :hat :hat))
           (compile "<bd sd>*2 [hat,hat,hat]" keyword))))
  (testing "newlines are converted to spaces"
    (is (= '(f :a :b :c :d) (compile "<a b\nc d>" keyword))))
  (testing "multi-line pattern with parallel"
    (is (= '(f (l :a :b) (p :c :d)) (compile "<\n[a b]\n[c,d]\n>" keyword))))
  (testing "polymeter - comma creates parallel of forks"
    (is (= '(p (f :a :b) (f :c :d)) (compile "<a b, c d>" keyword))))
  (testing "polymeter - three groups"
    (is (= '(p (f :a :b) (f :c :d) (f :e :f))
           (compile "<a b, c d, e f>" keyword))))
  (testing "polymeter - unequal lengths"
    (is (= '(p (f :a :b :e) (f :c :d)) (compile "<a b e, c d>" keyword))))
  (testing "polymeter - single element per group"
    (is (= '(p :a :c) (compile "<a, c>" keyword))))
  (testing "polymeter - with nested structures"
    (is (= '(p (f (l :a :b) (l :c :d)) (f (l :e :f) (l :g :h)))
           (compile "<[a b] [c d], [e f] [g h]>" keyword))))
  (testing "polymeter - with modifiers"
    (is (= '(rate 2 (p (f :a :b) (f :c :d))) (compile "<a b, c d>*2" keyword))))
  (testing "polymeter - melody and bass pattern"
    (is (= '(p
             (f (l :e5 :b4) (l :a4 :c5))
             (f (rate 4 (l :e2 :e3)) (rate 4 (l :a2 :a3))))
           (compile "<[e5 b4] [a4 c5], [[e2 e3]*4] [[a2 a3]*4]>" keyword)))))