tspec 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +14 -12
- data/lib/tspec.rb +35 -12
- data/tspec.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a07e9bb4da483559eef421219cb624def8ede4cd
|
4
|
+
data.tar.gz: 1fe473785a30b27f1160b9108f264817ea259167
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 838d9f1c2b18277fcb2a54c41bdb8b9894f8d312775a5a9900307a6e35ab8dee293e805dc7204bb79737c43e58942e8f49347c8f958744a025efd26c2a95b0fb
|
7
|
+
data.tar.gz: cea0a7a54424d0b0401b8bce18b24d071516db57b15185132b4d0ffd5c5bb7ee2dbdc26f3b0766b220603bea9729e7c723b9a724555cf1c5dc064cce40a8e084
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# TSpec
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/siman-man/tspec)
|
4
|
+
|
5
|
+
TSpec adds a method of simple type check to Ruby.
|
4
6
|
|
5
7
|
:construction: **Recommended for use only in hobby programming. Do not use this in production apps.** :construction:
|
6
8
|
|
@@ -16,18 +18,18 @@ And then execute:
|
|
16
18
|
|
17
19
|
$ bundle
|
18
20
|
|
19
|
-
Or install it yourself
|
21
|
+
Or install it by yourself:
|
20
22
|
|
21
23
|
$ gem install tspec
|
22
24
|
|
23
25
|
## Usage
|
24
26
|
|
25
|
-
|
27
|
+
TSpec can use `#receive` and `#return` method.
|
26
28
|
|
27
29
|
|
28
30
|
### receive
|
29
31
|
|
30
|
-
`receive`
|
32
|
+
`receive` defines the type of method arguments.
|
31
33
|
|
32
34
|
```ruby
|
33
35
|
require 'tspec'
|
@@ -37,7 +39,7 @@ def echo(str)
|
|
37
39
|
end.receive(str: String)
|
38
40
|
```
|
39
41
|
|
40
|
-
specify multiple type.
|
42
|
+
You can specify multiple type, too.
|
41
43
|
|
42
44
|
```ruby
|
43
45
|
require 'tspec'
|
@@ -50,7 +52,7 @@ echo('hello')
|
|
50
52
|
echo(3.14)
|
51
53
|
```
|
52
54
|
|
53
|
-
|
55
|
+
If single method argument is given, you can skip keyword.
|
54
56
|
|
55
57
|
```ruby
|
56
58
|
require 'tspec'
|
@@ -62,7 +64,7 @@ end.receive([String])
|
|
62
64
|
puts join_array(%w(hello world))
|
63
65
|
```
|
64
66
|
|
65
|
-
|
67
|
+
You can specify Array content type, although it may seem strange.
|
66
68
|
|
67
69
|
```ruby
|
68
70
|
require 'tspec'
|
@@ -77,7 +79,7 @@ puts receive_string_array(['hello', 'world'])
|
|
77
79
|
|
78
80
|
### return
|
79
81
|
|
80
|
-
`return`
|
82
|
+
`return` defines the type of method return value.
|
81
83
|
|
82
84
|
```ruby
|
83
85
|
require 'tspec'
|
@@ -87,7 +89,7 @@ def message
|
|
87
89
|
end.return(String)
|
88
90
|
```
|
89
91
|
|
90
|
-
multiple return value.
|
92
|
+
You can specify multiple return value, too.
|
91
93
|
|
92
94
|
```ruby
|
93
95
|
require 'tspec'
|
@@ -101,7 +103,7 @@ end.return(Float, String, Symbol)
|
|
101
103
|
end
|
102
104
|
```
|
103
105
|
|
104
|
-
specify Array content type.
|
106
|
+
Also, you can specify Array content type.
|
105
107
|
|
106
108
|
```ruby
|
107
109
|
require 'tspec'
|
@@ -115,7 +117,7 @@ p message_list
|
|
115
117
|
|
116
118
|
## Example
|
117
119
|
|
118
|
-
|
120
|
+
Combination of `receive` and `return` method.
|
119
121
|
|
120
122
|
```ruby
|
121
123
|
require 'tspec'
|
@@ -135,5 +137,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/siman-
|
|
135
137
|
|
136
138
|
## License
|
137
139
|
|
138
|
-
The gem is available
|
140
|
+
The gem is available under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
139
141
|
|
data/lib/tspec.rb
CHANGED
@@ -19,11 +19,32 @@ class Symbol
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
class UnboundMethod
|
23
|
+
def return(*types)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def receive(*type, **types)
|
28
|
+
self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Method
|
33
|
+
def return(*types)
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def receive(*type, **types)
|
38
|
+
self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
22
42
|
module TSpec
|
23
43
|
@method_return_type_table = {}
|
24
44
|
@method_arguments_type_table = {}
|
25
45
|
@before_trace = {}
|
26
46
|
@type_error_flag = false
|
47
|
+
DEFINE_METHOD_SYMBOLS = %i(method_added singleton_method_added define_method instance_method method)
|
27
48
|
|
28
49
|
def self.value_type_check(value, *types)
|
29
50
|
types.any? do |type|
|
@@ -44,10 +65,15 @@ module TSpec
|
|
44
65
|
TracePoint.trace do |tp|
|
45
66
|
case tp.event
|
46
67
|
when :call
|
47
|
-
if %i(return receive).include?(tp.method_id) &&
|
48
|
-
klass = (@before_trace[:method_id] == :singleton_method_added) ? @before_trace[:self].singleton_class : @before_trace[:self]
|
68
|
+
if %i(return receive).include?(tp.method_id) && DEFINE_METHOD_SYMBOLS.include?(@before_trace[:method_id])
|
49
69
|
ctx = tp.binding
|
50
|
-
|
70
|
+
|
71
|
+
if %i(instance_method method).include?(@before_trace[:method_id])
|
72
|
+
key = "#{tp.self.owner}::#{tp.self.name}"
|
73
|
+
else
|
74
|
+
klass = (@before_trace[:method_id] == :singleton_method_added) ? @before_trace[:self].singleton_class : @before_trace[:self]
|
75
|
+
key = "#{klass}::#{ctx.receiver}"
|
76
|
+
end
|
51
77
|
|
52
78
|
case tp.method_id
|
53
79
|
when :return
|
@@ -66,18 +92,15 @@ module TSpec
|
|
66
92
|
arguments = tp.binding.eval("method(:#{tp.method_id}).parameters.map(&:last)")
|
67
93
|
|
68
94
|
types.each do |name, type|
|
95
|
+
name = arguments.first if name == type.__id__
|
69
96
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
raise NotFoundArgumentNameError, "undefined arguments `#{name}' for #{key}"
|
74
|
-
end
|
75
|
-
|
76
|
-
value = tp.binding.local_variable_get(name)
|
77
|
-
else
|
78
|
-
value = tp.binding.local_variable_get(arguments.first)
|
97
|
+
unless arguments.include?(name)
|
98
|
+
@type_error_flag = true
|
99
|
+
raise NotFoundArgumentNameError, "undefined arguments `#{name}' for #{key}"
|
79
100
|
end
|
80
101
|
|
102
|
+
value = tp.binding.local_variable_get(name)
|
103
|
+
|
81
104
|
unless value_type_check(value, *type)
|
82
105
|
@type_error_flag = true
|
83
106
|
raise ArgumentTypeError, "##{tp.method_id} '#{name}' variable should be #{type.inspect}, but actual '#{value.inspect}' - #{value.class}"
|
data/tspec.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- siman-man
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|