data_spec 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41b97a4b8d4e7d9ba659c756dd00132cb8fc8865
4
- data.tar.gz: 6991ac05e24b5c297ebabfb3d8795669b6681f6a
3
+ metadata.gz: 38a6a7c19a43116b793ccc2565beba91ec40ad58
4
+ data.tar.gz: 78178e54b3ad7afc932a487ca8ce453104e95a52
5
5
  SHA512:
6
- metadata.gz: 4428020420b3c23d340b4893a6bc6882014bf78c860cac3b5540099ec333bf195518c9cfa230cb624ffcc419258ba809129687d190b9cd8b7cc9547f379f38d6
7
- data.tar.gz: 7d963c06e3a45144c6b5e05d540ea80a277b90de236cc05170f932b210d4180f0cf7fd6ebe9f09476d5c3077a8c8c9b9819cc4752a6c333e80e199d13e6f9abb
6
+ metadata.gz: ebd55fded46197f459fd651d339bcef2798f36681a8a0c5d27e96087f13dd92c3cd61d3788fdb90f840cabe2e24337409f40449921b87d503b8718bb0b915fc2
7
+ data.tar.gz: 23239a0654bdd2c85c817fcb00ff8b810a63c5f4d0eb77bf39fedd0b0d6495357858128c443416c15bff0bed87e67e6b50bdcd5a130f5900d52ed9b71298f449
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ bundler_args: --without development
3
+ rvm:
4
+ - 2.0.0
data/Gemfile CHANGED
@@ -4,4 +4,11 @@ ruby '2.0.0'
4
4
  # Specify your gem's dependencies in data_spec.gemspec
5
5
  gemspec
6
6
 
7
- gem 'debugger'
7
+ group :test do
8
+ gem 'rake'
9
+ end
10
+
11
+ group :development do
12
+ gem 'debugger'
13
+ gem 'bundler'
14
+ end
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  data_spec
2
2
  ========
3
3
 
