must 0.3.0 → 0.3.1
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/lib/must.rb +7 -0
- data/lib/must/differ.rb +24 -7
- data/lib/must/rule.rb +1 -1
- data/lib/must/version.rb +1 -1
- data/spec/differ_spec.rb +24 -1
- data/spec/must_spec.rb +26 -73
- data/spec/rule_spec.rb +96 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/struct_spec.rb +4 -4
- metadata +5 -4
data/lib/must.rb
CHANGED
@@ -9,6 +9,13 @@ module Must
|
|
9
9
|
|
10
10
|
def must(*args, &block)
|
11
11
|
if args.size > 0
|
12
|
+
# Fast type checking
|
13
|
+
args.each{|klass|
|
14
|
+
return self if self.class == klass # 1.must(Fixnum)
|
15
|
+
return self if self == klass # flag.must(true, false)
|
16
|
+
}
|
17
|
+
|
18
|
+
# Or, check it in a slow but strict way
|
12
19
|
Rule.new(self).be.kind_of(*args, &block)
|
13
20
|
else
|
14
21
|
Rule.new(self)
|
data/lib/must/differ.rb
CHANGED
@@ -2,7 +2,8 @@ module Must
|
|
2
2
|
class Differ
|
3
3
|
attr_reader :a, :b, :path
|
4
4
|
|
5
|
-
def initialize(a, b, path)
|
5
|
+
def initialize(a, b, path = nil)
|
6
|
+
path ||= a.class.name.downcase
|
6
7
|
@a, @b, @path = a, b, path
|
7
8
|
end
|
8
9
|
|
@@ -16,7 +17,11 @@ module Must
|
|
16
17
|
|
17
18
|
def execute!
|
18
19
|
unless a.class == b.class
|
19
|
-
|
20
|
+
if a == nil or b == nil
|
21
|
+
failed ValueMismatch, "%s expected %s, but got %s" % [path, a.class, b.class]
|
22
|
+
else
|
23
|
+
failed ClassMismatch, "%s expected %s, but got %s" % [path, a.class, b.class]
|
24
|
+
end
|
20
25
|
end
|
21
26
|
|
22
27
|
if a.is_a?(Array)
|
@@ -29,7 +34,7 @@ module Must
|
|
29
34
|
|
30
35
|
if a.is_a?(Hash)
|
31
36
|
(a.keys | b.keys).each do |key|
|
32
|
-
Differ.new(a[key], b[key], "#{path}[#{key}]").execute!
|
37
|
+
Differ.new(a[key], b[key], "#{path}[#{key.inspect}]").execute!
|
33
38
|
end
|
34
39
|
return true
|
35
40
|
end
|
@@ -43,16 +48,21 @@ module Must
|
|
43
48
|
unless eq
|
44
49
|
av = a.inspect.split(//)[0..50].join
|
45
50
|
bv = b.inspect.split(//)[0..50].join
|
46
|
-
|
51
|
+
if a.class == b.class
|
52
|
+
failed ValueMismatch, "%s expected %s, but got %s" % [path, av, bv]
|
53
|
+
else
|
54
|
+
failed ValueMismatch, "%s expected %s(%s), but got %s(%s)" % [path, av, a.class, bv, a.class]
|
55
|
+
end
|
47
56
|
end
|
48
57
|
|
49
58
|
return true
|
50
59
|
|
51
60
|
rescue Must::ClassMismatch => err
|
52
61
|
if a.class == b.class
|
53
|
-
as = Must::StructInfo.new(a).inspect
|
54
|
-
bs = Must::StructInfo.new(b).inspect
|
55
|
-
raise Must::StructMismatch, "%s expected %s, but got %s" % [path, as, bs]
|
62
|
+
# as = Must::StructInfo.new(a).inspect
|
63
|
+
# bs = Must::StructInfo.new(b).inspect
|
64
|
+
# raise Must::StructMismatch, "%s expected %s, but got %s" % [path, as, bs]
|
65
|
+
raise Must::StructMismatch, err.to_s
|
56
66
|
else
|
57
67
|
raise
|
58
68
|
end
|
@@ -65,6 +75,13 @@ module Must
|
|
65
75
|
return false
|
66
76
|
end
|
67
77
|
|
78
|
+
def message
|
79
|
+
execute!
|
80
|
+
return nil
|
81
|
+
rescue Must::Invalid => err
|
82
|
+
return err.message
|
83
|
+
end
|
84
|
+
|
68
85
|
def failed(klass, msg)
|
69
86
|
raise klass, msg
|
70
87
|
end
|
data/lib/must/rule.rb
CHANGED
@@ -110,7 +110,7 @@ module Must
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def struct(target, &block)
|
113
|
-
block ||= proc{ Must::Differ.new(@object, target, "").
|
113
|
+
block ||= proc{ raise Must::StructMismatch, Differ.new(@object, target, "").message }
|
114
114
|
valid?(struct?(target), &block)
|
115
115
|
end
|
116
116
|
|
data/lib/must/version.rb
CHANGED
data/spec/differ_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Must::Differ do
|
4
4
|
let(:a) {}
|
5
5
|
let(:b) {}
|
6
|
-
let(:path) {
|
6
|
+
let(:path) { nil }
|
7
7
|
|
8
8
|
subject { lambda { Must::Differ.new(a, b, path).execute! } }
|
9
9
|
|
@@ -67,4 +67,27 @@ describe Must::Differ do
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
context "complex object" do
|
71
|
+
let(:a) { {
|
72
|
+
"abc" => 0,
|
73
|
+
"xyz" => 1,
|
74
|
+
} }
|
75
|
+
|
76
|
+
let(:b) { {
|
77
|
+
"abc" => nil,
|
78
|
+
"xyz" => 1,
|
79
|
+
} }
|
80
|
+
|
81
|
+
it { should raise_error(Must::ValueMismatch) }
|
82
|
+
|
83
|
+
context "(with label)" do
|
84
|
+
let(:path) { "foo" }
|
85
|
+
it { should raise_error(/foo\["abc"\]/) }
|
86
|
+
end
|
87
|
+
|
88
|
+
context "(without label)" do
|
89
|
+
let(:path) { nil }
|
90
|
+
it { should raise_error(/hash\["abc"\]/) }
|
91
|
+
end
|
92
|
+
end
|
70
93
|
end
|
data/spec/must_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Must
|
3
|
+
describe Must, "must" do
|
4
4
|
def ok(&block)
|
5
5
|
block.should_not raise_error
|
6
6
|
end
|
@@ -9,88 +9,41 @@ describe Must::Rule, "must" do
|
|
9
9
|
block.should raise_error(error)
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
1.must.be(1).should == 1
|
18
|
-
[1,2,3].must.be([1,2,3]).should == [1,2,3]
|
19
|
-
{:a=>1, "b"=>2}.must.be({:a=>1, "b"=>2}).should == {:a=>1, "b"=>2}
|
20
|
-
String.must.be(String).should == String
|
21
|
-
end
|
22
|
-
|
23
|
-
specify "[NG]" do
|
24
|
-
ng {1.must.be 2}
|
25
|
-
end
|
26
|
-
|
27
|
-
specify "callback" do
|
28
|
-
1.must.be(2){:error}.should == :error
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
######################################################################
|
33
|
-
### must not be blank
|
12
|
+
context "1.must(klass)" do
|
13
|
+
specify do
|
14
|
+
ok { 1.must(Integer) }
|
15
|
+
ok { 1.must(Integer, String) }
|
16
|
+
ok { 1.must(Fixnum) }
|
34
17
|
|
35
|
-
|
36
|
-
|
37
|
-
specify do
|
38
|
-
"ok".must.not.be.blank.should == "ok"
|
39
|
-
"ok".must.not.be.blank{"ng"}.should == "ok"
|
40
|
-
"".must.not.be.blank{"ng"}.should == "ng"
|
41
|
-
ng { "".must.not.be.blank }
|
42
|
-
end
|
18
|
+
ng { 1.must(String) }
|
19
|
+
ng { 1.must(String, Array) }
|
43
20
|
end
|
44
21
|
end
|
45
22
|
|
46
|
-
|
47
|
-
######################################################################
|
48
|
-
### must(type)
|
49
|
-
|
50
|
-
describe "type" do
|
23
|
+
context "klass.must(klass)" do
|
51
24
|
specify do
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
25
|
+
ok { Fixnum.must(Fixnum) }
|
26
|
+
ok { Fixnum.must(Integer) }
|
27
|
+
ok { Fixnum.must(Numeric) }
|
28
|
+
ok { Fixnum.must(Integer, String) }
|
56
29
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
specify "callback" do
|
63
|
-
"ok".must(Integer){:error}.should == :error
|
30
|
+
ng { Integer.must(Fixnum) }
|
31
|
+
ng { Integer.must(String) }
|
32
|
+
ng { Integer.must(String, Array) }
|
64
33
|
end
|
65
34
|
end
|
66
35
|
|
67
|
-
|
68
|
-
### kind_of
|
69
|
-
|
70
|
-
describe "kind_of" do
|
36
|
+
context "true.must(bool)" do
|
71
37
|
specify do
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
ng {
|
80
|
-
|
81
|
-
|
82
|
-
context "(class)" do
|
83
|
-
module KindOfTest
|
84
|
-
module Core; end
|
85
|
-
class Base
|
86
|
-
include Core
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
specify "check ancestors when module given" do
|
91
|
-
ok { KindOfTest::Base.must.be.kind_of(KindOfTest::Core) }
|
92
|
-
ng { KindOfTest::Base.must.be.kind_of(Numeric) }
|
93
|
-
end
|
38
|
+
ok { true.must(true) }
|
39
|
+
ok { true.must(true,false) }
|
40
|
+
ng { true.must(false) }
|
41
|
+
ng { "xx".must(true,false) }
|
42
|
+
|
43
|
+
ok { false.must(false) }
|
44
|
+
ok { false.must(true,false) }
|
45
|
+
ng { false.must(true) }
|
46
|
+
ng { "xxx".must(true,false) }
|
94
47
|
end
|
95
48
|
end
|
96
49
|
end
|
data/spec/rule_spec.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Must::Rule, "must" do
|
4
|
+
def ok(&block)
|
5
|
+
block.should_not raise_error
|
6
|
+
end
|
7
|
+
|
8
|
+
def ng(error = Must::Invalid, &block)
|
9
|
+
block.should raise_error(error)
|
10
|
+
end
|
11
|
+
|
12
|
+
######################################################################
|
13
|
+
### must be
|
14
|
+
|
15
|
+
describe "be" do
|
16
|
+
specify "[OK]" do
|
17
|
+
1.must.be(1).should == 1
|
18
|
+
[1,2,3].must.be([1,2,3]).should == [1,2,3]
|
19
|
+
{:a=>1, "b"=>2}.must.be({:a=>1, "b"=>2}).should == {:a=>1, "b"=>2}
|
20
|
+
String.must.be(String).should == String
|
21
|
+
end
|
22
|
+
|
23
|
+
specify "[NG]" do
|
24
|
+
ng {1.must.be 2}
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "callback" do
|
28
|
+
1.must.be(2){:error}.should == :error
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
######################################################################
|
33
|
+
### must not be blank
|
34
|
+
|
35
|
+
describe "not be blank" do
|
36
|
+
if Object.instance_methods.include?("blank?")
|
37
|
+
specify do
|
38
|
+
"ok".must.not.be.blank.should == "ok"
|
39
|
+
"ok".must.not.be.blank{"ng"}.should == "ok"
|
40
|
+
"".must.not.be.blank{"ng"}.should == "ng"
|
41
|
+
ng { "".must.not.be.blank }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
######################################################################
|
48
|
+
### must(type)
|
49
|
+
|
50
|
+
describe "type" do
|
51
|
+
specify do
|
52
|
+
"ok".must(String).should == "ok"
|
53
|
+
"ok".must(Integer, String).should == "ok"
|
54
|
+
ng { "ok".must(Integer) }
|
55
|
+
end
|
56
|
+
|
57
|
+
specify "weird but it is" do
|
58
|
+
# NOTE: this passes because 1(integer) is a kind of 2(integer)
|
59
|
+
ok { 1.must(2) }
|
60
|
+
end
|
61
|
+
|
62
|
+
specify "callback" do
|
63
|
+
"ok".must(Integer){:error}.should == :error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
######################################################################
|
68
|
+
### kind_of
|
69
|
+
|
70
|
+
describe "kind_of" do
|
71
|
+
specify do
|
72
|
+
"ok".must.be.kind_of(String).should == "ok"
|
73
|
+
ng { "ok".must.be.kind_of(Integer) }
|
74
|
+
end
|
75
|
+
|
76
|
+
specify "multiple args" do
|
77
|
+
"ok".must.be.kind_of(Integer,String).should == "ok"
|
78
|
+
"ok".must.be.kind_of(String,Integer).should == "ok"
|
79
|
+
ng { "ok".must.be.kind_of(Integer, Array) }
|
80
|
+
end
|
81
|
+
|
82
|
+
context "(class)" do
|
83
|
+
module KindOfTest
|
84
|
+
module Core; end
|
85
|
+
class Base
|
86
|
+
include Core
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
specify "check ancestors when module given" do
|
91
|
+
ok { KindOfTest::Base.must.be.kind_of(KindOfTest::Core) }
|
92
|
+
ng { KindOfTest::Base.must.be.kind_of(Numeric) }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/struct_spec.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Must, "struct" do
|
4
|
-
let(:obj) { {"xyz" => ["a","b"] } }
|
5
|
-
|
6
4
|
def ok(type) obj.must.struct?(type) == true ; end
|
7
5
|
def ng(type) obj.must.struct?(type) == false; end
|
8
6
|
|
@@ -10,10 +8,11 @@ describe Must, "struct" do
|
|
10
8
|
### error message
|
11
9
|
|
12
10
|
describe "#struct" do
|
11
|
+
let(:obj) { {"xyz" => ["a","b"] } }
|
13
12
|
subject { lambda { obj.must.struct({String => [Hash]}) } }
|
14
13
|
|
15
14
|
it { should raise_error(Must::StructMismatch) }
|
16
|
-
it { should raise_error(/\{String=>\[Hash\]\}/) }
|
15
|
+
# it { should raise_error(/\{String=>\[Hash\]\}/) }
|
17
16
|
end
|
18
17
|
|
19
18
|
######################################################################
|
@@ -88,7 +87,6 @@ describe Must, "struct" do
|
|
88
87
|
end
|
89
88
|
end
|
90
89
|
|
91
|
-
|
92
90
|
context "(Hash(String, Array(Hash)))" do
|
93
91
|
let(:obj) { {"foo" => [{:a=>1}, {:a=>3}]} }
|
94
92
|
|
@@ -105,6 +103,8 @@ describe Must, "struct" do
|
|
105
103
|
end
|
106
104
|
|
107
105
|
context "(accept {String => [Hash]})" do
|
106
|
+
let(:obj) { {"xyz" => ["a","b"] } }
|
107
|
+
|
108
108
|
def ok(obj); obj.must.struct?({String => [Hash]}).should == true ; end
|
109
109
|
def ng(obj); obj.must.struct?({String => [Hash]}).should == false; end
|
110
110
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: must
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- maiha
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-
|
18
|
+
date: 2013-09-04 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rspec
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- spec/duck_spec.rb
|
59
59
|
- spec/match_spec.rb
|
60
60
|
- spec/must_spec.rb
|
61
|
+
- spec/rule_spec.rb
|
61
62
|
- spec/spec_helper.rb
|
62
63
|
- spec/struct_info_spec.rb
|
63
64
|
- spec/struct_spec.rb
|