xnd 0.2.0dev3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +42 -0
  3. data/Gemfile +3 -0
  4. data/History.md +0 -0
  5. data/README.md +7 -0
  6. data/Rakefile +135 -0
  7. data/ext/ruby_xnd/extconf.rb +70 -0
  8. data/ext/ruby_xnd/float_pack_unpack.c +277 -0
  9. data/ext/ruby_xnd/float_pack_unpack.h +39 -0
  10. data/ext/ruby_xnd/gc_guard.c +36 -0
  11. data/ext/ruby_xnd/gc_guard.h +12 -0
  12. data/ext/ruby_xnd/include/xnd.h +449 -0
  13. data/ext/ruby_xnd/lib/libxnd.a +0 -0
  14. data/ext/ruby_xnd/lib/libxnd.so +1 -0
  15. data/ext/ruby_xnd/lib/libxnd.so.0 +1 -0
  16. data/ext/ruby_xnd/lib/libxnd.so.0.2.0dev3 +0 -0
  17. data/ext/ruby_xnd/memory_block_object.c +32 -0
  18. data/ext/ruby_xnd/memory_block_object.h +33 -0
  19. data/ext/ruby_xnd/ruby_xnd.c +1953 -0
  20. data/ext/ruby_xnd/ruby_xnd.h +61 -0
  21. data/ext/ruby_xnd/ruby_xnd_internal.h +85 -0
  22. data/ext/ruby_xnd/util.h +170 -0
  23. data/ext/ruby_xnd/xnd/AUTHORS.txt +5 -0
  24. data/ext/ruby_xnd/xnd/INSTALL.txt +134 -0
  25. data/ext/ruby_xnd/xnd/LICENSE.txt +29 -0
  26. data/ext/ruby_xnd/xnd/MANIFEST.in +3 -0
  27. data/ext/ruby_xnd/xnd/Makefile.in +80 -0
  28. data/ext/ruby_xnd/xnd/README.rst +44 -0
  29. data/ext/ruby_xnd/xnd/config.guess +1530 -0
  30. data/ext/ruby_xnd/xnd/config.h.in +22 -0
  31. data/ext/ruby_xnd/xnd/config.sub +1782 -0
  32. data/ext/ruby_xnd/xnd/configure +4867 -0
  33. data/ext/ruby_xnd/xnd/configure.ac +164 -0
  34. data/ext/ruby_xnd/xnd/doc/Makefile +14 -0
  35. data/ext/ruby_xnd/xnd/doc/_static/copybutton.js +66 -0
  36. data/ext/ruby_xnd/xnd/doc/conf.py +26 -0
  37. data/ext/ruby_xnd/xnd/doc/index.rst +44 -0
  38. data/ext/ruby_xnd/xnd/doc/libxnd/data-structures.rst +186 -0
  39. data/ext/ruby_xnd/xnd/doc/libxnd/functions.rst +148 -0
  40. data/ext/ruby_xnd/xnd/doc/libxnd/index.rst +25 -0
  41. data/ext/ruby_xnd/xnd/doc/releases/index.rst +34 -0
  42. data/ext/ruby_xnd/xnd/doc/xnd/align-pack.rst +96 -0
  43. data/ext/ruby_xnd/xnd/doc/xnd/buffer-protocol.rst +42 -0
  44. data/ext/ruby_xnd/xnd/doc/xnd/index.rst +30 -0
  45. data/ext/ruby_xnd/xnd/doc/xnd/quickstart.rst +62 -0
  46. data/ext/ruby_xnd/xnd/doc/xnd/types.rst +674 -0
  47. data/ext/ruby_xnd/xnd/install-sh +527 -0
  48. data/ext/ruby_xnd/xnd/libxnd/Makefile.in +102 -0
  49. data/ext/ruby_xnd/xnd/libxnd/Makefile.vc +112 -0
  50. data/ext/ruby_xnd/xnd/libxnd/bitmaps.c +345 -0
  51. data/ext/ruby_xnd/xnd/libxnd/contrib.h +313 -0
  52. data/ext/ruby_xnd/xnd/libxnd/copy.c +944 -0
  53. data/ext/ruby_xnd/xnd/libxnd/equal.c +1216 -0
  54. data/ext/ruby_xnd/xnd/libxnd/inline.h +154 -0
  55. data/ext/ruby_xnd/xnd/libxnd/overflow.h +147 -0
  56. data/ext/ruby_xnd/xnd/libxnd/split.c +286 -0
  57. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.in +39 -0
  58. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.vc +44 -0
  59. data/ext/ruby_xnd/xnd/libxnd/tests/README.txt +2 -0
  60. data/ext/ruby_xnd/xnd/libxnd/tests/runtest.c +101 -0
  61. data/ext/ruby_xnd/xnd/libxnd/tests/test.h +48 -0
  62. data/ext/ruby_xnd/xnd/libxnd/tests/test_fixed.c +108 -0
  63. data/ext/ruby_xnd/xnd/libxnd/xnd.c +1304 -0
  64. data/ext/ruby_xnd/xnd/libxnd/xnd.h +449 -0
  65. data/ext/ruby_xnd/xnd/python/test_xnd.py +3144 -0
  66. data/ext/ruby_xnd/xnd/python/xnd/__init__.py +290 -0
  67. data/ext/ruby_xnd/xnd/python/xnd/_xnd.c +2822 -0
  68. data/ext/ruby_xnd/xnd/python/xnd/contrib/pretty.py +850 -0
  69. data/ext/ruby_xnd/xnd/python/xnd/docstrings.h +129 -0
  70. data/ext/ruby_xnd/xnd/python/xnd/pyxnd.h +200 -0
  71. data/ext/ruby_xnd/xnd/python/xnd/util.h +182 -0
  72. data/ext/ruby_xnd/xnd/python/xnd_randvalue.py +1121 -0
  73. data/ext/ruby_xnd/xnd/python/xnd_support.py +106 -0
  74. data/ext/ruby_xnd/xnd/setup.py +303 -0
  75. data/ext/ruby_xnd/xnd/vcbuild/INSTALL.txt +42 -0
  76. data/ext/ruby_xnd/xnd/vcbuild/runtest32.bat +16 -0
  77. data/ext/ruby_xnd/xnd/vcbuild/runtest64.bat +14 -0
  78. data/ext/ruby_xnd/xnd/vcbuild/vcbuild32.bat +29 -0
  79. data/ext/ruby_xnd/xnd/vcbuild/vcbuild64.bat +29 -0
  80. data/ext/ruby_xnd/xnd/vcbuild/vcclean.bat +13 -0
  81. data/ext/ruby_xnd/xnd/vcbuild/vcdistclean.bat +14 -0
  82. data/lib/ruby_xnd.so +0 -0
  83. data/lib/xnd.rb +306 -0
  84. data/lib/xnd/monkeys.rb +29 -0
  85. data/lib/xnd/version.rb +6 -0
  86. data/spec/debug_spec.rb +9 -0
  87. data/spec/gc_guard_spec.rb +10 -0
  88. data/spec/leakcheck.rb +9 -0
  89. data/spec/spec_helper.rb +877 -0
  90. data/spec/type_inference_spec.rb +81 -0
  91. data/spec/xnd_spec.rb +2921 -0
  92. data/xnd.gemspec +47 -0
  93. metadata +215 -0
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe XND::TypeInference do
4
+ MAX_DIM = NDTypes::MAX_DIM
5
+
6
+ context ".accumulate" do
7
+ it "returns accumulated of sum of an Array" do
8
+ arr = [1,2,3,4,5]
9
+ result = [1,3,6,10,15]
10
+
11
+ expect(XND::TypeInference.accumulate(arr)).to eq(result)
12
+ end
13
+ end
14
+
15
+ context ".search" do
16
+ it "searches for data and shape and loads in acc Array" do
17
+ data = [[0, 1], [2, 3, 4], [5, 6, 7, 8]]
18
+ result = [[3], [2, 3, 4], [0, 1, 2, 3, 4, 5, 6, 7, 8], *(Array.new(MAX_DIM-2) { [] })]
19
+
20
+ min_level = MAX_DIM + 1
21
+ max_level = 0
22
+ acc = Array.new(MAX_DIM + 1) { [] }
23
+ minmax = [min_level, max_level]
24
+
25
+ XND::TypeInference.search max_level, data, acc, minmax
26
+
27
+ expect(acc).to eq(result)
28
+ expect(minmax[0]).to eq(minmax[1])
29
+ end
30
+ end
31
+
32
+ context ".data_shapes" do
33
+ it "extracts the shape of nested Array data" do
34
+ data = [[0, 1], [2, 3, 4], [5, 6, 7, 8]]
35
+ result = [[0, 1, 2, 3, 4, 5, 6, 7, 8], [[2, 3, 4], [3]]]
36
+
37
+ expect(XND::TypeInference.data_shapes(data)).to eq(result)
38
+ end
39
+
40
+ it "works for empty array" do
41
+ data = []
42
+ result = [[], [[0]]]
43
+
44
+ expect(XND::TypeInference.data_shapes(data)).to eq(result)
45
+ end
46
+
47
+ it "works for empty nested array" do
48
+ data = [[]]
49
+ result = [[], [[0], [1]]]
50
+
51
+ expect(XND::TypeInference.data_shapes(data)).to eq(result)
52
+ end
53
+ end
54
+
55
+ context ".add_dim" do
56
+ it "calculates dimension" do
57
+
58
+ end
59
+ end
60
+
61
+ context ".type_of" do
62
+ it "generates correct ndtype for fixed array" do
63
+ value = [
64
+ [1,2,3],
65
+ [5,6,7]
66
+ ]
67
+ type = NDTypes.new "2 * 3 * int64"
68
+
69
+ expect(XND::TypeInference.type_of(value)).to eq(type)
70
+ end
71
+
72
+ it "generates correct ndtype for hash" do
73
+ value = {
74
+ "a" => "xyz",
75
+ "b" => [1,2,3]
76
+ }
77
+ type = NDTypes.new "{a : string, b : 3 * int64}"
78
+ expect(XND::TypeInference.type_of(value)).to eq(type)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,2921 @@
1
+ require 'spec_helper'
2
+
3
+ describe XND do
4
+ context ".new" do
5
+ context "Type Inference" do
6
+ context "Tuple" do
7
+ d = {'a' => XND::T.new(2.0, "bytes".b), 'b' => XND::T.new("str", Float::INFINITY) }
8
+ typeof_d = "{a: (float64, bytes), b: (string, float64)}"
9
+
10
+ [
11
+ [XND::T.new(), "()"],
12
+ [XND::T.new(XND::T.new()), "(())"],
13
+ [XND::T.new(XND::T.new(), XND::T.new()), "((), ())"],
14
+ [XND::T.new(XND::T.new(XND::T.new()), XND::T.new()), "((()), ())"],
15
+ [XND::T.new(XND::T.new(XND::T.new()), XND::T.new(XND::T.new(), XND::T.new())),
16
+ "((()), ((), ()))"],
17
+ [XND::T.new(1, 2, 3), "(int64, int64, int64)"],
18
+ [XND::T.new(1.0, 2, "str"), "(float64, int64, string)"],
19
+ [XND::T.new(1.0, 2, XND::T.new("str", "bytes".b, d)),
20
+ "(float64, int64, (string, bytes, #{typeof_d}))"]
21
+ ].each do |v, t|
22
+ it "type: #{t}" do
23
+ x = XND.new v
24
+
25
+ expect(x.type).to eq(NDT.new(t))
26
+ expect(x.value).to eq(XND::TypeInference.convert_xnd_t_to_ruby_array(v))
27
+ end
28
+ end
29
+ end
30
+
31
+ context "Record" do
32
+ d = {'a' => XND::T.new(2.0, "bytes".b), 'b' => XND::T.new("str", Float::INFINITY) }
33
+ typeof_d = "{a: (float64, bytes), b: (string, float64)}"
34
+
35
+ [
36
+ [{}, "{}"],
37
+ [{'x' => {}}, "{x: {}}"],
38
+ [{'x' => {}, 'y' => {}}, "{x: {}, y: {}}"],
39
+ [{'x' => {'y' => {}}, 'z' => {}}, "{x: {y: {}}, z: {}}"],
40
+ [{'x' => {'y' => {}}, 'z' => {'a' => {}, 'b' => {}}}, "{x: {y: {}}, z: {a: {}, b: {}}}"],
41
+ [d, typeof_d]
42
+ ].each do |v, t|
43
+ it "type: #{t}" do
44
+ x = XND.new v
45
+
46
+ expect(x.type).to eq(NDT.new(t))
47
+ expect(x.value).to eq(v)
48
+ end
49
+ end
50
+ end
51
+
52
+ context "Float64" do
53
+ d = {'a' => 2.221e100, 'b' => Float::INFINITY}
54
+ typeof_d = "{a: float64, b: float64}"
55
+
56
+ [
57
+ # 'float64' is the default dtype if there is no data at all.
58
+ [[], "0 * float64"],
59
+ [[[]], "1 * 0 * float64"],
60
+ [[[], []], "2 * 0 * float64"],
61
+ [[[[]], [[]]], "2 * 1 * 0 * float64"],
62
+ [[[[]], [[], []]],
63
+ "var(offsets=[0, 2]) * var(offsets=[0, 1, 3]) * var(offsets=[0, 0, 0, 0]) * float64"],
64
+
65
+ [[0.0], "1 * float64"],
66
+ [[0.0, 1.2], "2 * float64"],
67
+ [[[0.0], [1.2]], "2 * 1 * float64"],
68
+
69
+ [d, typeof_d],
70
+ [[d] * 2, "2 * %s" % typeof_d],
71
+ [[[d] * 2] * 10, "10 * 2 * #{typeof_d}"]
72
+ ].each do |v, t|
73
+ it "type: #{t}" do
74
+ x = XND.new v
75
+
76
+ expect(x.type).to eq(NDT.new(t))
77
+ expect(x.value).to eq(v)
78
+ end
79
+ end
80
+ end
81
+
82
+ context "Complex128" do
83
+ d = {'a' => 3.123+10i, 'b' => Complex(Float::INFINITY, Float::INFINITY)}
84
+ typeof_d = "{a: complex128, b: complex128}"
85
+
86
+ [
87
+ [[1+3e300i], "1 * complex128"],
88
+ [[-2.2-5i, 1.2-10i], "2 * complex128"],
89
+ [[-2.2-5i, 1.2-10i, nil], "3 * ?complex128"],
90
+ [[[-1+3i], [-3+5i]], "2 * 1 * complex128"],
91
+
92
+ [d, typeof_d],
93
+ [[d] * 2, "2 * #{typeof_d}"],
94
+ [[[d] * 2] * 10, "10 * 2 * #{typeof_d}"]
95
+ ].each do |v, t|
96
+ it "type: #{t}" do
97
+ x = XND.new v
98
+
99
+ expect(x.type).to eq(NDT.new(t))
100
+ expect(x.value).to eq(v)
101
+ end
102
+ end
103
+ end
104
+
105
+ context "Int64" do
106
+ t = XND::T.new(1, -2, -3)
107
+ typeof_t = "(int64, int64, int64)"
108
+
109
+ [
110
+ [[0], "1 * int64"],
111
+ [[0, 1], "2 * int64"],
112
+ [[[0], [1]], "2 * 1 * int64"],
113
+
114
+ [t, typeof_t],
115
+ [[t] * 2, "2 * #{typeof_t}"],
116
+ [[[t] * 2] * 10, "10 * 2 * #{typeof_t}"]
117
+ ].each do |v, t|
118
+ it "type: #{t}" do
119
+ x = XND.new v
120
+
121
+ expect(x.type).to eq(NDT.new(t))
122
+ expect(x.value).to eq(XND::TypeInference.convert_xnd_t_to_ruby_array(v))
123
+ end
124
+ end
125
+ end
126
+
127
+ context "String" do
128
+ t = XND::T.new("supererogatory", "exiguous")
129
+ typeof_t = "(string, string)"
130
+
131
+ [
132
+ [["mov"], "1 * string"],
133
+ [["mov", "$0"], "2 * string"],
134
+ [[["cmp"], ["$0"]], "2 * 1 * string"],
135
+
136
+ [t, typeof_t],
137
+ [[t] * 2, "2 * %s" % typeof_t],
138
+ [[[t] * 2] * 10, "10 * 2 * %s" % typeof_t]
139
+ ].each do |v, t|
140
+ it "type: #{t}" do
141
+ x = XND.new v
142
+
143
+ expect(x.type).to eq(NDT.new(t))
144
+ expect(x.value).to eq(XND::TypeInference.convert_xnd_t_to_ruby_array(v))
145
+ end
146
+ end
147
+ end
148
+
149
+ context "Bytes" do
150
+ t = XND::T.new("lagrange".b, "points".b)
151
+ typeof_t = "(bytes, bytes)"
152
+
153
+ [
154
+ [["L1".b], "1 * bytes"],
155
+ [["L2".b, "L3".b, "L4".b], "3 * bytes"],
156
+ [[["L5".b], ["none".b]], "2 * 1 * bytes"],
157
+
158
+ [t, typeof_t],
159
+ [[t] * 2, "2 * %s" % typeof_t],
160
+ [[[t] * 2] * 10, "10 * 2 * %s" % typeof_t]
161
+ ].each do |v, t|
162
+ it "type: {t}" do
163
+ x = XND.new v
164
+
165
+ expect(x.type).to eq(NDT.new(t))
166
+ expect(x.value).to eq(XND::TypeInference.convert_xnd_t_to_ruby_array(v))
167
+ end
168
+ end
169
+ end
170
+
171
+ context "Optional" do
172
+ [
173
+ [nil, "?float64"],
174
+ [[nil], "1 * ?float64"],
175
+ [[nil, nil], "2 * ?float64"],
176
+ [[nil, 10], "2 * ?int64"],
177
+ [[nil, 'abc'.b], "2 * ?bytes"],
178
+ [[nil, 'abc'], "2 * ?string"]
179
+ ].each do |v, t|
180
+ it "type: #{t}" do
181
+ x = XND.new v
182
+
183
+ expect(x.type).to eq(NDT.new(t))
184
+ expect(x.value).to eq(v)
185
+ end
186
+ end
187
+
188
+ [
189
+ [nil, []],
190
+ [[], nil],
191
+ [nil, [10]],
192
+ [[nil, [0, 1]], [[2, 3]]]
193
+ ].each do |v|
194
+ it "not implemented for value: #{v}" do
195
+ expect {
196
+ XND.new v
197
+ nnn }.to raise_error(NotImplementedError)
198
+ end
199
+ end
200
+ end # context Optional
201
+ end # context TypeInference
202
+
203
+ context "FixedDim" do
204
+ it "creates a fixed array" do
205
+ o = XND.new([[1,2,3], [2,3,4]])
206
+ expect(o.type).to eq(NDTypes.new("2 * 3 * int64"))
207
+ end
208
+
209
+ it "accepts a type for fixed array" do
210
+ t = NDT.new("2 * 3 * int64")
211
+ o = XND.new([[1,2,3], [2,3,4]], type: t)
212
+
213
+ expect(o.type).to eq(t)
214
+ end
215
+
216
+ it "raises ArgumentError for type and input mismatch" do
217
+ t = NDT.new "3 * 3 * int64"
218
+ expect {
219
+ XND.new([[1,2,3], [2,3,4]], type: t)
220
+ }.to raise_error(ArgumentError)
221
+ end
222
+
223
+ it "raises ValueError for wrong input type in int64 array" do
224
+ t = NDT.new "2 * 3 * int64"
225
+ expect {
226
+ XND.new([[1,2,"peep!"], [2,3,4]], type: t)
227
+ }.to raise_error(TypeError)
228
+ end
229
+ end
230
+
231
+ context "VarDim" do
232
+
233
+ end
234
+
235
+ skip "FixedString" do
236
+ it "creates FixedString utf16" do
237
+ t = "2 * fixed_string(3, 'utf16')"
238
+ v = ["\u1111\u2222\u3333", "\u1112\u2223\u3334"]
239
+ x = XND.new v, type: t
240
+
241
+ expect(x.value).to eq(v)
242
+ end
243
+
244
+ it "creates FixedString utf32 - figure a way to specify 32bit codepoints." do
245
+ t = "2 * fixed_string(3, 'utf32')"
246
+ v = ["\x00\x01\x11\x11\x00\x02\x22\x22\x00\x03\x33\x33".u32,
247
+ "\x00\x01\x11\x12\x00\x02\x22\x23\x00\x03\x33\x34".u32]
248
+ x = XND.new v, type: t
249
+
250
+ expect(x.value).to eq(v)
251
+ end
252
+ end
253
+
254
+ context "String" do
255
+ it "creates new String array" do
256
+ t = '2 * {a: complex128, b: string}'
257
+ x = XND.new([{'a' => 2+3i, 'b' => "thisguy"},
258
+ {'a' => 1+4i, 'b' => "thatguy"}], type: t)
259
+
260
+ expect(x[0]['b'].value).to eq("thisguy")
261
+ expect(x[1]['b'].value).to eq("thatguy")
262
+ end
263
+ end # context String
264
+
265
+ context "Bool" do
266
+ it "from bool" do
267
+ x = XND.new true, type: "bool"
268
+ expect(x.value).to eq(true)
269
+
270
+ x = XND.new false, type: "bool"
271
+ expect(x.value).to eq(false)
272
+ end
273
+
274
+ it "from int" do
275
+ x = XND.new 1, type: "bool"
276
+ expect(x.value).to eq(true)
277
+
278
+ x = XND.new 0, type: "bool"
279
+ expect(x.value).to eq(false)
280
+ end
281
+
282
+ it "from object" do
283
+ x = XND.new [1,2,3], type: "bool"
284
+ expect(x.value).to eq(true)
285
+
286
+ x = XND.new nil, type: "?bool"
287
+ expect(x.value).to eq(nil)
288
+
289
+ expect {
290
+ XND.new nil, type: "bool"
291
+ }.to raise_error(TypeError)
292
+ end
293
+
294
+ skip "tests broken input - how can this be done in Ruby?" do
295
+
296
+ end
297
+ end # context Bool
298
+
299
+ context "Signed" do
300
+ [8, 16, 32, 64].each do |n|
301
+ it "tests bounds for n=#{n}" do
302
+ t = "int#{n}"
303
+
304
+ v = -2**(n-1)
305
+ x = XND.new(v, type: t)
306
+ expect(x.value).to eq(v)
307
+ expect { XND.new v-1, type: t }.to raise_error(RangeError)
308
+
309
+ v = 2**(n-1) - 1
310
+ x = XND.new(v, type: t)
311
+ expect(x.value).to eq(v)
312
+ expect { XND.new v+1, type: t }.to raise_error(RangeError)
313
+ end
314
+ end
315
+ end # context Signed
316
+
317
+ context "Unsigned" do
318
+ [8, 16, 32, 64].each do |n|
319
+ it "tests bounds v-1. n=#{n}" do
320
+ t = "uint#{n}"
321
+
322
+ v = 0
323
+ x = XND.new v, type: t
324
+ expect(x.value).to eq(v)
325
+ expect { XND.new v-1, type: t }.to raise_error(RangeError)
326
+ end
327
+
328
+ it "tests bounds v+1. n=#{n}" do
329
+ t = "uint#{n}"
330
+
331
+ v = 2**n - 2
332
+ x = XND.new v, type: t
333
+ expect(x.value).to eq(v)
334
+ expect { XND.new v+2, type: t }.to raise_error(RangeError)
335
+ end
336
+ end
337
+ end # context Unsigned
338
+
339
+ context "Float32" do
340
+ it "tests inf bounds" do
341
+ inf = Float("0x1.ffffffp+127")
342
+
343
+ expect { XND.new(inf, type: "float32") }.to raise_error(RangeError)
344
+ expect { XND.new(-inf, type: "float32") }.to raise_error(RangeError)
345
+ end
346
+
347
+ it "tests denorm_min bounds" do
348
+ denorm_min = Float("0x1p-149")
349
+
350
+ x = XND.new denorm_min, type: "float32"
351
+ expect(x.value).to eq(denorm_min)
352
+ end
353
+
354
+ it "tests lowest bounds" do
355
+ lowest = Float("-0x1.fffffep+127")
356
+
357
+ x = XND.new lowest, type: "float32"
358
+ expect(x.value.nan?).to eq(lowest.nan?)
359
+ end
360
+
361
+ it "tests max bounds" do
362
+ max = Float("0x1.fffffep+127")
363
+
364
+ x = XND.new max, type: "float32"
365
+ expect(x.value).to eq(max)
366
+ end
367
+
368
+ it "tests special values" do
369
+ x = XND.new Float::INFINITY, type: "float32"
370
+ expect(x.value.infinite?).to eq(1)
371
+
372
+ x = XND.new Float::NAN, type: "float32"
373
+ expect(x.value.nan?).to eq(true)
374
+ end
375
+ end # context Float32
376
+
377
+ context "Float64" do
378
+ it "tests bounds" do
379
+ denorm_min = Float("0x0.0000000000001p-1022")
380
+ lowest = Float("-0x1.fffffffffffffp+1023")
381
+ max = Float("0x1.fffffffffffffp+1023")
382
+
383
+ x = XND.new denorm_min, type: "float64"
384
+ expect(x.value).to eq(denorm_min)
385
+
386
+ x = XND.new lowest, type: "float64"
387
+ expect(x.value).to eq(lowest)
388
+
389
+ x = XND.new max, type: "float64"
390
+ expect(x.value).to eq(max)
391
+ end
392
+
393
+ it "tests special values" do
394
+ x = XND.new Float::INFINITY, type: "float64"
395
+ expect(x.value.infinite?).to eq(1)
396
+
397
+ x = XND.new Float::NAN, type: "float64"
398
+ expect(x.value.nan?).to eq(true)
399
+ end
400
+ end # context Float64
401
+
402
+ context "Complex64" do
403
+ it "tests bounds" do
404
+ denorm_min = Float("0x1p-149")
405
+ lowest = Float("-0x1.fffffep+127")
406
+ max = Float("0x1.fffffep+127")
407
+ inf = Float("0x1.ffffffp+127")
408
+
409
+ v = Complex(denorm_min, denorm_min)
410
+ x = XND.new v, type: "complex64"
411
+ expect(x.value).to eq(v)
412
+
413
+ v = Complex(lowest, lowest)
414
+ x = XND.new v, type: "complex64"
415
+ expect(x.value).to eq(v)
416
+
417
+ v = Complex(max, max)
418
+ x = XND.new v, type: "complex64"
419
+ expect(x.value).to eq(v)
420
+
421
+ v = Complex(inf, inf)
422
+ expect { XND.new v, type: "complex64" }.to raise_error(RangeError)
423
+
424
+ v = Complex(-inf, -inf)
425
+ expect { XND.new v, type: "complex64" }.to raise_error(RangeError)
426
+ end
427
+
428
+ it "tests special values" do
429
+ x = XND.new Complex(Float::INFINITY, 0), type: "complex64"
430
+ expect(x.value.real.infinite?).to eq(1)
431
+ expect(x.value.imag).to eq(0.0)
432
+
433
+ x = XND.new Complex(Float::NAN, 0), type: "complex64"
434
+ expect(x.value.real.nan?).to eq(true)
435
+ expect(x.value.imag).to eq(0.0)
436
+ end
437
+ end # context Complex64
438
+
439
+ context "Complex128" do
440
+ it "tests bounds" do
441
+ denorm_min = Float("0x0.0000000000001p-1022")
442
+ lowest = Float("-0x1.fffffffffffffp+1023")
443
+ max = Float("0x1.fffffffffffffp+1023")
444
+
445
+ v = Complex(denorm_min, denorm_min)
446
+ x = XND.new v, type: "complex128"
447
+ expect(x.value).to eq(v)
448
+
449
+ v = Complex(lowest, lowest)
450
+ x = XND.new v, type: "complex128"
451
+ expect(x.value).to eq(v)
452
+
453
+ v = Complex(max, max)
454
+ x = XND.new v, type: "complex128"
455
+ expect(x.value).to eq(v)
456
+ end
457
+
458
+ it "tests special values" do
459
+ x = XND.new Complex(Float::INFINITY), type: "complex128"
460
+
461
+ expect(x.value.real.infinite?).to eq(1)
462
+ expect(x.value.imag).to eq(0.0)
463
+
464
+ x = XND.new Complex(Float::NAN), type: "complex128"
465
+
466
+ expect(x.value.real.nan?).to eq(true)
467
+ expect(x.value.imag).to eq(0.0)
468
+ end
469
+ end # context Complex128
470
+ end # context .new
471
+
472
+ context ".empty" do
473
+ context "FixedDim" do
474
+ DTYPE_EMPTY_TEST_CASES.each do |v, s|
475
+ [
476
+ [[v] * 0, "0 * #{s}" ],
477
+ [[v] * 1, "1 * #{s}" ],
478
+ [[v] * 2, "2 * #{s}" ],
479
+ [[v] * 1000, "1000 * #{s}" ],
480
+
481
+ [[[v] * 0] * 0, "0 * 0 * #{s}" ],
482
+ [[[v] * 1] * 0, "0 * 1 * #{s}" ],
483
+ [[[v] * 0] * 1, "1 * 0 * #{s}" ],
484
+
485
+ [[[v] * 1] * 1, "1 * 1 * #{s}" ],
486
+ [[[v] * 2] * 1, "1 * 2 * #{s}" ],
487
+ [[[v] * 1] * 2, "2 * 1 * #{s}" ],
488
+ [[[v] * 2] * 2, "2 * 2 * #{s}" ],
489
+ [[[v] * 3] * 2, "2 * 3 * #{s}" ],
490
+ [[[v] * 2] * 3, "3 * 2 * #{s}" ],
491
+ [[[v] * 40] *3 , "3 * 40 * #{s}" ]
492
+ ].each do |vv, ss|
493
+ it "type: #{ss}" do
494
+ t = NDT.new ss
495
+ x = XND.empty ss
496
+
497
+ expect(x.type).to eq(t)
498
+ expect(x.value).to eq(vv)
499
+ expect(x.size).to eq(vv.size)
500
+ end
501
+ end
502
+ end
503
+
504
+ it "checks overflow for general case" do
505
+ expect {
506
+ XND.empty "2147483648 * 2147483648 * 2 * uint8"
507
+ }.to raise_error(ValueError)
508
+ end
509
+ end # context FixedDim
510
+
511
+ context "VarDim" do
512
+ DTYPE_EMPTY_TEST_CASES[0..10].each do |v, s|
513
+ [
514
+ [[v] * 0, "var(offsets=[0,0]) * #{s}"],
515
+ [[v] * 1, "var(offsets=[0,1]) * #{s}"],
516
+ [[v] * 2, "var(offsets=[0,2]) * #{s}"],
517
+ [[v] * 1000, "var(offsets=[0,1000]) * #{s}"],
518
+
519
+ [[[v] * 0] * 1, "var(offsets=[0,1]) * var(offsets=[0,0]) * #{s}"],
520
+
521
+ [[[v], []], "var(offsets=[0,2]) * var(offsets=[0,1,1]) * #{s}"],
522
+ [[[], [v]], "var(offsets=[0,2]) * var(offsets=[0,0,1]) * #{s}"],
523
+
524
+ [[[v], [v]], "var(offsets=[0,2]) * var(offsets=[0,1,2]) * #{s}"],
525
+ [[[v], [v] * 2, [v] * 5], "var(offsets=[0,3]) * var(offsets=[0,1,3,8]) * #{s}"]
526
+ ].each do |vv, ss|
527
+ it "type: #{ss}" do
528
+ t = NDT.new ss
529
+ x = XND.empty ss
530
+
531
+ expect(x.type).to eq(t)
532
+ expect(x.value).to eq(vv)
533
+ expect(x.size).to eq(vv.size)
534
+ end
535
+ end
536
+ end
537
+
538
+ it "returns empty view" do
539
+ inner = [[0+0i] * 5] * 4
540
+ x = XND.empty "2 * 3 * ref(4 * 5 * complex128)"
541
+
542
+ y = x[1][2]
543
+ expect(y.is_a?(XND)).to eq(true)
544
+ expect(y.value).to eq(inner)
545
+
546
+ y = x[1, 2]
547
+ expect(y.is_a?(XND)).to eq(true)
548
+ expect(y.value).to eq(inner)
549
+ end
550
+ end # context VarDim
551
+
552
+ context "Fortran" do
553
+ DTYPE_EMPTY_TEST_CASES.each do |v, s|
554
+ [
555
+ [[v] * 0, "!0 * #{s}"],
556
+ [[v] * 1, "!1 * #{s}"],
557
+ [[v] * 2, "!2 * #{s}"],
558
+ [[v] * 1000, "!1000 * #{s}"],
559
+
560
+ [[[v] * 0] * 0, "!0 * 0 * #{s}"],
561
+ [[[v] * 1] * 0, "!0 * 1 * #{s}"],
562
+ [[[v] * 0] * 1, "!1 * 0 * #{s}"],
563
+
564
+ [[[v] * 1] * 1, "!1 * 1 * #{s}"],
565
+ [[[v] * 2] * 1, "!1 * 2 * #{s}"],
566
+ [[[v] * 1] * 2, "!2 * 1 * #{s}"],
567
+ [[[v] * 2] * 2, "!2 * 2 * #{s}"],
568
+ [[[v] * 3] * 2, "!2 * 3 * #{s}"],
569
+ [[[v] * 2] * 3, "!3 * 2 * #{s}"],
570
+ [[[v] * 40] * 3, "!3 * 40 * #{s}"]
571
+ ].each do |vv, ss|
572
+ it "type: #{ss}" do
573
+ t = NDT.new ss
574
+ x = XND.empty ss
575
+
576
+ expect(x.type).to eq(t)
577
+ expect(x.value).to eq(vv)
578
+ expect(x.size).to eq(vv.size)
579
+ end
580
+ end
581
+ end
582
+ end # context Fortran
583
+
584
+ context "SymbolicDim" do
585
+ DTYPE_EMPTY_TEST_CASES.each do |_, s|
586
+ [
587
+ [ValueError, "N * #{s}"],
588
+ [ValueError, "10 * N * #{s}"],
589
+ [ValueError, "N * 10 * N * #{s}"],
590
+ [ValueError, "X * 10 * N * #{s}"]
591
+ ].each do |err, ss|
592
+ it "raises error for type: #{ss}" do
593
+ t = NDT.new ss
594
+
595
+ expect {
596
+ XND.empty t
597
+ }.to raise_error(err)
598
+ end
599
+ end
600
+ end
601
+ end
602
+
603
+ context "EllipsisDim" do
604
+ DTYPE_EMPTY_TEST_CASES.each do |_, s|
605
+ [
606
+ [ValueError, "... * #{s}"],
607
+ [ValueError, "Dims... * #{s}"],
608
+ [ValueError, "... * 10 * #{s}"],
609
+ [ValueError, "B... *2 * 3 * ref(#{s})"],
610
+ [ValueError, "A... * 10 * Some(ref(#{s}))"],
611
+ [ValueError, "B... * 2 * 3 * Some(ref(ref(#{s})))"]
612
+ ].each do |err, ss|
613
+ it "raises error for type: #{ss}" do
614
+ t = NDT.new ss
615
+
616
+ expect {
617
+ XND.empty ss
618
+ }.to raise_error(err)
619
+ end
620
+ end
621
+ end
622
+ end
623
+
624
+ context "Tuple" do
625
+ DTYPE_EMPTY_TEST_CASES.each do |v, s|
626
+ [
627
+ [[v], "(#{s})"],
628
+ [[[v]], "((#{s}))"],
629
+ [[[[v]]], "(((#{s})))"],
630
+
631
+ [[[v] * 0], "(0 * #{s})"],
632
+ [[[[v] * 0]], "((0 * #{s}))"],
633
+ [[[v] * 1], "(1 * #{s})"],
634
+ [[[[v] * 1]], "((1 * #{s}))"],
635
+ [[[v] * 3], "(3 * #{s})"],
636
+ [[[[v] * 3]], "((3 * #{s}))"]
637
+ ].each do |vv, ss|
638
+ it "type: #{ss}" do
639
+ t = NDT.new ss
640
+ x = XND.empty ss
641
+
642
+ expect(x.type).to eq(t)
643
+ expect(x.value).to eq(vv)
644
+ expect(x.size).to eq(vv.size)
645
+ end
646
+ end
647
+ end
648
+ end
649
+
650
+ context "Record" do
651
+ DTYPE_EMPTY_TEST_CASES.each do |v, s|
652
+ [
653
+ [{'x' => v}, "{x: #{s}}"],
654
+ [{'x' => {'y' => v}}, "{x: {y: #{s}}}"],
655
+
656
+ [{'x' => [v] * 0}, "{x: 0 * #{s}}"],
657
+ [{'x' => {'y' => [v] * 0}}, "{x: {y: 0 * #{s}}}"],
658
+ [{'x' => [v] * 1}, "{x: 1 * #{s}}"],
659
+ [{'x' => [v] * 3}, "{x: 3 * #{s}}"]
660
+ ].each do |vv, ss|
661
+ it "type: #{ss}" do
662
+ t = NDT.new ss
663
+ x = XND.empty ss
664
+
665
+ expect(x.type).to eq(t)
666
+ expect(x.value).to eq(vv)
667
+ expect(x.size).to eq(vv.size)
668
+ end
669
+ end
670
+ end
671
+ end
672
+
673
+ context "Ref" do
674
+ DTYPE_EMPTY_TEST_CASES.each do |v, s|
675
+ [
676
+ [v, "ref(#{s})"],
677
+ [v, "ref(ref(#{s}))"],
678
+ [v, "ref(ref(ref(#{s})))"],
679
+
680
+ [[v] * 0, "ref(0 * #{s})"],
681
+ [[v] * 0, "ref(ref(0 * #{s}))"],
682
+ [[v] * 0, "ref(ref(ref(0 * #{s})))"],
683
+ [[v] * 1, "ref(1 * #{s})"],
684
+ [[v] * 1, "ref(ref(1 * #{s}))"],
685
+ [[v] * 1, "ref(ref(ref(1 * #{s})))"],
686
+ [[v] * 3, "ref(3 * #{s})"],
687
+ [[v] * 3, "ref(ref(3 * #{s}))"],
688
+ [[v] * 3, "ref(ref(ref(3 * #{s})))"]
689
+ ].each do |vv, ss|
690
+ it "type: #{ss}", vag: true do
691
+ t = NDT.new ss
692
+ x = XND.empty ss
693
+
694
+ expect(x.type).to eq(t)
695
+ expect(x.value).to eq(vv)
696
+ end
697
+ end
698
+ end
699
+ end
700
+
701
+ context "Constr" do
702
+ DTYPE_EMPTY_TEST_CASES.each do |v, s|
703
+ [
704
+ [v, "SomeConstr(#{s})"],
705
+ [v, "Just(Some(#{s}))"],
706
+
707
+ [[v] * 0, "Some(0 * #{s})"],
708
+ [[v] * 1, "Some(1 * #{s})"],
709
+ [[v] * 3, "Maybe(3 * #{s})"]
710
+ ].each do |vv, ss|
711
+ it "type: #{ss}" do
712
+ t = NDT.new ss
713
+ x = XND.empty ss
714
+
715
+ expect(x.type).to eq(t)
716
+ expect(x.value).to eq(vv)
717
+ if vv == 0
718
+ expect {
719
+ x.size
720
+ }.to raise_error(NoMethodError)
721
+ end
722
+ end
723
+ end
724
+ end
725
+
726
+ it "returns empty view" do
727
+ # If a constr is a dtype but contains an array itself, indexing should
728
+ # return a view and not a Python value.
729
+ inner = [[""] * 5] * 4
730
+ x = XND.empty("2 * 3 * InnerArray(4 * 5 * string)")
731
+
732
+ y = x[1][2]
733
+ expect(y.is_a?(XND)).to eq(true)
734
+ expect(y.value).to eq(inner)
735
+
736
+ y = x[1, 2]
737
+ expect(y.is_a?(XND)).to eq(true)
738
+ expect(y.value).to eq(inner)
739
+ end
740
+ end
741
+
742
+ context "Nominal" do
743
+ c = 0
744
+ DTYPE_EMPTY_TEST_CASES.each do |v, s|
745
+ NDT.typedef "some#{c}", s
746
+ NDT.typedef "just#{c}", "some#{c}"
747
+
748
+ [
749
+ [v, "some#{c}"],
750
+ [v, "just#{c}"]
751
+ ].each do |vv, ss|
752
+ it "type: #{ss}" do
753
+ t = NDT.new ss
754
+ x = XND.empty ss
755
+
756
+ expect(x.type).to eq(t)
757
+ expect(x.value).to eq(vv)
758
+ if vv == 0
759
+ expect {
760
+ x.size
761
+ }.to raise_error(NoMethodError)
762
+ end
763
+ end
764
+ end
765
+
766
+ c += 1
767
+ end
768
+
769
+ it "returns empty view" do
770
+ # If a typedef is a dtype but contains an array itself, indexing should
771
+ # return a view and not a Python value.
772
+ NDT.typedef("inner_array", "4 * 5 * string")
773
+ inner = [[""] * 5] * 4
774
+ x = XND.empty("2 * 3 * inner_array")
775
+
776
+ y = x[1][2]
777
+ expect(y.is_a?(XND)).to eq(true)
778
+ expect(y.value).to eq(inner)
779
+
780
+ y = x[1, 2]
781
+ expect(y.is_a?(XND)).to eq(true)
782
+ expect(y.value).to eq(inner)
783
+ end
784
+ end
785
+
786
+ context "Categorical" do
787
+ # Categorical values are stored as indices into the type's categories.
788
+ # Since empty xnd objects are initialized to zero, the value of an
789
+ # empty categorical entry is always the value of the first category.
790
+ # This is safe, since categorical types must have at least one entry.
791
+ r = {'a' => "", 'b' => 1.2}
792
+ rt = "{a: string, b: categorical(1.2, 10.0, NA)}"
793
+
794
+ [
795
+ ["January", "categorical('January')"],
796
+ [[nil], "(categorical(NA, 'January', 'August'))"],
797
+ [[[1.2] * 2] * 10, "10 * 2 * categorical(1.2, 10.0, NA)"],
798
+ [[[100] * 2] * 10, "10 * 2 * categorical(100, 'mixed')"],
799
+ [[[r] * 2] * 10, "10 * 2 * #{rt}"],
800
+ [[[r] * 2, [r] * 5, [r] * 3], "var(offsets=[0,3]) * var(offsets=[0,2,7,10]) * #{rt}"]
801
+ ].each do |v, s|
802
+
803
+ it "type: #{s}" do
804
+ t = NDT.new s
805
+ x = XND.empty s
806
+
807
+ expect(x.type).to eq(t)
808
+ expect(x.value).to eq(v)
809
+ end
810
+ end
811
+ end
812
+
813
+ context "FixedString" do
814
+ it "tests kind of string" do
815
+ expect {
816
+ XND.empty "FixedString"
817
+ }.to raise_error(ValueError)
818
+ end
819
+
820
+ [
821
+ ["fixed_string(1)", ""],
822
+ ["fixed_string(3)", "" * 3],
823
+ ["fixed_string(1, 'ascii')", ""],
824
+ ["fixed_string(3, 'utf8')", "" * 3],
825
+ ["fixed_string(3, 'utf16')", "" * 3],
826
+ ["fixed_string(3, 'utf32')", "" * 3],
827
+ ["2 * fixed_string(3, 'utf32')", ["" * 3] * 2],
828
+ ].each do |s, v|
829
+
830
+ it "type: #{s}" do
831
+ t = NDT.new s
832
+ x = XND.empty s
833
+
834
+ expect(x.type).to eq(t)
835
+ expect(x.value).to eq(v)
836
+ end
837
+ end
838
+ end
839
+
840
+ context "FixedBytes" do
841
+ r = {'a' => "\x00".b * 3, 'b' => "\x00".b * 10}
842
+
843
+ [
844
+ ["\x00".b, 'fixed_bytes(size=1)'],
845
+ ["\x00".b * 100, 'fixed_bytes(size=100)'],
846
+ ["\x00".b * 4, 'fixed_bytes(size=4, align=2)'],
847
+ ["\x00".b * 128, 'fixed_bytes(size=128, align=16)'],
848
+ [r, '{a: fixed_bytes(size=3), b: fixed_bytes(size=10)}'],
849
+ [[[r] * 3] * 2, '2 * 3 * {a: fixed_bytes(size=3), b: fixed_bytes(size=10)}']
850
+ ].each do |v, s|
851
+ it "type: #{s}" do
852
+ t = NDT.new s
853
+ x = XND.empty s
854
+
855
+ expect(x.type).to eq(t)
856
+ expect(x.value).to eq(v)
857
+ end
858
+ end
859
+ end
860
+
861
+ context "String" do
862
+ [
863
+ 'string',
864
+ '(string)',
865
+ '10 * 2 * string',
866
+ '10 * 2 * (string, string)',
867
+ '10 * 2 * {a: string, b: string}',
868
+ 'var(offsets=[0,3]) * var(offsets=[0,2,7,10]) * {a: string, b: string}'
869
+ ].each do |s|
870
+
871
+ it "type: #{s}" do
872
+ t = NDT.new s
873
+ x = XND.empty s
874
+ expect(x.type).to eq(t)
875
+ end
876
+ end
877
+
878
+ it "tests for single value" do
879
+ t = NDT.new "string"
880
+ x = XND.empty t
881
+
882
+ expect(x.type).to eq(t)
883
+ expect(x.value).to eq('')
884
+ end
885
+
886
+ xit "tests for multiple values" do
887
+ t = NDT.new "10 * string"
888
+ x = XND.empty t
889
+
890
+ expect(x.type).to eq(t)
891
+ 0.upto(10) do |i|
892
+ expect(x[i]).to eq(XND.new(['']))
893
+ end
894
+ end
895
+ end
896
+
897
+ context "Bytes" do
898
+ r = { 'a' => "".b, 'b' => "".b }
899
+
900
+ [
901
+ [''.b, 'bytes(align=16)'],
902
+ [[''.b], '(bytes(align=32))'],
903
+ [[[''.b] * 2] * 3, '3 * 2 * bytes'],
904
+ [[[[''.b, ''.b]] * 2] * 10, '10 * 2 * (bytes, bytes)'],
905
+ [[[r] * 2] * 10, '10 * 2 * {a: bytes(align=32), b: bytes(align=1)}'],
906
+ [[[r] * 2] * 10, '10 * 2 * {a: bytes(align=1), b: bytes(align=32)}'],
907
+ [[[r] * 2, [r] * 5, [r] * 3], 'var(offsets=[0,3]) * var(offsets=[0,2,7,10]) * {a: bytes(align=32), b: bytes}']
908
+ ].each do |v, s|
909
+ it "type: #{s}" do
910
+ t = NDT.new s
911
+ x = XND.empty t
912
+
913
+ expect(x.type).to eq(t)
914
+ expect(x.value).to eq(v)
915
+ end
916
+ end
917
+ end
918
+
919
+ context "Char" do
920
+ it "raises ValueError" do
921
+ expect {
922
+ XND.empty "char('utf8')"
923
+ }.to raise_error(ValueError)
924
+ end
925
+ end
926
+
927
+ context "SignedKind" do
928
+ it "raises ValueError" do
929
+ expect {
930
+ XND.empty "Signed"
931
+ }.to raise_error(ValueError)
932
+ end
933
+ end
934
+
935
+ context "UnsignedKind" do
936
+ it "raises ValueError" do
937
+ expect {
938
+ XND.empty "Unsigned"
939
+ }.to raise_error(ValueError)
940
+ end
941
+ end
942
+
943
+ context "FloatKind" do
944
+ it "raises ValueError" do
945
+ expect {
946
+ XND.empty "Float"
947
+ }.to raise_error(ValueError)
948
+ end
949
+ end
950
+
951
+ context "ComplexKind" do
952
+ it "raises ValueError" do
953
+ expect {
954
+ XND.empty "Complex"
955
+ }.to raise_error(ValueError)
956
+ end
957
+ end
958
+
959
+ context "FixedBytesKind" do
960
+ it "raises ValueError" do
961
+ expect {
962
+ XND.empty "FixedBytes"
963
+ }.to raise_error(ValueError)
964
+ end
965
+ end
966
+
967
+ context "Primitive" do
968
+ empty_test_cases.each do |value, type_string|
969
+ PRIMITIVE.each do |p|
970
+ ts = type_string % p
971
+
972
+ it "type: #{ts}" do
973
+ x = XND.empty ts
974
+
975
+ expect(x.value).to eq(value)
976
+ expect(x.type).to eq(NDT.new(ts))
977
+ end
978
+ end
979
+ end
980
+
981
+ empty_test_cases(false).each do |value, type_string|
982
+ BOOL_PRIMITIVE.each do |p|
983
+ ts = type_string % p
984
+
985
+ it "type: #{ts}" do
986
+ x = XND.empty ts
987
+
988
+ expect(x.value).to eq(value)
989
+ expect(x.type).to eq(NDT.new(ts))
990
+ end
991
+ end
992
+ end
993
+ end
994
+
995
+ context "TypeVar" do
996
+ [
997
+ "T",
998
+ "2 * 10 * T",
999
+ "{a: 2 * 10 * T, b: bytes}"
1000
+ ].each do |ts|
1001
+ it "#{ts} raises ValueError" do
1002
+ expect {
1003
+ XND.empty ts
1004
+ }.to raise_error(ValueError)
1005
+ end
1006
+ end
1007
+ end
1008
+ end
1009
+
1010
+ context ".from_buffer" do
1011
+ it "can import data from nmatrix objects" do
1012
+
1013
+ end
1014
+
1015
+ it "can import data from narray objects" do
1016
+
1017
+ end
1018
+ end
1019
+
1020
+ context "#[]" do
1021
+ context "FixedDim" do
1022
+ it "returns single number slice for 1D array/1 number" do
1023
+ xnd = XND.new([1,2,3,4])
1024
+ expect(xnd[1]).to eq(XND.new(2))
1025
+ end
1026
+
1027
+ it "returns single number slice for 2D array and 2 indices" do
1028
+ xnd = XND.new([[1,2,3], [4,5,6]])
1029
+ expect(xnd[0,0]).to eq(XND.new(1))
1030
+ end
1031
+
1032
+ it "returns row for single index in 2D array" do
1033
+ x = XND.new [[1,2,3], [4,5,6], [7,8,9]]
1034
+ expect(x[1]).to eq(XND.new([4,5,6]))
1035
+ end
1036
+
1037
+ it "returns single column in 2D array" do
1038
+ x = XND.new [[1,2,3], [4,5,6], [7,8,9]]
1039
+ expect(x[0..Float::INFINITY, 0]).to eq(XND.new([1,4,7]))
1040
+ end
1041
+
1042
+ it "returns the entire array" do
1043
+ x = XND.new [[1,2,3], [4,5,6], [7,8,9]]
1044
+ expect(x[0..Float::INFINITY]).to eq(x)
1045
+ end
1046
+
1047
+ [
1048
+ [
1049
+ [
1050
+ [11.12-2.3i, -1222+20e8i],
1051
+ [Complex(Float::INFINITY, Float::INFINITY), -0.00002i],
1052
+ [0.201+1i, -1+1e301i]
1053
+ ], "3 * 2 * complex128"],
1054
+ [
1055
+ [
1056
+ [11.12-2.3i, nil],
1057
+ [Complex(Float::INFINITY, Float::INFINITY), nil],
1058
+ [0.201+1i, -1+1e301i]
1059
+ ], "3 * 2 * ?complex128"]
1060
+ ].each do |v, s|
1061
+ context "type: #{s}" do
1062
+ before do
1063
+ @arr = v
1064
+ @t = NDT.new s
1065
+ @x = XND.new v, type: @t
1066
+ end
1067
+
1068
+ it "check values" do
1069
+ expect(@x.to_a).to eq(@arr.to_a)
1070
+ end
1071
+
1072
+ 0.upto(2) do |i|
1073
+ it "value: i= #{i}" do
1074
+ expect(@x[i].to_a).to eq(@arr[i])
1075
+ end
1076
+ end
1077
+
1078
+ 3.times do |i|
1079
+ 2.times do |k|
1080
+ it "value: i=#{i}. k=#{k}" do
1081
+ expect(@x[i][k].value).to eq(@arr[i][k])
1082
+ expect(@x[i, k].value).to eq(@arr[i][k])
1083
+ end
1084
+ end
1085
+ end
1086
+
1087
+ it "tests full slices" do
1088
+ expect(@x[INF].value).to eq(@arr)
1089
+ end
1090
+
1091
+ ((-3...4).to_a + [Float::INFINITY]).each do |start|
1092
+ ((-3...4).to_a + [Float::INFINITY]).each do |stop|
1093
+ [true, false].each do |exclude_end|
1094
+ # FIXME: add step count when ruby supports it.
1095
+ arr_s = get_inf_or_normal_range start, stop, exclude_end
1096
+
1097
+ it "Range[#{start}, #{stop}#{exclude_end ? ')' : ']'}" do
1098
+ r = Range.new(start, stop, exclude_end)
1099
+ expect(@x[r].value).to eq(@arr[arr_s])
1100
+ end
1101
+ end
1102
+ end
1103
+ end
1104
+
1105
+ it "tests single rows" do
1106
+ expect(@x[INF, 0].value).to eq(@arr.transpose[0])
1107
+ expect(@x[INF, 1].value).to eq(@arr.transpose[1])
1108
+ end
1109
+ end
1110
+ end
1111
+ end
1112
+
1113
+ context "Fortran" do
1114
+ [
1115
+ [[[11.12-2.3i, -1222+20e8i],
1116
+ [Complex(Float::INFINITY, Float::INFINITY), -0.00002i],
1117
+ [0.201+1i, -1+1e301i]], "!3 * 2 * complex128"],
1118
+ [[[11.12-2.3i, nil],
1119
+ [Complex(Float::INFINITY, Float::INFINITY), nil],
1120
+ [0.201+1i, -1+1e301i]], "!3 * 2 * ?complex128"]
1121
+ ].each do |v, s|
1122
+ context "type: #{s}" do
1123
+ before do
1124
+ @arr = v
1125
+ @t = NDT.new s
1126
+ @x = XND.new v, type: @t
1127
+ end
1128
+
1129
+ (0).upto(2) do |i|
1130
+ it "check row i= #{i}" do
1131
+ expect(@x[i].value).to eq(@arr[i])
1132
+ end
1133
+ end
1134
+
1135
+ (0).upto(2) do |i|
1136
+ (0).upto(1) do |k|
1137
+ it "check elements i=#{i} k=#{k}" do
1138
+ expect(@x[i][k].value).to eq(@arr[i][k])
1139
+ expect(@x[i, k].value).to eq(@arr[i][k])
1140
+ end
1141
+ end
1142
+ end
1143
+
1144
+ it "checks full slice" do
1145
+ expect(@x[INF].to_a).to eq(@arr)
1146
+ end
1147
+
1148
+ ((-3..-3).to_a + [Float::INFINITY]).each do |start|
1149
+ ((-3..-3).to_a + [Float::INFINITY]).each do |stop|
1150
+ [true, false].each do |exclude_end|
1151
+ # FIXME: add step count loop post Ruby 2.6
1152
+ arr_s = get_inf_or_normal_range start, stop, exclude_end
1153
+
1154
+ it "Range[#{start}, #{stop}#{exclude_end ? ')' : ']'}" do
1155
+ r = Range.new start, stop, exclude_end
1156
+ expect(@x[r].value).to eq(@arr[arr_s])
1157
+ end
1158
+ end
1159
+ end
1160
+ end
1161
+
1162
+ it "checks column slices" do
1163
+ expect(@x[INF, 0].value).to eq(@arr.transpose[0])
1164
+ expect(@x[INF, 1].value).to eq(@arr.transpose[1])
1165
+ end
1166
+ end
1167
+ end
1168
+ end
1169
+
1170
+ context "Ref" do
1171
+ before do
1172
+ # FIXME: If a ref is a dtype but contains an array itself, indexing through
1173
+ # the ref should work transparently. However for now it returns an XND object.
1174
+ # This will likely change in the future.
1175
+ @inner = [['a', 'b', 'c', 'd', 'e'],
1176
+ ['f', 'g', 'h', 'i', 'j'],
1177
+ ['k', 'l', 'm', 'n', 'o'],
1178
+ ['p', 'q', 'r', 's', 't']]
1179
+ @v = [[@inner] * 3] * 2
1180
+ @x = XND.new(@v, type: "2 * 3 * ref(4 * 5 * string)")
1181
+ end
1182
+
1183
+ (0).upto(1) do |i|
1184
+ (0).upto(2) do |j|
1185
+ (0).upto(3) do |k|
1186
+ (0).upto(4) do |l|
1187
+ it "index: i=#{i} j=#{j} k=#{k} l=#{l}" do
1188
+ expect(@x[i][j][k][l].value).to eq(@inner[k][l])
1189
+ expect(@x[i, j, k, l].value).to eq(@inner[k][l])
1190
+ end
1191
+ end
1192
+ end
1193
+ end
1194
+ end
1195
+ end
1196
+
1197
+ context "Constr" do
1198
+ before do
1199
+ # FIXME: If a constr is a dtype but contains an array itself, indexing through
1200
+ # the constructor should work transparently. However, for now it returns
1201
+ # an XND object, however this will likely change in the future.
1202
+ @inner = [['a', 'b', 'c', 'd', 'e'],
1203
+ ['f', 'g', 'h', 'i', 'j'],
1204
+ ['k', 'l', 'm', 'n', 'o'],
1205
+ ['p', 'q', 'r', 's', 't']]
1206
+ @v = [[@inner] * 3] * 2
1207
+ @x = XND.new(@v, type: "2 * 3 * InnerArray(4 * 5 * string)")
1208
+ end
1209
+
1210
+ (0).upto(1) do |i|
1211
+ (0).upto(2) do |j|
1212
+ (0).upto(3) do |k|
1213
+ (0).upto(4) do |l|
1214
+ it "slice: i=#{i} j=#{j} k=#{k} l=#{l}" do
1215
+
1216
+ expect(@x[i][j][k][l].value).to eq(@inner[k][l])
1217
+ expect(@x[i, j, k, l].value).to eq(@inner[k][l])
1218
+ end
1219
+ end
1220
+ end
1221
+ end
1222
+ end
1223
+ end # context Constr
1224
+
1225
+ context "Nominal" do
1226
+ before do
1227
+ # FIXME: If a typedef is a dtype but contains an array itself, indexing through
1228
+ # the constructor should work transparently. However, for now it returns an XND
1229
+ # object, however this will likely change in the future.
1230
+ NDT.typedef("inner", "4 * 5 * string")
1231
+ @inner = [['a', 'b', 'c', 'd', 'e'],
1232
+ ['f', 'g', 'h', 'i', 'j'],
1233
+ ['k', 'l', 'm', 'n', 'o'],
1234
+ ['p', 'q', 'r', 's', 't']]
1235
+ @v = [[@inner] * 3] * 2
1236
+ @x = XND.new(@v, type: "2 * 3 * inner")
1237
+ end
1238
+
1239
+
1240
+ (0).upto(1) do |i|
1241
+ (0).upto(2) do |j|
1242
+ (0).upto(3) do |k|
1243
+ (0).upto(4) do |l|
1244
+ it "slice: i=#{i} j=#{j} k=#{k} l=#{l}" do
1245
+ expect(@x[i][j][k][l].value).to eq(@inner[k][l])
1246
+ expect(@x[i, j, k, l].value).to eq(@inner[k][l])
1247
+ end
1248
+ end
1249
+ end
1250
+ end
1251
+ end
1252
+ end # context Nominal
1253
+ end # context #[]
1254
+
1255
+ context "#[]=" do
1256
+ context "FixedDim" do
1257
+ context "full data" do
1258
+ before do
1259
+ @x = XND.empty "2 * 4 * float64"
1260
+ @v = [[0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0]]
1261
+ end
1262
+
1263
+ it "assigns full slice" do
1264
+ @x[INF] = @v
1265
+ expect(@x.value).to eq(@v)
1266
+ end
1267
+
1268
+ it "assigns subarray" do
1269
+ @x[INF] = @v
1270
+
1271
+ @x[0] = @v[0] = [1.2, -3e45, Float::INFINITY, -322.25]
1272
+ expect(@x.value).to eq(@v)
1273
+
1274
+ @x[1] = @v[1] = [-11.25, 3.355e301, -0.000002, -5000.2]
1275
+ expect(@x.value).to eq (@v)
1276
+ end
1277
+
1278
+ it "assigns single values" do
1279
+ 0.upto(1) do |i|
1280
+ 0.upto(3) do |j|
1281
+ @x[i][j] = @v[i][j] = 3.22 * i + j
1282
+ end
1283
+ end
1284
+
1285
+ expect(@x.value).to eq(@v)
1286
+ end
1287
+
1288
+ it "supports tuple indexing" do
1289
+ 0.upto(1) do |i|
1290
+ 0.upto(3) do |j|
1291
+ @x[i, j] = @v[i][j] = -3.002e1 * i + j
1292
+ end
1293
+ end
1294
+
1295
+ expect(@x.value).to eq(@v)
1296
+ end
1297
+ end # context full data
1298
+
1299
+ context "optional data" do
1300
+ before do
1301
+ @x = XND.empty "2 * 4 * ?float64"
1302
+ @v = [[10.0, nil, 2.0, 100.12], [nil, nil, 6.0, 7.0]]
1303
+ end
1304
+
1305
+ it "assigns full slice" do
1306
+ @x[INF] = @v
1307
+ expect(@x.value).to eq(@v)
1308
+ end
1309
+
1310
+ it "assigns subarray" do
1311
+ @x[INF] = @v
1312
+
1313
+ @x[0] = @v[0] = [nil, 3e45, Float::INFINITY, nil]
1314
+ expect(@x.value).to eq(@v)
1315
+
1316
+ @x[1] = @v[1] = [-11.25, 3.355e301, -0.000002, nil]
1317
+ expect(@x.value).to eq(@v)
1318
+ end
1319
+
1320
+ it "assigns single values" do
1321
+ 2.times do |i|
1322
+ 4.times do |j|
1323
+ @x[i][j] = @v[i][j] = -325.99 * i + j
1324
+ end
1325
+ end
1326
+
1327
+ expect(@x.value).to eq(@v)
1328
+ end
1329
+
1330
+ it "supports assignment by tuple indexing" do
1331
+ 2.times do |i|
1332
+ 4.times do |j|
1333
+ @x[i, j] = @v[i][j] = -8.33e1 * i + j
1334
+ end
1335
+ end
1336
+
1337
+ expect(@x.value).to eq(@v)
1338
+ end
1339
+ end # context optional data
1340
+ end # context FixedDim
1341
+
1342
+ context "Fortran" do
1343
+ context "regular data" do
1344
+ before do
1345
+ @x = XND.empty "!2 * 4 * float64"
1346
+ @v = [[0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0]]
1347
+ end
1348
+
1349
+ it "assigns full slice" do
1350
+ @x[INF] = @v
1351
+ expect(@x.value).to eq(@v)
1352
+ end
1353
+
1354
+ it "assigns subarray" do
1355
+ @x[INF] = @v
1356
+
1357
+ @x[0] = @v[0] = [1.2, -3e45, Float::INFINITY, -322.25]
1358
+ expect(@x.value).to eq(@v)
1359
+
1360
+ @x[1] = @v[1] = [-11.25, 3.355e301, -0.000002, -5000.2]
1361
+ expect(@x.value).to eq (@v)
1362
+ end
1363
+
1364
+ it "assigns single values" do
1365
+ 0.upto(1) do |i|
1366
+ 0.upto(3) do |j|
1367
+ @x[i][j] = @v[i][j] = 3.22 * i + j
1368
+ end
1369
+ end
1370
+
1371
+ expect(@x.value).to eq(@v)
1372
+ end
1373
+
1374
+ it "supports tuple indexing" do
1375
+ 0.upto(1) do |i|
1376
+ 0.upto(3) do |j|
1377
+ @x[i, j] = @v[i][j] = -3.002e1 * i + j
1378
+ end
1379
+ end
1380
+
1381
+ expect(@x.value).to eq(@v)
1382
+ end
1383
+ end # context full data
1384
+
1385
+ context "optional data" do
1386
+ before do
1387
+ @x = XND.empty "!2 * 4 * ?float64"
1388
+ @v = [[10.0, nil, 2.0, 100.12], [nil, nil, 6.0, 7.0]]
1389
+ end
1390
+
1391
+ it "assigns full slice" do
1392
+ @x[INF] = @v
1393
+ expect(@x.value).to eq(@v)
1394
+ end
1395
+
1396
+ it "assigns subarray" do
1397
+ @x[INF] = @v
1398
+
1399
+ @x[0] = @v[0] = [nil, 3e45, Float::INFINITY, nil]
1400
+ expect(@x.value).to eq(@v)
1401
+
1402
+ @x[1] = @v[1] = [-11.25, 3.355e301, -0.000002, nil]
1403
+ expect(@x.value).to eq(@v)
1404
+ end
1405
+
1406
+ it "assigns single values" do
1407
+ 2.times do |i|
1408
+ 4.times do |j|
1409
+ @x[i][j] = @v[i][j] = -325.99 * i + j
1410
+ end
1411
+ end
1412
+
1413
+ expect(@x.value).to eq(@v)
1414
+ end
1415
+
1416
+ it "supports assignment by tuple indexing" do
1417
+ 2.times do |i|
1418
+ 4.times do |j|
1419
+ @x[i, j] = @v[i][j] = -8.33e1 * i + j
1420
+ end
1421
+ end
1422
+
1423
+ expect(@x.value).to eq(@v)
1424
+ end
1425
+ end # context optional data
1426
+ end # context Fortran
1427
+
1428
+ context "VarDim" do
1429
+ context "regular data" do
1430
+ before do
1431
+ @x = XND.empty "var(offsets=[0,2]) * var(offsets=[0,2,5]) * float64"
1432
+ @v = [[0.0, 1.0], [2.0, 3.0, 4.0]]
1433
+ end
1434
+
1435
+ it "assigns full slice" do
1436
+ @x[INF] = @v
1437
+ expect(@x.value).to eq(@v)
1438
+ end
1439
+
1440
+ it "assigns subarray" do
1441
+ @x[INF] = @v
1442
+
1443
+ @x[0] = @v[0] = [1.2, 2.5]
1444
+ expect(@x.value).to eq(@v)
1445
+
1446
+ @x[1] = @v[1] = [1.2, 2.5, 3.99]
1447
+ expect(@x.value).to eq(@v)
1448
+ end
1449
+
1450
+ it "assigns individual values" do
1451
+ 2.times do |i|
1452
+ @x[0][i] = @v[0][i] = 100.0 * i
1453
+ end
1454
+
1455
+ 3.times do |i|
1456
+ @x[1][i] = @v[1][i] = 200.0 * i
1457
+ end
1458
+
1459
+ expect(@x.value).to eq(@v)
1460
+ end
1461
+
1462
+ it "assigns tuple" do
1463
+ 2.times do |i|
1464
+ @x[0, i] = @v[0][i] = 300.0 * i + 1.222
1465
+ end
1466
+
1467
+ 3.times do |i|
1468
+ @x[1, i] = @v[1][i] = 400.0 * i + 1.333
1469
+ end
1470
+
1471
+ expect(@x.value).to eq(@v)
1472
+ end
1473
+ end # context regular data
1474
+
1475
+ context "optional data" do
1476
+ before do
1477
+ @x = XND.empty "var(offsets=[0,2]) * var(offsets=[0,2,5]) * ?float64"
1478
+ @v = [[0.0, nil], [nil, 3.0, 4.0]]
1479
+ end
1480
+
1481
+ it "assigns full slice" do
1482
+ @x[INF] = @v
1483
+ expect(@x.value).to eq(@v)
1484
+ end
1485
+
1486
+ it "assigns subarray" do
1487
+ @x[INF] = @v
1488
+
1489
+ @x[0] = @v[0] = [nil, 2.0]
1490
+ expect(@x.value).to eq(@v)
1491
+
1492
+ @x[1] = @v[1] = [1.22214, nil, 10.0]
1493
+ expect(@x.value).to eq(@v)
1494
+ end
1495
+
1496
+ it "assigns individual values" do
1497
+ 2.times do |i|
1498
+ @x[0][i] = @v[0][i] = 3.14 * i + 1.2222
1499
+ end
1500
+
1501
+ 3.times do |i|
1502
+ @x[1][i] = @v[1][i] = 23.333 * i
1503
+ end
1504
+
1505
+ expect(@x.value).to eq(@v)
1506
+ end
1507
+
1508
+ it "assigns tuple" do
1509
+ 2.times do |i|
1510
+ @x[0, i] = @v[0][i] = -122.5 * i + 1.222
1511
+ end
1512
+
1513
+ 3.times do |i|
1514
+ @x[1, i] = @v[1][i] = -3e22 * i
1515
+ end
1516
+
1517
+ expect(@x.value).to eq(@v)
1518
+ end
1519
+ end # context optional data
1520
+ end # context VarDim
1521
+
1522
+ context "Tuple" do
1523
+ context "regular data" do
1524
+ before do
1525
+ @x = XND.empty "(complex64, bytes, string)"
1526
+ @v = [1+20i, "abc".b, "any"]
1527
+ end
1528
+
1529
+ it "assigns each element" do
1530
+ @x[0] = @v[0]
1531
+ @x[1] = @v[1]
1532
+ @x[2] = @v[2]
1533
+
1534
+ expect(@x.value).to eq(@v)
1535
+ end
1536
+ end # context regular data
1537
+
1538
+ context "optional data" do
1539
+ before do
1540
+ @x = XND.empty "(complex64, ?bytes, ?string)"
1541
+ @v = [1+20i, nil, "Some"]
1542
+ end
1543
+
1544
+ it "assigns each element" do
1545
+ @x[0] = @v[0]
1546
+ @x[1] = @v[1]
1547
+ @x[2] = @v[2]
1548
+
1549
+ expect(@x.value).to eq(@v)
1550
+ end
1551
+
1552
+ it "assigns new each element" do
1553
+ v = [-2.5+125i, nil, nil]
1554
+ @x[0] = v[0]
1555
+ @x[1] = v[1]
1556
+ @x[2] = v[2]
1557
+
1558
+ expect(@x.value).to eq(v)
1559
+ end
1560
+
1561
+ it "assigns tuple and individual values" do
1562
+ x = XND.new([
1563
+ XND::T.new("a", 100, 10.5),
1564
+ XND::T.new("a", 100, 10.5)
1565
+ ])
1566
+ x[0][1] = 200000000
1567
+
1568
+ expect(x[0][1].value).to eq(200000000)
1569
+ expect(x[0, 1].value).to eq(200000000)
1570
+ end
1571
+ end # context optional data
1572
+ end # context Tuple
1573
+
1574
+ context "Record" do
1575
+ it "assigns regular data" do
1576
+ x = XND.empty "{x: complex64, y: bytes, z: string}"
1577
+ v = { 'x' => 1+20i, 'y' => "abc".b, 'z' => "any" }
1578
+
1579
+ x['x'] = v['x']
1580
+ x['y'] = v['y']
1581
+ x['z'] = v['z']
1582
+
1583
+ expect(x.value).to eq(v)
1584
+ end
1585
+
1586
+ context "optional data" do
1587
+ before do
1588
+ @x = XND.empty "{x: complex64, y: ?bytes, z: ?string}"
1589
+ end
1590
+
1591
+ [
1592
+ { 'x' => 1+20i, 'y' => nil, 'z' => "Some" },
1593
+ { 'x' => -2.5+125i, 'y' => nil, 'z' => nil }
1594
+ ].each do |v|
1595
+ it "assigns optional data #{v}" do
1596
+
1597
+ @x['x'] = v['x']
1598
+ @x['y'] = v['y']
1599
+ @x['z'] = v['z']
1600
+
1601
+ expect(@x.value).to eq(v)
1602
+ end
1603
+ end
1604
+ end # context optional data
1605
+ end # context Record
1606
+
1607
+ context "Ref" do
1608
+ # TODO: see line 1341 of pycode.
1609
+ end
1610
+
1611
+ context "Constr" do
1612
+ # TODO: see line 1484
1613
+ end
1614
+
1615
+ context "Nominal" do
1616
+ # TODO: see line 1637
1617
+ end
1618
+
1619
+ context "Categorical" do
1620
+ before do
1621
+ @s = "2 * categorical(NA, 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')"
1622
+ @x = XND.new [nil, nil], type: @s
1623
+ end
1624
+
1625
+ it "assigns regular data" do
1626
+ @x[0] = "August"
1627
+ @x[1] = "December"
1628
+
1629
+ expect(@x.value).to eq(["August", "December"])
1630
+ end
1631
+
1632
+ it "assigns nil" do
1633
+ @x[0] = nil
1634
+ @x[1] = "December"
1635
+
1636
+ expect(@x.value).to eq([nil, "December"])
1637
+ end
1638
+ end # context Categorical
1639
+
1640
+ skip "FixedString - need to figure out UTF-32 in Ruby." do
1641
+ it "assigns a fixed string" do
1642
+ t = "2 * fixed_string(3, 'utf32')"
1643
+ v = ["\U00011111\U00022222\U00033333", "\U00011112\U00022223\U00033334"]
1644
+ x = XND.new(v, type: t)
1645
+
1646
+ x[0] = "a"
1647
+ expect(x.value).to eq(["a", "\U00011112\U00022223\U00033334"])
1648
+
1649
+ x[0] = "a\x00\x00"
1650
+ expect(x.value).to eq(["a", "\U00011112\U00022223\U00033334"])
1651
+
1652
+ x[1] = "b\x00c"
1653
+ expect(x.value).to eq(["a", "b\x00c"])
1654
+ end
1655
+ end # context FixedString
1656
+
1657
+ context "FixedBytes" do
1658
+ it "assign single element" do
1659
+ t = "2 * fixed_bytes(size=3, align=1)"
1660
+ v = ["abc".b, "123".b]
1661
+ x = XND.new(v, type: t)
1662
+
1663
+ x[0] = "xyz".b
1664
+ expect(x.value).to eq(["xyz".b, "123".b])
1665
+ end
1666
+ end # context FixedString
1667
+
1668
+ context "String" do
1669
+ it "assigns single" do
1670
+ t = '2 * {a: complex128, b: string}'
1671
+ x = XND.new([{ 'a' => 2+3i, 'b' => "thisguy"},
1672
+ { 'a' => 1+4i, 'b' => "thatguy" }], type: t)
1673
+
1674
+ x[0] = { 'a' => 220i, 'b' => 'y'}
1675
+ x[1] = { 'a' => -12i, 'b' => 'z'}
1676
+
1677
+ expect(x.value).to eq([
1678
+ { 'a' => 220i, 'b' => 'y' },
1679
+ { 'a' => -12i, 'b' => 'z' }
1680
+ ])
1681
+ end
1682
+ end # context String
1683
+
1684
+ context "Bytes" do
1685
+ it "assigns bytes by tuple" do
1686
+ t = "2 * SomeByteArray(3 * bytes)"
1687
+ inner = ["a".b, "b".b, "c".b]
1688
+ v = [inner] * 2
1689
+ x = XND.new v, type: t
1690
+
1691
+ 2.times do |i|
1692
+ 3.times do |k|
1693
+ x[i, k] = inner[k] = ['x'.chr.ord + k].pack("C")
1694
+ end
1695
+ end
1696
+
1697
+ expect(x.value).to eq(v)
1698
+ end
1699
+ end # context Bytes
1700
+ end # context #[]=
1701
+
1702
+ context "#strict_equal" do
1703
+ context "FixedDim" do
1704
+ before do
1705
+ @x = XND.new [1,2,3,4]
1706
+ end
1707
+
1708
+ it "tests simple arrays" do
1709
+ x1 = XND.new [1,2,3,4]
1710
+
1711
+ expect_strict_equal @x, x1
1712
+ end
1713
+
1714
+ it "tests different shape and/or data" do
1715
+ expect_strict_unequal @x, XND.new([1,2,3,5])
1716
+ expect_strict_unequal @x, XND.new([1,2,3,100])
1717
+ expect_strict_unequal @x, XND.new([4,2,3,4,5])
1718
+ end
1719
+
1720
+ it "tests different shape" do
1721
+ expect_strict_unequal @x, XND.new([1,2,3])
1722
+ expect_strict_unequal @x, XND.new([[1,2,3,4]])
1723
+ expect_strict_unequal @x, XND.new([[1,2], [3,4]])
1724
+ end
1725
+
1726
+ it "tests simple multidim array" do
1727
+ x = XND.new([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
1728
+ y = XND.new([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
1729
+
1730
+ expect_strict_equal x, y
1731
+ end
1732
+
1733
+ it "tests slices" do
1734
+ x = XND.new([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
1735
+ y = XND.new([1,2,3])
1736
+
1737
+ expect_strict_equal x[0], y
1738
+
1739
+ y = XND.new [1,4,7,10]
1740
+
1741
+ expect_strict_equal x[0..Float::INFINITY,0], y
1742
+ end
1743
+
1744
+ EQUAL_TEST_CASES.each do |struct|
1745
+ v = struct.v
1746
+ t = struct.t
1747
+ u = struct.u
1748
+
1749
+ [
1750
+ [[v] * 0, "0 * #{t}", "0 * #{u}"],
1751
+ [[[v] * 0] * 0, "0 * 0 * #{t}", "0 * 0 * #{u}"],
1752
+ [[[v] * 1] * 0, "0 * 1 * #{t}", "0 * 1 * #{u}"],
1753
+ [[[v] * 0] * 1, "1 * 0 * #{t}", "1 * 0 * #{u}"]
1754
+ ].each do |vv, tt, uu|
1755
+ it "tests corner cases and many dtypes. type: #{tt}" do
1756
+ ttt = NDT.new tt
1757
+ uuu = NDT.new tt
1758
+
1759
+ x = XND.new vv, type: ttt
1760
+
1761
+ y = XND.new vv, type: ttt
1762
+ expect_strict_equal x, y
1763
+
1764
+ y = XND.new vv, type: uuu
1765
+ expect_strict_equal x, y
1766
+ end
1767
+ end
1768
+ end # EQUAL_TEST_CASES.each
1769
+
1770
+ EQUAL_TEST_CASES.each do |struct|
1771
+ v = struct.v
1772
+ t = struct.t
1773
+ u = struct.u
1774
+ w = struct.w
1775
+ eq = struct.eq
1776
+
1777
+ [
1778
+ [[v] * 1, "1 * #{t}", "1 * #{u}", [0]],
1779
+ [[v] * 2, "2 * #{t}", "2 * #{u}", [1]],
1780
+ [[v] * 1000, "1000 * #{t}", "1000 * #{u}", [961]],
1781
+
1782
+ [[[v] * 1] * 1, "1 * 1 * #{t}", "1 * 1 * #{u}", [0, 0]],
1783
+ [[[v] * 2] * 1, "1 * 2 * #{t}", "1 * 2 * #{u}", [0, 1]],
1784
+ [[[v] * 1] * 2, "2 * 1 * #{t}", "2 * 1 * #{u}", [1, 0]],
1785
+ [[[v] * 2] * 2, "2 * 2 * #{t}", "2 * 2 * #{u}", [1, 1]],
1786
+ [[[v] * 3] * 2, "2 * 3 * #{t}", "2 * 3 * #{u}", [1, 2]],
1787
+ [[[v] * 2] * 3, "3 * 2 * #{t}", "3 * 2 * #{u}", [2, 1]],
1788
+ [[[v] * 40] * 3, "3 * 40 * #{t}", "3 * 40 * #{u}", [1, 32]]
1789
+ ].each do |vv, tt, uu, indices|
1790
+ context "type: tt=\"#{tt}\" uu=\"#{uu}\"" do
1791
+ before do
1792
+ @ttt = NDT.new tt
1793
+ @uuu = NDT.new tt # uu?
1794
+ end
1795
+
1796
+ it "eq" do
1797
+ x = XND.new vv, type: @ttt
1798
+ y = XND.new vv, type: @ttt
1799
+
1800
+ if eq
1801
+ expect_strict_equal x, y
1802
+ else
1803
+ expect_strict_unequal x, y
1804
+ end
1805
+ end
1806
+
1807
+ it "unless u.nil?" do
1808
+ x = XND.new vv, type: @ttt
1809
+
1810
+ unless u.nil?
1811
+ y = XND.new vv, type: @uuu
1812
+
1813
+ if eq
1814
+ expect_strict_equal x, y
1815
+ else
1816
+ expect_strict_unequal x, y
1817
+ end
1818
+ end
1819
+ end
1820
+
1821
+ it "unless w.nil?" do
1822
+ if tt == "2 * 2 * {x: uint16, y: {z: ?complex64}}" &&
1823
+ uu == "2 * 2 * {x: uint16, y: {z: ?complex64}}"
1824
+ x = XND.new vv, type: @ttt
1825
+
1826
+ unless w.nil?
1827
+ y = XND.new vv, type: @ttt
1828
+
1829
+ y[*indices] = w
1830
+ expect_strict_unequal x, y
1831
+
1832
+ y = XND.new vv, type: @uuu
1833
+ y[*indices] = w
1834
+ expect_strict_unequal x, y
1835
+ end
1836
+ end
1837
+ end
1838
+ end
1839
+ end
1840
+ end
1841
+ end # context FixedDim
1842
+
1843
+ context "Fortran" do
1844
+ before do
1845
+ @x = XND.new [1,2,3,4], type: "!4 * int64"
1846
+ end
1847
+
1848
+ it "test basic case" do
1849
+ expect_strict_equal @x, XND.new([1,2,3,4], type: "!4 * int64")
1850
+ end
1851
+
1852
+ it "tests different shape and/or data" do
1853
+ expect_strict_unequal @x, XND.new([1,2,3,100], type: "!4 * int64")
1854
+ expect_strict_unequal @x, XND.new([1,2,3], type: "!3 * int64")
1855
+ expect_strict_unequal @x, XND.new([1,2,3,4,5], type: "!5 * int64")
1856
+ end
1857
+
1858
+ it "tests different shapes" do
1859
+ expect_strict_unequal @x, XND.new([1,2,3], type: "!3 * int64")
1860
+ expect_strict_unequal @x, XND.new([[1,2,3,4]], type: "!1 * 4 * int64")
1861
+ expect_strict_unequal @x, XND.new([[1,2], [3,4]], type: "!2 * 2 * int64")
1862
+ end
1863
+
1864
+ it "tests simple multidimensional arrays" do
1865
+ x = XND.new([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type: "!4 * 3 * int64")
1866
+ y = XND.new([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type: "!4 * 3 * int64")
1867
+
1868
+ expect_strict_equal x, y
1869
+ end
1870
+
1871
+ context "equality after assignment" do
1872
+ x = XND.new([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type: "!4 * 3 * int64")
1873
+ y = XND.new([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type: "!4 * 3 * int64")
1874
+ 4.times do |i|
1875
+ 3.times do |k|
1876
+ v = y[i, k]
1877
+ y[i, k] = 100
1878
+
1879
+ it "for i=#{i} k=#{k}" do
1880
+ expect_strict_unequal x, y
1881
+ end
1882
+ y[i, k] = v
1883
+ end
1884
+ end
1885
+ end # context equality after assignement
1886
+
1887
+ it "tests slices" do
1888
+ x = XND.new([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type: "!4 * 3 * int64")
1889
+ y = XND.new([[1,2,3], [4,5,6]])
1890
+
1891
+ expect_strict_equal x[0..1], y
1892
+
1893
+ y = XND.new([1,4,7,10], type: "!4 * int64")
1894
+
1895
+ expect_strict_equal x[INF, 0], y
1896
+ end
1897
+
1898
+ EQUAL_TEST_CASES.each do |struct|
1899
+ v = struct.v
1900
+ t = struct.t
1901
+ u = struct.u
1902
+
1903
+ [
1904
+ [[v] * 0, "!0 * #{t}", "!0 * #{u}"],
1905
+ [[[v] * 0] * 0, "!0 * 0 * #{t}", "!0 * 0 * #{u}"],
1906
+ [[[v] * 1] * 0, "!0 * 1 * #{t}", "!0 * 1 * #{u}"],
1907
+ [[[v] * 0] * 1, "!1 * 0 * #{t}", "!1 * 0 * #{u}"]
1908
+ ].each do |vv, tt, uu|
1909
+ it "tests corner case type: #{tt}" do
1910
+ ttt = NDT.new tt
1911
+ uuu = NDT.new tt
1912
+
1913
+ x = XND.new vv, type: ttt
1914
+ y = XND.new vv, type: ttt
1915
+ expect_strict_equal x, y
1916
+
1917
+ y = XND.new vv, type: uuu
1918
+ expect_strict_equal x, y
1919
+ end
1920
+ end
1921
+ end
1922
+
1923
+ EQUAL_TEST_CASES.each do |struct|
1924
+ v = struct.v
1925
+ t = struct.t
1926
+ u = struct.u
1927
+ w = struct.w
1928
+ eq = struct.eq
1929
+
1930
+ [
1931
+ [[v] * 1, "!1 * #{t}", "!1 * #{u}", [0]],
1932
+ [[v] * 2, "!2 * #{t}", "!2 * #{u}", [1]],
1933
+ [[v] * 1000, "!1000 * #{t}", "!1000 * #{u}", [961]],
1934
+
1935
+ [[[v] * 1] * 1, "!1 * 1 * #{t}", "!1 * 1 * #{u}", [0, 0]],
1936
+ [[[v] * 2] * 1, "!1 * 2 * #{t}", "!1 * 2 * #{u}", [0, 1]],
1937
+ [[[v] * 1] * 2, "!2 * 1 * #{t}", "!2 * 1 * #{u}", [1, 0]],
1938
+ [[[v] * 2] * 2, "!2 * 2 * #{t}", "!2 * 2 * #{u}", [1, 1]],
1939
+ [[[v] * 3] * 2, "!2 * 3 * #{t}", "!2 * 3 * #{u}", [1, 2]],
1940
+ [[[v] * 2] * 3, "!3 * 2 * #{t}", "!3 * 2 * #{u}", [2, 1]],
1941
+ [[[v] * 40] * 3, "!3 * 40 * #{t}", "!3 * 40 * #{u}", [1, 32]]
1942
+ ].each do |vv, tt, uu, indices|
1943
+ it "tests corner case type: #{tt}" do
1944
+ ttt = NDT.new tt
1945
+ uuu = NDT.new tt
1946
+
1947
+ x = XND.new vv, type: ttt
1948
+ y = XND.new vv, type: ttt
1949
+
1950
+ if eq
1951
+ expect_strict_equal x, y
1952
+ else
1953
+ expect_strict_unequal x, y
1954
+ end
1955
+
1956
+ unless u.nil?
1957
+ y = XND.new vv, type: uuu
1958
+ if eq
1959
+ expect_strict_equal x, y
1960
+ else
1961
+ expect_strict_unequal x, y
1962
+ end
1963
+ end
1964
+
1965
+ unless w.nil?
1966
+ y = XND.new vv, type: ttt
1967
+ y[*indices] = w
1968
+ expect_strict_unequal x, y
1969
+
1970
+ y = XND.new vv, type: uuu
1971
+ y[*indices] = w
1972
+ expect_strict_unequal x, y
1973
+ end
1974
+ end
1975
+ end
1976
+ end
1977
+ end # context Fortran
1978
+
1979
+ context "VarDim" do
1980
+ before do
1981
+ @x = XND.new [1,2,3,4], type: "var(offsets=[0,4]) * int64"
1982
+ end
1983
+
1984
+ it "compares full array" do
1985
+ expect_strict_equal @x, XND.new([1,2,3,4], type: "var(offsets=[0,4]) * int64")
1986
+ end
1987
+
1988
+ it "tests for different shape and/or data" do
1989
+ expect_strict_unequal @x, XND.new([1,2,3,100], type: "var(offsets=[0,4]) * int64")
1990
+ expect_strict_unequal @x, XND.new([1,2,3], type: "var(offsets=[0,3]) * int64")
1991
+ expect_strict_unequal @x, XND.new([1,2,3,4,5], type: "var(offsets=[0,5]) * int64")
1992
+ end
1993
+
1994
+ it "tests different shape" do
1995
+ expect_strict_unequal @x, XND.new([1,2,3], type: "var(offsets=[0,3]) * int64")
1996
+ expect_strict_unequal @x, XND.new([[1,2,3,4]],
1997
+ type: "var(offsets=[0,1]) * var(offsets=[0,4]) * int64")
1998
+ expect_strict_unequal @x, XND.new(
1999
+ [[1,2], [3,4]], type: "var(offsets=[0,2]) * var(offsets=[0,2,4]) * int64")
2000
+ end
2001
+
2002
+ it "tests multidimensional arrays" do
2003
+ x = XND.new([[1], [2,3,4,5], [6,7], [8,9,10]])
2004
+ y = XND.new([[1], [2,3,4,5], [6,7], [8,9,10]])
2005
+
2006
+ expect_strict_equal(x, y)
2007
+ end
2008
+
2009
+ it "tests multidim arrays after assign" do
2010
+ x = XND.new([[1], [2,3,4,5], [6,7], [8,9,10]])
2011
+ y = XND.new([[1], [2,3,4,5], [6,7], [8,9,10]])
2012
+
2013
+ (0..3).to_a.zip([1,4,2,3]).each do |i, shape|
2014
+ shape.times do |k|
2015
+ v = y[i, k]
2016
+ y[i, k] = 100
2017
+
2018
+ expect_strict_unequal x, y
2019
+
2020
+ y[i, k] = v
2021
+ end
2022
+ end
2023
+ end
2024
+
2025
+ it "tests slices" do
2026
+ x = XND.new([[1], [4,5], [6,7,8], [9,10,11,12]])
2027
+
2028
+ y = XND.new([[1], [4,5]])
2029
+ expect_strict_equal x[0..1], y
2030
+
2031
+ y = XND.new([[4,5], [6,7,8]])
2032
+ expect_strict_equal x[1..2], y
2033
+
2034
+ # TODO: make this pass after Ruby 2.6 step-range
2035
+ # y = XND.new([[12,11,10,9], [5,4]])
2036
+ # expect_strict_equal x[(0..) % -2, (0..) % -1], y
2037
+ end
2038
+
2039
+ EQUAL_TEST_CASES.each do |struct|
2040
+ v = struct.v
2041
+ t = struct.t
2042
+ u = struct.u
2043
+ [
2044
+ [[v] * 0, "var(offsets=[0,0]) * #{t}",
2045
+ "var(offsets=[0,0]) * #{u}"],
2046
+ [[[v] * 0] * 1, "var(offsets=[0,1]) * var(offsets=[0,0]) * #{t}",
2047
+ "var(offsets=[0,1]) * var(offsets=[0,0]) * #{u}"]
2048
+ ].each do |vv, tt, uu|
2049
+ it "tests edge case for type: #{tt}" do
2050
+ ttt = NDT.new tt
2051
+ uuu = NDT.new tt # uu?
2052
+
2053
+ x = XND.new vv, type: ttt
2054
+
2055
+ y = XND.new vv, type: ttt
2056
+ expect_strict_equal x, y
2057
+
2058
+ y = XND.new vv, type: uuu
2059
+ expect_strict_equal x, y
2060
+ end
2061
+ end
2062
+ end
2063
+
2064
+ EQUAL_TEST_CASES.each do |struct|
2065
+ v = struct.v
2066
+ t = struct.t
2067
+ u = struct.u
2068
+ w = struct.w
2069
+ eq = struct.eq
2070
+
2071
+ [
2072
+ [[v] * 1, "var(offsets=[0,1]) * #{t}", "var(offsets=[0,1]) * #{u}", [0]],
2073
+ [[v] * 2, "var(offsets=[0,2]) * #{t}", "var(offsets=[0,2]) * #{u}", [1]],
2074
+ [[v] * 1000, "var(offsets=[0,1000]) * #{t}", "var(offsets=[0,1000]) * #{u}", [961]],
2075
+ [[[v], []], "var(offsets=[0,2]) * var(offsets=[0,1,1]) * #{t}",
2076
+ "var(offsets=[0,2]) * var(offsets=[0,1,1]) * #{u}", [0, 0]],
2077
+ [[[], [v]], "var(offsets=[0,2]) * var(offsets=[0,0,1]) * #{t}",
2078
+ "var(offsets=[0,2]) * var(offsets=[0,0,1]) * #{u}", [1, 0]],
2079
+ [[[v], [v]], "var(offsets=[0,2]) * var(offsets=[0,1,2]) * #{t}",
2080
+ "var(offsets=[0,2]) * var(offsets=[0,1,2]) * #{u}", [1, 0]],
2081
+ [[[v], [v] * 2, [v] * 5], "var(offsets=[0,3]) * var(offsets=[0,1,3,8]) * #{t}",
2082
+ "var(offsets=[0,3]) * var(offsets=[0,1,3,8]) * #{u}", [2, 3]]
2083
+ ].each do |vv, tt, uu, indices|
2084
+ it "tests for type tt=#{tt}" do
2085
+ ttt = NDT.new tt
2086
+ uuu = NDT.new tt # uu?
2087
+
2088
+ x = XND.new vv, type: ttt
2089
+ y = XND.new vv, type: ttt
2090
+
2091
+ if eq
2092
+ expect_strict_equal x, y
2093
+ else
2094
+ expect_strict_unequal x, y
2095
+ end
2096
+
2097
+ unless u.nil?
2098
+ y = XND.new vv, type: uuu
2099
+ if eq
2100
+ expect_strict_equal x, y
2101
+ else
2102
+ expect_strict_unequal x, y
2103
+ end
2104
+ end
2105
+
2106
+ unless w.nil?
2107
+ y = XND.new vv, type: ttt
2108
+ y[*indices] = w
2109
+ expect_strict_unequal x, y
2110
+
2111
+ y = XND.new vv, type: uuu
2112
+ y[*indices] = w
2113
+ expect_strict_unequal x, y
2114
+ end
2115
+ end
2116
+ end
2117
+ end
2118
+ end # context VarDim
2119
+
2120
+ context "Tuple" do
2121
+ context "simple test" do
2122
+ before do
2123
+ @x = XND.new XND::T.new(1, 2.0, "3", "123".b)
2124
+ end
2125
+
2126
+ it "checks simple equality" do
2127
+ expect_strict_equal @x, XND.new(XND::T.new(1, 2.0, "3", "123".b))
2128
+ end
2129
+
2130
+ it "checks simple inequality" do
2131
+ expect_strict_unequal @x, XND.new(XND::T.new(2, 2.0, "3", "123".b))
2132
+ expect_strict_unequal @x, XND.new(XND::T.new(1, 2.1, "3", "123".b))
2133
+ expect_strict_unequal @x, XND.new(XND::T.new(1, 2.0, "", "123".b))
2134
+ expect_strict_unequal @x, XND.new(XND::T.new(1, 2.0, "345", "123".b))
2135
+ expect_strict_unequal @x, XND.new(XND::T.new(1, 2.0, "3", "".b))
2136
+ expect_strict_unequal @x, XND.new(XND::T.new(1, 2.0, "3", "12345".b))
2137
+ end
2138
+ end # context simple test
2139
+
2140
+ context "nested structures" do
2141
+ before do
2142
+ @t = "
2143
+ (uint8,
2144
+ fixed_string(100, 'utf8'),
2145
+ (complex128,
2146
+ 2 * 3 * (fixed_bytes(size=64, align=32), bytes)),
2147
+ ref(string))
2148
+ "
2149
+
2150
+ @v = [
2151
+ 10,
2152
+ "\u00001234\u00001001abc",
2153
+ [
2154
+ 12.1e244+3i,
2155
+ [[
2156
+ ["123".b, "22".b * 10],
2157
+ ["123456".b, "23".b * 10],
2158
+ ["123456789".b, "24".b * 10]
2159
+ ],
2160
+ [
2161
+ ["1".b, "a".b],
2162
+ ["12".b, "ab".b],
2163
+ ["123".b, "abc".b]
2164
+ ]]],
2165
+ "xyz"
2166
+ ]
2167
+
2168
+ @x = XND.new @v, type: @t
2169
+ @y = XND.new @v, type: @t
2170
+ end # before
2171
+
2172
+ it "simple equality" do
2173
+ expect_strict_equal @x, @y
2174
+ end
2175
+
2176
+ it "unequal after assignment" do
2177
+ w = @y[0].value
2178
+ @y[0] = 11
2179
+
2180
+ expect_strict_unequal @x, @y
2181
+ end
2182
+
2183
+ it "equal after assignment" do
2184
+ w = @y[0].value
2185
+ @y[0] = w
2186
+
2187
+ expect_strict_equal @x, @y
2188
+ end
2189
+
2190
+ it "unequal after UTF-8 assign" do
2191
+ w = @y[1].value
2192
+ @y[1] = "\U00001234\U00001001abx"
2193
+
2194
+ expect_strict_unequal @x, @y
2195
+
2196
+ @y[1] = w
2197
+ expect_strict_equal @x, @y
2198
+ end
2199
+
2200
+ it "equal after tuple assign" do
2201
+ w = @y[2,0].value
2202
+ @y[2,0] = 12.1e244-3i
2203
+ expect_strict_unequal @x, @y
2204
+
2205
+ @y[2,0] = w
2206
+ expect_strict_equal @x, @y
2207
+ end
2208
+
2209
+ it "assigns large index value" do
2210
+ w = @y[2,1,1,2,0].value
2211
+ @y[2,1,1,2,0] = "abc".b
2212
+ expect_strict_unequal @x, @y
2213
+
2214
+ @y[2,1,1,2,0] = w
2215
+ expect_strict_equal @x, @y
2216
+ end
2217
+
2218
+ it "assign empty string" do
2219
+ w = @y[3].value
2220
+ @y[3] = ""
2221
+ expect_strict_unequal @x, @y
2222
+
2223
+ @y[3] = w
2224
+ expect_strict_equal @x, @y
2225
+ end
2226
+ end # context nested structures
2227
+
2228
+ context "simple corner cases" do
2229
+ EQUAL_TEST_CASES.each do |struct|
2230
+ v = struct.v
2231
+ t = struct.t
2232
+ u = struct.u
2233
+
2234
+ [
2235
+ [[[v] * 0], "(0 * #{t})", "(0 * #{u})"],
2236
+ [[[[v] * 0]], "((0 * #{t}))", "((0 * #{u}))"]
2237
+ ].each do |vv, tt, uu|
2238
+ before do
2239
+ @uu = uu
2240
+ @vv = vv
2241
+ @tt = tt
2242
+ @ttt = NDT.new tt
2243
+ @uuu = NDT.new tt # uu?
2244
+ @x = XND.new vv, type: @ttt
2245
+ @y = XND.new(vv, type: @ttt)
2246
+ end
2247
+
2248
+ it "equals same type object. tt=\"#{tt}\". uu=\"#{uu}\"." do
2249
+ expect_strict_equal @x, @y
2250
+ end
2251
+
2252
+
2253
+ it "equals other type object. tt=\"#{tt}\". uu=\"#{uu}\"." do
2254
+ y = XND.new @vv, type: @uuu
2255
+ expect_strict_equal @x, y
2256
+ end
2257
+ end
2258
+ end
2259
+ end # context simple corner cases
2260
+
2261
+ it "tests complex corner cases" do
2262
+ EQUAL_TEST_CASES.each do |struct|
2263
+ v = struct.v
2264
+ t = struct.t
2265
+ u = struct.u
2266
+ w = struct.w
2267
+ eq = struct.eq
2268
+
2269
+ [
2270
+ [[v], "(#{t})", "(#{u})", [0]],
2271
+ [[[v]], "((#{t}))", "(#{u})", [0, 0]],
2272
+ [[[[v]]], "(((#{t})))", "(((#{u})))", [0, 0, 0]],
2273
+
2274
+ [[[v] * 1], "(1 * #{t})", "(1 * #{u})", [0, 0]],
2275
+ [[[[v] * 1]], "((1 * #{t}))", "((1 * #{u}))", [0, 0, 0]],
2276
+ [[[v] * 3], "(3 * #{t})", "(3 * #{u})", [0, 2]]
2277
+ ].each do |vv, tt, uu, indices|
2278
+ ttt = NDT.new tt
2279
+ uuu = NDT.new tt
2280
+ x = XND.new vv, type: ttt
2281
+
2282
+ y = XND.new vv, type: ttt
2283
+ if eq
2284
+ expect_strict_equal x, y
2285
+ else
2286
+ expect_strict_unequal x, y
2287
+ end
2288
+
2289
+ unless u.nil?
2290
+ y = XND.new vv, type: uuu
2291
+ if eq
2292
+ expect_strict_equal x, y
2293
+ else
2294
+ expect_strict_unequal x, y
2295
+ end
2296
+ end
2297
+
2298
+ unless w.nil?
2299
+ y = XND.new vv, type: ttt
2300
+ y[*indices] = w
2301
+ expect_strict_unequal x, y
2302
+
2303
+ y = XND.new vv, type: uuu
2304
+ y[*indices] = w
2305
+ expect_strict_unequal x, y
2306
+ end
2307
+ end
2308
+ end
2309
+ end # context "Tuple"
2310
+ end
2311
+
2312
+ context "Record" do
2313
+ it "simple tests" do
2314
+ x = XND.new({'a' => 1, 'b' => 2.0, 'c' => "3", 'd' => "123".b})
2315
+
2316
+ expect_strict_equal x, XND.new({'a' => 1, 'b' => 2.0, 'c' => "3", 'd' => "123".b})
2317
+
2318
+ expect_strict_unequal x, XND.new({'z' => 1, 'b' => 2.0, 'c' => "3", 'd' => "123".b})
2319
+ expect_strict_unequal x, XND.new({'a' => 2, 'b' => 2.0, 'c' => "3", 'd' => "123".b})
2320
+ expect_strict_unequal x, XND.new({'a' => 1, 'b' => 2.1, 'c' => "3", 'd' => "123".b})
2321
+ expect_strict_unequal x, XND.new({'a' => 1, 'b' => 2.0, 'c' => "", 'd' => "123".b})
2322
+ expect_strict_unequal x, XND.new({'a' => 1, 'b' => 2.0, 'c' => "345", 'd' => "123"})
2323
+ expect_strict_unequal x, XND.new({'a' => 1, 'b' => 2.0, 'c' => "3", 'd' => "".b})
2324
+ expect_strict_unequal x, XND.new({'a' => 1, 'b' => 2.0, 'c' => "3", 'd' => "12345".b})
2325
+ end
2326
+
2327
+ it "nested structures" do
2328
+ t = "
2329
+ {a: uint8,
2330
+ b: fixed_string(100, 'utf8'),
2331
+ c: {x: complex128,
2332
+ y: 2 * 3 * {v: fixed_bytes(size=64, align=32),
2333
+ u: bytes}},
2334
+ d: ref(string)}
2335
+ "
2336
+ v = {
2337
+ 'a' => 10,
2338
+ 'b' => "\U00001234\U00001001abc",
2339
+ 'c' => {'x' => 12.1e244+3i,
2340
+ 'y' => [[{'v' => "123".b, 'u' => "22".b * 10},
2341
+ {'v' => "123456".b, 'u' => "23".b * 10},
2342
+ {'v' => "123456789".b, 'u' => "24".b * 10}],
2343
+ [{'v' => "1".b, 'u' => "a".b},
2344
+ {'v' => "12".b, 'u' => "ab".b},
2345
+ {'v' => "123".b, 'u' => "abc".b}]]
2346
+ },
2347
+ 'd' => "xyz"
2348
+ }
2349
+
2350
+ x = XND.new v, type: t
2351
+ y = XND.new v, type: t
2352
+ expect_strict_equal x, y
2353
+
2354
+ w = y[0].value
2355
+ y[0] = 11
2356
+ expect_strict_unequal x, y
2357
+ y[0] = w
2358
+ expect_strict_equal x, y
2359
+
2360
+ w = y[1].value
2361
+ y[1] = "\U00001234\U00001001abx"
2362
+ expect_strict_unequal x, y
2363
+ y[1] = w
2364
+ expect_strict_equal x, y
2365
+
2366
+ w = y[2,0].value
2367
+ y[2,0] = 12.1e244-3i
2368
+ expect_strict_unequal x, y
2369
+
2370
+ y[2, 0] = w
2371
+ expect_strict_equal x, y
2372
+
2373
+ w = y[2,1,1,2,0].value
2374
+ y[2,1,1,2,0] = "abc".b
2375
+ expect_strict_unequal x, y
2376
+
2377
+ y[2,1,1,2,0] = w
2378
+ expect_strict_equal x, y
2379
+
2380
+ w = y[3].value
2381
+ y[3] = ""
2382
+ expect_strict_unequal x, y
2383
+ y[3] = w
2384
+ expect_strict_equal x, y
2385
+ end
2386
+
2387
+ it "test corner cases" do
2388
+ EQUAL_TEST_CASES.each do |struct|
2389
+ v = struct.v
2390
+ t = struct.t
2391
+ u = struct.u
2392
+
2393
+ [
2394
+ [{'x' => [v] * 0}, "{x: 0 * #{t}}", "{x: 0 * #{u}}"],
2395
+ [{'x' => {'y' => [v] * 0}}, "{x: {y: 0 * #{t}}}", "{x: {y: 0 * #{u}}}"]
2396
+ ].each do |vv, tt, uu|
2397
+ ttt = NDT.new tt
2398
+ uuu = NDT.new tt
2399
+
2400
+ x = XND.new vv, type: ttt
2401
+
2402
+ y = XND.new vv, type: ttt
2403
+ expect_strict_equal x, y
2404
+
2405
+ y = XND.new vv, type: uuu
2406
+ expect_strict_equal x, y
2407
+ end
2408
+ end
2409
+ end
2410
+
2411
+ it "test many dtypes" do
2412
+ EQUAL_TEST_CASES.each do |struct|
2413
+ v = struct.v
2414
+ t = struct.t
2415
+ u = struct.u
2416
+ w = struct.w
2417
+ eq = struct.eq
2418
+
2419
+ [
2420
+ [{'x' => v}, "{x: #{t}}", "{x: #{u}}", [0]],
2421
+ [{'x' => {'y' => v}}, "{x: {y: #{t}}}", "{x: {y: #{u}}}", [0, 0]],
2422
+ [{'x' => [v] * 1}, "{x: 1 * #{t}}", "{x: 1 * #{u}}", [0, 0]],
2423
+ [{'x' => [v] * 3}, "{x: 3 * #{t}}", "{x: 3 * #{u}}", [0, 2]]
2424
+ ].each do |vv, tt, uu, indices|
2425
+ ttt = NDT.new tt
2426
+ uuu = NDT.new tt
2427
+
2428
+ x = XND.new vv, type: ttt
2429
+
2430
+ y = XND.new vv, type: ttt
2431
+ if eq
2432
+ expect_strict_equal x, y
2433
+ else
2434
+ expect_strict_unequal x, y
2435
+ end
2436
+
2437
+ unless u.nil?
2438
+ y = XND.new vv, type: uuu
2439
+ if eq
2440
+ expect_strict_equal x, y
2441
+ else
2442
+ expect_strict_unequal x, y
2443
+ end
2444
+ end
2445
+
2446
+ unless w.nil?
2447
+ y = XND.new vv, type: ttt
2448
+ y[*indices] = w
2449
+
2450
+ expect_strict_unequal x, y
2451
+ end
2452
+ end
2453
+ end
2454
+ end
2455
+ end # context Record
2456
+
2457
+ context "Ref" do
2458
+ it "simple tests" do
2459
+ x = XND.new [1,2,3,4], type: "ref(4 * float32)"
2460
+
2461
+ expect_strict_equal x, XND.new([1,2,3,4], type: "ref(4 * float32)")
2462
+
2463
+ expect_strict_unequal x, XND.new([1,2,3,4,5], type: "ref(5 * float32)")
2464
+ expect_strict_unequal x, XND.new([1,2,3], type: "ref(3 * float32)")
2465
+ expect_strict_unequal x, XND.new([1,2,3,43,5], type: "ref(5 * float32)")
2466
+ end
2467
+
2468
+ it "corner cases and many dtypes" do
2469
+ EQUAL_TEST_CASES.each do |struct|
2470
+ v = struct.v
2471
+ t = struct.t
2472
+ u = struct.u
2473
+
2474
+ [
2475
+ [[v] * 0, "ref(0 * #{t})", "ref(0 * #{u})"],
2476
+ [[v] * 0, "ref(ref(0 * #{t}))", "ref(ref(0 * #{u}))"],
2477
+ [[v] * 0, "ref(ref(ref(0 * #{t})))", "ref(ref(ref(0 * #{u})))"]
2478
+ ].each do |vv, tt, uu|
2479
+ ttt = NDT.new tt
2480
+ uuu = NDT.new tt
2481
+
2482
+ x = XND.new vv, type: ttt
2483
+
2484
+ y = XND.new vv, type: ttt
2485
+ expect_strict_equal x, y
2486
+
2487
+ y = XND.new vv, type: uuu
2488
+ expect_strict_equal x, y
2489
+ end
2490
+ end
2491
+ end
2492
+
2493
+ it "many dtypes and indices", focus: true do
2494
+ EQUAL_TEST_CASES.each do |struct|
2495
+ v = struct.v
2496
+ t = struct.t
2497
+ u = struct.u
2498
+ w = struct.w
2499
+ eq = struct.eq
2500
+
2501
+ [
2502
+ [v, "ref(#{t})", "ref(#{u})", []],
2503
+ [v, "ref(ref(#{t}))", "ref(ref(#{u}))", []],
2504
+ [v, "ref(ref(ref(#{t})))", "ref(ref(ref(#{u})))", []],
2505
+ [[v] * 1, "ref(1 * #{t})", "ref(1 * #{u})", 0],
2506
+ [[v] * 3, "ref(3 * #{t})", "ref(3 * #{u})", 2]
2507
+ ].each do |vv, tt, uu, indices|
2508
+ ttt = NDT.new tt
2509
+ uuu = NDT.new tt
2510
+
2511
+ x = XND.new vv, type: ttt
2512
+
2513
+ y = XND.new vv, type: ttt
2514
+ if eq
2515
+ expect_strict_equal x, y
2516
+ else
2517
+ expect_strict_unequal x, y
2518
+ end
2519
+
2520
+ unless u.nil?
2521
+ y = XND.new vv, type: uuu
2522
+ if eq
2523
+ expect_strict_equal x, y
2524
+ else
2525
+ expect_strict_unequal x, y
2526
+ end
2527
+ end
2528
+
2529
+ unless w.nil?
2530
+ y = XND.new vv, type: ttt
2531
+ y[indices] = w
2532
+
2533
+ expect_strict_unequal x, y
2534
+ end
2535
+ end
2536
+ end
2537
+ end
2538
+ end # context Ref
2539
+
2540
+ context "Constr" do
2541
+ it "simple tests" do
2542
+ x = XND.new [1,2,3,4], type: "A(4 * float32)"
2543
+
2544
+ expect_strict_equal x, XND.new([1,2,3,4], type: "A(4 * float32)")
2545
+
2546
+ expect_strict_unequal x, XND.new([1,2,3,4], type: "B(4 * float32)")
2547
+ expect_strict_unequal x, XND.new([1,2,3,4,5], type: "A(5 * float32)")
2548
+ expect_strict_unequal x, XND.new([1,2,3], type: "A(3 * float32)")
2549
+ expect_strict_unequal x, XND.new([1,2,3,4,55], type: "A(5 * float32)")
2550
+ end
2551
+
2552
+ it "corner cases and dtypes" do
2553
+ EQUAL_TEST_CASES.each do |struct|
2554
+ v = struct.v
2555
+ t = struct.t
2556
+ u = struct.u
2557
+
2558
+ [
2559
+ [[v] * 0, "A(0 * #{t})", "A(0 * #{u})"],
2560
+ [[v] * 0, "A(B(0 * #{t}))", "A(B(0 * #{u}))"],
2561
+ [[v] * 0, "A(B(C(0 * #{t})))", "A(B(C(0 * #{u})))"]
2562
+ ].each do |vv, tt, uu|
2563
+ ttt = NDT.new tt
2564
+ uuu = NDT.new tt
2565
+
2566
+ x = XND.new vv, type: ttt
2567
+
2568
+ y = XND.new vv, type: ttt
2569
+ expect_strict_equal x, y
2570
+
2571
+ y = XND.new vv, type: uuu
2572
+ expect_strict_equal x, y
2573
+ end
2574
+ end
2575
+ end
2576
+
2577
+ it "more dtypes" do
2578
+ EQUAL_TEST_CASES.each do |struct|
2579
+ v = struct.v
2580
+ t = struct.t
2581
+ u = struct.u
2582
+ w = struct.w
2583
+ eq = struct.eq
2584
+
2585
+ [
2586
+ [v, "A(#{t})", "A(#{u})", []],
2587
+ [v, "A(B(#{t}))", "A(B(#{u}))", []],
2588
+ [v, "A(B(C(#{t})))", "A(B(C(#{u})))", []],
2589
+ [[v] * 1, "A(1 * #{t})", "A(1 * #{u})", 0],
2590
+ [[v] * 3, "A(3 * #{t})", "A(3 * #{u})", 2]
2591
+ ].each do |vv, tt, uu, indices|
2592
+ ttt = NDT.new tt
2593
+ uuu = NDT.new tt
2594
+
2595
+ x = XND.new vv, type: ttt
2596
+
2597
+ y = XND.new vv, type: ttt
2598
+ if eq
2599
+ expect_strict_equal x, y
2600
+ else
2601
+ expect_strict_unequal x, y
2602
+ end
2603
+
2604
+ unless u.nil?
2605
+ y = XND.new vv, type: uuu
2606
+ if eq
2607
+ expect_strict_equal x, y
2608
+ else
2609
+ expect_strict_unequal x, y
2610
+ end
2611
+ end
2612
+
2613
+ unless w.nil?
2614
+ y = XND.new vv, type: ttt
2615
+ y[indices] = w
2616
+
2617
+ expect_strict_unequal x, y
2618
+ end
2619
+ end
2620
+ end
2621
+ end
2622
+ end # context Constr
2623
+
2624
+ context "Nominal" do
2625
+ it "simple tests" do
2626
+ NDT.typedef "some1000", "4 * float32"
2627
+ NDT.typedef "some1001", "4 * float32"
2628
+
2629
+ x = XND.new([1,2,3,4], type: "some1000")
2630
+
2631
+ expect_strict_equal x, XND.new([1,2,3,4], type: "some1000")
2632
+
2633
+ expect_strict_unequal x, XND.new([1,2,3,4], type: "some1001")
2634
+ expect_strict_unequal x, XND.new([1,2,3,5], type: "some1000")
2635
+ end
2636
+ end # context Nominal
2637
+
2638
+ context "Categorical" do
2639
+ it "simple tests" do
2640
+ t = "3 * categorical(NA, 'January', 'August')"
2641
+ x = XND.new ['August', 'January', 'January'], type: t
2642
+
2643
+ y = XND.new ['August', 'January', 'January'], type: t
2644
+ expect_strict_equal x, y
2645
+
2646
+ y = XND.new ['August', 'January', 'August'], type: t
2647
+ expect_strict_unequal x, y
2648
+
2649
+ x = XND.new ['August', nil, 'August'], type: t
2650
+ y = XND.new ['August', nil, 'August'], type: t
2651
+
2652
+ expect_strict_unequal x, y
2653
+ end
2654
+ end # context Categorical
2655
+
2656
+ context "FixedString" do
2657
+ it "compare" do
2658
+ [
2659
+ ["fixed_string(1)", "", "x"],
2660
+ ["fixed_string(3)", "y" * 3, "yyz"],
2661
+ ["fixed_string(1, 'ascii')", "a".b, "b".b],
2662
+ ["fixed_string(3, 'utf8')", "a" * 3, "abc"],
2663
+ #["fixed_string(3, 'utf16')", "\u1234" * 3, "\u1234\u1235\u1234"],
2664
+ #["fixed_string(3, 'utf32')", "\U00001234" * 3, "\U00001234\U00001234\U00001235"]
2665
+ ].each do |t, v, w|
2666
+ x = XND.new v, type: t
2667
+ y = XND.new v, type: t
2668
+
2669
+ expect_strict_equal x, y
2670
+
2671
+ y[[]] = w
2672
+
2673
+ expect_strict_unequal x, y
2674
+ end
2675
+ end
2676
+ end # context FixedString
2677
+
2678
+ context "FixedBytes" do
2679
+ it "simple test" do
2680
+ [
2681
+ ["a".b, "fixed_bytes(size=1)", "b".b],
2682
+ ["a".b * 100, "fixed_bytes(size=100)", "a".b * 99 + "b".b],
2683
+ ["a".b * 4, "fixed_bytes(size=4, align=2)", "a".b * 2 + "b".b]
2684
+ ].each do |v, t, w|
2685
+ x = XND.new v, type: t
2686
+ y = XND.new v, type: t
2687
+
2688
+ expect_strict_equal x, y
2689
+
2690
+ y[[]] = w
2691
+ expect_strict_unequal x, y
2692
+ end
2693
+ end
2694
+
2695
+ it "align" do
2696
+ x = XND.new("a".b * 128, type: "fixed_bytes(size=128, align=16)")
2697
+ y = XND.new("a".b * 128, type: "fixed_bytes(size=128, align=16)")
2698
+ expect_strict_equal x, y
2699
+ end
2700
+ end # context FixedBytes
2701
+
2702
+ context "String" do
2703
+ it "compare" do
2704
+ x = XND.new "abc"
2705
+
2706
+ expect_strict_equal x, XND.new("abc")
2707
+ expect_strict_equal x, XND.new("abc\0\0")
2708
+
2709
+ expect_strict_unequal x, XND.new("acb")
2710
+ end
2711
+ end # context String
2712
+
2713
+ context "Bool" do
2714
+ it "compare" do
2715
+ expect_strict_equal XND.new(true), XND.new(true)
2716
+ expect_strict_equal XND.new(false), XND.new(false)
2717
+ expect_strict_unequal XND.new(true), XND.new(false)
2718
+ expect_strict_unequal XND.new(false), XND.new(true)
2719
+ end
2720
+ end # context Bool
2721
+
2722
+ context "Signed" do
2723
+ it "compare" do
2724
+ ["int8", "int16", "int32", "int64"].each do |t|
2725
+ expect_strict_equal XND.new(-10, type: t), XND.new(-10, type: t)
2726
+ expect_strict_unequal XND.new(-10, type: t), XND.new(100, type: t)
2727
+ end
2728
+ end
2729
+ end # context Signed
2730
+
2731
+ context "Unsigned" do
2732
+ it "compare" do
2733
+ ["uint8", "uint16", "uint32", "uint64"].each do |t|
2734
+ expect_strict_equal XND.new(10, type: t), XND.new(10, type: t)
2735
+ expect_strict_unequal XND.new(10, type: t), XND.new(100, type: t)
2736
+ end
2737
+ end
2738
+ end # context Unsigned
2739
+
2740
+ context "Float32" do
2741
+ it "compare" do
2742
+ expect_strict_equal XND.new(1.2e7, type: "float32"),
2743
+ XND.new(1.2e7, type: "float32")
2744
+ expect_strict_equal XND.new(Float::INFINITY, type: "float32"),
2745
+ XND.new(Float::INFINITY, type: "float32")
2746
+ expect_strict_equal XND.new(-Float::INFINITY, type: "float32"),
2747
+ XND.new(-Float::INFINITY, type: "float32")
2748
+
2749
+ expect_strict_unequal XND.new(1.2e7, type: "float32"),
2750
+ XND.new(-1.2e7, type: "float32")
2751
+ expect_strict_unequal XND.new(Float::INFINITY, type: "float32"),
2752
+ XND.new(-Float::INFINITY, type: "float32")
2753
+ expect_strict_unequal XND.new(-Float::INFINITY, type: "float32"),
2754
+ XND.new(Float::INFINITY, type: "float32")
2755
+ expect_strict_unequal XND.new(Float::NAN, type: "float32"),
2756
+ XND.new(Float::NAN, type: "float32")
2757
+ end
2758
+ end # context Float32
2759
+
2760
+ context "Float64" do
2761
+ it "compare" do
2762
+ expect_strict_equal XND.new(1.2e7, type: "float64"),
2763
+ XND.new(1.2e7, type: "float64")
2764
+ expect_strict_equal XND.new(Float::INFINITY, type: "float64"),
2765
+ XND.new(Float::INFINITY, type: "float64")
2766
+ expect_strict_equal XND.new(-Float::INFINITY, type: "float64"),
2767
+ XND.new(-Float::INFINITY, type: "float64")
2768
+
2769
+ expect_strict_unequal XND.new(1.2e7, type: "float64"),
2770
+ XND.new(-1.2e7, type: "float64")
2771
+ expect_strict_unequal XND.new(Float::INFINITY, type: "float64"),
2772
+ XND.new(-Float::INFINITY, type: "float64")
2773
+ expect_strict_unequal XND.new(-Float::INFINITY, type: "float64"),
2774
+ XND.new(Float::INFINITY, type: "float64")
2775
+ expect_strict_unequal XND.new(Float::NAN, type: "float64"),
2776
+ XND.new(Float::NAN, type: "float64")
2777
+ end
2778
+ end # context Float64
2779
+
2780
+ context "Complex64" do
2781
+ it "compare" do
2782
+ t = "complex64"
2783
+
2784
+ inf = Float("0x1.ffffffp+127")
2785
+ denorm_min = Float("0x1p-149")
2786
+ lowest = Float("-0x1.fffffep+127")
2787
+ max = Float("0x1.fffffep+127")
2788
+
2789
+ c = [denorm_min, lowest, max, Float::INFINITY, -Float::INFINITY, Float::NAN]
2790
+
2791
+ c.each do |r|
2792
+ c.each do |s|
2793
+ c.each do |i|
2794
+ c.each do |j|
2795
+ x = XND.new Complex(r, i), type: t
2796
+ y = XND.new Complex(s, j), type: t
2797
+
2798
+ if r == s && i == j
2799
+ expect_strict_equal x, y
2800
+ else
2801
+ expect_strict_unequal x, y
2802
+ end
2803
+ end
2804
+ end
2805
+ end
2806
+ end
2807
+ end
2808
+ end # context Complex64
2809
+
2810
+ context "Complex128" do
2811
+ it "compare" do
2812
+ t = "complex128"
2813
+
2814
+ denorm_min = Float("0x0.0000000000001p-1022")
2815
+ lowest = Float("-0x1.fffffffffffffp+1023")
2816
+ max = Float("0x1.fffffffffffffp+1023")
2817
+
2818
+ c = [denorm_min, lowest, max, Float::INFINITY, -Float::INFINITY, Float::NAN]
2819
+
2820
+ c.each do |r|
2821
+ c.each do |s|
2822
+ c.each do |i|
2823
+ c.each do |j|
2824
+ x = XND.new Complex(r, i), type: t
2825
+ y = XND.new Complex(s, j), type: t
2826
+
2827
+ if r == s && i == j
2828
+ expect_strict_equal x, y
2829
+ else
2830
+ expect_strict_unequal x, y
2831
+ end
2832
+ end
2833
+ end
2834
+ end
2835
+ end
2836
+ end
2837
+ end # context complex128
2838
+ end # Context #strict_equal
2839
+
2840
+ context "#match" do
2841
+ context "VarDim" do
2842
+
2843
+ end # context VarDim
2844
+ end # context #match
2845
+
2846
+ context "#to_a" do
2847
+ context "FixedDim" do
2848
+ it "returns simple array" do
2849
+ x = XND.new [1,2,3,4]
2850
+
2851
+ expect(x.to_a).to eq([1,2,3,4])
2852
+ end
2853
+
2854
+ it "returns multi-dim array" do
2855
+ x = XND.new [[1,2,3], [4,5,6]]
2856
+
2857
+ expect(x.to_a).to eq([[1,2,3], [4,5,6]])
2858
+ end
2859
+ end
2860
+ end # context to_a
2861
+
2862
+ context "#type" do
2863
+ it "returns the type of the XND array" do
2864
+ x = XND.new [[1,2,3], [4,5,6]], type: NDT.new("2 * 3 * int64")
2865
+
2866
+ expect(x.type).to eq(NDT.new("2 * 3 * int64"))
2867
+ end
2868
+ end # context type
2869
+
2870
+ context "#to_s" do
2871
+ it "returns String representation" do
2872
+
2873
+ end
2874
+ end # context to_s
2875
+
2876
+ context "#size" do
2877
+ context "FixedDim" do
2878
+ it "returns the size of the XND array" do
2879
+ x = XND.new [1,2,3,4,5]
2880
+ expect(x.size).to eq(5)
2881
+ end
2882
+ end
2883
+
2884
+ context "Bool" do
2885
+ it "raises error" do
2886
+ x = XND.new true, type: "bool"
2887
+ expect {
2888
+ x.size
2889
+ }.to raise_error(NoMethodError)
2890
+ end
2891
+ end
2892
+
2893
+ context "Signed" do
2894
+ it "raises error" do
2895
+ x = XND.new 10, type: "int16"
2896
+ expect { x.size }.to raise_error(NoMethodError)
2897
+ end
2898
+ end
2899
+
2900
+ context "Unsigned" do
2901
+ it "raises error" do
2902
+ x = XND.new 10, type: "uint64"
2903
+ expect { x.size }.to raise_error(NoMethodError)
2904
+ end
2905
+ end
2906
+ end # context #size
2907
+
2908
+ context "#each" do
2909
+ context "FixedDim" do
2910
+ it "iterates over all elements" do
2911
+ x = XND.new [1,2,3,4,5], type: "5 * int64"
2912
+ sum = 0
2913
+ x.each do |a|
2914
+ sum += x
2915
+ end
2916
+
2917
+ expect(sum).to eq(15)
2918
+ end
2919
+ end
2920
+ end # context #each
2921
+ end