4
+ [![Build Status](https://secure.travis-ci.org/narfanator/data_spec.png)](http://travis-ci.org/narfanator/data_spec) [![Dependency Status](https://gemnasium.com/narfanator/data_spec.png)](https://gemnasium.com/narfanator/data_spec) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/narfanator/data_spec)
5
+
4
6
  Easily compare hashes and arrays in RSpec and Cucumber
5
7
 
6
8
  Originally inspired by collectiveidea's json_spec gem
@@ -9,29 +11,29 @@ Installation
9
11
  ------------
10
12
 
11
13
  gem 'data_spec'
12
- {cucumber}
13
- {rspec}
14
14
 
15
- Cucumber
16
- ------------
15
+ # Cucumber
17
16
 
18
- # Setup:
17
+ Setup:
18
+ ------------
19
19
 
20
- Include `data_spec/cucumber` and define `data` in your Cucumber environment:
20
+ Include `data_spec` and define `data` in your Cucumber environment:
21
21
  ```ruby
22
22
  # features/support/env.rb
23
- require "data_spec/cucumber"
23
+ require "data_spec"
24
24
 
25
25
  def data
26
26
  #...
27
27
  end
28
28
  ```
29
29
 
30
- # Usage:
30
+ Usage:
31
+ ------------
32
+ **The step `Given the data is:` is not supplied by this gem**
31
33
 
32
34
  Use either YAML or JSON:
33
35
  ````ruby
34
- Given the data is: # You define this one
36
+ Given the data is:
35
37
  """
36
38
  chunky: bacon
37
39
  """
@@ -75,7 +77,7 @@ Then the data includes:
75
77
  - 1
76
78
  - 2
77
79
  """
78
- And the data at "even" includes "'in a': hash"
80
+ And the data at "3/even" includes "'in a': hash"
79
81
  ```
80
82
 
81
83
  Check types:
@@ -86,9 +88,9 @@ Given the data is:
86
88
  - 1
87
89
  - 2013-07-06 20:09:32.824102000 -07:00
88
90
  """
89
- Then the data at "0" is of type String
90
- Then the data at "1" is of type Fixnum
91
- Then the data at "2" is of type Time
91
+ Then the data at "0" should be of type String
92
+ Then the data at "1" should be of type Fixnum
93
+ Then the data at "2" should be of type Time
92
94
  ```
93
95
 
94
96
  Use embedded code:
@@ -97,80 +99,158 @@ Given the data is:
97
99
  """
98
100
  - `1+1`
99
101
  - '$1e2$'
100
- - `"bacon".class`
102
+ - `'bacon'.class`
101
103
  """
102
104
  Then the data at "0" should be 2
103
105
  Then the data at "1" should be 100
104
- Then the data at "2" should be `String.class`
106
+ Then the data at "2" should be `"chunky".class`
105
107
  ```
106
108
  (Among other things, this lets you work around Ruby YAML's lack of support for scientific notation)
109
+
107
110
  **Note: This is done via a raw `eval`, so it's dangerous**
108
111
 
109
- #Steps
112
+ Store data for later use:
113
+ ```ruby
114
+ Given `@samples` is:
115
+ """
116
+ where: "http://google.com"
117
+ when: `Time.now`
118
+ """
119
+ And `@samples` includes:
120
+ """
121
+ what: {}
122
+ """
123
+ And `@samples['what']` is:
124
+ """
125
+ - chunky
126
+ - bacon
127
+ """
128
+ And the data is:
129
+ """
130
+ meal:
131
+ main_course: `@samples['what'][1]`
132
+ style: `@samples['what'][0]`
133
+ ordered: `@samples['when']`
134
+ """
135
+ Then the data should be:
136
+ """
137
+ meal:
138
+ main_course: bacon
139
+ style: chunky
140
+ ordered: `@samples['when']`
141
+ """
142
+ ```
143
+
144
+ Again, this is done by raw eval, so it's dangerous, and it's definitely enough to shoot your foot off with.
145
+
146
+ If you're using this in anything like a complex sense, look up the "evaluation" and "remember" helpers, below
147
+
110
148
 
149
+ Steps
150
+ ----------
151
+
152
+ Matching:
111
153
  * `Then the data should be:`
112
154
  * `Then the data should be "..."`
113
155
  * `Then the data at "..." should be:`
114
156
  * `Then the data at "..." should be "..."`
115
157
 
158
+ Inclusion:
116
159
  * `Then the data includes:`
117
160
  * `Then the data includes "..."`
118
161
  * `Then the data at "..." includes:`
119
162
  * `Then the data at "..." includes "..."`
120
163
 
164
+ Type checking:
121
165
  * `Then the data is of type ...`
122
166
  * `Then the data at "..." if of type ...`
123
167
 
124
168
  Pathing is done like so: `data[:chunky]['Bacon'][0]` would be "chunky/bacon/0". Each element (when looking in a hash) is first tried as a symbol, then as a string.
125
169
 
126
- When checking inclusion against an array, you need to supply an array: `[1,2,3]` includes `[2]`, or `[1, [2,3], 4]` includes `[[2,3]]`
170
+ When checking inclusion against an array, you need to supply an array: `[1,2,3]` includes `[2]`, or `[1, [2,3], 4]` includes `[[2,3]]`.
127
171
 
128
172
  When checking inclusion against a hash, you need to supply a hash: `{one: :two, three: four}` includes `{one: :two}`
129
173
 
130
- RSpec
174
+ You don't see this quite the same in the Cucumber steps because YAML parsing from a string does this inherently: `"one: two"` becomes `{'one' => 'two'}` and
175
+ `"[one, two]"` or `"- one\n- two"` becomes `['one', 'two']`
176
+
177
+ # RSpec
178
+
179
+ Setup
131
180
  --------
181
+ ```ruby
182
+ #in spec/spec_helper.rb
183
+ require 'data_spec'
184
+ ```
132
185
 
186
+ Matchers
187
+ --------
188
+ Three matchers:
133
189
  * `match_data(...).at(...)`
134
190
  * `includes_data(...).at(...)`
135
191
  * `match_block(lambda{...}).at(...)`
136
192
 
137
- Exact matching is (as it turns out!) handled by `==`, while partial matching is handled by http://stackoverflow.com/questions/3826969/ruby-hash-include-another-hash-deep-check
138
- Note that pathing is applied to the object being checked: in `hash1.should match_data(hash2).at("path/0")`, `hash1[:path][0]` would be compared to `hash2`.
193
+ Exact matching is handled by `==`, while partial matching is handled by
194
+ [`deep_include?`](http://stackoverflow.com/questions/3826969/ruby-hash-include-another-hash-deep-check)
195
+
196
+ Note that pathing is applied to the object being checked:
197
+
198
+ hash1.should match_data(hash2).at("path/0")
199
+
200
+ results in:
201
+
202
+ hash1[:path][0].should match_data(hash2)
203
+
204
+ # Library
139
205
 
140
206
  Helpers
141
207
  --------
142
- * DataSpec::Helpers.at_path(data, path)
143
- * DataSpec.parse
208
+ * `DataSpec::Helpers.at_path(data, path)`
209
+ * `DataSpec.parse`
144
210
 
145
- `at_path` is what provides the "pathing" functionality, while `parse` provides interpreting embedded code.
211
+ `at_path` is what provides the "pathing" functionality, while `parse` provides the interpreting of embedded code.
146
212
 
147
213
  As seen in the examples, you can use $ at the beginning and end, or backticks instead of quotes.
148
- The backticks will actually be converted to dollar signs, but they're prettier and easier to read.
214
+ The backticks will actually be converted to dollar signs (YAML parsers choke on backticks),
215
+ but they're prettier and easier to read.
149
216
 
150
- Refinements
151
- -------
152
- `DataSpec::Refinements` adds `tree_walk_with_self` to both `Hash` and `Array`.
153
- It allows you to apply a block to every key/value pair in the hash or array, traversing recursively.
154
- Supply a block accepting `(key, value), hash`, where `hash` is the current node; `hash[key] == value`; this allows you to alter the values.
217
+ * `DataSpec::Helpers.evaluate(string)`
155
218
 
156
- Issues
157
- -------
158
- * The YAML/JSON equivelance check is failing.
159
- * The error messages suck. Plan is to provide them as a diff'd YAML, although I'm not sure what to do for blocks
160
- * No table syntax as in json_spec
161
- * No explicit testing of `tree_walks_with_self`
162
- * No support for XML
219
+ This simply does an `eval` on the string; however, _because it also used when parsing YAML/JSON_, you can add variables
220
+ in which it is run, and use those variables in your YAML and JSON.
163
221
 
164
- Contributing
165
- -----------
166
- Go for it! Accepted code will have Cucumber and RSpec testing and be minimalist; if you spot a bug, try to provide a failing test in the report.
222
+ * `DataSpec::Helpers.remember(string, data)
167
223
 
168
- "Minimalist" doesn't mean fewest lines of code (although that's usually the case); it generally means "fewest new functions and objects"
224
+ This is another way to add data to the evaulation scope; pass in the complete variable name (such as `@sample_data`) and the data to be stored.
225
+
226
+ Refinements
227
+ -------
228
+ Defined in `DataSpec::Refinements`; to use, `using DataSpec::Refinements`
169
229
 
230
+ * `Array.tree_walk_with_self{|(key, value), array| ... }`
231
+ * `Array.deep_include? sub_array`
232
+ * `Hash.tree_walk_with_self{|(key, value), hash| ... }`
233
+ * `Hash.deep_include? sub_hash`
170
234
 
235
+ `tree_walk_with_self` allows you to apply a block to every key/value pair in the hash or array, traversing recursively.
236
+ The third yielded value is the current node: `hash[key] == value` - this allows you to alter the values of the hash during traversal.
171
237
 
238
+ `Array.deep_include? sub_array` simply does `(sub_array - self).empty?`, which is true when all elements of the sub-array
239
+ are present in `self`
172
240
 
241
+ `Hash.deep_include? sub_hash` is used to detect if every key/value pair in the `sub_hash` is present in `self`
173
242
 
243
+ #Contributing
174
244
 
245
+ Remaining Issues
246
+ -------
247
+ * The error messages suck. Plan is to provide them as a diff'd YAML, although I'm not sure what to do for blocks
248
+ * No table syntax as in `json_spec`
249
+ * No explicit testing of `tree_walks_with_self`
250
+ * No support for XML
175
251
 
252
+ Pull Requests
253
+ -----------
254
+ Go for it! Accepted code will have Cucumber and RSpec testing and be minimalist; if you spot a bug, try to provide a failing test in the report.
176
255
 
256
+ "Minimalist" doesn't mean fewest lines of code (although that's usually the case); it means "fewest new functions and objects"
data/Rakefile CHANGED
@@ -1 +1,11 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "cucumber/rake/task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ Cucumber::Rake::Task.new(:cucumber) do |t|
7
+ t.cucumber_opts = "--tags ~@fail"
8
+ end
9
+
10
+ task :test => [:spec, :cucumber]
11
+ task :default => :test
data/data_spec.gemspec CHANGED
@@ -14,11 +14,9 @@ Gem::Specification.new do |spec|
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.test_files = spec.files.grep(%r{^(spec|features)/})
19
18
  spec.require_paths = ["lib"]
20
19
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
20
  spec.add_development_dependency "rake"
23
21
  spec.add_dependency "cucumber"
24
22
  spec.add_dependency "rspec"
@@ -3,33 +3,33 @@ Feature: Core Steps
3
3
  Scenario: JSON / YAML Equality
4
4
  Given the data is:
5
5
  """
6
- - chunky: bacon
7
- ordered_by:
8
- - person: joe
9
- wants:
10
- pieces: `1+1`
11
- - person: josephina
12
- wants:
13
- pieces: `1e2`
6
+ chunky: bacon
7
+ ordered_by:
8
+ - person: joe
9
+ wants:
10
+ pieces: `1+1`
11
+ - person: josephina
12
+ wants:
13
+ pieces: `1e2`
14
14
  """
15
15
  Then the data should be:
16
16
  """
17
17
  {
18
- "chunky": "bacon",
19
18
  "ordered_by": [
20
19
  {
21
- "person": "joe",
22
20
  "wants": {
23
21
  "pieces": "`1+1`"
24
- }
22
+ },
23
+ "person": "joe"
25
24
  },
26
25
  {
27
- "person": "josephina",
28
26
  "wants": {
29
27
  "pieces": "`1e2`"
30
- }
28
+ },
29
+ "person": "josephina"
31
30
  }
32
- ]
31
+ ],
32
+ "chunky": "bacon"
33
33
  }
34
34
  """
35
35
 
@@ -110,9 +110,9 @@ Feature: Core Steps
110
110
  hash: {}
111
111
  array: []
112
112
  """
113
- Then the data at "date" is of type Time
114
- And the data at "fixnum" is of type Fixnum
115
- And the data at "float" is of type Float
116
- And the data at "string" is of type String
117
- And the data at "hash" is of type Hash
118
- And the data at "array" is of type Array
113
+ Then the data at "date" should be of type Time
114
+ And the data at "fixnum" should be of type Fixnum
115
+ And the data at "float" should be of type Float
116
+ And the data at "string" should be of type String
117
+ And the data at "hash" should be of type Hash
118
+ And the data at "array" should be of type Array
@@ -0,0 +1,126 @@
1
+ Feature: Storage of local information
2
+
3
+ Scenario: Variable Assignment
4
+ Given `@var` is "chunky"
5
+ And the data is:
6
+ """
7
+ `@var`
8
+ """
9
+ Then the data should be:
10
+ """
11
+ chunky
12
+ """
13
+
14
+ Scenario: Array Assignment
15
+ Given `@var` is:
16
+ """
17
+ - chunky
18
+ - bacon
19
+ """
20
+ And the data is:
21
+ """
22
+ - `@var[0]`
23
+ - `@var[1]`
24
+ """
25
+ Then the data at "0" should be "`@var[0]`"
26
+ And the data should be:
27
+ """
28
+ `@var`
29
+ """
30
+
31
+ Scenario: Array Appending
32
+ Given `@var` is:
33
+ """
34
+ - chunky
35
+ - bacon
36
+ """
37
+ And `@var` includes:
38
+ """
39
+ - two
40
+ - three
41
+ """
42
+ And the data is:
43
+ """
44
+ `@var`
45
+ """
46
+ Then the data should include "`@var[2,3]`"
47
+
48
+ Scenario: Hash Assignment
49
+ Given `@var` is:
50
+ """
51
+ chunky: bacon
52
+ bacon: chunky
53
+ """
54
+ And the data is:
55
+ """
56
+ `@var`
57
+ """
58
+ Then the data at "chunky" should be "bacon"
59
+ And the data should be:
60
+ """
61
+ bacon: chunky
62
+ chunky: bacon
63
+ """
64
+
65
+ Scenario: Hash Appending
66
+ Given `@var` is:
67
+ """
68
+ chunky: bacon
69
+ bacon: chunky
70
+ """
71
+ And `@var` includes:
72
+ """
73
+ bacon: bacon
74
+ one: two
75
+ """
76
+ And the data is:
77
+ """
78
+ `@var`
79
+ """
80
+ Then the data at "bacon" should be "bacon"
81
+ And the data at "one" should be "two"
82
+
83
+ Scenario: Nesting:
84
+ Given `@var` is:
85
+ """
86
+ nested:
87
+ hash:
88
+ chunky: bacon
89
+ """
90
+ And `@var['nested']` includes:
91
+ """
92
+ array:
93
+ - 1
94
+ - 2
95
+ """
96
+ And the data is:
97
+ """
98
+ - `@var['nested']['hash']['chunky']`
99
+ - `@var['nested']['array']`
100
+ """
101
+ Then the data should be:
102
+ """
103
+ - bacon
104
+ - - 1
105
+ - 2
106
+ """
107
+
108
+ Scenario: Multiple Variables
109
+ Given `@one` is:
110
+ """
111
+ one: two
112
+ """
113
+ And `@two` is:
114
+ """
115
+ two: three
116
+ """
117
+ And the data is:
118
+ """
119
+ - `@one`
120
+ - `@two`
121
+ """
122
+ Then the data is:
123
+ """
124
+ - one: two
125
+ - two: three
126
+ """
@@ -0,0 +1,95 @@
1
+ Feature: Readme Examples
2
+
3
+ Scenario: Matching
4
+ Given the data is:
5
+ """
6
+ chunky: bacon
7
+ """
8
+ Then the data should be:
9
+ """
10
+ {
11
+ "chunky": "bacon"
12
+ }
13
+ """
14
+ Scenario: Path Selection
15
+ Given the data is:
16
+ """
17
+ interleaved:
18
+ - hashes:
19
+ and:
20
+ - arrays
21
+ """
22
+ Then the data at "interleaved/0/hashes" should be:
23
+ """
24
+ and:
25
+ - arrays
26
+ """
27
+
28
+ Scenario: Inclusion
29
+ Given the data is:
30
+ """
31
+ - 1
32
+ - 2
33
+ - 3
34
+ - even:
35
+ 'in a': hash
36
+ 'with only': some keys
37
+ """
38
+ Then the data should include:
39
+ """
40
+ - 1
41
+ - 2
42
+ """
43
+ And the data at "3/even" should include "'in a': hash"
44
+
45
+ Scenario: Type Checking
46
+ Given the data is:
47
+ """
48
+ - bacon
49
+ - 1
50
+ - 2013-07-06 20:09:32.824102000 -07:00
51
+ """
52
+ Then the data at "0" should be of type String
53
+ Then the data at "1" should be of type Fixnum
54
+ Then the data at "2" should be of type Time
55
+
56
+ Scenario: Embedded Code
57
+ Given the data is:
58
+ """
59
+ - `1+1`
60
+ - '$1e2$'
61
+ - `"bacon".class`
62
+ """
63
+ Then the data at "0" should be "2"
64
+ Then the data at "1" should be "100"
65
+ Then the data at "2" should be "`"chunky".class`"
66
+
67
+ Scenario: Memory
68
+ Given `@samples` is:
69
+ """
70
+ where: "http://google.com"
71
+ when: `Time.now`
72
+ """
73
+ And `@samples` includes:
74
+ """
75
+ what: {}
76
+ """
77
+ And `@samples['what']` is:
78
+ """
79
+ - chunky
80
+ - bacon
81
+ """
82
+ And the data is:
83
+ """
84
+ meal:
85
+ main_course: `@samples['what'][1]`
86
+ style: `@samples['what'][0]`
87
+ ordered: `@samples['when']`
88
+ """
89
+ Then the data should be:
90
+ """
91
+ meal:
92
+ main_course: bacon
93
+ style: chunky
94
+ ordered: `@samples['when']`
95
+ """
@@ -1,5 +1,5 @@
1
1
  require "data_spec/cucumber"
2
- require 'debugger'
2
+ #require 'debugger'
3
3
 
4
4
  def data
5
5
  @data
@@ -1,6 +1,20 @@
1
+ require File.expand_path("../../data_spec", __FILE__)
1
2
  require 'data_spec'
3
+ require 'time'
2
4
 
3
- World(DataSpec::Helpers, DataSpec::Matchers, DataSpec::Inclusion, DataSpec::Block)
5
+ World(DataSpec::Helpers, DataSpec::Matchers)
6
+
7
+ Given(/^`(.*?)` is:?(?: "(.*?)")?$/) do |var, inline, *block|
8
+ DataSpec::Helpers.evaluate("#{var} = DataSpec.parse(%##{(inline || block.first)}#)")
9
+ end
10
+
11
+ Given(/^`(.*?)` includes:?(?: "(.*?)")?$/) do |var, inline, *block|
12
+ if DataSpec.parse("`#{var}`").is_a? Hash
13
+ DataSpec::Helpers.evaluate("#{var}.merge! DataSpec.parse(%##{(inline || block.first)}#)")
14
+ elsif DataSpec.parse("`#{var}`").is_a? Array
15
+ DataSpec::Helpers.evaluate("#{var} += DataSpec.parse(%##{(inline || block.first)}#)")
16
+ end
17
+ end
4
18
 
5
19
  # Then the data at "path" should be "data"
6
20
  # Then the data should be: (...)
@@ -12,6 +26,12 @@ Then(/^the data(?: at "(.*?)")? should include:?(?: "(.*?)")?$/) do |path, inlin
12
26
  data.should include_data(DataSpec.parse(inline || block.first)).at(path)
13
27
  end
14
28
 
15
- Then(/^the data at "(.*?)" is of type ([A-Z][a-z]+)$/) do |path, type|
16
- data.should match_block(lambda{|item| item.is_a? Object.const_get(type)}).at(path)
29
+ Then(/^the data at "(.*?)" should be of type ([A-Z][a-z]+)$/) do |path, type|
30
+ if type == "Time"
31
+ #JSON doesn't actually interpret a time string into a Time,
32
+ # YAML will, but Time doesn't parse a Time object
33
+ data.should match_block(lambda{|item| Time.parse(item.to_s).is_a? Time}).at(path)
34
+ else
35
+ data.should match_block(lambda{|item| item.is_a? Object.const_get(type)}).at(path)
36
+ end
17
37
  end
@@ -1,11 +1,10 @@
1
+ require 'yaml'
1
2
  module DataSpec
2
3
  module Refinements
3
4
  refine Array do
4
5
  def tree_walk_with_self &block
5
6
  self.each_with_index do |element, index|
6
- if element.is_a? Hash
7
- element.tree_walk_with_self &block
8
- elsif element.is_a? Array
7
+ if element.is_a?(Hash) || element.is_a?(Array)
9
8
  element.tree_walk_with_self &block
10
9
  else
11
10
  yield [index, element], self
@@ -20,17 +19,16 @@ module DataSpec
20
19
 
21
20
  refine Hash do
22
21
  def tree_walk_with_self &block
23
- self.each do |key,value|
24
- if value.is_a? Hash
25
- value.tree_walk_with_self &block
26
- elsif value.is_a? Array
22
+ self.each do |key, value|
23
+ if value.is_a?(Hash) || value.is_a?(Array)
27
24
  value.tree_walk_with_self &block
28
25
  else
29
- yield [key,value], self
26
+ yield [key, value], self
30
27
  end
31
28
  end
32
29
  end
33
30
 
31
+ #TODO: Can I replace this with a block passed to Tree Walker?
34
32
  def deep_include?(sub_hash)
35
33
  sub_hash.keys.all? do |key|
36
34
  self.has_key?(key) && if sub_hash[key].is_a?(Hash)
@@ -47,17 +45,28 @@ end
47
45
  using DataSpec::Refinements
48
46
  module DataSpec
49
47
  module Helpers
48
+ def self.evaluate string
49
+ eval(string)
50
+ end
51
+ def self.remember varname, data
52
+ instance_variable_set(varname, data)
53
+ end
50
54
  def self.parse yaml
51
55
  # `code` is more readable, but not parsable, for our purposes we're converting it to $
52
56
  unrendered = YAML.load(yaml.gsub("`", "$"))
53
57
 
54
- return unrendered unless unrendered.is_a?(Array) || unrendered.is_a?(Hash)
55
-
56
- unrendered.tree_walk_with_self do |(k, v), h|
57
- if v =~ /^\$(.+)\$$/
58
- h[k] = eval($1)
58
+ if unrendered.is_a?(Array) || unrendered.is_a?(Hash)
59
+ rendered = unrendered.tree_walk_with_self do |(k, v), h|
60
+ if v =~ /^\$(.+)\$$/
61
+ h[k] = self.evaluate($1)
62
+ end
59
63
  end
64
+ elsif unrendered.is_a?(String) && unrendered =~ /^\$(.+)\$$/
65
+ rendered = self.evaluate($1)
66
+ else
67
+ rendered = unrendered
60
68
  end
69
+ rendered
61
70
  end
62
71
  def self.at_path data, path
63
72
  return data if path.nil? || path.empty?
@@ -15,12 +15,10 @@ module DataSpec
15
15
  @path = path
16
16
  end
17
17
 
18
- diffable
18
+ failure_message_for_should do |actual|
19
+ "Got:\n#{actual.to_yaml}\nExpected:\n#{expected.to_yaml}"
20
+ end
19
21
  end
20
- end
21
-
22
- module Inclusion
23
- extend RSpec::Matchers::DSL
24
22
 
25
23
  matcher :include_data do |expected|
26
24
  match do |actual|
@@ -31,12 +29,10 @@ module DataSpec
31
29
  @path = path
32
30
  end
33
31
 
34
- diffable
32
+ failure_message_for_should do |actual|
33
+ "Got:\n#{actual.to_yaml}\nExpected:\n#{expected.to_yaml}"
34
+ end
35
35
  end
36
- end
37
-
38
- module Block
39
- extend RSpec::Matchers::DSL
40
36
 
41
37
  matcher :match_block do |block|
42
38
  match do |actual|
@@ -48,7 +44,4 @@ module DataSpec
48
44
  end
49
45
  end
50
46
  end
51
-
52
- module Interpolation
53
- end
54
47
  end
@@ -1,3 +1,3 @@
1
1
  module DataSpec
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/data_spec.rb CHANGED
@@ -5,7 +5,10 @@ require 'data_spec/matchers'
5
5
  if RSpec && RSpec.respond_to?(:configure)
6
6
  RSpec.configure do |config|
7
7
  config.include DataSpec::Matchers
8
- config.include DataSpec::Inclusion
9
- config.include DataSpec::Block
8
+ config.include DataSpec::Helpers
10
9
  end
11
10
  end
11
+
12
+ if defined?(World)
13
+ require 'data_spec/cucumber'
14
+ end
@@ -1,8 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe DataSpec::Block do
3
+ describe DataSpec::Matchers do
4
4
  it "can check versus a block" do
5
5
  "chunky".should match_block(lambda{|got| got.is_a? String})
6
+
6
7
  "chunky".should_not match_block(lambda{|got| got.is_a? Integer})
7
8
  end
8
9
 
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataSpec do
4
+ it "can remember things for use in evaluation" do
5
+ time = Time.now
6
+ DataSpec::Helpers.remember("@var", time)
7
+ DataSpec::Helpers.evaluate("@var.day").should be(time.day)
8
+ end
9
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe DataSpec::Inclusion do
3
+ describe DataSpec::Matchers do
4
4
 
5
5
  it "can check array inclusion" do
6
6
  [1,2,3].should include_data([2])
@@ -46,9 +46,9 @@ describe DataSpec::Inclusion do
46
46
  end
47
47
 
48
48
  it "can check at a path" do
49
- [1, {array: [2, {chunky: :bacon, bacon: :chunky} ] } ].should include_data({chunky: :bacon}).at("1/array/1")
50
- [1, {array: [2, {chunky: :bacon, bacon: :chunky} ] } ].should include_data({chunky: :bacon}).at("1/array/1")
49
+ [1, {breakfast: [2, {chunky: :bacon, bacon: :chunky} ] } ].should include_data({chunky: :bacon}).at("1/breakfast/1")
50
+ [1, {breakfast: [2, {chunky: :bacon, bacon: :chunky} ] } ].should include_data({chunky: :bacon}).at("1/breakfast/1")
51
51
 
52
- [1, {array: [2, {chunky: :bacon, bacon: :chunky} ] } ].should_not include_data({chunky: :nocab}).at("1/array/1")
52
+ [1, {breakfast: [2, {chunky: :bacon, bacon: :chunky} ] } ].should_not include_data({chunky: :nocab}).at("1/breakfast/1")
53
53
  end
54
54
  end
@@ -6,30 +6,37 @@ describe DataSpec::Matchers do
6
6
  {}.should match_data({})
7
7
  {}.should_not match_data([])
8
8
  end
9
+
9
10
  it "should match empty arrays" do
10
11
  [].should match_data([])
11
12
  [].should_not match_data({})
12
13
  end
14
+
13
15
  it "should match strings" do
14
16
  "Bacon".should match_data("Bacon")
15
17
  "Bacon".should_not match_data("Chunky")
16
18
  end
19
+
17
20
  it "should match integers" do
18
21
  1.should match_data(1)
19
22
  2.should_not match_data(1)
20
23
  end
24
+
21
25
  it "should match floats" do
22
26
  1.1.should match_data(1.1)
23
27
  2.1.should_not match_data(1.1)
24
28
  end
29
+
25
30
  it "should match true" do
26
31
  true.should match_data(true)
27
32
  true.should_not match_data(false)
28
33
  end
34
+
29
35
  it "should match false" do
30
36
  false.should match_data(false)
31
37
  false.should_not match_data(true)
32
38
  end
39
+
33
40
  it "should match nil" do
34
41
  nil.should match_data(nil)
35
42
  nil.should_not match_data("something")
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
- require 'debugger'
3
+ #require 'debugger'
4
4
 
5
5
  require 'data_spec' # and any other gems you need
6
6
 
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_spec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - narfanator
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-07 00:00:00.000000000 Z
11
+ date: 2013-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: '1.3'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: '1.3'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rake
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -75,12 +61,15 @@ extra_rdoc_files: []
75
61
  files:
76
62
  - .gitignore
77
63
  - .rspec
64
+ - .travis.yml
78
65
  - Gemfile
79
66
  - LICENSE.txt
80
67
  - README.md
81
68
  - Rakefile
82
69
  - data_spec.gemspec
83
70
  - features/core.feature
71
+ - features/memory.feature
72
+ - features/readme.feature
84
73
  - features/step_definitions/steps.rb
85
74
  - features/support/env.rb
86
75
  - lib/data_spec.rb
@@ -89,6 +78,7 @@ files:
89
78
  - lib/data_spec/matchers.rb
90
79
  - lib/data_spec/version.rb
91
80
  - spec/data_spec/block_spec.rb
81
+ - spec/data_spec/helpers_spec.rb
92
82
  - spec/data_spec/inclusion_spec.rb
93
83
  - spec/data_spec/interpolation_spec.rb
94
84
  - spec/data_spec/matchers_spec.rb
@@ -120,9 +110,12 @@ summary: RSpec matchers and Cucumber steps for describing hash and array structu
120
110
  including deep nesting
121
111
  test_files:
122
112
  - features/core.feature
113
+ - features/memory.feature
114
+ - features/readme.feature
123
115
  - features/step_definitions/steps.rb
124
116
  - features/support/env.rb
125
117
  - spec/data_spec/block_spec.rb
118
+ - spec/data_spec/helpers_spec.rb
126
119
  - spec/data_spec/inclusion_spec.rb
127
120
  - spec/data_spec/interpolation_spec.rb
128
121
  - spec/data_spec/matchers_spec.rb