specify 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dbce3e763bb587ca4e22697758df1193f0c5390b
4
- data.tar.gz: bacc2a768947097371695d3cd5f7917ddb80fe2c
3
+ metadata.gz: 2176feee363e08774e5723e4eb96372ca4b7810b
4
+ data.tar.gz: b8461df286c06c232b85621f8a3b7f65d83efdc7
5
5
  SHA512:
6
- metadata.gz: 519d2f32a0c395e75ab89c7b0afa047c568e144abd664d2bb995890236eca9c99a2fe40e6907f46a208239d48b88bb87adcc6302e21fd36bf09630da9096c971
7
- data.tar.gz: a3de2b83e891d4c9a89f4d7e6082bf5097ec48be037b332a8463ead16238bdba3fb154585cf380bb384e67e7f780c98d5ed01de8ba3551ed866e5a8d51bab38f
6
+ metadata.gz: d78f06c2164d721397075a8f903c857ae83afdbe73d36891406ea1704abdb93053a8105ada7c9d3e8f0a287fea8e3e33bfbe7720cc4e04cbec5a2bcdd023a6a0
7
+ data.tar.gz: f0c3a121504a3708fabc43ba124598bea8a7995c8328c3b4ece93acf4b87d8425dd1c4fd01adebf1b423e53476ea1c049fff180f5718d28d57e14ffd2896154b
data/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  [![endorse](https://api.coderwall.com/jnyman/endorsecount.png)](https://coderwall.com/jnyman)
12
12
 
13
13
  > _"Simplicity is the ultimate sophistication."_
14
- > -- <cite>Leonardo DaVinci</cite>
14
+ > -- <cite>Leonardo da Vinci</cite>
15
15
 
16
16
  Specify is a test solution development tool that acts as a BDD-style micro-framework.
17
17
 
@@ -72,3 +72,14 @@ To work on Specify:
72
72
  ## License
73
73
 
74
74
  Specify is distributed under the [MIT](http://www.opensource.org/licenses/MIT) license.
75
+
76
+ ## Credits
77
+
78
+ Specify has been inspired by the following projects:
79
+
80
+ * [maniok_bdd](https://github.com/21croissants/maniok_bdd)
81
+ * [rspec-gherkin](https://github.com/sheerun/rspec-gherkin)
82
+ * [rspec example steps](https://github.com/railsware/rspec-example_steps)
83
+ * [XSpec](https://github.com/xaviershay/xspec)
84
+
85
+ The parameterized and table logic is pulled directly from [RSpec::Parameterized](https://github.com/tomykaira/rspec-parameterized) with just a few cosmetic changes.
@@ -0,0 +1,138 @@
1
+ require 'parser'
2
+ require 'unparser'
3
+ require 'proc_to_ast'
4
+
5
+ module RSpec
6
+ module Specify
7
+ module Parameterized
8
+ autoload :Tabular, 'specify/rspec/tabular'
9
+
10
+ module ExampleGroupMethods
11
+ class Parameter
12
+ attr_reader :arg_names, :table_format, :block
13
+
14
+ def initialize(arg_names, table_format, &block)
15
+ @arg_names, @table_format, @block = arg_names, table_format, block
16
+ end
17
+ end
18
+
19
+ def data_condition(*args, &block)
20
+ set_parameters(args, false, &block)
21
+ end
22
+
23
+ def data_table(*args, &block)
24
+ set_parameters(args, true, &block)
25
+ end
26
+
27
+ def test_condition(*args, &block)
28
+ if @parameter.nil?
29
+ @parameterized_pending_cases ||= []
30
+ @parameterized_pending_cases << [args, block]
31
+ else
32
+ define_cases(@parameter, *args, &block)
33
+ end
34
+ end
35
+
36
+ alias_method :where, :data_condition
37
+ alias_method :where_table, :data_table
38
+ alias_method :with_those, :test_condition
39
+
40
+ private
41
+
42
+ def set_parameters(arg_names, table_format, &block)
43
+ @parameter = Parameter.new(arg_names, table_format, &block)
44
+
45
+ if @parameterized_pending_cases
46
+ @parameterized_pending_cases.each { |e|
47
+ define_cases(@parameter, *e[0], &e[1])
48
+ }
49
+ end
50
+ end
51
+
52
+ def separate_table_like_block(b)
53
+ ast = b.to_ast
54
+ inner_ast = ast.children[2]
55
+ if inner_ast.type == :send
56
+ lines = [inner_ast]
57
+ else
58
+ lines = inner_ast.children
59
+ end
60
+
61
+ lines.map do |node|
62
+ if node.type == :send
63
+ buf = []
64
+ extract_value(node, buf)
65
+ buf.reverse
66
+ end
67
+ end
68
+ end
69
+
70
+ def extract_value(node, buf)
71
+ receiver, method, arg = node.children
72
+
73
+ if method == :|
74
+ buf << eval_source_fragment(Unparser.unparse(arg))
75
+ end
76
+
77
+ if receiver.is_a?(AST::Node) && receiver.type == :send && receiver.children[1] == :|
78
+ extract_value(receiver, buf)
79
+ else
80
+ buf << eval_source_fragment(Unparser.unparse(receiver))
81
+ end
82
+ end
83
+
84
+ def eval_source_fragment(source_fragment)
85
+ instance = new # for evaluate let methods.
86
+ if defined?(self.superclass::LetDefinitions)
87
+ instance.extend self.superclass::LetDefinitions
88
+ end
89
+ instance.instance_eval(source_fragment)
90
+ end
91
+
92
+ def define_cases(parameter, *args, &block)
93
+ instance = new # for evaluate let methods
94
+ if defined?(self.superclass::LetDefinitions)
95
+ instance.extend self.superclass::LetDefinitions
96
+ end
97
+
98
+ if parameter.table_format
99
+ param_sets = separate_table_like_block(parameter.block)
100
+ else
101
+ extracted = instance.instance_eval(&parameter.block)
102
+ param_sets = extracted.is_a?(Array) ? extracted : extracted.to_params
103
+ end
104
+
105
+ # for only one parameter
106
+ param_sets = param_sets.map { |x| Array[x] } if !param_sets[0].is_a?(Array)
107
+
108
+ param_sets.each do |params|
109
+ pairs = [parameter.arg_names, params].transpose
110
+ pretty_params = pairs.map {|t| "#{t[0]}: #{params_inspect(t[1])}"}.join(', ')
111
+ describe(pretty_params, *args) do
112
+ pairs.each do |n|
113
+ let(n[0]) { n[1] }
114
+ end
115
+
116
+ module_eval(&block)
117
+ end
118
+ end
119
+ end
120
+
121
+ def params_inspect(obj)
122
+ begin
123
+ obj.is_a?(Proc) ? obj.to_raw_source : obj.inspect
124
+ #rescue Parser::SyntaxError
125
+ # return obj.inspect
126
+ end
127
+ end
128
+
129
+ end
130
+ end
131
+ end
132
+
133
+ module Core
134
+ class ExampleGroup
135
+ extend ::RSpec::Specify::Parameterized::ExampleGroupMethods
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,54 @@
1
+ module RSpec
2
+ module Specify
3
+ module Parameterized
4
+ class Table
5
+ attr_reader :last_row
6
+
7
+ def initialize
8
+ @rows = []
9
+ @last_row = nil
10
+ end
11
+
12
+ def add_row(row)
13
+ unless @rows.find {|r| r.object_id == row.object_id}
14
+ @rows << row
15
+ @last_row = row
16
+ end
17
+ self
18
+ end
19
+
20
+ def add_param_to_last_row(param)
21
+ last_row.add_param(param)
22
+ self
23
+ end
24
+
25
+ alias :| :add_param_to_last_row
26
+
27
+ def to_a
28
+ @rows.map(&:to_a)
29
+ end
30
+
31
+ alias :to_params :to_a
32
+
33
+ class Row
34
+ def initialize(param)
35
+ @params = [param]
36
+ end
37
+
38
+ def add_param(param)
39
+ @params << param
40
+ end
41
+
42
+ def to_a
43
+ @params
44
+ end
45
+
46
+ #def to_params
47
+ # [@params]
48
+ #end
49
+ end
50
+
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ require 'binding_of_caller'
2
+ require 'specify/rspec/table'
3
+
4
+ module RSpec
5
+ module Specify
6
+ module Parameterized
7
+ module TabularSyntax
8
+ def |(other)
9
+ where_binding = binding.of_caller(1) # get where block binding
10
+ caller_instance = eval('self', where_binding) # get caller instance (ExampleGroup)
11
+
12
+ if caller_instance.instance_variable_defined?(:@__parameter_table)
13
+ table = caller_instance.instance_variable_get(:@__parameter_table)
14
+ else
15
+ table = RSpec::Specify::Parameterized::Table.new
16
+ caller_instance.instance_variable_set(:@__parameter_table, table)
17
+ end
18
+
19
+ row = Table::Row.new(self)
20
+ table.add_row(row)
21
+ row.add_param(other)
22
+ table
23
+ end
24
+ end
25
+
26
+ module Tabular
27
+ refine Object do
28
+ include TabularSyntax
29
+ end
30
+
31
+ refine Fixnum do
32
+ include TabularSyntax
33
+ end
34
+
35
+ refine Bignum do
36
+ include TabularSyntax
37
+ end
38
+
39
+ refine Array do
40
+ include TabularSyntax
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  module Specify
2
- VERSION = '0.9.0'
2
+ VERSION = '0.10.0'
3
3
  end
data/lib/specify.rb CHANGED
@@ -12,6 +12,7 @@ require 'specify/rspec/world'
12
12
  require 'specify/rspec/reporter'
13
13
  require 'specify/rspec/notification'
14
14
  require 'specify/rspec/example_group'
15
+ require 'specify/rspec/parameterized'
15
16
  require 'specify/rspec/documentation_formatter'
16
17
 
17
18
  RSpec::Core::ExampleGroup.send :include, RSpec::Specify::ExampleGroup
@@ -0,0 +1,229 @@
1
+ require 'spec_helper'
2
+
3
+ describe RSpec::Specify::Parameterized do
4
+ describe 'data_condition' do
5
+ data_condition(:a, :b, :answer) do
6
+ [
7
+ [1, 2, 3],
8
+ [5, 8, 13],
9
+ [0, 0, 0]
10
+ ]
11
+ end
12
+
13
+ test_condition do
14
+ it 'will perform additions' do
15
+ expect(a + b).to eq answer
16
+ end
17
+ end
18
+ end
19
+
20
+ describe 'lambda parameter' do
21
+ data_condition(:a, :b, :answer) do
22
+ [
23
+ [1 , 2 , -> {should == 3}],
24
+ [5 , 8 , -> {should == 13}],
25
+ [0 , 0 , -> {should == 0}]
26
+ ]
27
+ end
28
+
29
+ test_condition do
30
+ subject {a + b}
31
+ it 'will perform additions' do
32
+ self.instance_exec(&answer)
33
+ end
34
+ end
35
+ end
36
+
37
+ describe 'table separated with pipe' do
38
+ data_table(:a, :b, :answer) do
39
+ 1 | 2 | 3
40
+ 'hello ' | 'world' | 'hello world'
41
+ [1, 2, 3] | [4, 5, 6] | [1, 2, 3, 4, 5, 6]
42
+ end
43
+
44
+ test_condition do
45
+ it 'will calculate that a plus b is answer' do
46
+ expect(a + b).to eq answer
47
+ end
48
+ end
49
+ end
50
+
51
+ describe 'table separated with pipe (using Tabular syntax)' do
52
+ using RSpec::Specify::Parameterized::Tabular
53
+
54
+ data_condition(:a, :b, :answer) do
55
+ 1 | 2 | 3
56
+ 'hello ' | 'world' | 'hello world'
57
+ [1, 2, 3] | [4, 5, 6] | [1, 2, 3, 4, 5, 6]
58
+ end
59
+
60
+ test_condition do
61
+ it 'will calculate that a plus b is answer' do
62
+ expect(a + b).to eq answer
63
+ end
64
+ end
65
+ end
66
+
67
+ describe 'table separated with pipe and lambda parameter (using Tabular syntax)' do
68
+ using RSpec::Specify::Parameterized::Tabular
69
+
70
+ data_condition(:a, :b, :matcher) do
71
+ 1 | 2 | -> { eq(3) }
72
+ 'hello ' | 'world' | -> { eq('hello world') }
73
+ [1, 2, 3] | [4, 5, 6] | -> { be_a(Array) }
74
+ end
75
+
76
+ test_condition do
77
+ it 'will calculate that a plus b is answer' do
78
+ expect(a + b).to instance_exec(&matcher)
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'when the data_condition block is after test_condition' do
84
+ test_condition do
85
+ it 'will perform additions' do
86
+ expect(a + b).to eq answer
87
+ end
88
+ end
89
+
90
+ test_condition do
91
+ subject { a }
92
+ it { should be_a Numeric }
93
+ end
94
+
95
+ data_condition(:a, :b, :answer) do
96
+ [
97
+ [1 , 2 , 3],
98
+ [5 , 8 , 13],
99
+ [0 , 0 , 0]
100
+ ]
101
+ end
102
+ end
103
+
104
+ context 'when the data_condition block is between test_condition blocks' do
105
+ test_condition do
106
+ it 'should perform additions' do
107
+ expect(a + b).to eq answer
108
+ end
109
+ end
110
+
111
+ data_condition(:a, :b, :answer) do
112
+ [
113
+ [1 , 2 , 3],
114
+ [5 , 8 , 13],
115
+ [0 , 0 , 0]
116
+ ]
117
+ end
118
+
119
+ test_condition do
120
+ subject { a }
121
+ it { should be_a Numeric }
122
+ end
123
+ end
124
+
125
+ context 'when the data_condition has only one parameter to be set' do
126
+ data_condition(:x) do
127
+ [1, 2, 3]
128
+ end
129
+
130
+ test_condition do
131
+ it 'can take an array of elements' do
132
+ expect(x).to eq x
133
+ end
134
+ end
135
+ end
136
+
137
+ context 'when the table has only a row' do
138
+ data_table(:a, :b, :answer) do
139
+ 1 | 2 | 3
140
+ end
141
+
142
+ test_condition do
143
+ it 'will calculate that a plus b is answer' do
144
+ expect(a + b).to eq answer
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'when the table has only a row (using Tabular format)' do
150
+ using RSpec::Specify::Parameterized::Tabular
151
+
152
+ data_condition(:a, :b, :answer) do
153
+ 1 | 2 | 3
154
+ end
155
+
156
+ test_condition do
157
+ it 'will calculate that a plus b is answer' do
158
+ expect(a + b).to eq answer
159
+ end
160
+ end
161
+ end
162
+
163
+ context 'when the data_condition has let variables, defined by parent example group' do
164
+ describe 'parent (define let)' do
165
+ let(:five) { 5 }
166
+ let(:eight) { 8 }
167
+
168
+ describe 'child 1' do
169
+ data_condition(:a, :b, :answer) do
170
+ [
171
+ [1 , 2 , 3],
172
+ [five , eight , 13],
173
+ ]
174
+ end
175
+
176
+ test_condition do
177
+ it 'will calculate that a plus b is answer' do
178
+ expect(a + b).to eq answer
179
+ end
180
+ end
181
+ end
182
+
183
+ describe 'child 2 (data_table)' do
184
+ data_table(:a, :b, :answer) do
185
+ 1 | 2 | 3
186
+ five | eight | 13
187
+ end
188
+
189
+ test_condition do
190
+ it 'will calculate that a plus b is answer' do
191
+ expect(a + b).to eq answer
192
+ end
193
+ end
194
+ end
195
+
196
+ describe 'child 3 (Using Tabular)' do
197
+ using RSpec::Specify::Parameterized::Tabular
198
+
199
+ data_condition(:a, :b, :answer) do
200
+ 1 | 2 | 3
201
+ five | eight | 13
202
+ end
203
+
204
+ test_condition do
205
+ it 'will calculate that a plus b is answer' do
206
+ expect(a + b).to eq answer
207
+ end
208
+ end
209
+ end
210
+
211
+ let(:eq_matcher) { eq(13) }
212
+ describe 'child 3 (use matcher)' do
213
+ data_condition(:a, :b, :matcher) do
214
+ [
215
+ [1 , 2 , eq(3) ],
216
+ [five , eight , eq_matcher],
217
+ ]
218
+ end
219
+
220
+ test_condition do
221
+ it 'will calculate that a plus b is answer' do
222
+ expect(a + b).to matcher
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
228
+
229
+ end
data/specify.gemspec CHANGED
@@ -31,6 +31,10 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency 'rspec', '~> 3.1'
32
32
 
33
33
  spec.add_runtime_dependency 'rspec-core', '~> 3.1'
34
+ spec.add_runtime_dependency 'parser'
35
+ spec.add_runtime_dependency 'unparser'
36
+ spec.add_runtime_dependency 'proc_to_ast'
37
+ spec.add_runtime_dependency 'binding_of_caller'
34
38
 
35
39
  spec.post_install_message = %{
36
40
  (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: specify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Nyman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-07 00:00:00.000000000 Z
11
+ date: 2014-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,62 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: parser
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: unparser
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: proc_to_ast
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: binding_of_caller
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
69
125
  description: "\n Specify is a test framework that is designed to treat testing
70
126
  as a\n design activity by allowing requirements to be defined as tests.\n Those
71
127
  tests can then be executed via an automation layer. This is\n the basis of creating
@@ -85,12 +141,16 @@ files:
85
141
  - lib/specify/rspec/documentation_formatter.rb
86
142
  - lib/specify/rspec/example_group.rb
87
143
  - lib/specify/rspec/notification.rb
144
+ - lib/specify/rspec/parameterized.rb
88
145
  - lib/specify/rspec/reporter.rb
89
146
  - lib/specify/rspec/shared_steps.rb
147
+ - lib/specify/rspec/table.rb
148
+ - lib/specify/rspec/tabular.rb
90
149
  - lib/specify/rspec/world.rb
91
150
  - lib/specify/spec.rb
92
151
  - lib/specify/version.rb
93
152
  - spec/api_spec.rb
153
+ - spec/parameterized_spec.rb
94
154
  - spec/pending_spec.rb
95
155
  - spec/shared_steps_spec.rb
96
156
  - spec/spec_helper.rb
@@ -102,8 +162,8 @@ licenses:
102
162
  - MIT
103
163
  metadata: {}
104
164
  post_install_message: "\n(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)\n\n
105
- \ Specify 0.9.0 has been installed.\n\n(::) (::) (::) (::) (::) (::) (::) (::) (::)
106
- (::) (::) (::)\n "
165
+ \ Specify 0.10.0 has been installed.\n\n(::) (::) (::) (::) (::) (::) (::) (::)
166
+ (::) (::) (::) (::)\n "
107
167
  rdoc_options: []
108
168
  require_paths:
109
169
  - lib
@@ -125,6 +185,7 @@ specification_version: 4
125
185
  summary: Description Language Specification and Execution Engine
126
186
  test_files:
127
187
  - spec/api_spec.rb
188
+ - spec/parameterized_spec.rb
128
189
  - spec/pending_spec.rb
129
190
  - spec/shared_steps_spec.rb
130
191
  - spec/spec_helper.rb