cauterize 0.0.1.pre12 → 0.0.1.pre13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/example/Cauterize +0 -2
  4. data/lib/cauterize/builders/c/buildable.rb +7 -0
  5. data/lib/cauterize/builders/c/builtin.rb +4 -0
  6. data/lib/cauterize/builders/c/composite.rb +8 -0
  7. data/lib/cauterize/builders/c/enumeration.rb +8 -4
  8. data/lib/cauterize/builders/c/fixed_array.rb +11 -2
  9. data/lib/cauterize/builders/c/group.rb +26 -1
  10. data/lib/cauterize/builders/c/scalar.rb +4 -0
  11. data/lib/cauterize/builders/c/variable_array.rb +17 -3
  12. data/lib/cauterize/builders/cs/builtin.rb +1 -1
  13. data/lib/cauterize/builders/cs/fixed_array.rb +3 -1
  14. data/lib/cauterize/builders/ruby/builtin.rb +1 -1
  15. data/lib/cauterize/builders/ruby/composite.rb +10 -7
  16. data/lib/cauterize/builders/ruby/enumeration.rb +9 -9
  17. data/lib/cauterize/builders/ruby/fixed_array.rb +4 -4
  18. data/lib/cauterize/builders/ruby/group.rb +9 -9
  19. data/lib/cauterize/builders/ruby/scalar.rb +3 -3
  20. data/lib/cauterize/builders/ruby/variable_array.rb +5 -5
  21. data/lib/cauterize/c_builder.rb +6 -0
  22. data/lib/cauterize/enumeration.rb +4 -14
  23. data/lib/cauterize/representation.rb +32 -0
  24. data/lib/cauterize/ruby_builder.rb +7 -5
  25. data/lib/cauterize/variable_array.rb +3 -12
  26. data/lib/cauterize/version.rb +1 -1
  27. data/spec/base_type_spec.rb +2 -2
  28. data/spec/builders/c/group_spec.rb +21 -0
  29. data/spec/builders/c/variable_array_spec.rb +2 -4
  30. data/spec/builders/cs/fixed_array_spec.rb +2 -1
  31. data/spec/builders/cs/variable_array_spec.rb +0 -1
  32. data/spec/c_builder_spec.rb +22 -2
  33. data/spec/cs_builder_spec.rb +0 -2
  34. data/spec/doc_builder_spec.rb +0 -2
  35. data/spec/ruby_builder_spec.rb +5 -2
  36. data/spec/ruby_generated_spec.rb +735 -0
  37. data/spec/support/spec_sample_model.rb +1 -3
  38. data/spec/variable_array_spec.rb +5 -19
  39. data/support/cs/src/CauterizeFixedArrayFormatter.cs +27 -9
  40. data/support/cs/src/CauterizeVariableArrayFormatter.cs +28 -11
  41. data/support/ruby/src/cauterize_ruby_baseclasses.rb +297 -176
  42. data/support/ruby/src/cauterize_ruby_builtins.rb +121 -95
  43. metadata +25 -39
@@ -59,20 +59,10 @@ module Cauterize
59
59
  end
60
60
 
61
61
  def representation
62
- max_val = @values.values.map(&:value).max
63
- min_val = @values.values.map(&:value).min
64
-
65
- if -128 <= min_val and max_val <= 127
66
- BaseType.find_type!(:int8)
67
- elsif (-32768 <= min_val and max_val <= 32767)
68
- BaseType.find_type!(:int16)
69
- elsif (-2147483648 <= min_val and max_val <= 2147483647)
70
- BaseType.find_type!(:int32)
71
- elsif (-9223372036854775808 <= min_val and max_val <= 9223372036854775807)
72
- BaseType.find_type!(:int64)
73
- else
74
- raise Exception.new("Unable to represent enumeration (#{min_val} -> #{max_val})")
75
- end
62
+ Representation.enumRepresentation(
63
+ min: @values.values.map(&:value).min,
64
+ max: @values.values.map(&:value).max
65
+ )
76
66
  end
77
67
 
78
68
  protected
@@ -0,0 +1,32 @@
1
+ class Representation
2
+ def self.lengthRepresentation(max_length)
3
+ if max_length < 2**8
4
+ Cauterize::BaseType.find_type!(:uint8)
5
+ elsif max_length < 2**16
6
+ Cauterize::BaseType.find_type!(:uint16)
7
+ elsif max_length < 2**32
8
+ Cauterize::BaseType.find_type!(:uint32)
9
+ elsif max_length < 2**64
10
+ Cauterize::BaseType.find_type!(:uint64)
11
+ else
12
+ raise Exception.new("Unable to represent array length (#{max_length}).")
13
+ end
14
+ end
15
+
16
+ def self.enumRepresentation(args)
17
+ max_val = args[:max]
18
+ min_val = args[:min]
19
+
20
+ if -128 <= min_val and max_val <= 127
21
+ Cauterize::BaseType.find_type!(:int8)
22
+ elsif (-32768 <= min_val and max_val <= 32767)
23
+ Cauterize::BaseType.find_type!(:int16)
24
+ elsif (-2147483648 <= min_val and max_val <= 2147483647)
25
+ Cauterize::BaseType.find_type!(:int32)
26
+ elsif (-9223372036854775808 <= min_val and max_val <= 9223372036854775807)
27
+ Cauterize::BaseType.find_type!(:int64)
28
+ else
29
+ raise Exception.new("Unable to represent enumeration (#{min_val} -> #{max_val})")
30
+ end
31
+ end
32
+ end
@@ -19,18 +19,20 @@ module Cauterize
19
19
  f << ""
20
20
  f << "require_relative './cauterize_ruby_builtins'"
21
21
  f << ""
22
-
23
- f << "CAUTERIZE_GEN_VERSION = \"#{Cauterize.get_version}\""
24
- f << "CAUTERIZE_GEN_DATE = \"#{DateTime.now.to_s}\""
22
+ f << "module #{Cauterize.get_name.camel}"
23
+ f << ""
24
+ f << " CAUTERIZE_GEN_VERSION = \"#{Cauterize.get_version}\""
25
+ f << " CAUTERIZE_GEN_DATE = \"#{DateTime.now.to_s}\""
25
26
  f << ""
26
27
 
