assert_type 0.0.5 → 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/README.md +72 -0
- data/lib/assert_type.rb +8 -27
- data/lib/assert_type/type_string_parser.rb +31 -0
- data/lib/assert_type/type_string_tokeniser.rb +3 -0
- data/lib/assert_type/version.rb +1 -1
- data/spec/assert_type_spec.rb +47 -25
- metadata +4 -3
data/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
assert_type
|
|
2
|
+
===========
|
|
3
|
+
|
|
4
|
+
Provides a simple method to make assertions about the type of a value,
|
|
5
|
+
including nested types.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
gem install assert_type
|
|
10
|
+
|
|
11
|
+
## Example
|
|
12
|
+
|
|
13
|
+
### Set-up
|
|
14
|
+
|
|
15
|
+
#### In development
|
|
16
|
+
|
|
17
|
+
Include the AssertType::AssertMethods module in Object,
|
|
18
|
+
which will make the assert_type method available anywhere.
|
|
19
|
+
|
|
20
|
+
It doesn't need to live in Object if you're not comfortable having it there.
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
require 'assert_type'
|
|
24
|
+
class Object
|
|
25
|
+
include AssertType::AssertMethods
|
|
26
|
+
end
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
#### In production
|
|
30
|
+
|
|
31
|
+
Include the AssertType::NoOpMethods module instead of AssertType::AssertMethods
|
|
32
|
+
to include an assert_type method with the same signature that does nothing.
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
require 'assert_type'
|
|
36
|
+
class Object
|
|
37
|
+
include AssertType::NoOpMethods
|
|
38
|
+
end
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Making assertions
|
|
42
|
+
|
|
43
|
+
The first argument is the type string. It's based on YARD types. The entire YARD type syntax is not supported.
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
assert_type "Array", [] # wont raise
|
|
47
|
+
assert_type "Array", {} # will raise AssertType::AssertionError
|
|
48
|
+
|
|
49
|
+
assert_type "Array<Fixnum>", [1,2,3] # wont raise
|
|
50
|
+
assert_type "Array<Fixnum>", [] # wont raise
|
|
51
|
+
assert_type "Array<Fixnum>", [1.1,2.2,3.3] # will raise AssertType::AssertionError
|
|
52
|
+
assert_type "Array<Fixnum>", nil # will raise AssertType::AssertionError
|
|
53
|
+
|
|
54
|
+
assert_type "Array<Fixnum>, nil", [1,2,3] # wont raise
|
|
55
|
+
assert_type "Array<Fixnum>, nil", nil # wont raise
|
|
56
|
+
|
|
57
|
+
assert_type "String, Symbol", "three" # wont raise
|
|
58
|
+
assert_type "String, Symbol", :three # wont raise
|
|
59
|
+
assert_type "String, Symbol", 3 # will raise AssertType::AssertionError
|
|
60
|
+
|
|
61
|
+
assert_type "Array<String, Symbol>", ["three"] # wont raise
|
|
62
|
+
assert_type "Array<String, Symbol>", [:three] # wont raise
|
|
63
|
+
assert_type "Array<String, Symbol>", [] # wont raise
|
|
64
|
+
assert_type "Array<String, Symbol>", [3] # will raise AssertType::AssertionError
|
|
65
|
+
|
|
66
|
+
assert_type "Array<Set<Numeric>>", [Set.new([1,2])] # wont raise
|
|
67
|
+
assert_type "Array<Set<Numeric>>", [Set.new] # wont raise
|
|
68
|
+
assert_type "Array<Set<Numeric>>", [] # wont raise
|
|
69
|
+
assert_type "Array<Set<Numeric>>", [Set.new(["1","2"])] # will raise AssertType::AssertionError
|
|
70
|
+
assert_type "Array<Set<Numeric>>", [[1,2]] # will raise AssertType::AssertionError
|
|
71
|
+
assert_type "Array<Set<Numeric>>", [3] # will raise AssertType::AssertionError
|
|
72
|
+
```
|
data/lib/assert_type.rb
CHANGED
|
@@ -9,29 +9,13 @@ require "assert_type/type_validator"
|
|
|
9
9
|
module AssertType
|
|
10
10
|
|
|
11
11
|
module AssertMethods
|
|
12
|
-
def at_assert truth
|
|
13
|
-
unless truth
|
|
14
|
-
raise AssertionError, "Expected truthy but was #{truth.inspect}"
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def at_assert_equal expected, actual
|
|
19
|
-
unless expected == actual
|
|
20
|
-
raise AssertionError.new expected, actual
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
12
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
unless expected_type.any? {|t| t === value}
|
|
31
|
-
types = expected_type.join(' or ')
|
|
32
|
-
raise TypeAssertionError.new types, value
|
|
33
|
-
end
|
|
34
|
-
elsif expected_type.is_a? String
|
|
13
|
+
# @param expected_type [String] type string like "Array<Fixnum>"
|
|
14
|
+
# @param value [Object] value to check against type string
|
|
15
|
+
# @return [void]
|
|
16
|
+
# @raise [AssertType::AssertionError, AssertType::ParseError, AssertType::CallError]
|
|
17
|
+
def assert_type expected_type, value
|
|
18
|
+
if expected_type.is_a? String
|
|
35
19
|
if node = AssertType::TypeStringParser.parse(expected_type)
|
|
36
20
|
unless AssertType::TypeValidator.valid?(node, value)
|
|
37
21
|
raise TypeAssertionError.new expected_type, value
|
|
@@ -43,17 +27,14 @@ module AssertType
|
|
|
43
27
|
raise CallError.new
|
|
44
28
|
end
|
|
45
29
|
end
|
|
30
|
+
|
|
46
31
|
end
|
|
47
32
|
|
|
48
33
|
module NoOpMethods
|
|
49
|
-
def at_assert *args
|
|
50
|
-
end
|
|
51
34
|
|
|
52
|
-
def
|
|
35
|
+
def assert_type *args
|
|
53
36
|
end
|
|
54
37
|
|
|
55
|
-
def at_assert_type *args
|
|
56
|
-
end
|
|
57
38
|
end
|
|
58
39
|
|
|
59
40
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require File.expand_path('./type_string_tokeniser.rb', File.dirname(__FILE__))
|
|
2
2
|
require File.expand_path('./type_node.rb', File.dirname(__FILE__))
|
|
3
|
+
require File.expand_path('./parse_error.rb', File.dirname(__FILE__))
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
module AssertType
|
|
5
7
|
class TypeStringParser
|
|
@@ -14,6 +16,7 @@ module AssertType
|
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def parse
|
|
19
|
+
quick_check_tokens
|
|
17
20
|
root = TypeNode.root
|
|
18
21
|
previous_word = root
|
|
19
22
|
current_words = [root]
|
|
@@ -36,5 +39,33 @@ module AssertType
|
|
|
36
39
|
@tokens ||= TypeStringTokeniser.tokenise @type_string
|
|
37
40
|
end
|
|
38
41
|
|
|
42
|
+
def quick_check_tokens
|
|
43
|
+
unless check_angle_brackets_matched && check_angle_brackets_enclose_type
|
|
44
|
+
raise ParseError.new
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def check_angle_brackets_matched
|
|
49
|
+
open_angle_brackets = 0
|
|
50
|
+
tokens.each do |token|
|
|
51
|
+
if token.name == :open_angle
|
|
52
|
+
open_angle_brackets += 1
|
|
53
|
+
elsif token.name == :close_angle
|
|
54
|
+
open_angle_brackets -= 1
|
|
55
|
+
end
|
|
56
|
+
return false if open_angle_brackets < 0
|
|
57
|
+
end
|
|
58
|
+
open_angle_brackets == 0
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def check_angle_brackets_enclose_type
|
|
62
|
+
previous_name = nil
|
|
63
|
+
tokens.each do |token|
|
|
64
|
+
return false if previous_name == :open_angle && token.name != :word
|
|
65
|
+
previous_name = token.name
|
|
66
|
+
end
|
|
67
|
+
true
|
|
68
|
+
end
|
|
69
|
+
|
|
39
70
|
end
|
|
40
71
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require File.expand_path('./parse_error.rb', File.dirname(__FILE__))
|
|
2
|
+
|
|
1
3
|
module AssertType
|
|
2
4
|
class TypeStringTokeniser
|
|
3
5
|
|
|
@@ -15,6 +17,7 @@ module AssertType
|
|
|
15
17
|
while (t = next_token) do
|
|
16
18
|
tokens << t
|
|
17
19
|
end
|
|
20
|
+
raise ParseError.new unless @type_string.strip == ""
|
|
18
21
|
tokens
|
|
19
22
|
end
|
|
20
23
|
|
data/lib/assert_type/version.rb
CHANGED
data/spec/assert_type_spec.rb
CHANGED
|
@@ -4,32 +4,54 @@ include AssertType::AssertMethods
|
|
|
4
4
|
|
|
5
5
|
describe AssertType do
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
at_assert_type [Fixnum, String], "1"
|
|
19
|
-
expect { at_assert_type [Fixnum, String], 1.1 }.to raise_error(AssertType::AssertionError) { |error|
|
|
20
|
-
error.message.should include %{expected Fixnum or String but was 1.1}
|
|
21
|
-
}
|
|
22
|
-
at_assert_type "Array<Fixnum>, nil", [1,2,3]
|
|
23
|
-
at_assert_type "Array<Fixnum>, nil", []
|
|
24
|
-
at_assert_type "Array<Fixnum>, nil", nil
|
|
25
|
-
at_assert_type "String, Symbol", "hello"
|
|
26
|
-
expect { at_assert_type "Array<Fixnum>, nil", false }.to raise_error(AssertType::AssertionError)
|
|
27
|
-
expect { at_assert_type "Array<Fixnum>, nil", [nil] }.to raise_error(AssertType::AssertionError)
|
|
28
|
-
|
|
29
|
-
at_assert_type "String, Symbol", "hello"
|
|
30
|
-
at_assert_type "String, Symbol", :Symbol
|
|
31
|
-
expect { at_assert_type "String, Symbol", 42 }.to raise_error(AssertType::AssertionError)
|
|
7
|
+
def self.example_valid expected_type, value
|
|
8
|
+
it "should not raise when asserting #{value.inspect} is a #{expected_type}" do
|
|
9
|
+
assert_type expected_type, value
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.example_invalid expected_type, value
|
|
14
|
+
it "should raise assertion error when asserting #{value.inspect} is a #{expected_type}" do
|
|
15
|
+
expect { assert_type expected_type, value }.to raise_error(AssertType::AssertionError)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
32
18
|
|
|
19
|
+
def self.example_call_error expected_type, value
|
|
20
|
+
it "should raise call error when asserting #{value.inspect} is a #{expected_type}" do
|
|
21
|
+
expect { assert_type expected_type, value }.to raise_error(AssertType::CallError)
|
|
22
|
+
end
|
|
33
23
|
end
|
|
34
24
|
|
|
25
|
+
def self.example_parse_error expected_type, value
|
|
26
|
+
it "should raise parse error when asserting #{value.inspect} is a #{expected_type}" do
|
|
27
|
+
expect { assert_type expected_type, value }.to raise_error(AssertType::ParseError)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
example_valid "Array", []
|
|
32
|
+
example_valid "Array", [1,2,3]
|
|
33
|
+
|
|
34
|
+
example_valid "Array<Fixnum>", [1,2,3]
|
|
35
|
+
example_valid "Array<Fixnum>", []
|
|
36
|
+
example_invalid "Array<Fixnum>", ["one", "two", "three"]
|
|
37
|
+
|
|
38
|
+
example_valid "Array<Fixnum>, nil", [1,2,3]
|
|
39
|
+
example_valid "Array<Fixnum>, nil", []
|
|
40
|
+
example_valid "Array<Fixnum>, nil", nil
|
|
41
|
+
example_invalid "Array<Fixnum>, nil", false
|
|
42
|
+
example_invalid "Array<Fixnum>, nil", [nil]
|
|
43
|
+
|
|
44
|
+
example_valid "String, Symbol", "hello"
|
|
45
|
+
example_valid "String, Symbol", :Symbol
|
|
46
|
+
example_invalid "String, Symbol", 42
|
|
47
|
+
|
|
48
|
+
example_call_error Array, []
|
|
49
|
+
example_call_error [Fixnum, String], 1
|
|
50
|
+
example_call_error [1,2,3], "Array<Fixnum>"
|
|
51
|
+
|
|
52
|
+
example_parse_error "Array<", []
|
|
53
|
+
example_parse_error "Array<>", []
|
|
54
|
+
example_parse_error "Array>", []
|
|
55
|
+
example_parse_error "A{B => C}", []
|
|
56
|
+
|
|
35
57
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: assert_type
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 27
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
|
+
- 1
|
|
8
9
|
- 0
|
|
9
|
-
|
|
10
|
-
version: 0.0.5
|
|
10
|
+
version: 0.1.0
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Joel Plane
|
|
@@ -30,6 +30,7 @@ extra_rdoc_files: []
|
|
|
30
30
|
files:
|
|
31
31
|
- .gitignore
|
|
32
32
|
- Gemfile
|
|
33
|
+
- README.md
|
|
33
34
|
- Rakefile
|
|
34
35
|
- assert_type.gemspec
|
|
35
36
|
- lib/assert_type.rb
|