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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
(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)))))
|