27
- f << "CAUTERIZE_MODEL_HASH_LEN = #{BaseType.digest_class.new.length}"
28
- f << "CAUTERIZE_MODEL_HASH = [#{BaseType.model_hash.bytes.to_a.join(", ")}]"
28
+ f << " CAUTERIZE_MODEL_HASH_LEN = #{BaseType.digest_class.new.length}"
29
+ f << " CAUTERIZE_MODEL_HASH = [#{BaseType.model_hash.bytes.to_a.join(", ")}]"
29
30
  f << ""
30
31
 
31
32
  instances = BaseType.all_instances
32
33
  builders = instances.map {|i| Builders.get(:ruby, i)}
33
34
  builders.each { |b| b.class_defn(f) }
35
+ f << "end"
34
36
  f << ""
35
37
 
36
38
  File.open(@rb, "wb") do |fh|
@@ -40,17 +40,8 @@ module Cauterize
40
40
  end
41
41
  end
42
42
 
43
- def size_type(t = nil)
44
- if t
45
- _t = BaseType.find_type!(t)
46
- if _t.is_built_in? or _t.is_scalar?
47
- @size_type = _t
48
- else
49
- raise Exception.new("The type #{t} is not a built-in or scalar type")
50
- end
51
- else
52
- @size_type
53
- end
43
+ def size_type
44
+ Representation.lengthRepresentation(@array_size)
54
45
  end
55
46
 
56
47
  protected
@@ -58,7 +49,7 @@ module Cauterize
58
49
  def local_hash(digest)
59
50
  digest.update(@array_size.to_s)
60
51
  @array_type.type_hash(digest)
61
- @size_type.type_hash(digest)
52
+ size_type.type_hash(digest)
62
53
  end
63
54
  end
64
55
  end
@@ -1,3 +1,3 @@
1
1
  module Cauterize
2
- VERSION = "0.0.1.pre12"
2
+ VERSION = "0.0.1.pre13"
3
3
  end
@@ -101,10 +101,10 @@ module Cauterize
101
101
  end
102
102
 
103
103
  it "differs on differing size type in variable arrays" do
104
- f = Cauterize.variable_array(:foo) { |t| t.array_type :int8; t.array_size 2; t.size_type :uint8 }.type_hash
104
+ f = Cauterize.variable_array(:foo) { |t| t.array_type :int8; t.array_size 2 }.type_hash
105
105
  reset_for_test
106
106
 
107
- g = Cauterize.variable_array(:foo) { |t| t.array_type :int8; t.array_size 2; t.size_type :uint16 }.type_hash
107
+ g = Cauterize.variable_array(:foo) { |t| t.array_type :int8; t.array_size 2000 }.type_hash
108
108
  reset_for_test
109
109
 
110
110
  f.should_not == g
@@ -32,6 +32,27 @@ module Cauterize
32
32
  end
33
33
  end
34
34
 
35
+ describe ".preprocessor_defines" do
36
+ before do
37
+ f = default_formatter
38
+ @b.preprocessor_defines(f)
39
+ @fs = f.to_s
40
+ end
41
+
42
+ it "contains the maximum encoded length definition" do
43
+ @fs.should match /MAX_ENCODED_LENGTH_some_name/
44
+ end
45
+
46
+ it "includes the group length in the max encoded length" do
47
+ @fs.should match /MAX_ENCODED_LENGTH_some_name.+MAX_ENCODED_LENGTH_group_some_name_type/
48
+ end
49
+
50
+ it "includes the length of type synonyms 'a', 'b' in the max encoded length" do
51
+ @fs.should match /MAX_ENCODED_LENGTH_some_name.+MAX_ENCODED_LENGTH_uint8/
52
+ @fs.should match /MAX_ENCODED_LENGTH_some_name.+MAX_ENCODED_LENGTH_uint8/
53
+ end
54
+ end
55
+
35
56
  describe ".packer_defn" do
36
57
  before do
37
58
  f = default_formatter
@@ -5,7 +5,6 @@ module Cauterize
5
5
  Cauterize.variable_array(name) do |a|
6
6
  a.array_type(:uint8)
7
7
  a.array_size(8)
8
- a.size_type(:uint8)
9
8
  end
10
9
  end
11
10
  end
@@ -17,9 +16,8 @@ module Cauterize
17
16
  context "structure definition" do
18
17
  let(:vara) do
19
18
  _a = Cauterize.variable_array(:va) do |a|
20
- a.array_size(8)
19
+ a.array_size(700000)
21
20
  a.array_type(:int32)
22
- a.size_type(:int32)
23
21
  end
24
22
 
25
23
  Builders.get(:c, _a)
@@ -41,7 +39,7 @@ module Cauterize
41
39
 
42
40
  fs.should match /struct va/
43
41
  fs.should match /int32_t length;/
44
- fs.should match /int32_t data\[8\];/
42
+ fs.should match /int32_t data\[700000\];/
45
43
  fs.should match /};/
46
44
  end
47
45
  end
@@ -32,8 +32,9 @@ describe Cauterize::Builders::CS::FixedArray do
32
32
  end
33
33
 
34
34
  it "defines a size" do
35
+ text.should match /public static int MySize = 16;/
35
36
  text.should match /protected override int Size/
36
- text.should match /get { return 16; }/
37
+ text.should match /get { return MySize; }/
37
38
  end
38
39
  end
39
40
  end
@@ -5,7 +5,6 @@ describe Cauterize::Builders::CS::VariableArray do
5
5
  Cauterize.scalar(:uint32_t) {|t| t.type_name(:uint32)}
6
6
  Cauterize.scalar(:uint8_t) {|t| t.type_name(:uint8)}
7
7
  _va = Cauterize.variable_array(:myriad_data) do |a|
8
- a.size_type :uint8_t
9
8
  a.array_type :uint32_t
10
9
  a.array_size 16
11
10
  end
@@ -33,12 +33,10 @@ module Cauterize
33
33
  Cauterize.variable_array(:mac_table) do |t|
34
34
  t.array_type :mac_address
35
35
  t.array_size 64
36
- t.size_type :small_uint
37
36
  end
38
37
 
39
38
  Cauterize.variable_array(:name) do |va|
40
39
  va.array_type :small_uint
41
- va.size_type :small_uint
42
40
  va.array_size 32
43
41
  end
44
42
 
@@ -111,6 +109,24 @@ module Cauterize
111
109
  @h_text.should match /MALE = 0/
112
110
  @h_text.should match /FEMALE = 1/
113
111
  end
