qrb 0.1.0

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.
Files changed (159) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +58 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +11 -0
  6. data/README.md +118 -0
  7. data/Rakefile +11 -0
  8. data/lib/qrb/Q/default.q +29 -0
  9. data/lib/qrb/data_type.rb +23 -0
  10. data/lib/qrb/errors.rb +23 -0
  11. data/lib/qrb/support/attribute.rb +53 -0
  12. data/lib/qrb/support/collection_type.rb +25 -0
  13. data/lib/qrb/support/dress_helper.rb +68 -0
  14. data/lib/qrb/support/heading.rb +57 -0
  15. data/lib/qrb/support/type_factory.rb +178 -0
  16. data/lib/qrb/support.rb +5 -0
  17. data/lib/qrb/syntax/ad_type.rb +25 -0
  18. data/lib/qrb/syntax/attribute.rb +11 -0
  19. data/lib/qrb/syntax/builtin_type.rb +13 -0
  20. data/lib/qrb/syntax/constraint_def.rb +11 -0
  21. data/lib/qrb/syntax/constraints.rb +18 -0
  22. data/lib/qrb/syntax/contract.rb +25 -0
  23. data/lib/qrb/syntax/definitions.rb +14 -0
  24. data/lib/qrb/syntax/expression.rb +12 -0
  25. data/lib/qrb/syntax/heading.rb +15 -0
  26. data/lib/qrb/syntax/lambda_expr.rb +11 -0
  27. data/lib/qrb/syntax/named_constraint.rb +11 -0
  28. data/lib/qrb/syntax/q.citrus +195 -0
  29. data/lib/qrb/syntax/relation_type.rb +11 -0
  30. data/lib/qrb/syntax/seq_type.rb +12 -0
  31. data/lib/qrb/syntax/set_type.rb +12 -0
  32. data/lib/qrb/syntax/sub_type.rb +13 -0
  33. data/lib/qrb/syntax/support.rb +13 -0
  34. data/lib/qrb/syntax/system.rb +15 -0
  35. data/lib/qrb/syntax/tuple_type.rb +11 -0
  36. data/lib/qrb/syntax/type_def.rb +14 -0
  37. data/lib/qrb/syntax/type_ref.rb +13 -0
  38. data/lib/qrb/syntax/union_type.rb +12 -0
  39. data/lib/qrb/syntax/unnamed_constraint.rb +11 -0
  40. data/lib/qrb/syntax.rb +42 -0
  41. data/lib/qrb/system.rb +63 -0
  42. data/lib/qrb/type/ad_type.rb +111 -0
  43. data/lib/qrb/type/builtin_type.rb +56 -0
  44. data/lib/qrb/type/relation_type.rb +81 -0
  45. data/lib/qrb/type/seq_type.rb +51 -0
  46. data/lib/qrb/type/set_type.rb +52 -0
  47. data/lib/qrb/type/sub_type.rb +94 -0
  48. data/lib/qrb/type/tuple_type.rb +99 -0
  49. data/lib/qrb/type/union_type.rb +78 -0
  50. data/lib/qrb/type.rb +63 -0
  51. data/lib/qrb/version.rb +14 -0
  52. data/lib/qrb.rb +63 -0
  53. data/qrb.gemspec +186 -0
  54. data/spec/acceptance/Q/test_default.rb +96 -0
  55. data/spec/acceptance/Q/test_parsing.rb +15 -0
  56. data/spec/acceptance/ad_type/test_in_q.rb +82 -0
  57. data/spec/acceptance/ad_type/test_in_ruby.rb +60 -0
  58. data/spec/spec_helper.rb +68 -0
  59. data/spec/unit/attribute/test_equality.rb +26 -0
  60. data/spec/unit/attribute/test_fetch_on.rb +50 -0
  61. data/spec/unit/attribute/test_initialize.rb +13 -0
  62. data/spec/unit/attribute/test_to_name.rb +10 -0
  63. data/spec/unit/heading/test_each.rb +28 -0
  64. data/spec/unit/heading/test_equality.rb +28 -0
  65. data/spec/unit/heading/test_initialize.rb +36 -0
  66. data/spec/unit/heading/test_size.rb +30 -0
  67. data/spec/unit/heading/test_to_name.rb +32 -0
  68. data/spec/unit/qrb/test_parse.rb +18 -0
  69. data/spec/unit/syntax/nodes/test_ad_type.rb +94 -0
  70. data/spec/unit/syntax/nodes/test_attribute.rb +25 -0
  71. data/spec/unit/syntax/nodes/test_builtin_type.rb +32 -0
  72. data/spec/unit/syntax/nodes/test_comment.rb +26 -0
  73. data/spec/unit/syntax/nodes/test_constraint_def.rb +27 -0
  74. data/spec/unit/syntax/nodes/test_constraints.rb +51 -0
  75. data/spec/unit/syntax/nodes/test_contract.rb +62 -0
  76. data/spec/unit/syntax/nodes/test_expression.rb +43 -0
  77. data/spec/unit/syntax/nodes/test_heading.rb +41 -0
  78. data/spec/unit/syntax/nodes/test_named_constraint.rb +31 -0
  79. data/spec/unit/syntax/nodes/test_relation_type.rb +41 -0
  80. data/spec/unit/syntax/nodes/test_seq_type.rb +24 -0
  81. data/spec/unit/syntax/nodes/test_set_type.rb +24 -0
  82. data/spec/unit/syntax/nodes/test_spacing.rb +25 -0
  83. data/spec/unit/syntax/nodes/test_sub_type.rb +52 -0
  84. data/spec/unit/syntax/nodes/test_tuple_type.rb +41 -0
  85. data/spec/unit/syntax/nodes/test_union_type.rb +23 -0
  86. data/spec/unit/syntax/nodes/test_unnamed_constraint.rb +31 -0
  87. data/spec/unit/syntax/test_compile_type.rb +22 -0
  88. data/spec/unit/system/test_add_type.rb +47 -0
  89. data/spec/unit/system/test_dsl.rb +30 -0
  90. data/spec/unit/system/test_dup.rb +30 -0
  91. data/spec/unit/system/test_fetch.rb +42 -0
  92. data/spec/unit/system/test_get_type.rb +30 -0
  93. data/spec/unit/system/test_initialize.rb +10 -0
  94. data/spec/unit/test_qrb.rb +15 -0
  95. data/spec/unit/type/ad_type/test_default_name.rb +15 -0
  96. data/spec/unit/type/ad_type/test_dress.rb +55 -0
  97. data/spec/unit/type/ad_type/test_include.rb +22 -0
  98. data/spec/unit/type/ad_type/test_initialize.rb +40 -0
  99. data/spec/unit/type/ad_type/test_name.rb +20 -0
  100. data/spec/unit/type/builtin_type/test_default_name.rb +12 -0
  101. data/spec/unit/type/builtin_type/test_dress.rb +33 -0
  102. data/spec/unit/type/builtin_type/test_equality.rb +26 -0
  103. data/spec/unit/type/builtin_type/test_include.rb +22 -0
  104. data/spec/unit/type/builtin_type/test_initialize.rb +12 -0
  105. data/spec/unit/type/builtin_type/test_name.rb +24 -0
  106. data/spec/unit/type/relation_type/test_default_name.rb +16 -0
  107. data/spec/unit/type/relation_type/test_dress.rb +164 -0
  108. data/spec/unit/type/relation_type/test_equality.rb +32 -0
  109. data/spec/unit/type/relation_type/test_include.rb +46 -0
  110. data/spec/unit/type/relation_type/test_initialize.rb +26 -0
  111. data/spec/unit/type/relation_type/test_name.rb +24 -0
  112. data/spec/unit/type/seq_type/test_default_name.rb +14 -0
  113. data/spec/unit/type/seq_type/test_dress.rb +49 -0
  114. data/spec/unit/type/seq_type/test_equality.rb +26 -0
  115. data/spec/unit/type/seq_type/test_include.rb +43 -0
  116. data/spec/unit/type/seq_type/test_initialize.rb +28 -0
  117. data/spec/unit/type/seq_type/test_name.rb +24 -0
  118. data/spec/unit/type/set_type/test_default_name.rb +14 -0
  119. data/spec/unit/type/set_type/test_dress.rb +66 -0
  120. data/spec/unit/type/set_type/test_equality.rb +26 -0
  121. data/spec/unit/type/set_type/test_include.rb +43 -0
  122. data/spec/unit/type/set_type/test_initialize.rb +28 -0
  123. data/spec/unit/type/set_type/test_name.rb +24 -0
  124. data/spec/unit/type/sub_type/test_default_name.rb +14 -0
  125. data/spec/unit/type/sub_type/test_dress.rb +75 -0
  126. data/spec/unit/type/sub_type/test_equality.rb +34 -0
  127. data/spec/unit/type/sub_type/test_include.rb +34 -0
  128. data/spec/unit/type/sub_type/test_initialize.rb +16 -0
  129. data/spec/unit/type/sub_type/test_name.rb +24 -0
  130. data/spec/unit/type/tuple_type/test_default_name.rb +14 -0
  131. data/spec/unit/type/tuple_type/test_dress.rb +112 -0
  132. data/spec/unit/type/tuple_type/test_equality.rb +32 -0
  133. data/spec/unit/type/tuple_type/test_include.rb +38 -0
  134. data/spec/unit/type/tuple_type/test_initialize.rb +30 -0
  135. data/spec/unit/type/tuple_type/test_name.rb +24 -0
  136. data/spec/unit/type/union_type/test_default_name.rb +12 -0
  137. data/spec/unit/type/union_type/test_dress.rb +43 -0
  138. data/spec/unit/type/union_type/test_equality.rb +30 -0
  139. data/spec/unit/type/union_type/test_include.rb +28 -0
  140. data/spec/unit/type/union_type/test_initialize.rb +24 -0
  141. data/spec/unit/type/union_type/test_name.rb +20 -0
  142. data/spec/unit/type_factory/dsl/test_adt.rb +54 -0
  143. data/spec/unit/type_factory/dsl/test_attribute.rb +37 -0
  144. data/spec/unit/type_factory/dsl/test_attributes.rb +41 -0
  145. data/spec/unit/type_factory/dsl/test_builtin.rb +45 -0
  146. data/spec/unit/type_factory/dsl/test_relation.rb +85 -0
  147. data/spec/unit/type_factory/dsl/test_seq.rb +57 -0
  148. data/spec/unit/type_factory/dsl/test_set.rb +57 -0
  149. data/spec/unit/type_factory/dsl/test_subtype.rb +91 -0
  150. data/spec/unit/type_factory/dsl/test_tuple.rb +73 -0
  151. data/spec/unit/type_factory/dsl/test_union.rb +81 -0
  152. data/spec/unit/type_factory/factory/test_builtin.rb +24 -0
  153. data/spec/unit/type_factory/factory/test_seq_type.rb +44 -0
  154. data/spec/unit/type_factory/factory/test_set_type.rb +44 -0
  155. data/spec/unit/type_factory/factory/test_sub_type.rb +53 -0
  156. data/spec/unit/type_factory/factory/test_tuple_type.rb +43 -0
  157. data/tasks/gem.rake +73 -0
  158. data/tasks/test.rake +31 -0
  159. metadata +344 -0
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe SetType, 'initialize' do
4
+
5
+ subject{
6
+ SetType.new(intType)
7
+ }
8
+
9
+ context 'with valid arguments' do
10
+ it{ should be_a(SetType) }
11
+
12
+ it 'should set the instance variables' do
13
+ subject.elm_type.should eq(intType)
14
+ end
15
+ end
16
+
17
+ context 'with invalid arguments' do
18
+ subject{ SetType.new("foo") }
19
+
20
+ it 'should raise an error' do
21
+ ->{
22
+ subject
23
+ }.should raise_error(ArgumentError, 'Qrb::Type expected, got `foo`')
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe SetType, 'name' do
4
+
5
+ subject{ type.name }
6
+
7
+ context 'when not specified' do
8
+ let(:type){
9
+ SetType.new(intType)
10
+ }
11
+
12
+ it{ should eq('{intType}') }
13
+ end
14
+
15
+ context 'when specified' do
16
+ let(:type){
17
+ SetType.new(intType, "foo")
18
+ }
19
+
20
+ it{ should eq('foo') }
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe SubType, "default_name" do
4
+
5
+ let(:type){ SubType.new(intType, posint: ->(i){}) }
6
+
7
+ subject{ type.default_name }
8
+
9
+ it 'uses the first constraint name' do
10
+ subject.should eq("Posint")
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe SubType, "dress" do
4
+
5
+ let(:type){ SubType.new(intType, {default: ->(i){ i>0 }, small: ->(i){ i<255 }}, "byte") }
6
+
7
+ subject{ type.dress(arg) }
8
+
9
+ context 'with an valid Integer' do
10
+ let(:arg){ 12 }
11
+
12
+ it{ should be(arg) }
13
+ end
14
+
15
+ context 'when raising an Error' do
16
+
17
+ subject do
18
+ type.dress(arg) rescue $!
19
+ end
20
+
21
+ context 'with a Float' do
22
+ let(:arg){ 12.0 }
23
+
24
+ it 'should raise an Error' do
25
+ subject.should be_a(TypeError)
26
+ subject.message.should eq("Invalid value `12.0` for byte")
27
+ end
28
+
29
+ it "should have the proper cause from super type's up" do
30
+ subject.cause.should be_a(TypeError)
31
+ subject.cause.message.should eq("Invalid value `12.0` for intType")
32
+ end
33
+
34
+ it "should have an empty location" do
35
+ subject.location.should eq('')
36
+ end
37
+ end
38
+
39
+ context 'with a negative integer' do
40
+ let(:arg){ -12 }
41
+
42
+ it 'should raise an Error' do
43
+ subject.should be_a(TypeError)
44
+ subject.message.should eq("Invalid value `-12` for byte")
45
+ end
46
+
47
+ it "should have no cause" do
48
+ subject.cause.should be_nil
49
+ end
50
+
51
+ it "should have an empty location" do
52
+ subject.location.should eq('')
53
+ end
54
+ end
55
+
56
+ context 'with a non small integer' do
57
+ let(:arg){ 1000 }
58
+
59
+ it 'should raise an Error' do
60
+ subject.should be_a(TypeError)
61
+ subject.message.should eq("Invalid value `1000` for byte (not small)")
62
+ end
63
+
64
+ it "should have no cause" do
65
+ subject.cause.should be_nil
66
+ end
67
+
68
+ it "should have an empty location" do
69
+ subject.location.should eq('')
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe SubType, "equality" do
4
+
5
+ let(:c1){ ->(i){ i>0 } }
6
+ let(:c2){ ->(i){ i<255 } }
7
+
8
+ let(:type) { SubType.new(intType, default: c1) }
9
+ let(:type2){ SubType.new(intType, default: c1) }
10
+ let(:type3){ SubType.new(intType, another_name: c1) }
11
+ let(:type4){ SubType.new(intType, default: c2) }
12
+ let(:type5){ SubType.new(floatType, default: c1) }
13
+
14
+ it 'should apply structural equality' do
15
+ (type == type2).should be_true
16
+ (type == type3).should be_true
17
+ end
18
+
19
+ it 'should apply distinguish different types' do
20
+ (type == type4).should be_false
21
+ (type == type5).should be_false
22
+ end
23
+
24
+ it 'should be a total function, with nil for non types' do
25
+ (type == 12).should be_false
26
+ end
27
+
28
+ it 'should implement hash accordingly' do
29
+ (type.hash == type2.hash).should be_true
30
+ (type.hash == type3.hash).should be_true
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe SubType, "include?" do
4
+
5
+ let(:type){ SubType.new(intType, {default: ->(i){ i>0 }, small: ->(i){ i<255 }}, "byte") }
6
+
7
+ subject{ type.include?(arg) }
8
+
9
+ context 'when included on int' do
10
+ let(:arg){ 12 }
11
+
12
+ it{ should be_true }
13
+ end
14
+
15
+ context 'when not included on int (I)' do
16
+ let(:arg){ -12 }
17
+
18
+ it{ should be_false }
19
+ end
20
+
21
+ context 'when not included on int (II)' do
22
+ let(:arg){ 255 }
23
+
24
+ it{ should be_false }
25
+ end
26
+
27
+ context 'when not included' do
28
+ let(:arg){ "12" }
29
+
30
+ it{ should be_false }
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe SubType, "initialize" do
4
+
5
+ let(:c1){ ->(i){ i>0 } }
6
+ let(:c2){ ->(i){ i<255 } }
7
+
8
+ let(:sub){ SubType.new(intType, positive: c1, small: c2) }
9
+
10
+ it 'sets the variable instances' do
11
+ sub.super_type.should eq(intType)
12
+ sub.constraints.should eq(positive: c1, small: c2)
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe SubType, "name" do
4
+
5
+ subject{ type.name }
6
+
7
+ context 'when provided' do
8
+ let(:type){ SubType.new(intType, {posint: ->(i){}}, "Foo") }
9
+
10
+ it 'uses the specified one' do
11
+ subject.should eq("Foo")
12
+ end
13
+ end
14
+
15
+ context 'when not provided' do
16
+ let(:type){ SubType.new(intType, posint: ->(i){}) }
17
+
18
+ it 'uses the first constraint name' do
19
+ subject.should eq("Posint")
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe TupleType, "default_name" do
4
+
5
+ let(:heading){
6
+ Heading.new([Attribute.new(:a, byte)])
7
+ }
8
+
9
+ subject{ TupleType.new(heading).default_name }
10
+
11
+ it{ should eq("{a: Byte}") }
12
+
13
+ end
14
+ end
@@ -0,0 +1,112 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe TupleType, "dress" do
4
+
5
+ let(:heading){
6
+ Heading.new([Attribute.new(:r, byte),
7
+ Attribute.new(:g, byte),
8
+ Attribute.new(:b, byte)])
9
+ }
10
+
11
+ let(:type){
12
+ TupleType.new(heading, "color")
13
+ }
14
+
15
+ subject{ type.dress(arg) }
16
+
17
+ context 'with a valid Hash' do
18
+ let(:arg){
19
+ { "r" => 12, "g" => 13, "b" => 255 }
20
+ }
21
+
22
+ it 'should coerce to a tuple' do
23
+ subject.should eq(r: 12, g: 13, b: 255)
24
+ end
25
+ end
26
+
27
+ context 'when raising an error' do
28
+
29
+ subject do
30
+ type.dress(arg) rescue $!
31
+ end
32
+
33
+ context 'with something else than a Hash' do
34
+ let(:arg){
35
+ "foo"
36
+ }
37
+
38
+ it 'should raise a TypeError' do
39
+ subject.should be_a(TypeError)
40
+ subject.message.should eq("Invalid value `foo` for color")
41
+ end
42
+
43
+ it 'should have no cause' do
44
+ subject.cause.should be_nil
45
+ end
46
+
47
+ it 'should have an empty location' do
48
+ subject.location.should eq('')
49
+ end
50
+ end
51
+
52
+ context 'with a missing attribute' do
53
+ let(:arg){
54
+ { "r" => 12, "g" => 13 }
55
+ }
56
+
57
+ it 'should raise a TypeError' do
58
+ subject.should be_a(TypeError)
59
+ subject.message.should eq("Missing attribute `b`")
60
+ end
61
+
62
+ it 'should have no cause' do
63
+ subject.cause.should be_nil
64
+ end
65
+
66
+ it 'should have an empty location' do
67
+ subject.location.should eq('')
68
+ end
69
+ end
70
+
71
+ context 'with an extra attribute' do
72
+ let(:arg){
73
+ { "r" => 12, "g" => 13, "b" => 255, "extr" => 165 }
74
+ }
75
+
76
+ it 'should raise a TypeError' do
77
+ subject.should be_a(TypeError)
78
+ subject.message.should eq("Unrecognized attribute `extr`")
79
+ end
80
+
81
+ it 'should have no cause' do
82
+ subject.cause.should be_nil
83
+ end
84
+
85
+ it 'should have an empty location' do
86
+ subject.location.should eq('')
87
+ end
88
+ end
89
+
90
+ context 'with an invalid attribute' do
91
+ let(:arg){
92
+ { "r" => 12.0, "g" => 13, "b" => 255 }
93
+ }
94
+
95
+ it 'should raise a TypeError' do
96
+ subject.should be_a(TypeError)
97
+ subject.message.should eq("Invalid value `12.0` for Byte")
98
+ end
99
+
100
+ it 'should have the correct cause' do
101
+ subject.cause.should be_a(TypeError)
102
+ subject.cause.message.should eq("Invalid value `12.0` for intType")
103
+ end
104
+
105
+ it 'should have the correct location' do
106
+ subject.location.should eq("r")
107
+ end
108
+ end
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe TupleType, "equality" do
4
+
5
+ let(:h1){ Heading.new([Attribute.new(:r, intType), Attribute.new(:b, intType)]) }
6
+ let(:h2){ Heading.new([Attribute.new(:b, intType), Attribute.new(:r, intType)]) }
7
+ let(:h3){ Heading.new([Attribute.new(:b, intType)]) }
8
+
9
+ let(:type1) { TupleType.new(h1) }
10
+ let(:type2) { TupleType.new(h2) }
11
+ let(:type3) { TupleType.new(h3) }
12
+
13
+ it 'should apply structural equality' do
14
+ (type1 == type2).should be_true
15
+ (type2 == type1).should be_true
16
+ end
17
+
18
+ it 'should apply distinguish different types' do
19
+ (type1 == type3).should be_false
20
+ (type2 == type3).should be_false
21
+ end
22
+
23
+ it 'should be a total function, with nil for non types' do
24
+ (type1 == 12).should be_false
25
+ end
26
+
27
+ it 'should implement hash accordingly' do
28
+ [type1, type2].map(&:hash).uniq.size.should eq(1)
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe TupleType, "include?" do
4
+
5
+ let(:heading){
6
+ Heading.new([Attribute.new(:a, intType)])
7
+ }
8
+
9
+ let(:type){ TupleType.new(heading) }
10
+
11
+ subject{ type.include?(arg) }
12
+
13
+ context 'when a valid hash' do
14
+ let(:arg){ {a: 12} }
15
+
16
+ it{ should be_true }
17
+ end
18
+
19
+ context 'when an invalid hash (too many attributes)' do
20
+ let(:arg){ {a: 12, b: 15} }
21
+
22
+ it{ should be_false }
23
+ end
24
+
25
+ context 'when an invalid hash (too few attributes)' do
26
+ let(:arg){ {b: 12} }
27
+
28
+ it{ should be_false }
29
+ end
30
+
31
+ context 'when an invalid hash (wrong type)' do
32
+ let(:arg){ {a: 12.0} }
33
+
34
+ it{ should be_false }
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe TupleType, "initialize" do
4
+
5
+ let(:heading){
6
+ Heading.new([Attribute.new(:a, intType)])
7
+ }
8
+
9
+ context 'with a valid heading' do
10
+ subject{ TupleType.new(heading) }
11
+
12
+ it{ should be_a(TupleType) }
13
+
14
+ it 'correctly sets the instance variable' do
15
+ subject.heading.should eq(heading)
16
+ end
17
+ end
18
+
19
+ context 'with an invalid heading' do
20
+ subject{ TupleType.new("foo") }
21
+
22
+ it 'should raise an error' do
23
+ ->{
24
+ subject
25
+ }.should raise_error(ArgumentError, "Heading expected, got `foo`")
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe TupleType, "name" do
4
+
5
+ let(:heading){
6
+ Heading.new([Attribute.new(:a, byte)])
7
+ }
8
+
9
+ subject{ type.name }
10
+
11
+ context 'when not provided' do
12
+ let(:type){ TupleType.new(heading) }
13
+
14
+ it{ should eq("{a: Byte}") }
15
+ end
16
+
17
+ context 'when provided' do
18
+ let(:type){ TupleType.new(heading, "Color") }
19
+
20
+ it{ should eq("Color") }
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe UnionType, "default_name" do
4
+
5
+ subject{ type.default_name }
6
+
7
+ let(:type){ UnionType.new([intType, floatType]) }
8
+
9
+ it{ should eq('intType|floatType') }
10
+
11
+ end
12
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe UnionType, "dress" do
4
+
5
+ let(:type) { UnionType.new([intType, floatType], "union") }
6
+
7
+ subject{ type.dress(arg) }
8
+
9
+ context 'with an Integer' do
10
+ let(:arg){ 12 }
11
+
12
+ it{ should be(arg) }
13
+ end
14
+
15
+ context 'with a Float' do
16
+ let(:arg){ 12.0 }
17
+
18
+ it{ should be(arg) }
19
+ end
20
+
21
+ context 'with a String' do
22
+ let(:arg){ "foo" }
23
+
24
+ subject{
25
+ type.dress(arg) rescue $!
26
+ }
27
+
28
+ it 'should raise an Error' do
29
+ subject.should be_a(TypeError)
30
+ subject.message.should eq("Invalid value `foo` for union")
31
+ end
32
+
33
+ it 'should have no cause' do
34
+ subject.cause.should be_nil
35
+ end
36
+
37
+ it 'should have an empty location' do
38
+ subject.location.should eq('')
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe UnionType, "equality" do
4
+
5
+ let(:uType) { UnionType.new([intType, floatType]) }
6
+ let(:uType2) { UnionType.new([floatType, intType]) }
7
+ let(:uType3) { UnionType.new([floatType, intType]) }
8
+ let(:uType4) { UnionType.new([intType]) }
9
+
10
+ it 'should apply structural equality' do
11
+ (uType == uType2).should be_true
12
+ (uType == uType3).should be_true
13
+ (uType2 == uType3).should be_true
14
+ end
15
+
16
+ it 'should apply distinguish different types' do
17
+ (uType == uType4).should be_false
18
+ (uType == intType).should be_false
19
+ end
20
+
21
+ it 'should be a total function, with nil for non types' do
22
+ (uType == 12).should be_false
23
+ end
24
+
25
+ it 'should implement hash accordingly' do
26
+ [uType, uType2, uType3].map(&:hash).uniq.size.should eq(1)
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe UnionType, "include?" do
4
+
5
+ let(:type){ UnionType.new([intType, floatType]) }
6
+
7
+ subject{ type.include?(arg) }
8
+
9
+ context 'when not included' do
10
+ let(:arg){ "12" }
11
+
12
+ it{ should be_false }
13
+ end
14
+
15
+ context 'when included on int' do
16
+ let(:arg){ 12 }
17
+
18
+ it{ should be_true }
19
+ end
20
+
21
+ context 'when included on float' do
22
+ let(:arg){ 12.0 }
23
+
24
+ it{ should be_true }
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe UnionType, "initialize" do
4
+
5
+ context 'with valid candidates' do
6
+ let(:union){ UnionType.new([intType, floatType]) }
7
+
8
+ it 'sets the variable instances' do
9
+ union.candidates.should eq([intType, floatType])
10
+ end
11
+ end
12
+
13
+ context 'with invalid candidates' do
14
+ let(:union){ UnionType.new(["bar"]) }
15
+
16
+ it 'should raise an error' do
17
+ ->{
18
+ union
19
+ }.should raise_error(ArgumentError, %Q{[Qrb::Type] expected, got ["bar"]})
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ module Qrb
3
+ describe UnionType, "name" do
4
+
5
+ subject{ type.name }
6
+
7
+ context 'when not provided' do
8
+ let(:type){ UnionType.new([intType, floatType]) }
9
+
10
+ it{ should eq('intType|floatType') }
11
+ end
12
+
13
+ context 'when provided' do
14
+ let(:type){ UnionType.new([intType, floatType], "union") }
15
+
16
+ it{ should eq('union') }
17
+ end
18
+
19
+ end
20
+ end