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.
- data/CHANGELOG.md +5 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +58 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +11 -0
- data/README.md +118 -0
- data/Rakefile +11 -0
- data/lib/qrb/Q/default.q +29 -0
- data/lib/qrb/data_type.rb +23 -0
- data/lib/qrb/errors.rb +23 -0
- data/lib/qrb/support/attribute.rb +53 -0
- data/lib/qrb/support/collection_type.rb +25 -0
- data/lib/qrb/support/dress_helper.rb +68 -0
- data/lib/qrb/support/heading.rb +57 -0
- data/lib/qrb/support/type_factory.rb +178 -0
- data/lib/qrb/support.rb +5 -0
- data/lib/qrb/syntax/ad_type.rb +25 -0
- data/lib/qrb/syntax/attribute.rb +11 -0
- data/lib/qrb/syntax/builtin_type.rb +13 -0
- data/lib/qrb/syntax/constraint_def.rb +11 -0
- data/lib/qrb/syntax/constraints.rb +18 -0
- data/lib/qrb/syntax/contract.rb +25 -0
- data/lib/qrb/syntax/definitions.rb +14 -0
- data/lib/qrb/syntax/expression.rb +12 -0
- data/lib/qrb/syntax/heading.rb +15 -0
- data/lib/qrb/syntax/lambda_expr.rb +11 -0
- data/lib/qrb/syntax/named_constraint.rb +11 -0
- data/lib/qrb/syntax/q.citrus +195 -0
- data/lib/qrb/syntax/relation_type.rb +11 -0
- data/lib/qrb/syntax/seq_type.rb +12 -0
- data/lib/qrb/syntax/set_type.rb +12 -0
- data/lib/qrb/syntax/sub_type.rb +13 -0
- data/lib/qrb/syntax/support.rb +13 -0
- data/lib/qrb/syntax/system.rb +15 -0
- data/lib/qrb/syntax/tuple_type.rb +11 -0
- data/lib/qrb/syntax/type_def.rb +14 -0
- data/lib/qrb/syntax/type_ref.rb +13 -0
- data/lib/qrb/syntax/union_type.rb +12 -0
- data/lib/qrb/syntax/unnamed_constraint.rb +11 -0
- data/lib/qrb/syntax.rb +42 -0
- data/lib/qrb/system.rb +63 -0
- data/lib/qrb/type/ad_type.rb +111 -0
- data/lib/qrb/type/builtin_type.rb +56 -0
- data/lib/qrb/type/relation_type.rb +81 -0
- data/lib/qrb/type/seq_type.rb +51 -0
- data/lib/qrb/type/set_type.rb +52 -0
- data/lib/qrb/type/sub_type.rb +94 -0
- data/lib/qrb/type/tuple_type.rb +99 -0
- data/lib/qrb/type/union_type.rb +78 -0
- data/lib/qrb/type.rb +63 -0
- data/lib/qrb/version.rb +14 -0
- data/lib/qrb.rb +63 -0
- data/qrb.gemspec +186 -0
- data/spec/acceptance/Q/test_default.rb +96 -0
- data/spec/acceptance/Q/test_parsing.rb +15 -0
- data/spec/acceptance/ad_type/test_in_q.rb +82 -0
- data/spec/acceptance/ad_type/test_in_ruby.rb +60 -0
- data/spec/spec_helper.rb +68 -0
- data/spec/unit/attribute/test_equality.rb +26 -0
- data/spec/unit/attribute/test_fetch_on.rb +50 -0
- data/spec/unit/attribute/test_initialize.rb +13 -0
- data/spec/unit/attribute/test_to_name.rb +10 -0
- data/spec/unit/heading/test_each.rb +28 -0
- data/spec/unit/heading/test_equality.rb +28 -0
- data/spec/unit/heading/test_initialize.rb +36 -0
- data/spec/unit/heading/test_size.rb +30 -0
- data/spec/unit/heading/test_to_name.rb +32 -0
- data/spec/unit/qrb/test_parse.rb +18 -0
- data/spec/unit/syntax/nodes/test_ad_type.rb +94 -0
- data/spec/unit/syntax/nodes/test_attribute.rb +25 -0
- data/spec/unit/syntax/nodes/test_builtin_type.rb +32 -0
- data/spec/unit/syntax/nodes/test_comment.rb +26 -0
- data/spec/unit/syntax/nodes/test_constraint_def.rb +27 -0
- data/spec/unit/syntax/nodes/test_constraints.rb +51 -0
- data/spec/unit/syntax/nodes/test_contract.rb +62 -0
- data/spec/unit/syntax/nodes/test_expression.rb +43 -0
- data/spec/unit/syntax/nodes/test_heading.rb +41 -0
- data/spec/unit/syntax/nodes/test_named_constraint.rb +31 -0
- data/spec/unit/syntax/nodes/test_relation_type.rb +41 -0
- data/spec/unit/syntax/nodes/test_seq_type.rb +24 -0
- data/spec/unit/syntax/nodes/test_set_type.rb +24 -0
- data/spec/unit/syntax/nodes/test_spacing.rb +25 -0
- data/spec/unit/syntax/nodes/test_sub_type.rb +52 -0
- data/spec/unit/syntax/nodes/test_tuple_type.rb +41 -0
- data/spec/unit/syntax/nodes/test_union_type.rb +23 -0
- data/spec/unit/syntax/nodes/test_unnamed_constraint.rb +31 -0
- data/spec/unit/syntax/test_compile_type.rb +22 -0
- data/spec/unit/system/test_add_type.rb +47 -0
- data/spec/unit/system/test_dsl.rb +30 -0
- data/spec/unit/system/test_dup.rb +30 -0
- data/spec/unit/system/test_fetch.rb +42 -0
- data/spec/unit/system/test_get_type.rb +30 -0
- data/spec/unit/system/test_initialize.rb +10 -0
- data/spec/unit/test_qrb.rb +15 -0
- data/spec/unit/type/ad_type/test_default_name.rb +15 -0
- data/spec/unit/type/ad_type/test_dress.rb +55 -0
- data/spec/unit/type/ad_type/test_include.rb +22 -0
- data/spec/unit/type/ad_type/test_initialize.rb +40 -0
- data/spec/unit/type/ad_type/test_name.rb +20 -0
- data/spec/unit/type/builtin_type/test_default_name.rb +12 -0
- data/spec/unit/type/builtin_type/test_dress.rb +33 -0
- data/spec/unit/type/builtin_type/test_equality.rb +26 -0
- data/spec/unit/type/builtin_type/test_include.rb +22 -0
- data/spec/unit/type/builtin_type/test_initialize.rb +12 -0
- data/spec/unit/type/builtin_type/test_name.rb +24 -0
- data/spec/unit/type/relation_type/test_default_name.rb +16 -0
- data/spec/unit/type/relation_type/test_dress.rb +164 -0
- data/spec/unit/type/relation_type/test_equality.rb +32 -0
- data/spec/unit/type/relation_type/test_include.rb +46 -0
- data/spec/unit/type/relation_type/test_initialize.rb +26 -0
- data/spec/unit/type/relation_type/test_name.rb +24 -0
- data/spec/unit/type/seq_type/test_default_name.rb +14 -0
- data/spec/unit/type/seq_type/test_dress.rb +49 -0
- data/spec/unit/type/seq_type/test_equality.rb +26 -0
- data/spec/unit/type/seq_type/test_include.rb +43 -0
- data/spec/unit/type/seq_type/test_initialize.rb +28 -0
- data/spec/unit/type/seq_type/test_name.rb +24 -0
- data/spec/unit/type/set_type/test_default_name.rb +14 -0
- data/spec/unit/type/set_type/test_dress.rb +66 -0
- data/spec/unit/type/set_type/test_equality.rb +26 -0
- data/spec/unit/type/set_type/test_include.rb +43 -0
- data/spec/unit/type/set_type/test_initialize.rb +28 -0
- data/spec/unit/type/set_type/test_name.rb +24 -0
- data/spec/unit/type/sub_type/test_default_name.rb +14 -0
- data/spec/unit/type/sub_type/test_dress.rb +75 -0
- data/spec/unit/type/sub_type/test_equality.rb +34 -0
- data/spec/unit/type/sub_type/test_include.rb +34 -0
- data/spec/unit/type/sub_type/test_initialize.rb +16 -0
- data/spec/unit/type/sub_type/test_name.rb +24 -0
- data/spec/unit/type/tuple_type/test_default_name.rb +14 -0
- data/spec/unit/type/tuple_type/test_dress.rb +112 -0
- data/spec/unit/type/tuple_type/test_equality.rb +32 -0
- data/spec/unit/type/tuple_type/test_include.rb +38 -0
- data/spec/unit/type/tuple_type/test_initialize.rb +30 -0
- data/spec/unit/type/tuple_type/test_name.rb +24 -0
- data/spec/unit/type/union_type/test_default_name.rb +12 -0
- data/spec/unit/type/union_type/test_dress.rb +43 -0
- data/spec/unit/type/union_type/test_equality.rb +30 -0
- data/spec/unit/type/union_type/test_include.rb +28 -0
- data/spec/unit/type/union_type/test_initialize.rb +24 -0
- data/spec/unit/type/union_type/test_name.rb +20 -0
- data/spec/unit/type_factory/dsl/test_adt.rb +54 -0
- data/spec/unit/type_factory/dsl/test_attribute.rb +37 -0
- data/spec/unit/type_factory/dsl/test_attributes.rb +41 -0
- data/spec/unit/type_factory/dsl/test_builtin.rb +45 -0
- data/spec/unit/type_factory/dsl/test_relation.rb +85 -0
- data/spec/unit/type_factory/dsl/test_seq.rb +57 -0
- data/spec/unit/type_factory/dsl/test_set.rb +57 -0
- data/spec/unit/type_factory/dsl/test_subtype.rb +91 -0
- data/spec/unit/type_factory/dsl/test_tuple.rb +73 -0
- data/spec/unit/type_factory/dsl/test_union.rb +81 -0
- data/spec/unit/type_factory/factory/test_builtin.rb +24 -0
- data/spec/unit/type_factory/factory/test_seq_type.rb +44 -0
- data/spec/unit/type_factory/factory/test_set_type.rb +44 -0
- data/spec/unit/type_factory/factory/test_sub_type.rb +53 -0
- data/spec/unit/type_factory/factory/test_tuple_type.rb +43 -0
- data/tasks/gem.rake +73 -0
- data/tasks/test.rake +31 -0
- 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,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,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
|