112
+
113
+ it "includes preprocessor definitions for fixed and variable arrays" do
114
+ @h_text.should match /FIXED_ARRAY_LENGTH_mac_address/
115
+ @h_text.should match /VARIABLE_ARRAY_MAX_LENGTH_mac_table/
116
+ @h_text.should match /VARIABLE_ARRAY_MAX_LENGTH_name/
117
+ end
118
+
119
+ it "includes preprocessor definitions for maximum encoded length" do
120
+ @h_text.should match /MAX_ENCODED_LENGTH_small_uint/
121
+ @h_text.should match /MAX_ENCODED_LENGTH_mac_address/
122
+ @h_text.should match /MAX_ENCODED_LENGTH_mac_table/
123
+ @h_text.should match /MAX_ENCODED_LENGTH_name/
124
+ @h_text.should match /MAX_ENCODED_LENGTH_gender/
125
+ @h_text.should match /MAX_ENCODED_LENGTH_place/
126
+ @h_text.should match /MAX_ENCODED_LENGTH_person/
127
+ @h_text.should match /MAX_ENCODED_LENGTH_dog/
128
+ @h_text.should match /MAX_ENCODED_LENGTH_creature/
129
+ end
114
130
  end
115
131
 
116
132
  describe "c body generation" do
@@ -121,6 +137,10 @@ module Cauterize
121
137
  it "includes the generated header file" do
122
138
  @c_text.should match /#include "testing.h"/
123
139
  end
140
+
141
+ it "uses the fixed array length preprocessor define" do
142
+ @c_text.should match /FIXED_ARRAY_LENGTH_mac_address/
143
+ end
124
144
  end
125
145
 
126
146
  describe "compilation" do
@@ -29,12 +29,10 @@ module Cauterize
29
29
  Cauterize.variable_array(:mac_table) do |t|
30
30
  t.array_type :mac_address
31
31
  t.array_size 64
32
- t.size_type :uint8_t
33
32
  end
34
33
 
35
34
  Cauterize.variable_array(:name) do |va|
36
35
  va.array_type :uint8_t
37
- va.size_type :uint8_t
38
36
  va.array_size 32
39
37
  end
40
38
 
@@ -51,13 +51,11 @@ module Cauterize
51
51
  Cauterize.variable_array(:a_var_array, "maybe some things") do |t|
52
52
  t.array_type :an_int
53
53
  t.array_size 5
54
- t.size_type :uint8
55
54
  end
56
55
 
57
56
  Cauterize.variable_array(:a_var_mystery) do |t|
58
57
  t.array_type :uint8
59
58
  t.array_size 1
60
- t.size_type :uint8
61
59
  end
62
60
 
63
61
  Cauterize.enumeration(:some_colors, "several colors to choose from") do |t|
@@ -12,6 +12,7 @@ module Cauterize
12
12
 
13
13
  describe :build do
14
14
  before do
15
+ Cauterize.set_name("example_project")
15
16
  Cauterize.set_version("1.2.3")
16
17
 
17
18
  Cauterize.scalar(:small_uint) {|t| t.type_name(:uint8)}
@@ -24,12 +25,10 @@ module Cauterize
24
25
  Cauterize.variable_array(:mac_table) do |t|
25
26
  t.array_type :mac_address
26
27
  t.array_size 64
27
- t.size_type :small_uint
28
28
  end
29
29
 
30
30
  Cauterize.variable_array(:name) do |va|
31
31
  va.array_type :small_uint
32
- va.size_type :small_uint
33
32
  va.array_size 32
34
33
  end
35
34
 
@@ -74,6 +73,10 @@ module Cauterize
74
73
  @ruby_text.should include("require_relative './cauterize_ruby_builtins'")
75
74
  end
76
75
 
76
+ it "The generated code is wrapped in a module" do
77
+ @ruby_text.should include("module ExampleProject")
78
+ end
79
+
77
80
  end
78
81
  end
79
82
  end
