erlang_rb 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data.tar.gz.sig CHANGED
Binary file
data/README.markdown CHANGED
@@ -5,3 +5,4 @@ Provides all encoding and decoding for the Erlang Binary Term Format
5
5
  (as defined at [http://erlang.org/doc/apps/erts/erl_ext_dist.html](http://erlang.org/doc/apps/erts/erl_ext_dist.html))
6
6
  in a single Ruby module.
7
7
 
8
+ Available as a [Ruby gem at `https://rubygems.org/gems/erlang_rb`](https://rubygems.org/gems/erlang_rb).
data/lib/erlang.rb CHANGED
@@ -38,48 +38,28 @@
38
38
  # DAMAGE.
39
39
  #
40
40
 
41
- module Erlang
41
+ require 'zlib'
42
42
 
43
- class OtpErlangList
44
- def initialize(value)
45
- @value = value
46
- end
47
- def to_s
48
- arity = @value.length
49
- if arity == 0
50
- return TAG_NIL_EXT.chr
51
- else
52
- arity_packed = [arity].pack('N')
53
- list_packed = @value.map{ |element|
54
- term_to_binary_(element)
55
- }.join
56
- return "#{TAG_LIST_EXT.chr}#{arity_packed}#{list_packed}#{TAG_NIL_EXT.chr}"
57
- end
58
- end
59
- def hash
60
- return to_s.hash
61
- end
62
- def ==(other)
63
- return to_s == other.to_s
64
- end
65
- alias eql? ==
66
- end
43
+ module Erlang
67
44
 
68
45
  class OtpErlangAtom
69
46
  def initialize(value)
70
47
  @value = value
71
48
  end
72
- def to_s
49
+ attr_reader :value
50
+ def binary
73
51
  if @value.kind_of?(Integer)
74
52
  return "#{TAG_ATOM_CACHE_REF.chr}#{@value.chr}"
75
53
  elsif @value.kind_of?(String)
76
54
  size = @value.bytesize
77
55
  if @value.encoding.name == 'UTF-8'
78
56
  if size < 256
79
- return "#{TAG_SMALL_ATOM_UTF8_EXT.chr}#{size.chr}#{@value}"
57
+ return "#{TAG_SMALL_ATOM_UTF8_EXT.chr}#{size.chr}" \
58
+ "#{@value}"
80
59
  else
81
60
  size_packed = [size].pack('n')
82
- return "#{TAG_ATOM_UTF8_EXT.chr}#{size_packed}#{@value}"
61
+ return "#{TAG_ATOM_UTF8_EXT.chr}#{size_packed}" \
62
+ "#{@value}"
83
63
  end
84
64
  else
85
65
  if size < 256
@@ -93,34 +73,90 @@ module Erlang
93
73
  raise OutputException, 'unknown atom type', caller
94
74
  end
95
75
  end
76
+ def to_s
77
+ return "#{self.class.name}('#{@value.to_s}')"
78
+ end
96
79
  def hash
97
- return to_s.hash
80
+ return binary.hash
98
81
  end
99
82
  def ==(other)
100
- return to_s == other.to_s
83
+ return binary == other.binary
101
84
  end
102
85
  alias eql? ==
103
86
  end
104
87
 
88
+ class OtpErlangList
89
+ def initialize(value, improper = false)
90
+ @value = value
91
+ @improper = improper
92
+ end
93
+ attr_reader :value
94
+ attr_reader :improper
95
+ def binary
96
+ if @value.kind_of?(Array)
97
+ length = @value.length
98
+ if length == 0
99
+ return TAG_NIL_EXT.chr
100
+ elsif @improper
101
+ length_packed = [length - 1].pack('N')
102
+ list_packed = @value.map{ |element|
103
+ Erlang::term_to_binary_(element)
104
+ }.join
105
+ return "#{TAG_LIST_EXT.chr}#{length_packed}#{list_packed}"
106
+ else
107
+ length_packed = [length].pack('N')
108
+ list_packed = @value.map{ |element|
109
+ Erlang::term_to_binary_(element)
110
+ }.join
111
+ return "#{TAG_LIST_EXT.chr}#{length_packed}" \
112
+ "#{list_packed}#{TAG_NIL_EXT.chr}"
113
+ end
114
+ else
115
+ raise OutputException, 'unknown list type', caller
116
+ end
117
+ end
118
+ def to_s
119
+ return "#{self.class.name}" \
120
+ "(#{@value.to_s},improper=#{@improper.to_s})"
121
+ end
122
+ def hash
123
+ return binary.hash
124
+ end
125
+ def ==(other)
126
+ return binary == other.binary
127
+ end
128
+ alias eql? ==
129
+ end
130
+
105
131
  class OtpErlangBinary
106
132
  def initialize(value, bits = 8)
107
133
  @value = value
108
134
  @bits = bits # bits in last byte
109
135
  end
110
- def to_s
111
- size = @value.bytesize
112
- size_packed = [size].pack('N')
113
- if @bits != 8
114
- return "#{TAG_BIT_BINARY_EXT.chr}#{size_packed}#{@bits.chr}#{@value}"
136
+ attr_reader :value
137
+ attr_reader :bits
138
+ def binary
139
+ if @value.kind_of?(String)
140
+ size = @value.bytesize
141
+ size_packed = [size].pack('N')
142
+ if @bits != 8
143
+ return "#{TAG_BIT_BINARY_EXT.chr}#{size_packed}" \
144
+ "#{@bits.chr}#{@value}"
145
+ else
146
+ return "#{TAG_BINARY_EXT.chr}#{size_packed}#{@value}"
147
+ end
115
148
  else
116
- return "#{TAG_BINARY_EXT.chr}#{size_packed}#{@value}"
149
+ raise OutputException, 'unknown binary type', caller
117
150
  end
118
151
  end
152
+ def to_s
153
+ return "#{self.class.name}('#{@value.to_s}',bits=#{@bits.to_s})"
154
+ end
119
155
  def hash
120
- return to_s.hash
156
+ return binary.hash
121
157
  end
122
158
  def ==(other)
123
- return to_s == other.to_s
159
+ return binary == other.binary
124
160
  end
125
161
  alias eql? ==
126
162
  end
@@ -130,14 +166,19 @@ module Erlang
130
166
  @tag = tag
131
167
  @value = value
132
168
  end
133
- def to_s
169
+ attr_reader :tag
170
+ attr_reader :value
171
+ def binary
134
172
  return "#{@tag.chr}#{@value}"
135
173
  end
174
+ def to_s
175
+ return "#{self.class.name}('#{@tag.to_s}','#{@value.to_s}')"
176
+ end
136
177
  def hash
137
- return to_s.hash
178
+ return binary.hash
138
179
  end
139
180
  def ==(other)
140
- return to_s == other.to_s
181
+ return binary == other.binary
141
182
  end
142
183
  alias eql? ==
143
184
  end
@@ -148,20 +189,29 @@ module Erlang
148
189
  @id = id
149
190
  @creation = creation
150
191
  end
151
- def to_s
192
+ attr_reader :node
193
+ attr_reader :id
194
+ attr_reader :creation
195
+ def binary
152
196
  size = @id.bytesize / 4
153
197
  if size > 1
154
198
  size_packed = [size].pack('n')
155
- return "#{TAG_NEW_REFERENCE_EXT.chr}#{size_packed}#{@node.to_s}#{@creation}#{@id}"
199
+ return "#{TAG_NEW_REFERENCE_EXT.chr}#{size_packed}" \
200
+ "#{@node.binary}#{@creation}#{@id}"
156
201
  else
157
- return "#{TAG_REFERENCE_EXT.chr}#{@node.to_s}#{@id}#{@creation}"
202
+ return "#{TAG_REFERENCE_EXT.chr}" \
203
+ "#{@node.binary}#{@id}#{@creation}"
158
204
  end
159
205
  end
206
+ def to_s
207
+ return "#{self.class.name}" \
208
+ "('#{@node.to_s}','#{@id.to_s}','#{@creation.to_s}')"
209
+ end
160
210
  def hash
161
- return to_s.hash
211
+ return binary.hash
162
212
  end
163
213
  def ==(other)
164
- return to_s == other.to_s
214
+ return binary == other.binary
165
215
  end
166
216
  alias eql? ==
167
217
  end
@@ -172,14 +222,21 @@ module Erlang
172
222
  @id = id
173
223
  @creation = creation
174
224
  end
225
+ attr_reader :node
226
+ attr_reader :id
227
+ attr_reader :creation
228
+ def binary
229
+ return "#{TAG_PORT_EXT.chr}#{@node.binary}#{@id}#{@creation}"
230
+ end
175
231
  def to_s
176
- return "#{TAG_PORT_EXT.chr}#{@node.to_s}#{@id}#{@creation}"
232
+ return "#{self.class.name}" \
233
+ "('#{@node.to_s}','#{@id.to_s}','#{@creation.to_s}')"
177
234
  end
178
235
  def hash
179
- return to_s.hash
236
+ return binary.hash
180
237
  end
181
238
  def ==(other)
182
- return to_s == other.to_s
239
+ return binary == other.binary
183
240
  end
184
241
  alias eql? ==
185
242
  end
@@ -191,39 +248,75 @@ module Erlang
191
248
  @serial = serial
192
249
  @creation = creation
193
250
  end
251
+ attr_reader :node
252
+ attr_reader :id
253
+ attr_reader :serial
254
+ attr_reader :creation
255
+ def binary
256
+ return "#{TAG_PID_EXT.chr}" \
257
+ "#{@node.binary}#{@id}#{@serial}#{@creation}"
258
+ end
194
259
  def to_s
195
- return "#{TAG_PID_EXT.chr}#{@node.to_s}#{@id}#{@serial}#{@creation}"
260
+ return "#{self.class.name}" \
261
+ "('#{@node.to_s}','#{@id.to_s}','#{@serial.to_s}'," \
262
+ "'#{@creation.to_s}')"
196
263
  end
197
264
  def hash
198
- return to_s.hash
265
+ return binary.hash
199
266
  end
200
267
  def ==(other)
201
- return to_s == other.to_s
268
+ return binary == other.binary
202
269
  end
203
270
  alias eql? ==
204
271
  end
205
272
 
206
- def binary_to_term(data)
273
+ def self.binary_to_term(data)
274
+ size = data.bytesize
275
+ if size <= 1
276
+ raise ParseException, 'null input', caller
277
+ end
207
278
  if data[0].ord != TAG_VERSION
208
279
  raise ParseException, 'invalid version', caller
209
280
  end
210
- result = binary_to_term_(1, data)
211
- if result[0] != data.bytesize
212
- raise ParseException, 'unparsed data', caller
281
+ begin
282
+ result = binary_to_term_(1, data)
283
+ if result[0] != size
284
+ raise ParseException, 'unparsed data', caller
285
+ end
286
+ return result[1]
287
+ rescue NoMethodError => e
288
+ raise ParseException, 'missing data', e.backtrace
289
+ rescue TypeError => e
290
+ raise ParseException, 'missing data', e.backtrace
291
+ rescue ArgumentError => e
292
+ raise ParseException, 'missing data', e.backtrace
213
293
  end
214
- return result[1]
215
294
  end
216
295
 
217
- def term_to_binary(term)
218
- term_packed = term_to_binary_(term)
219
- return "#{TAG_VERSION.chr}#{term_packed}"
296
+ def self.term_to_binary(term, compressed = false)
297
+ data_uncompressed = term_to_binary_(term)
298
+ if compressed == false
299
+ return "#{TAG_VERSION.chr}#{data_uncompressed}"
300
+ else
301
+ if compressed == true
302
+ compressed = 6
303
+ end
304
+ if compressed < 0 or compressed > 9
305
+ raise InputException, 'compressed in [0..9]', caller
306
+ end
307
+ data_compressed = Zlib::Deflate.deflate(data_uncompressed,
308
+ compressed)
309
+ size_uncompressed_packed = [data_uncompressed.bytesize].pack('N')
310
+ return "#{TAG_VERSION.chr}#{TAG_COMPRESSED_ZLIB.chr}" \
311
+ "#{size_uncompressed_packed}#{data_compressed}"
312
+ end
220
313
  end
221
314
 
222
315
  private
223
316
 
224
317
  # binary_to_term
225
318
 
226
- def binary_to_term_(i, data)
319
+ def self.binary_to_term_(i, data)
227
320
  tag = data[i].ord
228
321
  i += 1
229
322
  if tag == TAG_NEW_FLOAT_EXT
@@ -237,13 +330,10 @@ module Erlang
237
330
  elsif tag == TAG_ATOM_CACHE_REF
238
331
  return [i + 1, OtpErlangAtom.new(ord(data[i,1]))]
239
332
  elsif tag == TAG_SMALL_INTEGER_EXT
240
- return [i + 1, ord(data[i])]
333
+ return [i + 1, data[i].ord]
241
334
  elsif tag == TAG_INTEGER_EXT
242
- value = data[i,4].unpack('N')[0]
243
- if value & 0x80000000
244
- value = -1 * (value & 0x7fffffff)
245
- end
246
- return [i + 4, Fixnum.induced_from(value)]
335
+ value = data[i,4].unpack('i>')[0]
336
+ return [i + 4, value]
247
337
  elsif tag == TAG_FLOAT_EXT
248
338
  value = data[i,31].partition(0.chr)[0].to_f
249
339
  return [i + 31, value]
@@ -252,7 +342,7 @@ module Erlang
252
342
  i += 2
253
343
  atom_name = data[i,j].force_encoding('ISO-8859-1')
254
344
  if atom_name.valid_encoding?
255
- return [i + j, OtpErlangAtom.new(atom_name)]
345
+ return [i + j, atom_name.to_sym]
256
346
  else
257
347
  raise ParseException, 'invalid atom_name latin1', caller
258
348
  end
@@ -302,10 +392,13 @@ module Erlang
302
392
  i = result[0]; tmp = result[1]
303
393
  result = binary_to_term_(i, data)
304
394
  i = result[0]; tail = result[1]
305
- if tail.iskind?(OtpErlangList) == false
306
- tmp.append(tail)
395
+ if tail.kind_of?(OtpErlangList) == false or tail.value != []
396
+ tmp.push(tail)
397
+ tmp = OtpErlangList.new(tmp, improper=true)
398
+ else
399
+ tmp = OtpErlangList.new(tmp)
307
400
  end
308
- return [i, OtpErlangList.new(tmp)]
401
+ return [i, tmp]
309
402
  elsif tag == TAG_BINARY_EXT
310
403
  j = data[i,4].unpack('N')[0]
311
404
  i += 4
@@ -319,15 +412,15 @@ module Erlang
319
412
  i += 4
320
413
  end
321
414
  sign = data[i].ord
322
- i += 1
323
415
  bignum = 0
324
416
  (0...j).each do |bignum_index|
325
- digit = data[i...(j - bignum_index)].ord
417
+ digit = data[i + j - bignum_index].ord
326
418
  bignum = bignum * 256 + digit
327
419
  end
328
- if sign
420
+ if sign == 1
329
421
  bignum *= -1
330
422
  end
423
+ i += 1
331
424
  return [i + j, bignum]
332
425
  elsif tag == TAG_NEW_FUN_EXT
333
426
  size = data[i,4].unpack('N')[0]
@@ -359,7 +452,14 @@ module Erlang
359
452
  i += 1
360
453
  atom_name = data[i,j].force_encoding('ISO-8859-1')
361
454
  if atom_name.valid_encoding?
362
- return [i + j, OtpErlangAtom.new(atom_name)]
455
+ if atom_name == 'true'
456
+ tmp = true
457
+ elsif atom_name == 'false'
458
+ tmp = false
459
+ else
460
+ tmp = atom_name.to_sym
461
+ end
462
+ return [i + j, tmp]
363
463
  else
364
464
  raise ParseException, 'invalid atom_name latin1', caller
365
465
  end
@@ -408,22 +508,40 @@ module Erlang
408
508
  else
409
509
  raise ParseException, 'invalid atom_name unicode', caller
410
510
  end
511
+ elsif tag == TAG_COMPRESSED_ZLIB
512
+ size_uncompressed = data[i,4].unpack('N')[0]
513
+ if size_uncompressed == 0
514
+ raise ParseException, 'compressed data null', caller
515
+ end
516
+ i += 4
517
+ data_compressed = data[i..-1]
518
+ j = data_compressed.bytesize
519
+ data_uncompressed = Zlib::Inflate.inflate(data_compressed)
520
+ if size_uncompressed != data_uncompressed.bytesize
521
+ raise ParseException, 'compression corrupt', caller
522
+ end
523
+ result = binary_to_term_(0, data_uncompressed)
524
+ i_new = result[0]; term = result[1]
525
+ if i_new != size_uncompressed
526
+ raise ParseException, 'unparsed data', caller
527
+ end
528
+ return [i + j, term]
411
529
  else
412
530
  raise ParseException, 'invalid tag', caller
413
531
  end
414
532
  end
415
533
 
416
- def binary_to_term_sequence(i, arity, data)
534
+ def self.binary_to_term_sequence(i, arity, data)
417
535
  sequence = []
418
536
  (0...arity).each do |arity_index|
419
537
  result = binary_to_term_(i, data)
420
538
  i = result[0]; element = result[1]
421
- sequence.append(element)
539
+ sequence.push(element)
422
540
  end
423
541
  return [i, sequence]
424
542
  end
425
543
 
426
- def binary_to_integer(i, data)
544
+ def self.binary_to_integer(i, data)
427
545
  tag = data[i].ord
428
546
  i += 1
429
547
  if tag == TAG_SMALL_INTEGER_EXT
@@ -439,7 +557,7 @@ module Erlang
439
557
  end
440
558
  end
441
559
 
442
- def binary_to_pid(i, data)
560
+ def self.binary_to_pid(i, data)
443
561
  tag = data[i].ord
444
562
  i += 1
445
563
  if tag == TAG_PID_EXT
@@ -457,7 +575,7 @@ module Erlang
457
575
  end
458
576
  end
459
577
 
460
- def binary_to_atom(i, data)
578
+ def self.binary_to_atom(i, data)
461
579
  tag = data[i].ord
462
580
  i += 1
463
581
  if tag == TAG_ATOM_EXT
@@ -495,11 +613,9 @@ module Erlang
495
613
 
496
614
  # term_to_binary
497
615
 
498
- def term_to_binary_(term)
616
+ def self.term_to_binary_(term)
499
617
  if term.kind_of?(String)
500
618
  return string_to_binary(term)
501
- elsif term.kind_of?(OtpErlangList)
502
- return term.to_s
503
619
  elsif term.kind_of?(Array)
504
620
  return tuple_to_binary(term)
505
621
  elsif term.kind_of?(Float)
@@ -509,29 +625,35 @@ module Erlang
509
625
  elsif term.kind_of?(Hash)
510
626
  return hash_to_binary(term)
511
627
  elsif term.kind_of?(Symbol)
512
- return OtpErlangAtom.new(term.to_s).to_s
628
+ return OtpErlangAtom.new(term.to_s).binary
513
629
  elsif term.kind_of?(TrueClass)
514
- return OtpErlangAtom.new("true").to_s
630
+ return OtpErlangAtom.new(
631
+ 'true'.force_encoding('ISO-8859-1')
632
+ ).binary
515
633
  elsif term.kind_of?(FalseClass)
516
- return OtpErlangAtom.new("false").to_s
634
+ return OtpErlangAtom.new(
635
+ 'false'.force_encoding('ISO-8859-1')
636
+ ).binary
517
637
  elsif term.kind_of?(OtpErlangAtom)
518
- return term.to_s
638
+ return term.binary
639
+ elsif term.kind_of?(OtpErlangList)
640
+ return term.binary
519
641
  elsif term.kind_of?(OtpErlangBinary)
520
- return term.to_s
642
+ return term.binary
521
643
  elsif term.kind_of?(OtpErlangFunction)
522
- return term.to_s
644
+ return term.binary
523
645
  elsif term.kind_of?(OtpErlangReference)
524
- return term.to_s
646
+ return term.binary
525
647
  elsif term.kind_of?(OtpErlangPort)
526
- return term.to_s
648
+ return term.binary
527
649
  elsif term.kind_of?(OtpErlangPid)
528
- return term.to_s
650
+ return term.binary
529
651
  else
530
652
  raise OutputException, 'unknown ruby type', caller
531
653
  end
532
654
  end
533
655
 
534
- def string_to_binary(term)
656
+ def self.string_to_binary(term)
535
657
  arity = term.bytesize
536
658
  if arity == 0
537
659
  return TAG_NIL_EXT.chr
@@ -543,11 +665,12 @@ module Erlang
543
665
  term_packed = term.unpack("C#{arity}").map{ |c|
544
666
  "#{TAG_SMALL_INTEGER_EXT.chr}#{c}"
545
667
  }.join
546
- return "#{TAG_LIST_EXT.chr}#{arity_packed}#{term_packed}#{TAG_NIL_EXT.chr}"
668
+ return "#{TAG_LIST_EXT.chr}#{arity_packed}#{term_packed}" \
669
+ "#{TAG_NIL_EXT.chr}"
547
670
  end
548
671
  end
549
672
 
550
- def tuple_to_binary(term)
673
+ def self.tuple_to_binary(term)
551
674
  arity = term.length
552
675
  term_packed = term.map{ |element|
553
676
  term_to_binary_(element)
@@ -560,7 +683,7 @@ module Erlang
560
683
  end
561
684
  end
562
685
 
563
- def integer_to_binary(term)
686
+ def self.integer_to_binary(term)
564
687
  if 0 <= term and term <= 255
565
688
  return "#{TAG_SMALL_INTEGER_EXT.chr}#{term.chr}"
566
689
  elsif -2147483648 <= term and term <= 2147483647
@@ -571,9 +694,9 @@ module Erlang
571
694
  end
572
695
  end
573
696
 
574
- def bignum_to_binary(term)
697
+ def self.bignum_to_binary(term)
575
698
  bignum = term.abs
576
- size = Integer.new(Math.log(bignum) / Math.log(256)) + 1
699
+ size = (bignum_bit_length(bignum) / 8.0).ceil.to_i
577
700
  if term < 0
578
701
  sign = 1.chr
579
702
  else
@@ -581,7 +704,7 @@ module Erlang
581
704
  end
582
705
  l = [sign]
583
706
  (0...size).each do |byte|
584
- l.append((bignum & 255).chr)
707
+ l.push((bignum & 255).chr)
585
708
  bignum >>= 8
586
709
  end
587
710
  if size < 256
@@ -591,13 +714,17 @@ module Erlang
591
714
  return "#{TAG_LARGE_BIG_EXT.chr}#{size_packed}#{l.join}"
592
715
  end
593
716
  end
717
+
718
+ def self.bignum_bit_length(bignum)
719
+ return bignum.to_s(2).bytesize
720
+ end
594
721
 
595
- def float_to_binary(term)
722
+ def self.float_to_binary(term)
596
723
  term_packed = [term].pack('G')
597
724
  return "#{TAG_NEW_FLOAT_EXT.chr}#{term_packed}"
598
725
  end
599
726
 
600
- def hash_to_binary(term)
727
+ def self.hash_to_binary(term)
601
728
  arity = term.length
602
729
  term_packed = term.to_a.map{ |element|
603
730
  key_packed = term_to_binary_(element[0])
@@ -613,11 +740,15 @@ module Erlang
613
740
  class ParseException < SyntaxError
614
741
  end
615
742
 
743
+ class InputException < ArgumentError
744
+ end
745
+
616
746
  class OutputException < TypeError
617
747
  end
618
748
 
619
749
  # tag values here http://www.erlang.org/doc/apps/erts/erl_ext_dist.html
620
750
  TAG_VERSION = 131
751
+ TAG_COMPRESSED_ZLIB = 80
621
752
  TAG_NEW_FLOAT_EXT = 70
622
753
  TAG_BIT_BINARY_EXT = 77
623
754
  TAG_ATOM_CACHE_REF = 78
@@ -0,0 +1,620 @@
1
+ #!/usr/bin/env ruby
2
+ #-*-Mode:ruby;coding:binary;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*-
3
+ # ex: set ft=ruby fenc=binary sts=4 ts=4 sw=4 et:
4
+ #
5
+ # BSD LICENSE
6
+ #
7
+ # Copyright (c) 2014, Michael Truog <mjtruog at gmail dot com>
8
+ # Copyright (c) 2009-2013, Dmitry Vasiliev <dima@hlabs.org>
9
+ # All rights reserved.
10
+ #
11
+ # Redistribution and use in source and binary forms, with or without
12
+ # modification, are permitted provided that the following conditions are met
13
+ #
14
+ # * Redistributions of source code must retain the above copyright
15
+ # notice, this list of conditions and the following disclaimer.
16
+ # * Redistributions in binary form must reproduce the above copyright
17
+ # notice, this list of conditions and the following disclaimer in
18
+ # the documentation and/or other materials provided with the
19
+ # distribution.
20
+ # * All advertising materials mentioning features or use of this
21
+ # software must display the following acknowledgment
22
+ # This product includes software developed by Michael Truog
23
+ # * The name of the author may not be used to endorse or promote
24
+ # products derived from this software without specific prior
25
+ # written permission
26
+ #
27
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
28
+ # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
29
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
32
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
37
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
40
+ # DAMAGE.
41
+ #
42
+
43
+ path = File.split(File.dirname(__FILE__)); path.pop(1)
44
+ $:.unshift File.join(*path, *%w[lib])
45
+ require 'test/unit'
46
+ require 'erlang'
47
+
48
+ # many of the test cases were adapted
49
+ # from erlport (https://github.com/hdima/erlport)
50
+ # to make the tests more exhaustive
51
+
52
+ class AtomTestCase < Test::Unit::TestCase
53
+ def test_atom
54
+ atom1 = Erlang::OtpErlangAtom.new('test')
55
+ assert(atom1.kind_of?(Erlang::OtpErlangAtom))
56
+ assert_equal(Erlang::OtpErlangAtom.new('test'), atom1)
57
+ assert_equal("Erlang::OtpErlangAtom('test')", atom1.to_s)
58
+ atom2 = Erlang::OtpErlangAtom.new('test2')
59
+ atom1_new = Erlang::OtpErlangAtom.new('test')
60
+ assert_not_equal(atom1, atom2)
61
+ assert_not_equal(atom1.hash, atom2.hash)
62
+ assert_equal(atom1, atom1_new)
63
+ assert_equal(atom1.hash, atom1_new.hash)
64
+ assert_equal('X' * 255, Erlang::OtpErlangAtom.new('X' * 255).value)
65
+ assert_equal('X' * 256, Erlang::OtpErlangAtom.new('X' * 256).value)
66
+ end
67
+ def test_invalid_atom
68
+ assert_raise(Erlang::OutputException){
69
+ Erlang::OtpErlangAtom.new([1, 2]).binary
70
+ }
71
+ end
72
+ end
73
+
74
+ class ListTestCase < Test::Unit::TestCase
75
+ def test_list
76
+ lst = Erlang::OtpErlangList.new([116, 101, 115, 116])
77
+ assert(lst.kind_of?(Erlang::OtpErlangList))
78
+ assert_equal(Erlang::OtpErlangList.new([116, 101, 115, 116]), lst)
79
+ assert_equal([116, 101, 115, 116], lst.value)
80
+ assert_equal('Erlang::OtpErlangList([116, 101, 115, 116],' \
81
+ 'improper=false)', lst.to_s)
82
+ end
83
+ end
84
+
85
+ class ImproperListTestCase < Test::Unit::TestCase
86
+ def test_improper_list
87
+ lst = Erlang::OtpErlangList.new([1, 2, 3, 4], improper=true)
88
+ assert(lst.kind_of?(Erlang::OtpErlangList))
89
+ assert_equal(Erlang::OtpErlangList.new([1, 2, 3, 4]).value, lst.value)
90
+ assert_equal(4, lst.value[-1])
91
+ assert_equal('Erlang::OtpErlangList([1, 2, 3, 4],' \
92
+ 'improper=true)', lst.to_s)
93
+ end
94
+ def test_comparison
95
+ lst = Erlang::OtpErlangList.new([1, 2, 3, 4], improper=true)
96
+ assert_equal(lst, lst)
97
+ assert_equal(lst,
98
+ Erlang::OtpErlangList.new([1, 2, 3, 4], improper=true))
99
+ assert_not_equal(lst,
100
+ Erlang::OtpErlangList.new([1, 2, 3, 5], improper=true))
101
+ assert_not_equal(lst,
102
+ Erlang::OtpErlangList.new([1, 2, 3], improper=true))
103
+ end
104
+ def test_errors
105
+ assert_raise(Erlang::OutputException){
106
+ Erlang::OtpErlangList.new('invalid', improper=true).binary
107
+ }
108
+ end
109
+ end
110
+
111
+ class DecodeTestCase < Test::Unit::TestCase
112
+ def test_binary_to_term
113
+ assert_raise(Erlang::ParseException){
114
+ Erlang::binary_to_term("")
115
+ }
116
+ assert_raise(Erlang::ParseException){
117
+ Erlang::binary_to_term("\0")
118
+ }
119
+ assert_raise(Erlang::ParseException){
120
+ Erlang::binary_to_term("\x83")
121
+ }
122
+ assert_raise(Erlang::ParseException){
123
+ Erlang::binary_to_term("\x83z")
124
+ }
125
+ end
126
+ def test_binary_to_term_atom
127
+ assert_raise(Erlang::ParseException){
128
+ Erlang::binary_to_term("\x83d")
129
+ }
130
+ assert_raise(Erlang::ParseException){
131
+ Erlang::binary_to_term("\x83d\0")
132
+ }
133
+ assert_raise(Erlang::ParseException){
134
+ Erlang::binary_to_term("\x83d\0\1")
135
+ }
136
+ assert_equal(:'', Erlang::binary_to_term("\x83d\0\0"))
137
+ assert_equal(:'', Erlang::binary_to_term("\x83s\0"))
138
+ assert_equal(:test, Erlang::binary_to_term("\x83d\0\4test"))
139
+ assert_equal(:test, Erlang::binary_to_term("\x83s\4test"))
140
+ end
141
+ def test_binary_to_term_predefined_atoms
142
+ assert_equal(true,
143
+ Erlang::binary_to_term("\x83s\4true"))
144
+ assert_equal(false,
145
+ Erlang::binary_to_term("\x83s\5false"))
146
+ assert_equal(:undefined,
147
+ Erlang::binary_to_term("\x83d\0\11undefined"))
148
+ end
149
+ def test_binary_to_term_empty_list
150
+ assert_equal(Erlang::OtpErlangList.new([]),
151
+ Erlang::binary_to_term("\x83j"))
152
+ end
153
+ def test_binary_to_term_string_list
154
+ assert_raise(Erlang::ParseException){
155
+ Erlang::binary_to_term("\x83k")
156
+ }
157
+ assert_raise(Erlang::ParseException){
158
+ Erlang::binary_to_term("\x83k\0")
159
+ }
160
+ assert_raise(Erlang::ParseException){
161
+ Erlang::binary_to_term("\x83k\0\1")
162
+ }
163
+ assert_equal('', Erlang::binary_to_term("\x83k\0\0"))
164
+ assert_equal('test', Erlang::binary_to_term("\x83k\0\4test"))
165
+ end
166
+ def test_binary_to_term_list
167
+ assert_raise(Erlang::ParseException){
168
+ Erlang::binary_to_term("\x83l")
169
+ }
170
+ assert_raise(Erlang::ParseException){
171
+ Erlang::binary_to_term("\x83l\0")
172
+ }
173
+ assert_raise(Erlang::ParseException){
174
+ Erlang::binary_to_term("\x83l\0\0")
175
+ }
176
+ assert_raise(Erlang::ParseException){
177
+ Erlang::binary_to_term("\x83l\0\0\0")
178
+ }
179
+ assert_raise(Erlang::ParseException){
180
+ Erlang::binary_to_term("\x83l\0\0\0\0")
181
+ }
182
+ assert_equal(Erlang::OtpErlangList.new([]),
183
+ Erlang::binary_to_term("\x83l\0\0\0\0j"))
184
+ assert_equal(Erlang::OtpErlangList.new([Erlang::OtpErlangList.new([]),
185
+ Erlang::OtpErlangList.new([])]),
186
+ Erlang::binary_to_term("\x83l\0\0\0\2jjj"))
187
+ end
188
+ def test_binary_to_term_improper_list
189
+ assert_raise(Erlang::ParseException){
190
+ Erlang::binary_to_term("\x83l\0\0\0\0k")
191
+ }
192
+ lst = Erlang::binary_to_term("\x83l\0\0\0\1jd\0\4tail")
193
+ assert(lst.kind_of?(Erlang::OtpErlangList))
194
+ assert_equal([Erlang::OtpErlangList.new([]), :tail], lst.value)
195
+ assert_equal(true, lst.improper)
196
+ end
197
+ def test_binary_to_term_small_tuple
198
+ assert_raise(Erlang::ParseException){
199
+ Erlang::binary_to_term("\x83h")
200
+ }
201
+ assert_raise(Erlang::ParseException){
202
+ Erlang::binary_to_term("\x83h\1")
203
+ }
204
+ assert(Erlang::binary_to_term("\x83h\0").kind_of?(Array))
205
+ assert_equal([], Erlang::binary_to_term("\x83h\0"))
206
+ assert_equal([Erlang::OtpErlangList.new([]),
207
+ Erlang::OtpErlangList.new([])],
208
+ Erlang::binary_to_term("\x83h\2jj"))
209
+ end
210
+ def test_binary_to_term_large_tuple
211
+ assert_raise(Erlang::ParseException){
212
+ Erlang::binary_to_term("\x83i")
213
+ }
214
+ assert_raise(Erlang::ParseException){
215
+ Erlang::binary_to_term("\x83i\0")
216
+ }
217
+ assert_raise(Erlang::ParseException){
218
+ Erlang::binary_to_term("\x83i\0\0")
219
+ }
220
+ assert_raise(Erlang::ParseException){
221
+ Erlang::binary_to_term("\x83i\0\0\0")
222
+ }
223
+ assert_raise(Erlang::ParseException){
224
+ Erlang::binary_to_term("\x83i\0\0\0\1")
225
+ }
226
+ assert_equal([], Erlang::binary_to_term("\x83i\0\0\0\0"))
227
+ assert_equal([Erlang::OtpErlangList.new([]),
228
+ Erlang::OtpErlangList.new([])],
229
+ Erlang::binary_to_term("\x83i\0\0\0\2jj"))
230
+ end
231
+ def test_binary_to_term_small_integer
232
+ assert_raise(Erlang::ParseException){
233
+ Erlang::binary_to_term("\x83a")
234
+ }
235
+ assert_equal(0, Erlang::binary_to_term("\x83a\0"))
236
+ assert_equal(255, Erlang::binary_to_term("\x83a\xff"))
237
+ end
238
+ def test_binary_to_term_integer
239
+ assert_raise(Erlang::ParseException){
240
+ Erlang::binary_to_term("\x83b")
241
+ }
242
+ assert_raise(Erlang::ParseException){
243
+ Erlang::binary_to_term("\x83b\0")
244
+ }
245
+ assert_raise(Erlang::ParseException){
246
+ Erlang::binary_to_term("\x83b\0\0")
247
+ }
248
+ assert_raise(Erlang::ParseException){
249
+ Erlang::binary_to_term("\x83b\0\0\0")
250
+ }
251
+ assert_equal(0, Erlang::binary_to_term("\x83b\0\0\0\0"))
252
+ assert_equal(2147483647,
253
+ Erlang::binary_to_term("\x83b\x7f\xff\xff\xff"))
254
+ assert_equal(-2147483648,
255
+ Erlang::binary_to_term("\x83b\x80\0\0\0"))
256
+ assert_equal(-1, Erlang::binary_to_term("\x83b\xff\xff\xff\xff"))
257
+ end
258
+ def test_binary_to_term_binary
259
+ assert_raise(Erlang::ParseException){
260
+ Erlang::binary_to_term("\x83m")
261
+ }
262
+ assert_raise(Erlang::ParseException){
263
+ Erlang::binary_to_term("\x83m\0")
264
+ }
265
+ assert_raise(Erlang::ParseException){
266
+ Erlang::binary_to_term("\x83m\0\0")
267
+ }
268
+ assert_raise(Erlang::ParseException){
269
+ Erlang::binary_to_term("\x83m\0\0\0")
270
+ }
271
+ assert_raise(Erlang::ParseException){
272
+ Erlang::binary_to_term("\x83m\0\0\0\1")
273
+ }
274
+ assert_equal(Erlang::OtpErlangBinary.new(""),
275
+ Erlang::binary_to_term("\x83m\0\0\0\0"))
276
+ assert_equal(Erlang::OtpErlangBinary.new("data"),
277
+ Erlang::binary_to_term("\x83m\0\0\0\4data"))
278
+ end
279
+ def test_binary_to_term_float
280
+ assert_raise(Erlang::ParseException){
281
+ Erlang::binary_to_term("\x83F")
282
+ }
283
+ assert_raise(Erlang::ParseException){
284
+ Erlang::binary_to_term("\x83F\0")
285
+ }
286
+ assert_raise(Erlang::ParseException){
287
+ Erlang::binary_to_term("\x83F\0\0")
288
+ }
289
+ assert_raise(Erlang::ParseException){
290
+ Erlang::binary_to_term("\x83F\0\0\0")
291
+ }
292
+ assert_raise(Erlang::ParseException){
293
+ Erlang::binary_to_term("\x83F\0\0\0\0")
294
+ }
295
+ assert_raise(Erlang::ParseException){
296
+ Erlang::binary_to_term("\x83F\0\0\0\0\0")
297
+ }
298
+ assert_raise(Erlang::ParseException){
299
+ Erlang::binary_to_term("\x83F\0\0\0\0\0\0")
300
+ }
301
+ assert_raise(Erlang::ParseException){
302
+ Erlang::binary_to_term("\x83F\0\0\0\0\0\0\0")
303
+ }
304
+ assert_equal(0.0, Erlang::binary_to_term("\x83F\0\0\0\0\0\0\0\0"))
305
+ assert_equal(1.5, Erlang::binary_to_term("\x83F?\xf8\0\0\0\0\0\0"))
306
+ end
307
+ def test_binary_to_term_small_big_integer
308
+ assert_raise(Erlang::ParseException){
309
+ Erlang::binary_to_term("\x83n")
310
+ }
311
+ assert_raise(Erlang::ParseException){
312
+ Erlang::binary_to_term("\x83n\0")
313
+ }
314
+ assert_raise(Erlang::ParseException){
315
+ Erlang::binary_to_term("\x83n\1\0")
316
+ }
317
+ assert_equal(0, Erlang::binary_to_term("\x83n\0\0"))
318
+ assert_equal(6618611909121,
319
+ Erlang::binary_to_term("\x83n\6\0\1\2\3\4\5\6"))
320
+ assert_equal(-6618611909121,
321
+ Erlang::binary_to_term("\x83n\6\1\1\2\3\4\5\6"))
322
+ end
323
+ def test_binary_to_term_big_integer
324
+ assert_raise(Erlang::ParseException){
325
+ Erlang::binary_to_term("\x83o")
326
+ }
327
+ assert_raise(Erlang::ParseException){
328
+ Erlang::binary_to_term("\x83o\0")
329
+ }
330
+ assert_raise(Erlang::ParseException){
331
+ Erlang::binary_to_term("\x83o\0\0")
332
+ }
333
+ assert_raise(Erlang::ParseException){
334
+ Erlang::binary_to_term("\x83o\0\0\0")
335
+ }
336
+ assert_raise(Erlang::ParseException){
337
+ Erlang::binary_to_term("\x83o\0\0\0\0")
338
+ }
339
+ assert_raise(Erlang::ParseException){
340
+ Erlang::binary_to_term("\x83o\0\0\0\1\0")
341
+ }
342
+ assert_equal(0, Erlang::binary_to_term("\x83o\0\0\0\0\0"))
343
+ assert_equal(6618611909121,
344
+ Erlang::binary_to_term("\x83o\0\0\0\6\0\1\2\3\4\5\6"))
345
+ assert_equal(-6618611909121,
346
+ Erlang::binary_to_term("\x83o\0\0\0\6\1\1\2\3\4\5\6"))
347
+ end
348
+ def test_binary_to_term_compressed_term
349
+ assert_raise(Erlang::ParseException){
350
+ Erlang::binary_to_term("\x83P")
351
+ }
352
+ assert_raise(Erlang::ParseException){
353
+ Erlang::binary_to_term("\x83P\0")
354
+ }
355
+ assert_raise(Erlang::ParseException){
356
+ Erlang::binary_to_term("\x83P\0\0")
357
+ }
358
+ assert_raise(Erlang::ParseException){
359
+ Erlang::binary_to_term("\x83P\0\0\0")
360
+ }
361
+ assert_raise(Erlang::ParseException){
362
+ Erlang::binary_to_term("\x83P\0\0\0\0")
363
+ }
364
+ assert_raise(Erlang::ParseException){
365
+ Erlang::binary_to_term("\x83P\0\0\0\x16\x78\xda\xcb\x66" \
366
+ "\x10\x49\xc1\2\0\x5d\x60\x08\x50")
367
+ }
368
+ assert_equal("d" * 20,
369
+ Erlang::binary_to_term("\x83P\0\0\0\x17\x78\xda\xcb\x66" \
370
+ "\x10\x49\xc1\2\0\x5d\x60\x08\x50")
371
+ )
372
+ end
373
+ end
374
+
375
+ class EncodeTestCase < Test::Unit::TestCase
376
+ def test_term_to_binary_tuple
377
+ assert_equal("\x83h\0", Erlang::term_to_binary([]))
378
+ assert_equal("\x83h\2h\0h\0",
379
+ Erlang::term_to_binary([[], []]))
380
+ assert_equal("\x83h\xff" + "h\0" * 255,
381
+ Erlang::term_to_binary([[]] * 255))
382
+ assert_equal("\x83i\0\0\1\0" + "h\0" * 256,
383
+ Erlang::term_to_binary([[]] * 256))
384
+ end
385
+ def test_term_to_binary_empty_list
386
+ assert_equal("\x83j",
387
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([])))
388
+ end
389
+ def test_term_to_binary_string_list
390
+ assert_equal("\x83k\0\1\0", Erlang::term_to_binary("\0"))
391
+ s = (0...256).to_a.map{ |i| i.chr }.join
392
+ assert_equal("\x83k\1\0" + s, Erlang::term_to_binary(s))
393
+ end
394
+ def test_term_to_binary_list_basic
395
+ assert_equal("\x83\x6A",
396
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([])))
397
+ assert_equal("\x83\x6C\x00\x00\x00\x01\x6A\x6A",
398
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([""])))
399
+ assert_equal("\x83\x6C\x00\x00\x00\x01\x61\x01\x6A",
400
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([1])))
401
+ assert_equal("\x83\x6C\x00\x00\x00\x01\x61\xFF\x6A",
402
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([255])))
403
+ assert_equal("\x83\x6C\x00\x00\x00\x01\x62\x00\x00\x01\x00\x6A",
404
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([256])))
405
+ assert_equal(
406
+ "\x83\x6C\x00\x00\x00\x01\x62\x7F\xFF\xFF\xFF\x6A",
407
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([2147483647]))
408
+ )
409
+ assert_equal(
410
+ "\x83\x6C\x00\x00\x00\x01\x6E\x04\x00\x00\x00\x00\x80\x6A",
411
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([2147483648]))
412
+ )
413
+ assert_equal("\x83\x6C\x00\x00\x00\x01\x61\x00\x6A",
414
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([0])))
415
+ assert_equal("\x83\x6C\x00\x00\x00\x01\x62\xFF\xFF\xFF\xFF\x6A",
416
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([-1])))
417
+ assert_equal("\x83\x6C\x00\x00\x00\x01\x62\xFF\xFF\xFF\x00\x6A",
418
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([-256])))
419
+ assert_equal("\x83\x6C\x00\x00\x00\x01\x62\xFF\xFF\xFE\xFF\x6A",
420
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([-257])))
421
+ assert_equal(
422
+ "\x83\x6C\x00\x00\x00\x01\x62\x80\x00\x00\x00\x6A",
423
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([-2147483648]))
424
+ )
425
+ assert_equal(
426
+ "\x83\x6C\x00\x00\x00\x01\x6E\x04\x01\x01\x00\x00\x80\x6A",
427
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([-2147483649]))
428
+ )
429
+ assert_equal(
430
+ "\x83\x6C\x00\x00\x00\x01\x6B\x00\x04\x74\x65\x73\x74\x6A",
431
+ Erlang::term_to_binary(Erlang::OtpErlangList.new(["test"]))
432
+ )
433
+ assert_equal(
434
+ "\x83\x6C\x00\x00\x00\x02\x62\x00\x00\x01\x75\x62\x00\x00" \
435
+ "\x01\xC7\x6A",
436
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([373, 455]))
437
+ )
438
+ assert_equal(
439
+ "\x83\x6C\x00\x00\x00\x01\x6A\x6A",
440
+ Erlang::term_to_binary(
441
+ Erlang::OtpErlangList.new([Erlang::OtpErlangList.new([])])
442
+ )
443
+ )
444
+ assert_equal(
445
+ "\x83\x6C\x00\x00\x00\x02\x6A\x6A\x6A",
446
+ Erlang::term_to_binary(
447
+ Erlang::OtpErlangList.new([Erlang::OtpErlangList.new([]),
448
+ Erlang::OtpErlangList.new([])])
449
+ )
450
+ )
451
+ assert_equal(
452
+ "\x83\x6C\x00\x00\x00\x03\x6C\x00\x00\x00\x02\x6B\x00\x04\x74\x68" \
453
+ "\x69\x73\x6B\x00\x02\x69\x73\x6A\x6C\x00\x00\x00\x01\x6C\x00\x00" \
454
+ "\x00\x01\x6B\x00\x01\x61\x6A\x6A\x6B\x00\x04\x74\x65\x73\x74\x6A",
455
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([
456
+ Erlang::OtpErlangList.new(["this", "is"]),
457
+ Erlang::OtpErlangList.new([
458
+ Erlang::OtpErlangList.new(["a"])
459
+ ]),
460
+ "test"
461
+ ]))
462
+ )
463
+ end
464
+ def test_term_to_binary_list
465
+ assert_equal(
466
+ "\x83l\0\0\0\1jj",
467
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([
468
+ Erlang::OtpErlangList.new([])
469
+ ]))
470
+ )
471
+ assert_equal(
472
+ "\x83l\0\0\0\5jjjjjj",
473
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([
474
+ Erlang::OtpErlangList.new([]),
475
+ Erlang::OtpErlangList.new([]),
476
+ Erlang::OtpErlangList.new([]),
477
+ Erlang::OtpErlangList.new([]),
478
+ Erlang::OtpErlangList.new([])
479
+ ]))
480
+ )
481
+ end
482
+ def test_term_to_binary_improper_list
483
+ assert_equal(
484
+ "\x83l\0\0\0\1h\0h\0",
485
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([
486
+ [], []
487
+ ], improper=true))
488
+ )
489
+ assert_equal(
490
+ "\x83l\0\0\0\1a\0a\1",
491
+ Erlang::term_to_binary(Erlang::OtpErlangList.new([
492
+ 0, 1
493
+ ], improper=true))
494
+ )
495
+ end
496
+ def test_term_to_binary_atom
497
+ assert_equal("\x83s\0", Erlang::term_to_binary(:""))
498
+ assert_equal("\x83s\4test", Erlang::term_to_binary(:test))
499
+ end
500
+ def test_term_to_binary_string_basic
501
+ assert_equal("\x83\x6A", Erlang::term_to_binary(""))
502
+ assert_equal("\x83\x6B\x00\x04\x74\x65\x73\x74",
503
+ Erlang::term_to_binary("test"))
504
+ assert_equal(
505
+ "\x83\x6B\x00\x09\x74\x77\x6F\x20\x77\x6F\x72\x64\x73",
506
+ Erlang::term_to_binary("two words")
507
+ )
508
+ assert_equal(
509
+ "\x83\x6B\x00\x16\x74\x65\x73\x74\x69\x6E\x67\x20\x6D\x75\x6C\x74" \
510
+ "\x69\x70\x6C\x65\x20\x77\x6F\x72\x64\x73",
511
+ Erlang::term_to_binary("testing multiple words")
512
+ )
513
+ assert_equal("\x83\x6B\x00\x01\x20",
514
+ Erlang::term_to_binary(" "))
515
+ assert_equal("\x83\x6B\x00\x02\x20\x20",
516
+ Erlang::term_to_binary(" "))
517
+ assert_equal("\x83\x6B\x00\x01\x31",
518
+ Erlang::term_to_binary("1"))
519
+ assert_equal("\x83\x6B\x00\x02\x33\x37",
520
+ Erlang::term_to_binary("37"))
521
+ assert_equal("\x83\x6B\x00\x07\x6F\x6E\x65\x20\x3D\x20\x31",
522
+ Erlang::term_to_binary("one = 1"))
523
+ assert_equal(
524
+ "\x83\x6B\x00\x20\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x5F\x2B" \
525
+ "\x2D\x3D\x5B\x5D\x7B\x7D\x5C\x7C\x3B\x27\x3A\x22\x2C\x2E\x2F\x3C" \
526
+ "\x3E\x3F\x7E\x60",
527
+ Erlang::term_to_binary("!@#\$%^&*()_+-=[]{}\\|;':\",./<>?~`")
528
+ )
529
+ assert_equal(
530
+ "\x83\x6B\x00\x09\x22\x08\x0C\x0A\x0D\x09\x0B\x53\x12",
531
+ Erlang::term_to_binary("\"\b\f\n\r\t\v\123\x12")
532
+ )
533
+ end
534
+ def test_term_to_binary_string
535
+ assert_equal("\x83j", Erlang::term_to_binary(''))
536
+ assert_equal("\x83k\0\1\0",
537
+ Erlang::term_to_binary("\0"))
538
+ assert_equal("\x83k\0\4test",
539
+ Erlang::term_to_binary('test'))
540
+ end
541
+ def test_term_to_binary_boolean
542
+ assert_equal("\x83s\4true", Erlang::term_to_binary(true))
543
+ assert_equal("\x83s\5false", Erlang::term_to_binary(false))
544
+ end
545
+ def test_term_to_binary_short_integer
546
+ assert_equal("\x83a\0", Erlang::term_to_binary(0))
547
+ assert_equal("\x83a\xff", Erlang::term_to_binary(255))
548
+ end
549
+ def test_term_to_binary_integer
550
+ assert_equal("\x83b\xff\xff\xff\xff", Erlang::term_to_binary(-1))
551
+ assert_equal("\x83b\x80\0\0\0",
552
+ Erlang::term_to_binary(-2147483648))
553
+ assert_equal("\x83b\0\0\1\0",
554
+ Erlang::term_to_binary(256))
555
+ assert_equal("\x83b\x7f\xff\xff\xff",
556
+ Erlang::term_to_binary(2147483647))
557
+ end
558
+ def test_term_to_binary_long_integer
559
+ assert_equal("\x83n\4\0\0\0\0\x80",
560
+ Erlang::term_to_binary(2147483648))
561
+ assert_equal("\x83n\4\1\1\0\0\x80",
562
+ Erlang::term_to_binary(-2147483649))
563
+ assert_equal("\x83o\0\0\1\0\0" + "\0" * 255 + "\1",
564
+ Erlang::term_to_binary(2 ** 2040))
565
+ assert_equal("\x83o\0\0\1\0\1" + "\0" * 255 + "\1",
566
+ Erlang::term_to_binary(-2 ** 2040))
567
+ end
568
+ def test_term_to_binary_float
569
+ assert_equal("\x83F\0\0\0\0\0\0\0\0",
570
+ Erlang::term_to_binary(0.0))
571
+ assert_equal("\x83F?\xe0\0\0\0\0\0\0",
572
+ Erlang::term_to_binary(0.5))
573
+ assert_equal("\x83F\xbf\xe0\0\0\0\0\0\0",
574
+ Erlang::term_to_binary(-0.5))
575
+ assert_equal("\x83F@\t!\xfbM\x12\xd8J",
576
+ Erlang::term_to_binary(3.1415926))
577
+ assert_equal("\x83F\xc0\t!\xfbM\x12\xd8J",
578
+ Erlang::term_to_binary(-3.1415926))
579
+ end
580
+ def test_term_to_binary_compressed_term
581
+ assert_equal(
582
+ "\x83P\x00\x00\x00\x15x\x9c\xcba``\xe0\xcfB\x03\x00B@\x07\x1c",
583
+ Erlang::term_to_binary(
584
+ Erlang::OtpErlangList.new([
585
+ Erlang::OtpErlangList.new([])
586
+ ] * 15), compressed=true
587
+ )
588
+ )
589
+ assert_equal(
590
+ "\x83P\x00\x00\x00\x15x\x9c\xcba``\xe0\xcfB\x03\x00B@\x07\x1c",
591
+ Erlang::term_to_binary(
592
+ Erlang::OtpErlangList.new([
593
+ Erlang::OtpErlangList.new([])
594
+ ] * 15), compressed=6
595
+ )
596
+ )
597
+ assert_equal(
598
+ "\x83P\x00\x00\x00\x15x\xda\xcba``\xe0\xcfB\x03\x00B@\x07\x1c",
599
+ Erlang::term_to_binary(
600
+ Erlang::OtpErlangList.new([
601
+ Erlang::OtpErlangList.new([])
602
+ ] * 15), compressed=9
603
+ )
604
+ )
605
+ assert_equal(
606
+ "\x83P\x00\x00\x00\x15x\x01\x01\x15\x00\xea\xffl\x00\x00\x00" \
607
+ "\x0fjjjjjjjjjjjjjjjjB@\x07\x1c",
608
+ Erlang::term_to_binary(
609
+ Erlang::OtpErlangList.new([
610
+ Erlang::OtpErlangList.new([])
611
+ ] * 15), compressed=0
612
+ )
613
+ )
614
+ assert_equal(
615
+ "\x83P\0\0\0\x17\x78\xda\xcb\x66\x10\x49\xc1\2\0\x5d\x60\x08\x50",
616
+ Erlang::term_to_binary("d" * 20, compressed=9)
617
+ )
618
+ end
619
+ end
620
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erlang_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.3.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -50,7 +50,7 @@ cert_chain:
50
50
  -----END CERTIFICATE-----
51
51
 
52
52
  '
53
- date: 2014-06-24 00:00:00.000000000 Z
53
+ date: 2014-09-30 00:00:00.000000000 Z
54
54
  dependencies: []
55
55
  description: Erlang Binary Term Format for Ruby
56
56
  email: mjtruog@gmail.com
@@ -61,6 +61,7 @@ extra_rdoc_files:
61
61
  files:
62
62
  - lib/erlang.rb
63
63
  - README.markdown
64
+ - tests/erlang_tests.rb
64
65
  homepage: https://github.com/okeuday/erlang_rb
65
66
  licenses:
66
67
  - BSD
@@ -86,4 +87,5 @@ rubygems_version: 1.8.11
86
87
  signing_key:
87
88
  specification_version: 3
88
89
  summary: Erlang
89
- test_files: []
90
+ test_files:
91
+ - tests/erlang_tests.rb
metadata.gz.sig CHANGED
Binary file