|
| 1 | +// A little custom class to showcase the minimum trait implementation. |
| 2 | +// All other Indexable methods will be based on this minimal implementation. |
| 3 | +:class _ASCIILettersExample |
| 4 | + :is Indexable(String) |
| 5 | + |
| 6 | + :fun size USize: 26 |
| 7 | + :fun "[]!"(index USize) |
| 8 | + error! if index >= @size |
| 9 | + "\((index + 'a').format.printable_ascii)" |
| 10 | + |
| 11 | +:class _ArrayWrapperExample(T val) // TODO: val constraint should not be required |
| 12 | + :is Indexable(T) |
| 13 | + :let array Array(T) |
| 14 | + :new (@array) |
| 15 | + |
| 16 | + :fun size: @array.size |
| 17 | + :fun "[]!"(index USize): @array[index]! |
| 18 | + |
1 | 19 | :class Savi.Indexable.Spec |
2 | 20 | :is Spec |
3 | 21 | :const describes: "Indexable" |
4 | 22 |
|
5 | 23 | :it "yields each element" |
6 | 24 | array Array(String) = [] |
7 | | - ["foo", "bar", "baz"].each -> (string | array << string) |
8 | | - assert: array == ["foo", "bar", "baz"] |
| 25 | + _ASCIILettersExample.new.each -> (string | array << string) |
| 26 | + assert: array == [ |
| 27 | + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m" |
| 28 | + "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" |
| 29 | + ] |
9 | 30 |
|
10 | 31 | :it "yields each element of a subslice" |
11 | 32 | array Array(String) = [] |
12 | | - ["a", "b", "c", "d", "e", "f"].each(1, 5) -> (string | array << string) |
| 33 | + _ASCIILettersExample.new.each(1, 5) -> (string | array << string) |
13 | 34 | assert: array == ["b", "c", "d", "e"] |
14 | 35 |
|
15 | 36 | :it "yields each element along with the index" |
16 | 37 | array_a Array(String) = [] |
17 | 38 | array_b Array(USize) = [] |
18 | | - ["foo", "bar", "baz"].each_with_index -> (string, index | |
| 39 | + _ASCIILettersExample.new.each_with_index -> (string, index | |
19 | 40 | array_a << string |
20 | 41 | array_b << index |
21 | 42 | ) |
22 | | - assert: array_a == ["foo", "bar", "baz"] |
23 | | - assert: array_b == [0, 1, 2] |
| 43 | + assert: array_a == [ |
| 44 | + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m" |
| 45 | + "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" |
| 46 | + ] |
| 47 | + assert: array_b == [ |
| 48 | + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 |
| 49 | + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 |
| 50 | + ] |
24 | 51 |
|
25 | 52 | :it "yields each element, in reverse" |
26 | 53 | array Array(String) = [] |
27 | | - ["foo", "bar", "baz"].reverse_each -> (string | array << string) |
28 | | - assert: array == ["baz", "bar", "foo"] |
| 54 | + _ASCIILettersExample.new.reverse_each -> (string | array << string) |
| 55 | + assert: array == [ |
| 56 | + "z", "y", "x", "w", "v", "u", "t", "s", "r", "q", "p", "o", "n" |
| 57 | + "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a" |
| 58 | + ] |
29 | 59 |
|
30 | 60 | :it "yields each element, in reverse, along with the index" |
31 | 61 | array_a Array(String) = [] |
32 | 62 | array_b Array(USize) = [] |
33 | | - ["foo", "bar", "baz"].reverse_each_with_index -> (string, index | |
| 63 | + _ASCIILettersExample.new.reverse_each_with_index -> (string, index | |
34 | 64 | array_a << string |
35 | 65 | array_b << index |
36 | 66 | ) |
37 | | - assert: array_b == [2, 1, 0] |
38 | | - assert: |
39 | | - array_a == ["baz", "bar", "foo"] |
40 | | - |
41 | | - :it "yields each element, stopping early if the criteria is met" |
42 | | - array Array(String) = [] |
43 | | - early_stop = ["foo", "bar", "baz"].each_until -> (string | |
44 | | - array << string |
45 | | - string == "bar" |
46 | | - ) |
47 | | - assert: early_stop |
48 | | - assert: array == ["foo", "bar"] |
49 | | - |
50 | | - array.clear |
51 | | - early_stop = ["foo", "bar", "baz"].each_until -> (string | |
52 | | - array << string |
53 | | - string == "bard" |
54 | | - ) |
55 | | - assert: early_stop.is_false |
56 | | - assert: array == ["foo", "bar", "baz"] |
57 | | - |
58 | | - :it "yields each element of a subslice, stopping early if the criteria is met" |
59 | | - array Array(String) = [] |
60 | | - early_stop = ["a", "b", "c", "d", "e", "f"].each_until(1, 5) -> (string | |
61 | | - array << string |
62 | | - string == "d" |
63 | | - ) |
64 | | - assert: early_stop |
65 | | - assert: array == ["b", "c", "d"] |
66 | | - |
67 | | - array.clear |
68 | | - early_stop = ["a", "b", "c", "d", "e", "f"].each_until(1, 5) -> (string | |
69 | | - array << string |
70 | | - string == "z" |
71 | | - ) |
72 | | - assert: early_stop.is_false |
73 | | - assert: array == ["b", "c", "d", "e"] |
| 67 | + assert: array_a == [ |
| 68 | + "z", "y", "x", "w", "v", "u", "t", "s", "r", "q", "p", "o", "n" |
| 69 | + "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a" |
| 70 | + ] |
| 71 | + assert: array_b == [ |
| 72 | + 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13 |
| 73 | + 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 |
| 74 | + ] |
74 | 75 |
|
75 | 76 | :it "returns True if any element meets the criteria" |
76 | | - array Array(U8) = [11, 22, 33, 44, 36, 27, 18] |
| 77 | + array = _ArrayWrapperExample(U8).new([11, 22, 33, 44, 36, 27, 18]) |
77 | 78 | assert: array.has_any -> (num | num > 30) |
78 | 79 | assert: array.has_any -> (num | num > 50).is_false |
79 | 80 |
|
80 | 81 | :it "returns True if all elements meet the criteria" |
81 | | - array Array(U8) = [11, 22, 33, 44, 36, 27, 18] |
| 82 | + array = _ArrayWrapperExample(U8).new([11, 22, 33, 44, 36, 27, 18]) |
82 | 83 | assert: array.has_all -> (num | num > 10) |
83 | 84 | assert: array.has_all -> (num | num > 30).is_false |
84 | 85 |
|
85 | 86 | :it "finds the first element that meets the criteria" |
86 | | - array Array(U8) = [11, 22, 33, 44, 36, 27, 18] |
| 87 | + array = _ArrayWrapperExample(U8).new([11, 22, 33, 44, 36, 27, 18]) |
87 | 88 | assert: array.find! -> (num | num > 30) == 33 |
88 | 89 | assert error: array.find! -> (num | num > 50) |
89 | 90 |
|
90 | 91 | :it "finds the first index that meets the criteria" |
91 | | - array Array(U8) = [11, 22, 33, 44, 36, 27, 18] |
| 92 | + array = _ArrayWrapperExample(U8).new([11, 22, 33, 44, 36, 27, 18]) |
92 | 93 | assert: array.find_index! -> (num | num > 30) == 2 |
93 | 94 | assert error: array.find_index! -> (num | num > 50) |
94 | 95 |
|
95 | 96 | :it "finds, starting from the end, the first element that meets the criteria" |
96 | | - array Array(U8) = [11, 22, 33, 44, 36, 27, 18] |
| 97 | + array = _ArrayWrapperExample(U8).new([11, 22, 33, 44, 36, 27, 18]) |
97 | 98 | assert: array.reverse_find! -> (num | num > 30) == 36 |
98 | 99 | assert error: array.reverse_find! -> (num | num > 50) |
99 | 100 |
|
100 | 101 | :it "finds, starting from the end, the first index that meets the criteria" |
101 | | - array Array(U8) = [11, 22, 33, 44, 36, 27, 18] |
| 102 | + array = _ArrayWrapperExample(U8).new([11, 22, 33, 44, 36, 27, 18]) |
102 | 103 | assert: array.reverse_find_index! -> (num | num > 30) == 4 |
103 | 104 | assert error: array.reverse_find_index! -> (num | num > 50) |
104 | 105 |
|
105 | 106 | :it "selects those elements that meet the criteria" |
106 | | - array Array(U8) = [11, 22, 33, 44, 36, 27, 18] |
| 107 | + array = _ArrayWrapperExample(U8).new([11, 22, 33, 44, 36, 27, 18]) |
107 | 108 | selected = array.select -> (num | num < 30) |
108 | 109 | assert: selected == [11, 22, 27, 18] |
109 | 110 |
|
110 | 111 | :it "rejects those elements that do not meet the criteria" |
111 | | - array Array(U8) = [1, 2, 3, 4, 5] |
| 112 | + array = _ArrayWrapperExample(U8).new([1, 2, 3, 4, 5]) |
112 | 113 | odds = array.reject -> (num | num % 2 == 0) |
113 | 114 | assert: odds == [1, 3, 5] |
114 | 115 |
|
115 | 116 | :it "rejects nothing from an empty array" |
116 | | - array Array(U8) = [] |
117 | | - assert: array.reject -> (num | num % 2 == 0) == array |
| 117 | + array = _ArrayWrapperExample(U8).new([]) |
| 118 | + assert: array.reject -> (num | num % 2 == 0) == [] |
118 | 119 |
|
119 | 120 | :it "rejects nothing if criteria is always false" |
120 | | - array Array(U8) = [1, 2, 3] |
121 | | - assert: array.reject -> (num | False) == array |
| 121 | + array = _ArrayWrapperExample(U8).new([1, 2, 3]) |
| 122 | + assert: array.reject -> (num | False) == [1, 2, 3] |
0 commit comments