@@ -0,0 +1,735 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+
4
+ def range_test_type(s)
5
+ ("range_test_" + s.to_s)
6
+ end
7
+
8
+ def integer_builtin_type_ranges
9
+ [ [:uint8, 0, 2**8-1, 1],
10
+ [:int8, -2**7, 2**7-1, 1],
11
+ [:uint16, 0, 2**16-1, 2],
12
+ [:int16, -2**15, 2**15-1, 2],
13
+ [:uint32, 0, 2**32-1, 4],
14
+ [:int32, -2**31, 2**31-1, 4],
15
+ [:uint64, 0, 2**64-1, 8],
16
+ [:int64, -2**63, 2**63-1, 8],
17
+ ]
18
+ end
19
+
20
+ def floating_builtin_type_ranges
21
+ [ [:float32, -3.4028234e38, 3.4028234e38, 4],
22
+ [:float64, Float::MIN, Float::MAX, 8],
23
+ ]
24
+ end
25
+
26
+ def integer_builtin_types
27
+ integer_builtin_type_ranges.each do |t, min_val, max_val, num_bytes|
28
+ t_class = ExampleProject.const_get(range_test_type(t).camel.to_sym)
29
+ yield t_class, min_val, max_val, num_bytes
30
+ end
31
+ end
32
+
33
+ def floating_builtin_types
34
+ floating_builtin_type_ranges.each do |t, min_val, max_val, num_bytes|
35
+ t_class = ExampleProject.const_get(range_test_type(t).camel.to_sym)
36
+ yield t_class, min_val, max_val, num_bytes
37
+ end
38
+ end
39
+
40
+ def numeric_builtin_types
41
+ integer_builtin_types do |t, min_val, max_val, num_bytes|
42
+ yield t, min_val, max_val, num_bytes
43
+ end
44
+ floating_builtin_types do |t, min_val, max_val, num_bytes|
45
+ yield t, min_val, max_val, num_bytes
46
+ end
47
+ end
48
+
49
+
50
+
51
+ Cauterize.set_name("example_project")
52
+ Cauterize.set_version("1.2.3")
53
+
54
+ integer_builtin_type_ranges.each do |builtin_type, min_val, max_val, num_bytes|
55
+ Cauterize.scalar(range_test_type(builtin_type).to_sym) do |t|
56
+ t.type_name(builtin_type)
57
+ end
58
+ end
59
+
60
+ floating_builtin_type_ranges.each do |builtin_type, min_val, max_val, num_bytes|
61
+ Cauterize.scalar(range_test_type(builtin_type).to_sym) do |t|
62
+ t.type_name(builtin_type)
63
+ end
64
+ end
65
+
66
+ Cauterize.scalar(:small_uint) {|t| t.type_name(:uint8)}
67
+
68
+ Cauterize.scalar(:a_test_bool) {|t| t.type_name(:bool)}
69
+ Cauterize.scalar(:a_test_float) {|t| t.type_name(:float32)}
70
+
71
+ Cauterize.fixed_array(:simple_integer_fixed_array) do |fa|
72
+ fa.array_type :uint8
73
+ fa.array_size 5
74
+ end
75
+
76
+ Cauterize.enumeration(:color) do |e|
77
+ e.value :red
78
+ e.value :blue
79
+ e.value :green
80
+ end
81
+
82
+ Cauterize.enumeration(:wacky_enum) do |e|
83
+ e.value :negative, -500
84
+ e.value :negative_plus_one
85
+ e.value :positive, 500
86
+ e.value :positive_plus_one
87
+ end
88
+
89
+ Cauterize.fixed_array(:mac_address) do |fa|
90
+ fa.array_type :small_uint
91
+ fa.array_size 6
92
+ end
93
+
94
+ Cauterize.variable_array(:mac_table) do |t|
95
+ t.array_type :mac_address
96
+ t.array_size 64
97
+ end
98
+
99
+ Cauterize.variable_array(:name) do |va|
100
+ va.array_type :small_uint
101
+ va.array_size 32
102
+ end
103
+
104
+ Cauterize.enumeration(:gender) do |e|
105
+ e.value :male
106
+ e.value :female
107
+ end
108
+
109
+ Cauterize.composite(:place) do |c|
110
+ c.field :name, :name
111
+ c.field :elevation, :uint32
112
+ end
113
+
114
+ Cauterize.composite(:person) do |c|
115
+ c.field :first_name, :name
116
+ c.field :last_name, :name
117
+ c.field :gender, :gender
118
+ end
119
+
120
+ Cauterize.composite(:dog) do |c|
121
+ c.field :name, :name
122
+ c.field :gender, :gender
123
+ c.field :leg_count, :small_uint
124
+ end
125
+
126
+ Cauterize.group(:creature) do |g|
127
+ g.field :person, :person
128
+ g.field :dog, :dog
129
+ g.dataless :void
130
+ end
131
+
132
+ Dir.mktmpdir do |tmpdir|
133
+ @rb_path = File.join(tmpdir, "testing.rb")
134
+
135
+ # copy support files into temporary directory
136
+ Dir["support/ruby/src/*"].each do |path|
137
+ FileUtils.cp(path, tmpdir + "/")
138
+ end
139
+
140
+ @rb = Cauterize::RubyBuilder.new(@rb_path, "testing")
141
+ @rb.build
142
+ require @rb_path
143
+
144
+ # puts File.read(@rb.rb)
145
+ end
146
+
147
+ # class FastName < CauterizeData
148
+ # attr_reader :length
149
+ # def initialize(raw_data)
150
+ # @raw_data = raw_data.to_s
151
+ # @length = ExampleProject::Name.size_type.construct(@raw_data.length)
152
+ # raise "Invalid length: #{@raw_data.length}, max length is: #{ExampleProject::Name.max_length}" if @raw_data.length > ExampleProject::Name.max_length
153
+ # end
154
+
155
+ # def to_string
156
+ # @raw_data
157
+ # end
158
+
159
+ # alias to_ruby to_string
160
+ # alias pack to_string
161
+
162
+ # def packio(x)
163
+ # x << length.pack
164
+ # x << @raw_data
165
+ # end
166
+
167
+ # def self.do_unpackio(x)
168
+ # len = ExampleProject::Name.size_type.unpackio(x)
169
+ # self.new(x.read(len.to_ruby))
170
+ # end
171
+ # end
172
+
173
+ # ExampleProject::Name.set_specializer(FastName)
174
+
175
+ module Cauterize
176
+ describe Cauterize::RubyBuilder do
177
+ before(:all) do
178
+
179
+ end
180
+
181
+ after(:all) do
182
+ end
183
+
184
+ describe CauterizeRuby::Scalar do
185
+ numeric_builtin_types do |c, min_val, max_val, num_bytes|
186
+ describe c do
187
+ it "should be able to store its minimum value" do
188
+ c.new(min_val).to_ruby.should == min_val
189
+ end
190
+ it "should be able to store its maximum value" do
191
+ c.new(max_val).to_ruby.should == max_val
192
+ end
193
+ it "can construct from existing #{c}" do
194
+ existing = c.new(max_val)
195
+ c.construct(existing).to_ruby.should == max_val
196
+ end
197
+ it "pack and unpack should be inverses" do
198
+ c.unpack(c.new(123).pack).to_ruby.should == 123
199
+ end
200
+ it "pack should return .num_bytes bytes" do
201
+ x = c.new(123)
202
+ x.pack.length.should == x.num_bytes
203
+ # and for builtins these should also be the same:
204
+ x.pack.length.should == c::max_size
205
+ x.pack.length.should == c::min_size
206
+ end
207
+ it "to_i should result in an Integer" do
208
+ c.new(max_val).to_i.is_a?(Integer).should be_true
209
+ end
210
+ it "to_f should result in a Float" do
211
+ c.new(max_val).to_f.class.should == Float
212
+ end
213
+ it "min val should be smaller than max val" do
214
+ (c.new(min_val) <=> max_val).should == -1
215
+ (c.new(min_val) <=> c.new(max_val)).should == -1
216
+ end
217
+ it "max val should be bigger than min val" do
218
+ (c.new(max_val) <=> min_val).should == 1
219
+ (c.new(max_val) <=> min_val).should == 1
220
+ end
221
+ it "equal numbers should be equal" do
222
+ (c.new(123) <=> 123).should == 0
223
+ (c.new(123) <=> c.new(123)).should == 0
224
+ (c.new(123) == c.new(123)).should be_true
225
+ (c.new(123) == 123).should be_true
226
+ (c.new(123) != 123).should be_false
227
+ (c.new(123) != c.new(123)).should be_false
228
+ (c.new(123) != c.new(124)).should be_true
229
+ (c.new(123) != 124).should be_true
230
+ end
231
+ it "should raise exception if comparing to wrong cauterize type" do
232
+ thing = ExampleProject::ATestBool.new(false)
233
+ lambda { c.new(123) <=> thing }.should raise_error("Invalid Type: was #{ExampleProject::ATestBool}, expected #{c.name}")
234
+ end
235
+ it "num_bytes should match expected num_bytes" do
236
+ c.new(max_val).num_bytes.should == num_bytes
237
+ c::max_size.should == num_bytes
238
+ c::min_size.should == num_bytes
239
+ end
240
+ end
241
+ end
242
+
243
+ integer_builtin_types do |c, min_val, max_val, num_byte|
244
+ describe c do
245
+ it "should not be able to store #{max_val + 1}" do
246
+ lambda { c.new(max_val + 1)}.should raise_error("#{c}: Out of range value: #{max_val + 1}, for #{c}")
247
+ end
248
+ it "should not be able to store #{min_val - 1}" do
249
+ lambda { c.new(min_val - 1)}.should raise_error("#{c}: Out of range value: #{min_val - 1}, for #{c}")
250
+ end
251
+ it "to_ruby and to_i and to_f should return the same number" do
252
+ x = c.new(max_val)
253
+ x.to_i.should == x.to_ruby
254
+ x.to_f.should be_within(0.0001).of(x.to_ruby)
255
+ end
256
+ it "storing a float should truncate it to an Integer" do
257
+ x = c.new(1.5)
258
+ x.to_f.should == 1.0
259
+ end
260
+ it "to_ruby should result in an Integer" do
261
+ c.new(max_val).to_ruby.is_a?(Integer).should be_true
262
+ end
263
+ end
264
+ end
265
+
266
+ floating_builtin_types do |c, min_val, max_val|
267
+ describe c do
268
+ it "to_ruby and to_f should return the same number" do
269
+ x = c.new(max_val)
270
+ x.to_f.should == x.to_ruby
271
+ end
272
+ it "to_ruby should result in a Float" do
273
+ c.new(max_val).to_ruby.is_a?(Float).should be_true
274
+ end
275
+ it "to_i should return the same number, but truncated" do
276
+ x = c.new(123.532)
277
+ x.to_i.should == 123
278
+ end
279
+ end
280
+ end
281
+
282
+ describe ExampleProject::ATestFloat do
283
+ max_plus = 3.402824e38
284
+ it "should not be able to store #{max_plus}" do
285
+ lambda { ExampleProject::ATestFloat.new(max_plus)}.should raise_error("ExampleProject::ATestFloat: Out of range value: #{max_plus}, for #{ExampleProject::ATestFloat}")
286
+ end
287
+ min_minus = -3.402824e38
288
+ it "should not be able to store #{min_minus}" do
289
+ lambda { ExampleProject::ATestFloat.new(min_minus)}.should raise_error("ExampleProject::ATestFloat: Out of range value: #{min_minus}, for #{ExampleProject::ATestFloat}")
290
+ end
291
+ end
292
+
293
+ describe ExampleProject::ATestBool do
294
+ it "pack and unpack should be inverses" do
295
+ ExampleProject::ATestBool.unpack(ExampleProject::ATestBool.new(true).pack).to_ruby.should == true
296
+ ExampleProject::ATestBool.unpack(ExampleProject::ATestBool.new(false).pack).to_ruby.should == false
297
+ end
298
+ it "should be construct from existing ATestBool" do
299
+ existing = ExampleProject::ATestBool.new(false)
300
+ ExampleProject::ATestBool.construct(existing).to_ruby.should == false
301
+ end
302
+ it "should be able to store true" do
303
+ ExampleProject::ATestBool.new(true).to_ruby.should == true
304
+ end
305
+ it "should be able to store false" do
306
+ ExampleProject::ATestBool.new(false).to_ruby.should == false
307
+ end
308
+ it "should convert a truthy true" do
309
+ ExampleProject::ATestBool.new([]).to_ruby.should == true
310
+ end
311
+ it "should convert a falsy false" do
312
+ ExampleProject::ATestBool.new(nil).to_ruby.should == false
313
+ end
314
+ it "true should equal true" do
315
+ (ExampleProject::ATestBool.new(true) == true).should be_true
316
+ (ExampleProject::ATestBool.new(true) != true).should be_false
317
+ (ExampleProject::ATestBool.new(true) <=> true).should == 0
318
+ end
319
+ it "false should equal false" do
320
+ (ExampleProject::ATestBool.new(false) == false).should be_true
321
+ (ExampleProject::ATestBool.new(false) != false).should be_false
322
+ (ExampleProject::ATestBool.new(false) <=> false).should == 0
323
+ end
324
+ it "false comes before than true" do
325
+ (ExampleProject::ATestBool.new(false) <=> true).should == -1
326
+ (ExampleProject::ATestBool.new(false) <=> ExampleProject::ATestBool.new(true)).should == -1
327
+ end
328
+ it "true comes after false" do
329
+ (ExampleProject::ATestBool.new(true) <=> false).should == 1
330
+ (ExampleProject::ATestBool.new(true) <=> ExampleProject::ATestBool.new(false)).should == 1
331
+ end
332
+ it "num_bytes == 1" do
333
+ ExampleProject::ATestBool.new(true).pack.length.should == 1
334
+ ExampleProject::ATestBool.new(true).num_bytes.should == 1
335
+ ExampleProject::ATestBool::max_size.should == 1
336
+ ExampleProject::ATestBool::min_size.should == 1
337
+ end
338
+ end
339
+ end
340
+
341
+ describe CauterizeRuby::Enumeration do
342
+ describe ExampleProject::Color do
343
+ example_colors = [:RED, :BLUE, :GREEN]
344
+ example_not_colors = [:DIRT, :LASERS, :HUNGRY, 0, 1.0, true]
345
+
346
+ example_colors.each_with_index do |color, i|
347
+ it ".new and .to_ruby should be inverses" do
348
+ ExampleProject::Color.new(color).to_ruby.should == color
349
+ end
350
+ it "pack and unpack should be inverses" do
351
+ ExampleProject::Color.unpack(ExampleProject::Color.new(color).pack).to_ruby.should == color
352
+ end
353
+ it "should pack to .num_bytes bytes" do
354
+ x = ExampleProject::Color.new(color)
355
+ x.pack.length.should == x.num_bytes
356
+ end
357
+ it ".to_i should be the value index (in this case)" do
358
+ ExampleProject::Color.new(color).to_i.should == i
359
+ end
360
+ it ".from_int and .to_i should be inverses" do
361
+ ExampleProject::Color.from_int(i).to_i.should == i
362
+ end
363
+ end
364
+ example_not_colors.each do |non_color|
365
+ it "should not be able to construct from non-colors" do
366
+ lambda { ExampleProject::Color.new(non_color)}.should raise_error("ExampleProject::Color: Invalid field name: #{non_color}, Valid field names are: [:RED, :BLUE, :GREEN]")
367
+ end
368
+ end
369
+ it ".from_int should raise error on invalid input" do
370
+ lambda { ExampleProject::Color.from_int(-1)}.should raise_error("ExampleProject::Color: Invalid enumeration value: -1")
371
+ lambda { ExampleProject::Color.from_int(3)}.should raise_error("ExampleProject::Color: Invalid enumeration value: 3")
372
+ end
373
+ end
374
+ describe ExampleProject::WackyEnum do
375
+ example_wacky = { NEGATIVE: -500,
376
+ NEGATIVE_PLUS_ONE: -499,
377
+ POSITIVE: 500,
378
+ POSITIVE_PLUS_ONE: 501}
379
+ example_wacky.each do |k, v|
380
+ it ".new and .to_ruby should be inverses" do
381
+ ExampleProject::WackyEnum.new(k).to_ruby.should == k
382
+ end
383
+ it "pack and unpack should be inverses" do
384
+ ExampleProject::WackyEnum.unpack(ExampleProject::WackyEnum.new(k).pack).to_ruby.should == k
385
+ end
386
+ it "should pack to .num_bytes bytes" do
387
+ x = ExampleProject::WackyEnum.new(k)
388
+ x.pack.length.should == x.num_bytes
389
+ end
390
+ it "max_size == min_size should be 2 for our wacky enum" do
391
+ ExampleProject::WackyEnum::max_size.should == 2
392
+ ExampleProject::WackyEnum::min_size.should == 2
393
+ end
394
+ it ".to_i should be the enum value" do
395
+ ExampleProject::WackyEnum.new(k).to_i.should == v
396
+ end
397
+ it ".from_int and .to_i should be inverses" do
398
+ ExampleProject::WackyEnum.from_int(v).to_i.should == v
399
+ end
400
+ end
401
+ it ".from_int should raise error on invalid input" do
402
+ lambda { ExampleProject::WackyEnum.from_int(0)}.should raise_error("ExampleProject::WackyEnum: Invalid enumeration value: 0")
403
+ lambda { ExampleProject::WackyEnum.from_int(-498)}.should raise_error("ExampleProject::WackyEnum: Invalid enumeration value: -498")
404
+ end
405
+ describe "#<=>" do
406
+ example_wacky.each do |k1, v1|
407
+ example_wacky.each do |k2, v2|
408
+ it "should have the same ordering as the enum values" do
409
+ (ExampleProject::WackyEnum.new(k1) <=> ExampleProject::WackyEnum.new(k2)).should == (v1 <=> v2)
410
+ end
411
+ end
412
+ end
413
+ end
414
+ describe "#==" do
415
+ example_wacky.each do |k1, v1|
416
+ example_wacky.each do |k2, v2|
417
+ it "should be equal if enum values are equal" do
418
+ if v1 == v2
419
+ (ExampleProject::WackyEnum.new(k1) == ExampleProject::WackyEnum.new(k2)).should be_true
420
+ (ExampleProject::WackyEnum.new(k1) != ExampleProject::WackyEnum.new(k2)).should be_false
421
+ else
422
+ (ExampleProject::WackyEnum.new(k1) == ExampleProject::WackyEnum.new(k2)).should be_false
423
+ (ExampleProject::WackyEnum.new(k1) != ExampleProject::WackyEnum.new(k2)).should be_true
424
+ end
425
+ end
426
+ end
427
+ end
428
+ end
429
+ end
430
+ describe "#<=>" do
431
+ it "should automatically promote a symbol when compared against" do
432
+ (ExampleProject::Color.new(:RED) <=> :RED).should == 0
433
+ (ExampleProject::Color.new(:RED) <=> :BLUE).should == -1
434
+ (ExampleProject::Color.new(:BLUE) <=> :RED).should == 1
435
+ end
436
+ it "should raise a type error if compared against a non-symbol or value of different type" do
437
+ lambda { (ExampleProject::Color.new(:RED) <=> 0) }.should raise_error("ExampleProject::Color: Invalid field name: 0, Valid field names are: [:RED, :BLUE, :GREEN]")
438
+ lambda { (ExampleProject::Color.new(:RED) <=> :ORANGE) }.should raise_error("ExampleProject::Color: Invalid field name: ORANGE, Valid field names are: [:RED, :BLUE, :GREEN]")
439
+ lambda { (ExampleProject::WackyEnum.new(:NEGATIVE) <=> ExampleProject::Color.new(:RED)) }.should raise_error("Invalid Type: was ExampleProject::Color, expected ExampleProject::WackyEnum")
440
+ end
441
+ end
442
+ end
443
+
444
+ describe CauterizeRuby::VariableArray do
445
+ it "can be constructed from an existing variable array of same type" do
446
+ test_string = "this is a test"
447
+ test_array = ExampleProject::Name.new(test_string.bytes)
448
+ new_array = ExampleProject::Name.new(test_array)
449
+ new_array.to_ruby.should == test_string.bytes.to_a
450
+ end
451
+
452
+ it "can pack, and unpack to its original value" do
453
+ test_string = "this is a test"
454
+ ExampleProject::Name.unpack(ExampleProject::Name.new(test_string.bytes).pack).to_string.should == test_string
455
+ end
456
+ end
457
+
458
+ describe CauterizeRuby::FixedArray do
459
+
460
+ it ".new and .to_ruby are inverses" do
461
+ test_array = [1, 2, 6, 10, 100, 0]
462
+ ExampleProject::MacAddress.new(test_array).to_ruby.should == test_array
463
+ end
464
+
465
+ it "can pack, and unpack to its original value" do
466
+ test_array = [1, 2, 6, 10, 100, 0]
467
+ ExampleProject::MacAddress.unpack(ExampleProject::MacAddress.new(test_array).pack).to_ruby.should == test_array
468
+ end
469
+
470
+ it "should pack to .num_bytes bytes" do
471
+ test_array = [1, 2, 6, 10, 100, 0]
472
+ x = ExampleProject::MacAddress.new(test_array)
473
+ x.pack.length.should == x.num_bytes
474
+ end
475
+
476
+ it "raises an exception if the array length is wrong" do
477
+ lambda { ExampleProject::MacAddress.new([1, 2, 6, 10, 100]) }.should raise_error("ExampleProject::MacAddress: Invalid length: 5, expected: 6")
478
+ lambda { ExampleProject::MacAddress.new([1, 2, 6, 10, 100, 1, 12]) }.should raise_error("ExampleProject::MacAddress: Invalid length: 7, expected: 6")
479
+ end
480
+
481
+ it "it has a valid enumerator interface" do
482
+ test_array = [1, 2, 6, 10, 100, 0]
483
+ x = ExampleProject::MacAddress.new(test_array)
484
+ x.to_enum.to_a.should == test_array
485
+ x.min.should == 0
486
+ x.max.should == 100
487
+ x.sort.should == test_array.sort
488
+ end
489
+
490
+ it "can be converted to a string if elements are in the right range" do
491
+ test_array = "foobar".bytes
492
+ ExampleProject::MacAddress.new(test_array).to_string.should == "foobar"
493
+ ExampleProject::MacAddress.new("asdfas").to_string.should == "asdfas"
494
+ end
495
+
496
+ describe "#==" do
497
+ it "should return true for equal arrays" do
498
+ (ExampleProject::MacAddress.new([1, 2, 6, 10, 100, 0]) == [1, 2, 6, 10, 100, 0]).should be_true
499
+ (ExampleProject::MacAddress.new([1, 2, 6, 10, 100, 0]) == ExampleProject::MacAddress.new([1, 2, 6, 10, 100, 0])).should be_true
500
+ (ExampleProject::MacAddress.new([1, 2, 6, 10, 100, 0]) != ExampleProject::MacAddress.new([1, 2, 6, 10, 100, 0])).should be_false
501
+ end
502
+ it "should return false for non-equal arrays" do
503
+ (ExampleProject::MacAddress.new([1, 2, 10, 100, 5, 0]) == ExampleProject::MacAddress.new([1, 2, 6, 10, 100, 0])).should be_false
504
+ (ExampleProject::MacAddress.new([1, 2, 10, 100, 5, 0]) != ExampleProject::MacAddress.new([1, 2, 6, 10, 100, 0])).should be_true
505
+ end
506
+ end
507
+
508
+ # describe "#num_bytes" do
509
+ # it "should match "
510
+ # end
511
+
512
+ it "num_bytes == max_size == min_size but _just for this particular fixed array_" do
513
+ test_array = [1, 2, 6, 10, 100, 0]
514
+ ExampleProject::MacAddress.new(test_array).num_bytes.should == 6
515
+ ExampleProject::MacAddress::max_size.should == 6
516
+ ExampleProject::MacAddress::min_size.should == 6
517
+ end
518
+
519
+ describe "#<=>" do
520
+ sample_arrays = [[0, 0, 0, 0, 1, 2],
521
+ [0, 1, 0, 0, 0, 0],
522
+ [0, 1, 0, 1, 0, 0]]
523
+ sample_arrays.each_with_index do |arr_a, i|
524
+ sample_arrays.each_with_index do |arr_b, j|
525
+ it "should give a lexicographical ordering" do
526
+ (ExampleProject::MacAddress.new(arr_a) <=> ExampleProject::MacAddress.new(arr_b)).should == (i <=> j)
527
+ end
528
+ end
529
+ end
530
+ end
531
+ end
532
+
533
+ describe CauterizeRuby::VariableArray do
534
+
535
+ test_arrays = ["Job Vranish".bytes.to_a,
536
+ [] ]
537
+ test_arrays.each do |test_array|
538
+ it ".new and .to_ruby are inverses" do
539
+ ExampleProject::Name.new(test_array).to_ruby.should == test_array
540
+ end
541
+
542
+ it "can pack, and unpack to its original value" do
543
+ ExampleProject::Name.unpack(ExampleProject::Name.new(test_array).pack).to_ruby.should == test_array
544
+ end
545
+
546
+ it "should pack to .num_bytes bytes" do
547
+ x = ExampleProject::Name.new(test_array)
548
+ x.pack.length.should == x.num_bytes
549
+ end
550
+ end
551
+
552
+ it "raises an exception if the array it too long" do
553
+ lambda { ExampleProject::Name.new([1] * 33) }.should raise_error("ExampleProject::Name: Invalid length: 33, max length is: 32")
554
+ end
555
+
556
+ it "it has a valid enumerator interface" do
557
+ test_array = [1, 2, 6, 10, 100, 0]
558
+ x = ExampleProject::Name.new(test_array)
559
+ x.to_enum.to_a.should == test_array
560
+ x.min.should == 0
561
+ x.max.should == 100
562
+ x.sort.should == test_array.sort
563
+ end
564
+
565
+ it "can be converted to a string if elements are in the right range" do
566
+ test_array = "Job Vranish".bytes
567
+ ExampleProject::Name.new(test_array).to_string.should == "Job Vranish"
568
+ ExampleProject::Name.new("asdfas").to_string.should == "asdfas"
569
+ ExampleProject::Name.new("").to_string.should == ""
570
+ end
571
+
572
+ it "min size is just the size of the size type, max size is max size of all elements" do
573
+ c = ExampleProject::Name
574
+ test_array = [1, 2, 6, 10, 100, 0]
575
+ c.new(test_array).num_bytes.should == 7
576
+ c::max_size.should == c::size_type::max_size + (c::elem_type::max_size * c::max_length)
577
+ c::min_size.should == c::size_type::min_size
578
+ end
579
+
580
+ describe "#==" do
581
+ it "should return true for equal arrays" do
582
+ (ExampleProject::Name.new([1, 2, 6, 10, 100, 0]) == [1, 2, 6, 10, 100, 0]).should be_true
583
+ (ExampleProject::Name.new([1, 2, 6, 10, 100, 0]) == ExampleProject::Name.new([1, 2, 6, 10, 100, 0])).should be_true
584
+ (ExampleProject::Name.new([1, 2, 6, 10, 100, 0]) != ExampleProject::Name.new([1, 2, 6, 10, 100, 0])).should be_false
585
+ end
586
+ it "should return false for non-equal arrays" do
587
+ (ExampleProject::Name.new([1, 2, 10, 100, 0]) == ExampleProject::Name.new([1, 2, 6, 10, 100, 0])).should be_false
588
+ (ExampleProject::Name.new([1, 2, 10, 100, 0]) != ExampleProject::Name.new([1, 2, 6, 10, 100, 0])).should be_true
589
+ end
590
+ end
591
+
592
+ describe "#<=>" do
593
+ sample_arrays = [[0, 1, 2],
594
+ [0, 2, 2],
595
+ [1, 0, 0]]
596
+ sample_arrays.each_with_index do |arr_a, i|
597
+ sample_arrays.each_with_index do |arr_b, j|
598
+ it "should give a lexicographical ordering" do
599
+ (ExampleProject::Name.new(arr_a) <=> ExampleProject::Name.new(arr_b)).should == (i <=> j)
600
+ end
601
+ end
602
+ end
603
+ end
604
+
605
+ end
606
+
607
+ describe CauterizeRuby::Composite do
608
+ sample_persons = [ { first_name: "Jane", last_name: "Smith", gender: :MALE },
609
+ { first_name: "Jill", last_name: "Smith", gender: :FEMALE},
610
+ { first_name: "John", last_name: "Smit", gender: :MALE },
611
+ { first_name: "John", last_name: "Smith", gender: :MALE }]
612
+
613
+ sample_persons.each do |p|
614
+ it ".new and .to_ruby are inverses" do
615
+ ExampleProject::Person.new(p).should == p
616
+ end
617
+ it "can pack, and unpack to its original value" do
618
+ ExampleProject::Person.unpack((ExampleProject::Person.new(p).pack)).should == p
619
+ end
620
+ it "pack should pack to .num_bytes bytes" do
621
+ x = ExampleProject::Person.new(p)
622
+ x.pack.length.should == x.num_bytes
623
+ end
624
+ end
625
+
626
+ it "should raise an error if fields are missing during initialization" do
627
+ lambda { ExampleProject::Person.new({ last_name: "Smith", gender: :MALE }) }.should raise_error("ExampleProject::Person: Invalid initialization params, missing fields: [:first_name], extra fields: []")
628
+ end
629
+
630
+ it "should raise an error if there are extra fields during initialization" do
631
+ lambda { ExampleProject::Person.new({ first_name: "Jane", last_name: "Smith", age: 12, gender: :MALE }) }.should raise_error("ExampleProject::Person: Invalid initialization params, missing fields: [], extra fields: [:age]")
632
+ end
633
+
634
+ describe "#max_size" do
635
+ it "should be the sum of the max sizes of the fields" do
636
+ c = ExampleProject::Person
637
+ c::max_size.should == c::fields.values.reduce(0) {|sum, v| sum + v::max_size}
638
+ end
639
+ end
640
+ describe "#min_size" do
641
+ it "should be the sum of the min sizes of the fields" do
642
+ c = ExampleProject::Person
643
+ c::min_size.should == c::fields.values.reduce(0) {|sum, v| sum + v::min_size}
644
+ end
645
+ end
646
+
647
+ it "should have accessors for all the fields" do
648
+ test_person = ExampleProject::Person.new({ first_name: "test", last_name: "thing", gender: :MALE})
649
+ test_person.first_name.should == "test"
650
+ test_person.last_name.should == "thing"
651
+ test_person.gender.should == :MALE
652
+ end
653
+
654
+ describe "#<=>" do
655
+ sample_persons.each_with_index do |p1, i|
656
+ sample_persons.each_with_index do |p2, j|
657
+ it "should give a lexicographical ordering" do
658
+ (ExampleProject::Person.new(p1) <=> p2).should == (i <=> j)
659
+ (ExampleProject::Person.new(p1) <=> ExampleProject::Person.new(p2)).should == (i <=> j)
660
+ end
661
+ end
662
+ end
663
+ end
664
+
665
+ describe "#==" do
666
+ sample_persons.each_with_index do |p1, i|
667
+ sample_persons.each_with_index do |p2, j|
668
+ it "should return true for equal things, false otherwise" do
669
+ (ExampleProject::Person.new(p1) == p2).should == (i == j)
670
+ (ExampleProject::Person.new(p1) == ExampleProject::Person.new(p2)).should == (i == j)
671
+ (ExampleProject::Person.new(p1) != p2).should == (i != j)
672
+ (ExampleProject::Person.new(p1) != ExampleProject::Person.new(p2)).should == (i != j)
673
+ end
674
+ end
675
+ end
676
+ end
677
+ end
678
+
679
+ describe CauterizeRuby::Group do
680
+ test_groups = [ { tag: :PERSON, data: { first_name: "Jane", last_name: "Smith", gender: :MALE }},
681
+ { tag: :DOG, data: { name: "Fido", leg_count: 3, gender: :MALE }}]
682
+
683
+ test_groups.each do |g|
684
+ it ".new and .to_ruby are inverses" do
685
+ ExampleProject::Creature.new(g).should == g
686
+ end
687
+ it "can pack, and unpack to its original value" do
688
+ ExampleProject::Creature.unpack((ExampleProject::Creature.new(g).pack)).should == g
689
+ end
690
+ it "pack should pack to .num_bytes bytes" do
691
+ x = ExampleProject::Creature.new(g)
692
+ x.pack.length.should == x.num_bytes
693
+ end
694
+ end
695
+
696
+ describe "#max_size" do
697
+ it "should be the max size of the tag + max of the max sizes of the fields" do
698
+ c = ExampleProject::Creature
699
+ c::max_size.should == c::tag_type::max_size + c::fields.values.map{|v| (v.nil?) ? 0 : v::max_size}.max
700
+ end
701
+ end
702
+
703
+ describe "#min_size" do
704
+ it "should be the max size of the tag + min of the min sizes of the fields" do
705
+ c = ExampleProject::Creature
706
+ c::min_size.should == c::tag_type::min_size + c::fields.values.map{|v| (v.nil?) ? 0 : v::min_size}.min
707
+ end
708
+ end
709
+
710
+ describe "#<=>" do
711
+ test_groups.each_with_index do |a, i|
712
+ test_groups.each_with_index do |b, j|
713
+ it "should give a lexicographical ordering" do
714
+ (ExampleProject::Creature.new(a) <=> b).should == (i <=> j)
715
+ (ExampleProject::Creature.new(a) <=> ExampleProject::Creature.new(b)).should == (i <=> j)
716
+ end
717
+ end
718
+ end
719
+ end
720
+
721
+ describe "#==" do
722
+ test_groups.each_with_index do |a, i|
723
+ test_groups.each_with_index do |b, j|
724
+ it "should return true for equal things, false otherwise" do
725
+ (ExampleProject::Creature.new(a) == b).should == (i == j)
726
+ (ExampleProject::Creature.new(a) == ExampleProject::Creature.new(b)).should == (i == j)
727
+ (ExampleProject::Creature.new(a) != b).should == (i != j)
728
+ (ExampleProject::Creature.new(a) != ExampleProject::Creature.new(b)).should == (i != j)
729
+ end
730
+ end
731
+ end
732
+ end
733
+ end
734
+ end
735
+ end