data_spec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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