argspec 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +26 -6
- data/lib/argspec/argument.rb +37 -10
- data/lib/argspec/constants.rb +1 -1
- data/lib/argspec/dsl/matchers.rb +30 -0
- data/lib/argspec/dsl.rb +7 -29
- data/lib/argspec/matchers/base_matcher.rb +1 -1
- data/lib/argspec/matchers/be.rb +4 -12
- data/lib/argspec/matchers/be_compared_to.rb +89 -0
- data/lib/argspec/matchers/be_nil.rb +5 -1
- data/lib/argspec/matchers/be_one_of.rb +36 -0
- data/lib/argspec.rb +1 -0
- metadata +5 -6
- data/lib/argspec/matchers/be_greater_than.rb +0 -32
- data/lib/argspec/matchers/be_greater_than_or_equal_to.rb +0 -32
- data/lib/argspec/matchers/be_less_than.rb +0 -32
- data/lib/argspec/matchers/be_less_than_or_equal_to.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f6a9d2738f76290fa9b362e0b324eb6e60c3318
|
4
|
+
data.tar.gz: 5c70bae7e6ddd2d018ba54d42aaa81ba46f57414
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b49f0e5af1ee8057b7fe1bf820155b24b6242b3e7cf47f19c99f42d0916b63c14f33631b1deb9ad360b165467a26263a93ae473991aaa766926bc78ed54f4836
|
7
|
+
data.tar.gz: 7d260f1446eb41e61b7d54ca30d170c745f40e1a5d946fa8db8969e038370684d55a0553b1ba17c20d2c9e1603ac4e4f3d7300adf6c744139ac35840cca31ed6
|
data/README.md
CHANGED
@@ -61,13 +61,13 @@ class Person
|
|
61
61
|
attr_reader :name, :gender, :birthdate
|
62
62
|
|
63
63
|
def initialize(name, gender, birthdate)
|
64
|
-
argument(name)
|
65
|
-
|
66
|
-
|
64
|
+
argument(name) do
|
65
|
+
should be_a(String)
|
66
|
+
should_not be_empty
|
67
|
+
end
|
67
68
|
|
68
|
-
argument(
|
69
|
-
argument(
|
70
|
-
argument(birthdate).should_not(:be, nil)
|
69
|
+
argument(gender) { should be_a(Symbol) }
|
70
|
+
argument(birthdate) { should be_a(Date) }
|
71
71
|
|
72
72
|
@name = name
|
73
73
|
@gender = gender
|
@@ -78,6 +78,26 @@ end
|
|
78
78
|
|
79
79
|
That's better. It's now really clear what validations you're performing.
|
80
80
|
|
81
|
+
Method chaining is also supported:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
class Person
|
85
|
+
include ArgumentSpecification::DSL
|
86
|
+
|
87
|
+
attr_reader :name, :gender, :birthdate
|
88
|
+
|
89
|
+
def initialize(name, gender, birthdate)
|
90
|
+
argument(name) { should(be_a(Symbol)).and_not(be_empty) }
|
91
|
+
argument(gender) { should be_a(Symbol) }
|
92
|
+
argument(birthdate) { should be_a(Date) }
|
93
|
+
|
94
|
+
@name = name
|
95
|
+
@gender = gender
|
96
|
+
@birthdate = birthdate
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
81
101
|
## Development
|
82
102
|
|
83
103
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/argspec/argument.rb
CHANGED
@@ -1,19 +1,26 @@
|
|
1
1
|
module ArgumentSpecification
|
2
2
|
class Argument
|
3
|
+
include ArgumentSpecification::DSL::Matchers
|
4
|
+
|
3
5
|
attr_reader :actual
|
4
6
|
|
5
7
|
# Create a new argument
|
6
8
|
#
|
7
9
|
# Arguments:
|
8
10
|
# actual: (Object)
|
11
|
+
# block: (Block)
|
9
12
|
#
|
10
13
|
# Example:
|
11
14
|
# >> test = :test
|
12
|
-
# >> ArgumentSpecification::Argument.new(test)
|
15
|
+
# >> ArgumentSpecification::Argument.new(test) do
|
16
|
+
# >> should_not be_nil
|
17
|
+
# >> end
|
13
18
|
# => #<Argument:0x00000000000000 @actual=:test>
|
14
19
|
#
|
15
|
-
def initialize(actual)
|
20
|
+
def initialize(actual, &block)
|
16
21
|
@actual = actual
|
22
|
+
|
23
|
+
instance_eval(&block)
|
17
24
|
end
|
18
25
|
|
19
26
|
# Ensure the argument matches
|
@@ -22,18 +29,18 @@ module ArgumentSpecification
|
|
22
29
|
# matcher: (Matchers::BaseMatcher)
|
23
30
|
#
|
24
31
|
# Example:
|
25
|
-
# >>
|
26
|
-
# =>
|
32
|
+
# >> should be_a(Symbol)
|
33
|
+
# => #<Argument:0x00000000000000 @actual=:test>
|
27
34
|
#
|
28
35
|
# Raises:
|
29
36
|
# ArgumentError: When the argument does not match
|
30
37
|
#
|
31
38
|
def should(matcher)
|
32
|
-
return
|
39
|
+
return self unless matcher.is_a?(Matchers::BaseMatcher)
|
33
40
|
|
34
41
|
matcher.send(:actual=, @actual)
|
35
42
|
|
36
|
-
return
|
43
|
+
return self if matcher.matches?
|
37
44
|
|
38
45
|
raise ArgumentError, matcher.failure_message
|
39
46
|
end
|
@@ -44,20 +51,40 @@ module ArgumentSpecification
|
|
44
51
|
# matcher: (Matchers::BaseMatcher)
|
45
52
|
#
|
46
53
|
# Example:
|
47
|
-
# >>
|
48
|
-
# =>
|
54
|
+
# >> should_not be_a(Symbol)
|
55
|
+
# => #<Argument:0x00000000000000 @actual=:test>
|
49
56
|
#
|
50
57
|
# Raises:
|
51
58
|
# ArgumentError: When the argument matches
|
52
59
|
#
|
53
60
|
def should_not(matcher)
|
54
|
-
return
|
61
|
+
return self unless matcher.is_a?(Matchers::BaseMatcher)
|
55
62
|
|
56
63
|
matcher.send(:actual=, @actual)
|
57
64
|
|
58
|
-
return
|
65
|
+
return self unless matcher.matches?
|
59
66
|
|
60
67
|
raise ArgumentError, matcher.failure_message_when_negated
|
61
68
|
end
|
69
|
+
|
70
|
+
# Alias for should
|
71
|
+
#
|
72
|
+
# Example:
|
73
|
+
# >> and be_a(Symbol)
|
74
|
+
# => #<Argument:0x00000000000000 @actual=:test>
|
75
|
+
#
|
76
|
+
def and(*args)
|
77
|
+
should(*args)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Alias for should_not
|
81
|
+
#
|
82
|
+
# Example:
|
83
|
+
# >> and_not be_a(Symbol)
|
84
|
+
# => #<Argument:0x00000000000000 @actual=:test>
|
85
|
+
#
|
86
|
+
def and_not(*args)
|
87
|
+
should_not(*args)
|
88
|
+
end
|
62
89
|
end
|
63
90
|
end
|
data/lib/argspec/constants.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module ArgumentSpecification
|
2
|
+
module DSL
|
3
|
+
module Matchers
|
4
|
+
class << self
|
5
|
+
# Register a matcher
|
6
|
+
#
|
7
|
+
# Arguments:
|
8
|
+
# klass: (ArgumentSpecification::Matchers::BaseMatcher)
|
9
|
+
# name: (Symbol)
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
# >> Matchers.register(TestMatcher, :test_matcher)
|
13
|
+
# => true
|
14
|
+
#
|
15
|
+
def register(klass, name)
|
16
|
+
return unless klass.ancestors.include?(ArgumentSpecification::Matchers::BaseMatcher)
|
17
|
+
return unless name.is_a?(Symbol)
|
18
|
+
|
19
|
+
module_eval <<-EOS
|
20
|
+
def #{name}(*args, &block)
|
21
|
+
instance = #{klass}.new(*args, &block)
|
22
|
+
instance.send(:setup, '#{name}'.to_sym, args)
|
23
|
+
instance
|
24
|
+
end
|
25
|
+
EOS
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/argspec/dsl.rb
CHANGED
@@ -1,42 +1,20 @@
|
|
1
1
|
module ArgumentSpecification
|
2
2
|
module DSL
|
3
|
-
class << self
|
4
|
-
# Register a matcher
|
5
|
-
#
|
6
|
-
# Arguments:
|
7
|
-
# klass: (Matchers::BaseMatcher)
|
8
|
-
# name: (Symbol)
|
9
|
-
#
|
10
|
-
# Example:
|
11
|
-
# >> register_matcher(TestMatcher, :test_matcher)
|
12
|
-
# => true
|
13
|
-
#
|
14
|
-
def register_matcher(klass, name)
|
15
|
-
return unless klass.ancestors.include?(Matchers::BaseMatcher)
|
16
|
-
return unless name.is_a?(Symbol)
|
17
|
-
|
18
|
-
module_eval <<-EOS
|
19
|
-
def #{name}(*args, &block)
|
20
|
-
instance = #{klass}.new(*args, &block)
|
21
|
-
instance.send(:setup, '#{name}'.to_sym, args)
|
22
|
-
instance
|
23
|
-
end
|
24
|
-
EOS
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
3
|
# Get an argument object
|
29
4
|
#
|
30
5
|
# Arguments:
|
31
6
|
# object: (Object)
|
7
|
+
# block: (Block)
|
32
8
|
#
|
33
9
|
# Example:
|
34
10
|
# >> test = :test
|
35
|
-
# >> argument(test)
|
36
|
-
# =>
|
11
|
+
# >> argument(test) { should_not be_nil }
|
12
|
+
# => nil
|
37
13
|
#
|
38
|
-
def argument(object)
|
39
|
-
ArgumentSpecification::Argument.new(object)
|
14
|
+
def argument(object, &block)
|
15
|
+
ArgumentSpecification::Argument.new(object, &block)
|
16
|
+
|
17
|
+
nil
|
40
18
|
end
|
41
19
|
end
|
42
20
|
end
|
data/lib/argspec/matchers/be.rb
CHANGED
@@ -3,19 +3,11 @@ module ArgumentSpecification
|
|
3
3
|
class Be < BaseMatcher
|
4
4
|
matcher_name :be
|
5
5
|
|
6
|
-
|
7
|
-
:== => :equal,
|
8
|
-
:=== => :case_equal,
|
9
|
-
:=~ => :match,
|
10
|
-
:< => :be_less_than,
|
11
|
-
:> => :be_greater_than,
|
12
|
-
:<= => :be_less_than_or_equal_to,
|
13
|
-
:>= => :be_greater_than_or_equal_to
|
14
|
-
}
|
15
|
-
|
16
|
-
OPERATORS.keys.each do |operator|
|
6
|
+
[:==, :===, :=~, :<, :>, :<=, :>=].each do |operator|
|
17
7
|
define_method(operator) do |expected|
|
18
|
-
|
8
|
+
instance = BeComparedTo.new(operator, expected)
|
9
|
+
instance.send(:setup, operator, [operator, expected])
|
10
|
+
instance
|
19
11
|
end
|
20
12
|
end
|
21
13
|
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module ArgumentSpecification
|
2
|
+
module Matchers
|
3
|
+
class BeComparedTo < BaseMatcher
|
4
|
+
attr_reader :operator, :expected
|
5
|
+
|
6
|
+
# Create a new matcher instance
|
7
|
+
#
|
8
|
+
# Arguments:
|
9
|
+
# operator: (Symbol)
|
10
|
+
# expected: (Object)
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# >> ArgumentSpecification::Matchers::BeComparedTo.new(:==, 10)
|
14
|
+
# => #<ArgumentSpecification::Matchers::BeComparedTo:0x00000000000000 @operator=:==, @expected=10>
|
15
|
+
#
|
16
|
+
def initialize(operator, expected)
|
17
|
+
@operator = operator
|
18
|
+
@expected = expected
|
19
|
+
end
|
20
|
+
|
21
|
+
# The failure message when using 'should'
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
# >> matcher.failure_message
|
25
|
+
# => "':foo' should be equal to ':test'"
|
26
|
+
#
|
27
|
+
def failure_message
|
28
|
+
actual = prettify_args(@actual)
|
29
|
+
|
30
|
+
"'#{actual}' should #{pretty_matcher} '#{@expected}'"
|
31
|
+
end
|
32
|
+
|
33
|
+
# The failure message when using 'should not'
|
34
|
+
#
|
35
|
+
# Example:
|
36
|
+
# >> matcher.failure_message_when_negated
|
37
|
+
# => "':test' should not be equal to ':test'"
|
38
|
+
#
|
39
|
+
def failure_message_when_negated
|
40
|
+
actual = prettify_args(@actual)
|
41
|
+
|
42
|
+
"'#{actual}' should not #{pretty_matcher} '#{@expected}'"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Check if the actual object matches
|
46
|
+
#
|
47
|
+
# Example:
|
48
|
+
# >> matcher.matches?
|
49
|
+
# => true
|
50
|
+
#
|
51
|
+
def matches?
|
52
|
+
begin
|
53
|
+
@actual.send(@operator, @expected)
|
54
|
+
rescue ArgumentError
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
# Get the pretty matcher name
|
61
|
+
#
|
62
|
+
# Example:
|
63
|
+
# >> matcher = BeComparedTo.new(:==, 1)
|
64
|
+
# >> matcher.pretty_matcher
|
65
|
+
# => "equal"
|
66
|
+
#
|
67
|
+
def pretty_matcher
|
68
|
+
case @operator
|
69
|
+
when :==
|
70
|
+
"equal"
|
71
|
+
when :===
|
72
|
+
"case equal"
|
73
|
+
when :=~
|
74
|
+
"match"
|
75
|
+
when :<
|
76
|
+
"be less than"
|
77
|
+
when :>
|
78
|
+
"be greater than"
|
79
|
+
when :<=
|
80
|
+
"be less than or equal to"
|
81
|
+
when :>=
|
82
|
+
"be greater than or equal to"
|
83
|
+
else
|
84
|
+
"pass comparison #{@operator} to"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ArgumentSpecification
|
2
|
+
module Matchers
|
3
|
+
class BeOneOf < BaseMatcher
|
4
|
+
matcher_name :be_one_of
|
5
|
+
|
6
|
+
attr_reader :values
|
7
|
+
|
8
|
+
# Create a new matcher instance
|
9
|
+
#
|
10
|
+
# Arguments:
|
11
|
+
# values: (Splat|Range)
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
# >> ArgumentSpecification::Matchers::BeOneOf.new(1, 2)
|
15
|
+
# => #<ArgumentSpecification::Matchers::BeOneOf:0x00000000000000 @values=[1, 2]>
|
16
|
+
#
|
17
|
+
def initialize(*values)
|
18
|
+
if values && values.first.is_a?(Range)
|
19
|
+
@values = values.first.to_a
|
20
|
+
else
|
21
|
+
@values = values
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if the actual object matches
|
26
|
+
#
|
27
|
+
# Example:
|
28
|
+
# >> matcher.matches?
|
29
|
+
# => true
|
30
|
+
#
|
31
|
+
def matches?
|
32
|
+
@values.include?(@actual)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/argspec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: argspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nialto Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,18 +72,17 @@ files:
|
|
72
72
|
- lib/argspec/argument.rb
|
73
73
|
- lib/argspec/constants.rb
|
74
74
|
- lib/argspec/dsl.rb
|
75
|
+
- lib/argspec/dsl/matchers.rb
|
75
76
|
- lib/argspec/matchers.rb
|
76
77
|
- lib/argspec/matchers/all.rb
|
77
78
|
- lib/argspec/matchers/base_matcher.rb
|
78
79
|
- lib/argspec/matchers/be.rb
|
79
80
|
- lib/argspec/matchers/be_a.rb
|
81
|
+
- lib/argspec/matchers/be_compared_to.rb
|
80
82
|
- lib/argspec/matchers/be_empty.rb
|
81
83
|
- lib/argspec/matchers/be_falsey.rb
|
82
|
-
- lib/argspec/matchers/be_greater_than.rb
|
83
|
-
- lib/argspec/matchers/be_greater_than_or_equal_to.rb
|
84
|
-
- lib/argspec/matchers/be_less_than.rb
|
85
|
-
- lib/argspec/matchers/be_less_than_or_equal_to.rb
|
86
84
|
- lib/argspec/matchers/be_nil.rb
|
85
|
+
- lib/argspec/matchers/be_one_of.rb
|
87
86
|
- lib/argspec/matchers/be_truthy.rb
|
88
87
|
- lib/argspec/matchers/be_within_range.rb
|
89
88
|
- lib/argspec/matchers/case_equal.rb
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module ArgumentSpecification
|
2
|
-
module Matchers
|
3
|
-
class BeGreaterThan < BaseMatcher
|
4
|
-
matcher_name :be_greater_than
|
5
|
-
|
6
|
-
attr_reader :expected
|
7
|
-
|
8
|
-
# Create a new matcher instance
|
9
|
-
#
|
10
|
-
# Arguments:
|
11
|
-
# expected: (Object)
|
12
|
-
#
|
13
|
-
# Example:
|
14
|
-
# >> ArgumentSpecification::Matchers::BeGreaterThan.new(10)
|
15
|
-
# => #<ArgumentSpecification::Matchers::BeGreaterThan:0x00000000000000 @expected=10>
|
16
|
-
#
|
17
|
-
def initialize(expected)
|
18
|
-
@expected = expected
|
19
|
-
end
|
20
|
-
|
21
|
-
# Check if the actual object matches
|
22
|
-
#
|
23
|
-
# Example:
|
24
|
-
# >> matcher.matches?
|
25
|
-
# => true
|
26
|
-
#
|
27
|
-
def matches?
|
28
|
-
@actual > @expected
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module ArgumentSpecification
|
2
|
-
module Matchers
|
3
|
-
class BeGreaterThanOrEqualTo < BaseMatcher
|
4
|
-
matcher_name :be_greater_than_or_equal_to
|
5
|
-
|
6
|
-
attr_reader :expected
|
7
|
-
|
8
|
-
# Create a new matcher instance
|
9
|
-
#
|
10
|
-
# Arguments:
|
11
|
-
# expected: (Object)
|
12
|
-
#
|
13
|
-
# Example:
|
14
|
-
# >> ArgumentSpecification::Matchers::BeGreaterThanOrEqualTo.new(10)
|
15
|
-
# => #<ArgumentSpecification::Matchers::BeGreaterThanOrEqualTo:0x00000000000000 @expected=10>
|
16
|
-
#
|
17
|
-
def initialize(expected)
|
18
|
-
@expected = expected
|
19
|
-
end
|
20
|
-
|
21
|
-
# Check if the actual object matches
|
22
|
-
#
|
23
|
-
# Example:
|
24
|
-
# >> matcher.matches?
|
25
|
-
# => true
|
26
|
-
#
|
27
|
-
def matches?
|
28
|
-
@actual >= @expected
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module ArgumentSpecification
|
2
|
-
module Matchers
|
3
|
-
class BeLessThan < BaseMatcher
|
4
|
-
matcher_name :be_less_than
|
5
|
-
|
6
|
-
attr_reader :expected
|
7
|
-
|
8
|
-
# Create a new matcher instance
|
9
|
-
#
|
10
|
-
# Arguments:
|
11
|
-
# expected: (Object)
|
12
|
-
#
|
13
|
-
# Example:
|
14
|
-
# >> ArgumentSpecification::Matchers::BeLessThan.new(10)
|
15
|
-
# => #<ArgumentSpecification::Matchers::BeLessThan:0x00000000000000 @expected=10>
|
16
|
-
#
|
17
|
-
def initialize(expected)
|
18
|
-
@expected = expected
|
19
|
-
end
|
20
|
-
|
21
|
-
# Check if the actual object matches
|
22
|
-
#
|
23
|
-
# Example:
|
24
|
-
# >> matcher.matches?
|
25
|
-
# => true
|
26
|
-
#
|
27
|
-
def matches?
|
28
|
-
@actual < @expected
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module ArgumentSpecification
|
2
|
-
module Matchers
|
3
|
-
class BeLessThanOrEqualTo < BaseMatcher
|
4
|
-
matcher_name :be_less_than_or_equal_to
|
5
|
-
|
6
|
-
attr_reader :expected
|
7
|
-
|
8
|
-
# Create a new matcher instance
|
9
|
-
#
|
10
|
-
# Arguments:
|
11
|
-
# expected: (Object)
|
12
|
-
#
|
13
|
-
# Example:
|
14
|
-
# >> ArgumentSpecification::Matchers::BeLessThanOrEqualTo.new(10)
|
15
|
-
# => #<ArgumentSpecification::Matchers::BeLessThanOrEqualTo:0x00000000000000 @expected=10>
|
16
|
-
#
|
17
|
-
def initialize(expected)
|
18
|
-
@expected = expected
|
19
|
-
end
|
20
|
-
|
21
|
-
# Check if the actual object matches
|
22
|
-
#
|
23
|
-
# Example:
|
24
|
-
# >> matcher.matches?
|
25
|
-
# => true
|
26
|
-
#
|
27
|
-
def matches?
|
28
|
-
@actual <= @expected
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|