data_spec 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 41b97a4b8d4e7d9ba659c756dd00132cb8fc8865
4
+ data.tar.gz: 6991ac05e24b5c297ebabfb3d8795669b6681f6a
5
+ SHA512:
6
+ metadata.gz: 4428020420b3c23d340b4893a6bc6882014bf78c860cac3b5540099ec333bf195518c9cfa230cb624ffcc419258ba809129687d190b9cd8b7cc9547f379f38d6
7
+ data.tar.gz: 7d963c06e3a45144c6b5e05d540ea80a277b90de236cc05170f932b210d4180f0cf7fd6ebe9f09476d5c3077a8c8c9b9819cc4752a6c333e80e199d13e6f9abb
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+ ruby '2.0.0'
3
+
4
+ # Specify your gem's dependencies in data_spec.gemspec
5
+ gemspec
6
+
7
+ gem 'debugger'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 nick.barone
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,176 @@
1
+ data_spec
2
+ ========
3
+
4
+ Easily compare hashes and arrays in RSpec and Cucumber
5
+
6
+ Originally inspired by collectiveidea's json_spec gem
7
+
8
+ Installation
9
+ ------------
10
+
11
+ gem 'data_spec'
12
+ {cucumber}
13
+ {rspec}
14
+
15
+ Cucumber
16
+ ------------
17
+
18
+ # Setup:
19
+
20
+ Include `data_spec/cucumber` and define `data` in your Cucumber environment:
21
+ ```ruby
22
+ # features/support/env.rb
23
+ require "data_spec/cucumber"
24
+
25
+ def data
26
+ #...
27
+ end
28
+ ```
29
+
30
+ # Usage:
31
+
32
+ Use either YAML or JSON:
33
+ ````ruby
34
+ Given the data is: # You define this one
35
+ """
36
+ chunky: bacon
37
+ """
38
+ Then the data should be:
39
+ """
40
+ {
41
+ "chunky": "bacon"
42
+ }
43
+ """
44
+ ```
45
+
46
+ Use path selection:
47
+ ```ruby
48
+ Given the data is:
49
+ """
50
+ interleaved:
51
+ - hashes:
52
+ and:
53
+ - arrays
54
+ """
55
+ Then the data at "interleaved/0/hashes" should be:
56
+ """
57
+ and:
58
+ - arrays
59
+ """
60
+ ```
61
+
62
+ Check inclusion:
63
+ ```ruby
64
+ Given the data is:
65
+ """
66
+ - 1
67
+ - 2
68
+ - 3
69
+ - even:
70
+ 'in a': hash
71
+ 'with only': some keys
72
+ """
73
+ Then the data includes:
74
+ """
75
+ - 1
76
+ - 2
77
+ """
78
+ And the data at "even" includes "'in a': hash"
79
+ ```
80
+
81
+ Check types:
82
+ ```ruby
83
+ Given the data is:
84
+ """
85
+ - bacon
86
+ - 1
87
+ - 2013-07-06 20:09:32.824102000 -07:00
88
+ """
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
92
+ ```
93
+
94
+ Use embedded code:
95
+ ```ruby
96
+ Given the data is:
97
+ """
98
+ - `1+1`
99
+ - '$1e2$'
100
+ - `"bacon".class`
101
+ """
102
+ Then the data at "0" should be 2
103
+ Then the data at "1" should be 100
104
+ Then the data at "2" should be `String.class`
105
+ ```
106
+ (Among other things, this lets you work around Ruby YAML's lack of support for scientific notation)
107
+ **Note: This is done via a raw `eval`, so it's dangerous**
108
+
109
+ #Steps
110
+
111
+ * `Then the data should be:`
112
+ * `Then the data should be "..."`
113
+ * `Then the data at "..." should be:`
114
+ * `Then the data at "..." should be "..."`
115
+
116
+ * `Then the data includes:`
117
+ * `Then the data includes "..."`
118
+ * `Then the data at "..." includes:`
119
+ * `Then the data at "..." includes "..."`
120
+
121
+ * `Then the data is of type ...`
122
+ * `Then the data at "..." if of type ...`
123
+
124
+ 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
+
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]]`
127
+
128
+ When checking inclusion against a hash, you need to supply a hash: `{one: :two, three: four}` includes `{one: :two}`
129
+
130
+ RSpec
131
+ --------
132
+
133
+ * `match_data(...).at(...)`
134
+ * `includes_data(...).at(...)`
135
+ * `match_block(lambda{...}).at(...)`
136
+
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`.
139
+
140
+ Helpers
141
+ --------
142
+ * DataSpec::Helpers.at_path(data, path)
143
+ * DataSpec.parse
144
+
145
+ `at_path` is what provides the "pathing" functionality, while `parse` provides interpreting embedded code.
146
+
147
+ 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.
149
+
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.
155
+
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
163
+
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.
167
+
168
+ "Minimalist" doesn't mean fewest lines of code (although that's usually the case); it generally means "fewest new functions and objects"
169
+
170
+
171
+
172
+
173
+
174
+
175
+
176
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/data_spec.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'data_spec/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "data_spec"
8
+ spec.version = DataSpec::VERSION
9
+ spec.authors = ["narfanator"]
10
+ spec.email = ["narafanator@gmail.com"]
11
+ spec.description = %q{RSpec & Cucumber for Data Examination}
12
+ spec.summary = %q{RSpec matchers and Cucumber steps for describing hash and array structures, including deep nesting}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
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)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_dependency "cucumber"
24
+ spec.add_dependency "rspec"
25
+ end
@@ -0,0 +1,118 @@
1
+ Feature: Core Steps
2
+
3
+ Scenario: JSON / YAML Equality
4
+ Given the data is:
5
+ """
6
+ - chunky: bacon
7
+ ordered_by:
8
+ - person: joe
9
+ wants:
10
+ pieces: `1+1`
11
+ - person: josephina
12
+ wants:
13
+ pieces: `1e2`
14
+ """
15
+ Then the data should be:
16
+ """
17
+ {
18
+ "chunky": "bacon",
19
+ "ordered_by": [
20
+ {
21
+ "person": "joe",
22
+ "wants": {
23
+ "pieces": "`1+1`"
24
+ }
25
+ },
26
+ {
27
+ "person": "josephina",
28
+ "wants": {
29
+ "pieces": "`1e2`"
30
+ }
31
+ }
32
+ ]
33
+ }
34
+ """
35
+
36
+ Scenario: Array Equality
37
+ Given the data is:
38
+ """
39
+ - 1
40
+ - array:
41
+ - 2
42
+ - chunky: bacon
43
+ """
44
+ Then the data at "1/array/1" should be "chunky: bacon"
45
+ Then the data should be:
46
+ """
47
+ - 1
48
+ - array:
49
+ - 2
50
+ - chunky: bacon
51
+ """
52
+
53
+ Scenario: Hash Equality
54
+ Given the data is:
55
+ """
56
+ one: two
57
+ three: four
58
+ five:
59
+ chunky: bacon
60
+ bacon: chunky
61
+ """
62
+ Then the data at "five/chunky" should be "bacon"
63
+ Then the data should be:
64
+ """
65
+ five:
66
+ bacon: chunky
67
+ chunky: bacon
68
+ three: four
69
+ one: two
70
+ """
71
+
72
+ Scenario: Inclusion
73
+ Given the data is:
74
+ """
75
+ array:
76
+ - chunky: bacon
77
+ - 2
78
+ bacon: chunky
79
+ """
80
+ Then the data should include "bacon: chunky"
81
+ And the data at "array" should include "[2]"
82
+ And the data should include:
83
+ """
84
+ array:
85
+ - chunky: bacon
86
+ - 2
87
+ """
88
+
89
+ Scenario: Interpolation
90
+ Given the data is:
91
+ """
92
+ - 1
93
+ - `1+1`
94
+ - `1+1+1`
95
+ """
96
+ Then the data should be:
97
+ """
98
+ - 1
99
+ - 2
100
+ - 3
101
+ """
102
+
103
+ Scenario: Types
104
+ Given the data is:
105
+ """
106
+ date: 2013-07-06 20:09:32.824102000 -07:00
107
+ fixnum: 1
108
+ float: 1.0
109
+ string: bacon
110
+ hash: {}
111
+ array: []
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
@@ -0,0 +1,4 @@
1
+ Given(/^the data is:$/) do |yaml|
2
+ @data = DataSpec.parse(yaml)
3
+ end
4
+
@@ -0,0 +1,6 @@
1
+ require "data_spec/cucumber"
2
+ require 'debugger'
3
+
4
+ def data
5
+ @data
6
+ end
@@ -0,0 +1,17 @@
1
+ require 'data_spec'
2
+
3
+ World(DataSpec::Helpers, DataSpec::Matchers, DataSpec::Inclusion, DataSpec::Block)
4
+
5
+ # Then the data at "path" should be "data"
6
+ # Then the data should be: (...)
7
+ Then(/^the data(?: at "(.*?)")? should be:?(?: "(.*?)")?$/) do |path, inline, *block|
8
+ data.should match_data(DataSpec.parse(inline || block.first)).at(path)
9
+ end
10
+
11
+ Then(/^the data(?: at "(.*?)")? should include:?(?: "(.*?)")?$/) do |path, inline, *block|
12
+ data.should include_data(DataSpec.parse(inline || block.first)).at(path)
13
+ end
14
+
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)
17
+ end
@@ -0,0 +1,74 @@
1
+ module DataSpec
2
+ module Refinements
3
+ refine Array do
4
+ def tree_walk_with_self &block
5
+ 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
9
+ element.tree_walk_with_self &block
10
+ else
11
+ yield [index, element], self
12
+ end
13
+ end
14
+ end
15
+
16
+ def deep_include? sub_array
17
+ (sub_array - self).empty?
18
+ end
19
+ end
20
+
21
+ refine Hash do
22
+ 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
27
+ value.tree_walk_with_self &block
28
+ else
29
+ yield [key,value], self
30
+ end
31
+ end
32
+ end
33
+
34
+ def deep_include?(sub_hash)
35
+ sub_hash.keys.all? do |key|
36
+ self.has_key?(key) && if sub_hash[key].is_a?(Hash)
37
+ self[key].is_a?(Hash) && self[key].deep_include?(sub_hash[key])
38
+ else
39
+ self[key] == sub_hash[key]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ using DataSpec::Refinements
48
+ module DataSpec
49
+ module Helpers
50
+ def self.parse yaml
51
+ # `code` is more readable, but not parsable, for our purposes we're converting it to $
52
+ unrendered = YAML.load(yaml.gsub("`", "$"))
53
+
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)
59
+ end
60
+ end
61
+ end
62
+ def self.at_path data, path
63
+ return data if path.nil? || path.empty?
64
+ path.split('/').each do |key|
65
+ key = key.to_i if data.is_a? Array
66
+ data = data[key] || data[key.to_sym]
67
+ end
68
+ data
69
+ end
70
+ end
71
+ def self.parse string
72
+ DataSpec::Helpers.parse(string)
73
+ end
74
+ end
@@ -0,0 +1,54 @@
1
+ require 'data_spec/helpers'
2
+
3
+ using DataSpec::Refinements
4
+
5
+ module DataSpec
6
+ module Matchers
7
+ extend RSpec::Matchers::DSL
8
+
9
+ matcher :match_data do |expected|
10
+ match do |actual|
11
+ DataSpec::Helpers.at_path(actual, @path) == expected
12
+ end
13
+
14
+ chain :at do |path|
15
+ @path = path
16
+ end
17
+
18
+ diffable
19
+ end
20
+ end
21
+
22
+ module Inclusion
23
+ extend RSpec::Matchers::DSL
24
+
25
+ matcher :include_data do |expected|
26
+ match do |actual|
27
+ DataSpec::Helpers.at_path(actual, @path).deep_include? expected
28
+ end
29
+
30
+ chain :at do |path|
31
+ @path = path
32
+ end
33
+
34
+ diffable
35
+ end
36
+ end
37
+
38
+ module Block
39
+ extend RSpec::Matchers::DSL
40
+
41
+ matcher :match_block do |block|
42
+ match do |actual|
43
+ block.call DataSpec::Helpers.at_path(actual, @path)
44
+ end
45
+
46
+ chain :at do |path|
47
+ @path = path
48
+ end
49
+ end
50
+ end
51
+
52
+ module Interpolation
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ module DataSpec
2
+ VERSION = "0.0.1"
3
+ end
data/lib/data_spec.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "data_spec/version"
2
+ require 'data_spec/helpers'
3
+ require 'data_spec/matchers'
4
+
5
+ if RSpec && RSpec.respond_to?(:configure)
6
+ RSpec.configure do |config|
7
+ config.include DataSpec::Matchers
8
+ config.include DataSpec::Inclusion
9
+ config.include DataSpec::Block
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataSpec::Block do
4
+ it "can check versus a block" do
5
+ "chunky".should match_block(lambda{|got| got.is_a? String})
6
+ "chunky".should_not match_block(lambda{|got| got.is_a? Integer})
7
+ end
8
+
9
+ it "can check versus a block at a path" do
10
+ [1, 'bacon'].should match_block(lambda{|got| got.is_a? String}).at("1")
11
+
12
+ [1, 'bacon'].should_not match_block(lambda{|got| got.is_a? Integer}).at("1")
13
+ end
14
+
15
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataSpec::Inclusion do
4
+
5
+ it "can check array inclusion" do
6
+ [1,2,3].should include_data([2])
7
+ [1,2,3].should include_data([2,3])
8
+
9
+ [1,2,3].should_not include_data([3,4])
10
+ end
11
+
12
+ it "can check nested array inclusion" do
13
+ [1,[2,3],[4,5],6].should include_data([[2,3]])
14
+ [1,[2,3],[4,5],6].should include_data([[2,3],[4,5]])
15
+
16
+
17
+ [1,[2,3],[4,5],6].should_not include_data([2,3])
18
+ [1,[2,3],[4,5],6].should_not include_data([[3,3],[4,5]])
19
+ [1,[2,3],[4,5],6].should_not include_data([[2,3],[5,5]])
20
+ [1,[2,3],[4,5],6].should_not include_data([3,4])
21
+ end
22
+
23
+ it "can check hash inclusion" do
24
+ {one: :two, three: :four}.should include_data({three: :four})
25
+
26
+ {one: :two, three: :four}.should_not include_data({four: :four})
27
+ end
28
+
29
+ it "can check nested hash inclusion" do
30
+ {one: :two, three: {four: :five, seven: :eight}}.should include_data({three: {four: :five}})
31
+
32
+ {one: :two, three: {four: :five, seven: :eight}}.should_not include_data({four: :five})
33
+ {one: :two, three: {four: :five, seven: :eight}}.should_not include_data({three: {nine: :five}})
34
+ {one: :two, three: {four: :five, seven: :eight}}.should_not include_data({three: {four: :ten}})
35
+ {one: :two, three: {four: :five, seven: :eight}}.should_not include_data({nine: :ten})
36
+ end
37
+
38
+ it "can check mixed nested inclusion" do
39
+ [1, {one: :two}].should include_data([{one: :two}])
40
+
41
+ [1, {one: :two}].should_not include_data([{two: :two}])
42
+
43
+ {one: :two, three: [1,2]}.should include_data({three: [1,2]})
44
+
45
+ {one: :two, three: [1,2]}.should_not include_data({three: [2,2]})
46
+ end
47
+
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")
51
+
52
+ [1, {array: [2, {chunky: :bacon, bacon: :chunky} ] } ].should_not include_data({chunky: :nocab}).at("1/array/1")
53
+ end
54
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataSpec::Helpers do
4
+
5
+ it "parses YAML" do
6
+ DataSpec.parse("[1, {array: [2, {chunky: bacon} ] } ]").should match_data([1, {'array' => [2, {'chunky' => 'bacon'} ] } ])
7
+ yaml =
8
+ """
9
+ - 1
10
+ - array:
11
+ - 2
12
+ - chunky: bacon
13
+ """
14
+ DataSpec.parse(yaml).should match_data([1, {'array' => [2, {'chunky' => 'bacon'} ] } ])
15
+ end
16
+
17
+ it "parses JSON" do
18
+ DataSpec.parse('[1, {"array": [2, {"chunky": "bacon"} ] } ]').should match_data([1, {'array' => [2, {'chunky' => 'bacon'} ] } ])
19
+
20
+ json = <<-eot
21
+ [
22
+ 1,
23
+ {
24
+ "array": [
25
+ 2,
26
+ {
27
+ "chunky": "bacon"
28
+ }
29
+ ]
30
+ }
31
+ ]
32
+ eot
33
+
34
+ DataSpec.parse(json).should match_data([1, {'array' => [2, {'chunky' => 'bacon'} ] } ])
35
+ end
36
+
37
+ it "interpolates json" do
38
+ json = <<-eot
39
+ [
40
+ 1,
41
+ {
42
+ "array": [
43
+ `1+1`,
44
+ {
45
+ "chunky": "bacon"
46
+ }
47
+ ]
48
+ }
49
+ ]
50
+ eot
51
+ DataSpec.parse(json).should match_data([1, {'array' => [2, {'chunky' => 'bacon'} ] } ])
52
+ end
53
+
54
+ it "interpolates array values" do
55
+ DataSpec.parse("[1, 2, `1+2`]").should match_data([1,2,3])
56
+
57
+ DataSpec.parse("[1, 2, `1+2`]").should_not match_data([1,2,4])
58
+ end
59
+
60
+ it "interpolates hash values" do
61
+ DataSpec.parse("{one: two, three: `2+2`}").should match_data({'one' => 'two', 'three' => 4})
62
+
63
+ DataSpec.parse("{one: two, three: `2+2`}").should_not match_data({'one' => 'two', 'three' => 5})
64
+ end
65
+
66
+ it "interpolates nested values" do
67
+ DataSpec.parse("[1, {array: [`1+1`, {chunky: `'bacon'.to_sym`} ] } ]").should match_data([1, {'array' => [2, {'chunky' => :bacon} ] } ])
68
+
69
+ DataSpec.parse("[1, {array: [`1+1`, {chunky: `'bacon'.to_sym`} ] } ]").should_not match_data([1, {'array' => [3, {'chunky' => :bacon} ] } ])
70
+ DataSpec.parse("[1, {array: [`1+1`, {chunky: `'bacon'.to_sym`} ] } ]").should_not match_data([1, {'array' => [2, {'chunky' => :nocab} ] } ])
71
+ end
72
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataSpec::Matchers do
4
+
5
+ it "should match empty hashes" do
6
+ {}.should match_data({})
7
+ {}.should_not match_data([])
8
+ end
9
+ it "should match empty arrays" do
10
+ [].should match_data([])
11
+ [].should_not match_data({})
12
+ end
13
+ it "should match strings" do
14
+ "Bacon".should match_data("Bacon")
15
+ "Bacon".should_not match_data("Chunky")
16
+ end
17
+ it "should match integers" do
18
+ 1.should match_data(1)
19
+ 2.should_not match_data(1)
20
+ end
21
+ it "should match floats" do
22
+ 1.1.should match_data(1.1)
23
+ 2.1.should_not match_data(1.1)
24
+ end
25
+ it "should match true" do
26
+ true.should match_data(true)
27
+ true.should_not match_data(false)
28
+ end
29
+ it "should match false" do
30
+ false.should match_data(false)
31
+ false.should_not match_data(true)
32
+ end
33
+ it "should match nil" do
34
+ nil.should match_data(nil)
35
+ nil.should_not match_data("something")
36
+ end
37
+
38
+ it "should match hashes" do
39
+ {1 => 2}.should match_data({1 => 2})
40
+ {1 => 2, 3 => 4, 5 => 6}.should match_data({1 => 2, 3 => 4, 5 => 6})
41
+ {1 => 2, 5 => 6, 3 => 4}.should match_data({1 => 2, 3 => 4, 5 => 6})
42
+
43
+ {1 => 2}.should_not match_data({1 => 3})
44
+ {1 => 2}.should_not match_data({2 => 2})
45
+ end
46
+
47
+ it "should match arrays" do
48
+ [1,2,3].should match_data([1,2,3])
49
+
50
+ [1,2,3].should_not match_data([2,1,3])
51
+ [1,2,3].should_not match_data([2,2,3])
52
+ [1,2,3].should_not match_data([1,2])
53
+ [1,2,3].should_not match_data([1,2,3,4])
54
+ end
55
+
56
+ it "should match hash nesting" do
57
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should match_data( { three: :four, nested: { one: :two, hash: { bacon: :chunky, chunky: :bacon } } })
58
+
59
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { four: :four, nested: { one: :two, hash: { bacon: :chunky, chunky: :bacon } } } )
60
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { three: :five, nested: { one: :two, hash: { bacon: :chunky, chunky: :bacon } } } )
61
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { three: :five, nested: { two: :two, hash: { bacon: :chunky, chunky: :bacon } } } )
62
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { three: :five, nested: { one: :one, hash: { bacon: :chunky, chunky: :bacon } } } )
63
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { three: :five, nested: { one: :two, hash: { nocab: :chunky, chunky: :bacon } } } )
64
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { three: :five, nested: { one: :two, hash: { bacon: :yknuhc, chunky: :bacon } } } )
65
+
66
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { nested: { one: :two, hash: { bacon: :chunky, chunky: :bacon } } })
67
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { three: :four, nested: { hash: { bacon: :chunky, chunky: :bacon } } })
68
+ { nested: { hash: { chunky: :bacon, bacon: :chunky }, one: :two }, three: :four }.should_not match_data( { three: :four, nested: { one: :two, hash: { chunky: :bacon } } })
69
+ end
70
+
71
+ it "should match array nesting" do
72
+ [1, [2, [3, 4], 5], 6].should match_data([1, [2, [3, 4], 5], 6])
73
+
74
+ [1, [2, [3, 4], 5], 6].should_not match_data([2, [2, [3, 4], 5], 6])
75
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [3, [3, 4], 5], 6])
76
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [2, [4, 4], 5], 6])
77
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [2, [3, 5], 6], 6])
78
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [2, [3, 4], 5], 7])
79
+
80
+ [1, [2, [3, 4], 5], 6].should_not match_data([ [2, [3, 4], 5], 6])
81
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [ [3, 4], 5], 6])
82
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [2, [ 4], 5], 6])
83
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [2, [3 ], 5], 6])
84
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [2, [3, 4] ], 6])
85
+ [1, [2, [3, 4], 5], 6].should_not match_data([1, [2, [3, 4], 5] ])
86
+ end
87
+
88
+ it "should match mixed nesting" do
89
+ [1, {array: [2, {chunky: :bacon} ] } ].should match_data([1, {array: [2, {chunky: :bacon} ] } ])
90
+
91
+ [1, {array: [2, {chunky: :bacon} ] } ].should_not match_data([2, {array: [2, {chunky: :bacon} ] } ])
92
+ [1, {array: [2, {chunky: :bacon} ] } ].should_not match_data([1, {yarra: [2, {chunky: :bacon} ] } ])
93
+ [1, {array: [2, {chunky: :bacon} ] } ].should_not match_data([1, {array: [3, {chunky: :bacon} ] } ])
94
+ [1, {array: [2, {chunky: :bacon} ] } ].should_not match_data([1, {array: [2, {yknuhc: :bacon} ] } ])
95
+ [1, {array: [2, {chunky: :bacon} ] } ].should_not match_data([1, {array: [2, {chunky: :nocab} ] } ])
96
+
97
+ [1, {array: [2, {chunky: :bacon} ] } ].should_not match_data([ {array: [2, {chunky: :bacon} ] } ])
98
+ [1, {array: [2, {chunky: :bacon} ] } ].should_not match_data([1, {array: [ {chunky: :bacon} ] } ])
99
+ end
100
+
101
+ it "should match at a path" do
102
+ [1, {array: [2, {chunky: :bacon} ] } ].should match_data({chunky: :bacon}).at('1/array/1')
103
+
104
+ [1, {array: [2, {chunky: :bacon} ] } ].should_not match_data({bacon: :chunky}).at('1/array/1')
105
+ end
106
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'debugger'
4
+
5
+ require 'data_spec' # and any other gems you need
6
+
7
+ RSpec.configure do |config|
8
+ # some (optional) config here
9
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: data_spec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - narfanator
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-07 00:00:00.000000000 Z
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
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cucumber
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: RSpec & Cucumber for Data Examination
70
+ email:
71
+ - narafanator@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - data_spec.gemspec
83
+ - features/core.feature
84
+ - features/step_definitions/steps.rb
85
+ - features/support/env.rb
86
+ - lib/data_spec.rb
87
+ - lib/data_spec/cucumber.rb
88
+ - lib/data_spec/helpers.rb
89
+ - lib/data_spec/matchers.rb
90
+ - lib/data_spec/version.rb
91
+ - spec/data_spec/block_spec.rb
92
+ - spec/data_spec/inclusion_spec.rb
93
+ - spec/data_spec/interpolation_spec.rb
94
+ - spec/data_spec/matchers_spec.rb
95
+ - spec/spec_helper.rb
96
+ homepage: ''
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.0.3
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: RSpec matchers and Cucumber steps for describing hash and array structures,
120
+ including deep nesting
121
+ test_files:
122
+ - features/core.feature
123
+ - features/step_definitions/steps.rb
124
+ - features/support/env.rb
125
+ - spec/data_spec/block_spec.rb
126
+ - spec/data_spec/inclusion_spec.rb
127
+ - spec/data_spec/interpolation_spec.rb
128
+ - spec/data_spec/matchers_spec.rb
129
+ - spec/spec_helper.rb