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,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe Syntax, "spacing" do
|
|
4
|
+
|
|
5
|
+
subject{
|
|
6
|
+
Syntax.parse(input, root: "spacing")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
[
|
|
10
|
+
' ',
|
|
11
|
+
"\n",
|
|
12
|
+
" \t\n",
|
|
13
|
+
" # foo\n"
|
|
14
|
+
].each do |source|
|
|
15
|
+
context "when `#{source}`" do
|
|
16
|
+
let(:input){ source }
|
|
17
|
+
|
|
18
|
+
it 'should parse' do
|
|
19
|
+
subject.should eq(source)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe Syntax, "sub_type" do
|
|
4
|
+
|
|
5
|
+
subject{
|
|
6
|
+
Syntax.parse(input, root: "sub_type")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let(:compiled){
|
|
10
|
+
subject.compile(type_factory)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
context '.Integer( i | i >= 0 )' do
|
|
14
|
+
let(:input){ '.Integer( i | i >= 0 )' }
|
|
15
|
+
|
|
16
|
+
it 'compiles to a SubType' do
|
|
17
|
+
compiled.should be_a(SubType)
|
|
18
|
+
compiled.super_type.should be_a(BuiltinType)
|
|
19
|
+
compiled.super_type.ruby_type.should be(Integer)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context '.Integer( i | positive: i >= 0 )' do
|
|
24
|
+
let(:input){ '.Integer( i | positive: i >= 0 )' }
|
|
25
|
+
|
|
26
|
+
it 'compiles to a SubType' do
|
|
27
|
+
compiled.should be_a(SubType)
|
|
28
|
+
compiled.super_type.should be_a(BuiltinType)
|
|
29
|
+
compiled.super_type.ruby_type.should be(Integer)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'has the correct constraints' do
|
|
33
|
+
compiled.constraints.keys.should eq([:positive])
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context '.Integer( i | positive: i >= 0, ... )' do
|
|
38
|
+
let(:input){ '.Integer( i | positive: i >= 0, small: i <= 255 )' }
|
|
39
|
+
|
|
40
|
+
it 'compiles to a SubType' do
|
|
41
|
+
compiled.should be_a(SubType)
|
|
42
|
+
compiled.super_type.should be_a(BuiltinType)
|
|
43
|
+
compiled.super_type.ruby_type.should be(Integer)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'has the correct constraints' do
|
|
47
|
+
compiled.constraints.keys.should eq([:positive, :small])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe Syntax, "tuple_type" do
|
|
4
|
+
|
|
5
|
+
subject{
|
|
6
|
+
Syntax.parse(input, root: "tuple_type")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let(:compiled){
|
|
10
|
+
subject.compile(type_factory)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
context 'empty heading' do
|
|
14
|
+
let(:input){ '{ }' }
|
|
15
|
+
|
|
16
|
+
it 'compiles to a TupleType' do
|
|
17
|
+
compiled.should be_a(TupleType)
|
|
18
|
+
compiled.heading.should be_empty
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context '{a: .Integer}' do
|
|
23
|
+
let(:input){ '{a: .Integer}' }
|
|
24
|
+
|
|
25
|
+
it 'compiles to a TupleType' do
|
|
26
|
+
compiled.should be_a(TupleType)
|
|
27
|
+
compiled.heading.size.should eq(1)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context '{a: .Integer, b: .Float}' do
|
|
32
|
+
let(:input){ '{a: .Integer, b: .Float}' }
|
|
33
|
+
|
|
34
|
+
it 'compiles to a TupleType' do
|
|
35
|
+
compiled.should be_a(TupleType)
|
|
36
|
+
compiled.heading.size.should eq(2)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe Syntax, "union_type" do
|
|
4
|
+
|
|
5
|
+
subject{
|
|
6
|
+
Syntax.parse(input, root: "union_type")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let(:compiled){
|
|
10
|
+
subject.compile(type_factory)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
context '.Integer|.Float' do
|
|
14
|
+
let(:input){ '.Integer|.Float' }
|
|
15
|
+
|
|
16
|
+
it 'compiles to a UnionType' do
|
|
17
|
+
compiled.should be_a(UnionType)
|
|
18
|
+
compiled.should eq(UnionType.new([intType, floatType]))
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe Syntax, "unnamed_constraint" do
|
|
4
|
+
|
|
5
|
+
subject{
|
|
6
|
+
Syntax.parse(input, root: "unnamed_constraint")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let(:compiled){
|
|
10
|
+
subject.compile("a")
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
context 'a >= 10' do
|
|
14
|
+
let(:input){ 'a >= 10' }
|
|
15
|
+
|
|
16
|
+
it 'compiles to an Hash' do
|
|
17
|
+
compiled.should be_a(Hash)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'has expected keys' do
|
|
21
|
+
compiled.keys.should eq([:predicate])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should be the correct Proc' do
|
|
25
|
+
compiled[:predicate].call(12).should be_true
|
|
26
|
+
compiled[:predicate].call(9).should be_false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe Syntax, '.compile' do
|
|
4
|
+
|
|
5
|
+
let(:source){
|
|
6
|
+
<<-EOF
|
|
7
|
+
{
|
|
8
|
+
name: .String,
|
|
9
|
+
color: { red: .Integer, green: .Integer, blue: .Integer },
|
|
10
|
+
sex: .String( s | s =~ /^M|F$/ )
|
|
11
|
+
}
|
|
12
|
+
EOF
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
subject do
|
|
16
|
+
Syntax.compile_type(source)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it{ should be_a(Type) }
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe System, "add_type" do
|
|
4
|
+
|
|
5
|
+
let(:system){ System.new }
|
|
6
|
+
|
|
7
|
+
subject{ system.add_type(type) }
|
|
8
|
+
|
|
9
|
+
context 'with a valid type' do
|
|
10
|
+
let(:type){ intType }
|
|
11
|
+
|
|
12
|
+
it 'should return the created type' do
|
|
13
|
+
subject.should be(type)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'should add the type' do
|
|
17
|
+
subject
|
|
18
|
+
system[type.name].should be(type)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'with an invalid type' do
|
|
23
|
+
let(:type){ "foo" }
|
|
24
|
+
|
|
25
|
+
it 'should raise an error' do
|
|
26
|
+
->{
|
|
27
|
+
subject
|
|
28
|
+
}.should raise_error(ArgumentError, "Qrb::Type expected, got `foo`")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'with a duplicate type name' do
|
|
33
|
+
let(:type){ intType }
|
|
34
|
+
|
|
35
|
+
before do
|
|
36
|
+
system.add_type(type)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'should raise an error' do
|
|
40
|
+
->{
|
|
41
|
+
subject
|
|
42
|
+
}.should raise_error(Qrb::Error, "Duplicate type name `intType`")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe System, "initialize" do
|
|
4
|
+
|
|
5
|
+
let(:system){ System.new }
|
|
6
|
+
|
|
7
|
+
context 'for building a tuple type' do
|
|
8
|
+
subject{
|
|
9
|
+
system.tuple(r: Integer)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
it{ should be_a(TupleType) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'for building a sub type' do
|
|
16
|
+
subject{
|
|
17
|
+
system.subtype(Integer){|i| i>=0 }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
it{ should be_a(SubType) }
|
|
21
|
+
|
|
22
|
+
it 'should apply the constraint' do
|
|
23
|
+
->{
|
|
24
|
+
subject.dress(-9)
|
|
25
|
+
}.should raise_error(TypeError)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe System, "dup" do
|
|
4
|
+
|
|
5
|
+
let(:system){ System.new }
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
system.add_type(intType)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
subject{ system.dup }
|
|
12
|
+
|
|
13
|
+
it{ should be_a(System) }
|
|
14
|
+
|
|
15
|
+
it 'should not be the same object' do
|
|
16
|
+
subject.should_not be(system)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'should have intType' do
|
|
20
|
+
subject['intType'].should eq(intType)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should not share internals with the original' do
|
|
24
|
+
subject.add_type(floatType)
|
|
25
|
+
subject['floatType'].should_not be_nil
|
|
26
|
+
system['floatType'].should be_nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe System, "fetch" do
|
|
4
|
+
|
|
5
|
+
let(:system){ System.new }
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
system.add_type(intType)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
subject{ system.fetch(name) }
|
|
12
|
+
|
|
13
|
+
context 'with an existing type name' do
|
|
14
|
+
let(:name){ "intType" }
|
|
15
|
+
|
|
16
|
+
it 'should return the type' do
|
|
17
|
+
subject.should eq(intType)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'with a non existing type name and no block' do
|
|
22
|
+
let(:name){ "noSuchOne" }
|
|
23
|
+
|
|
24
|
+
it 'should raise an error' do
|
|
25
|
+
->{
|
|
26
|
+
subject
|
|
27
|
+
}.should raise_error(KeyError, /noSuchOne/)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'with a non existing type name and a block' do
|
|
32
|
+
subject{
|
|
33
|
+
system.fetch("noSuchOne"){ "bar" }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
it 'should yield the block' do
|
|
37
|
+
subject.should eq("bar")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe System, "[]" do
|
|
4
|
+
|
|
5
|
+
let(:system){ System.new }
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
system.add_type(intType)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
subject{ system[name] }
|
|
12
|
+
|
|
13
|
+
context 'with an existing type name' do
|
|
14
|
+
let(:name){ "intType" }
|
|
15
|
+
|
|
16
|
+
it 'should return the type' do
|
|
17
|
+
subject.should eq(intType)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'with a non existing type name' do
|
|
22
|
+
let(:name){ "noSuchOne" }
|
|
23
|
+
|
|
24
|
+
it 'should return nil' do
|
|
25
|
+
subject.should be_nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
describe Qrb do
|
|
3
|
+
|
|
4
|
+
it "should have a version number" do
|
|
5
|
+
Qrb.const_defined?(:VERSION).should be_true
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'should have DSL methods' do
|
|
9
|
+
t = Qrb.type(Fixnum){|i| i>=0 }
|
|
10
|
+
t.should be_a(Qrb::SubType)
|
|
11
|
+
t.dress(12).should eq(12)
|
|
12
|
+
->{ t.dress(-12) }.should raise_error(Qrb::TypeError)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe AdType, "default_name" do
|
|
4
|
+
|
|
5
|
+
subject{ type.default_name }
|
|
6
|
+
|
|
7
|
+
let(:type){
|
|
8
|
+
AdType.new(Color, rgb: [intType, Color.method(:rgb) ],
|
|
9
|
+
hex: [floatType, Color.method(:hex) ])
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
it{ should eq('Color') }
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe AdType, 'dress' do
|
|
4
|
+
|
|
5
|
+
let(:type){
|
|
6
|
+
AdType.new(Color, rgb: [intType, ->(i){ i*2 } ],
|
|
7
|
+
hex: [floatType, ->(f){ f*3 } ])
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
subject{
|
|
11
|
+
type.dress(arg)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
context 'with a color' do
|
|
15
|
+
let(:arg){ Color.new(12, 13, 15) }
|
|
16
|
+
|
|
17
|
+
it{ should be(arg) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'with an integer' do
|
|
21
|
+
let(:arg){ 12 }
|
|
22
|
+
|
|
23
|
+
it{ should eq(24) }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context 'with a float' do
|
|
27
|
+
let(:arg){ 12.0 }
|
|
28
|
+
|
|
29
|
+
it{ should eq(36.0) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'with an unrecognized' do
|
|
33
|
+
let(:arg){ "foo" }
|
|
34
|
+
|
|
35
|
+
it 'should raise an error' do
|
|
36
|
+
->{
|
|
37
|
+
subject
|
|
38
|
+
}.should raise_error(TypeError, "Invalid value `foo` for Color")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'when the upper raises an error' do
|
|
43
|
+
let(:type){
|
|
44
|
+
AdType.new(Color, rgb: [ intType, ->(t){ raise ArgumentError } ])
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
it 'should hide the error' do
|
|
48
|
+
err = type.dress(12) rescue $!
|
|
49
|
+
err.should be_a(TypeError)
|
|
50
|
+
err.message.should eq("Invalid value `12` for Color")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe AdType, "include?" do
|
|
4
|
+
|
|
5
|
+
let(:type){ AdType.new(Color, {}) }
|
|
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' do
|
|
16
|
+
let(:arg){ blueviolet }
|
|
17
|
+
|
|
18
|
+
it{ should be_true }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe AdType, 'initialize' do
|
|
4
|
+
|
|
5
|
+
subject{
|
|
6
|
+
AdType.new(Color, rgb: [intType, Color.method(:rgb) ],
|
|
7
|
+
hex: [floatType, Color.method(:hex) ])
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
context 'with valid arguments' do
|
|
11
|
+
it{ should be_a(AdType) }
|
|
12
|
+
|
|
13
|
+
it 'should set the instance variables' do
|
|
14
|
+
subject.ruby_type.should be(Color)
|
|
15
|
+
subject.contracts.should be_a(Hash)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'with invalid arguments (I)' do
|
|
20
|
+
subject{ AdType.new("foo", {}) }
|
|
21
|
+
|
|
22
|
+
it 'should raise an error' do
|
|
23
|
+
->{
|
|
24
|
+
subject
|
|
25
|
+
}.should raise_error(ArgumentError, 'Module expected, got `foo`')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'with invalid arguments (II)' do
|
|
30
|
+
subject{ AdType.new(Object, "bar") }
|
|
31
|
+
|
|
32
|
+
it 'should raise an error' do
|
|
33
|
+
->{
|
|
34
|
+
subject
|
|
35
|
+
}.should raise_error(ArgumentError, 'Hash expected, got `bar`')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe AdType, "name" do
|
|
4
|
+
|
|
5
|
+
subject{ type.name }
|
|
6
|
+
|
|
7
|
+
context 'when provided' do
|
|
8
|
+
let(:type){ AdType.new(Color, {}, "Foo") }
|
|
9
|
+
|
|
10
|
+
it{ should eq('Foo') }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'when not provided' do
|
|
14
|
+
let(:type){ AdType.new(Color, {}) }
|
|
15
|
+
|
|
16
|
+
it{ should eq('Color') }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe BuiltinType, "dress" do
|
|
4
|
+
|
|
5
|
+
let(:type){ BuiltinType.new(Integer, 'int') }
|
|
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
|
+
subject{
|
|
19
|
+
type.dress(arg) rescue $!
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
it 'should raise an Error' do
|
|
23
|
+
subject.should be_a(TypeError)
|
|
24
|
+
subject.message.should eq("Invalid value `12.0` for int")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should have no location' do
|
|
28
|
+
subject.location.should eq('')
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe BuiltinType, "equality" do
|
|
4
|
+
|
|
5
|
+
let(:intType) { BuiltinType.new(Integer) }
|
|
6
|
+
let(:intType2){ BuiltinType.new(Integer) }
|
|
7
|
+
let(:fltType) { BuiltinType.new(Float) }
|
|
8
|
+
|
|
9
|
+
it 'should apply structural equality' do
|
|
10
|
+
(intType == intType2).should be_true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should apply distinguish different types' do
|
|
14
|
+
(intType == fltType).should be_false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should be a total function, with nil for non types' do
|
|
18
|
+
(intType == 12).should be_false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'should implement hash accordingly' do
|
|
22
|
+
(intType.hash == intType2.hash).should be_true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Qrb
|
|
3
|
+
describe BuiltinType, "include?" do
|
|
4
|
+
|
|
5
|
+
let(:type){ BuiltinType.new(Integer) }
|
|
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' do
|
|
16
|
+
let(:arg){ 12 }
|
|
17
|
+
|
|
18
|
+
it{ should be_true }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|