any_value 0.1.0

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: 34e46954b67b61b298a1fb9032192aa102cf7c47
4
+ data.tar.gz: 922af0fc2c8b978580bab08fd6b94809af4e9748
5
+ SHA512:
6
+ metadata.gz: 4015a9e6956be16714891d3923be52db9a238d0da720abe18a623a7b722f381f9a65547580053b7ca90ba22d5c565127351b6aedf365811fcd872247144b692b
7
+ data.tar.gz: 0d0e6c196643d1992b8ca8f417594f4e450243e750f27f1fd8c030946bf87c3fd03d8ecffba4d5fdebb12cdb3c1269c5f3654b0ff267e5b482fc08ebfbf15517
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in anything.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Wojtek Mach
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # Anything
2
+
3
+ [![Build Status](https://travis-ci.org/wojtekmach/anything.svg)](https://travis-ci.org/wojtekmach/anything)
4
+
5
+ Anything is a collection of helper methods like: `anything`, `any_number`, `any_string` that is useful for testing nested data structures (like arrays or hashes) when you care more about some particular elements and the "shape" of the data, than about the entire data structure.
6
+
7
+ So, instead of either:
8
+
9
+ * Asserting all elements, even the attributes you don't really care about (ids, created_at fields etc)
10
+
11
+ ```ruby
12
+ def test_create
13
+ item1 = Item.create!(name: "Item 1")
14
+ item2 = Item.create!(name: "Item 2")
15
+
16
+ get "/items"
17
+
18
+ assert_equal [
19
+ {"id" => item1.id, "name" => "Item 1"},
20
+ {"id" => item2.id, "name" => "Item 2"},
21
+ ], JSON(response.body)
22
+ end
23
+ ```
24
+
25
+ or
26
+
27
+ * Extracting out subset of attributes you care about:
28
+
29
+ ```ruby
30
+ def test_create
31
+ item1 = Item.create!(name: "Item 1")
32
+ item2 = Item.create!(name: "Item 2")
33
+
34
+ get "/items"
35
+
36
+ assert_equal [
37
+ "Item 1", "Item 2",
38
+ ], JSON(response.body).map { |h| h['name'] }
39
+ end
40
+ ```
41
+
42
+ You can do this:
43
+
44
+ ```ruby
45
+ def test_create
46
+ item1 = Item.create!(name: "Item 1")
47
+ item2 = Item.create!(name: "Item 2")
48
+
49
+ get "/items"
50
+
51
+ assert_equal [
52
+ {"id" => any_integer, "name" => "Item 1"},
53
+ {"id" => any_integer, "name" => "Item 2"},
54
+ ], JSON(response.body)
55
+ end
56
+ ```
57
+
58
+ ## Usage
59
+
60
+ All you have to do is to include `Anything` module to your program/test/whatever.
61
+
62
+ Example:
63
+
64
+ ```ruby
65
+ require 'anything'
66
+
67
+ class Minitest::Test
68
+ include Anything
69
+ end
70
+
71
+ require 'minitest/autorun'
72
+
73
+ class Test < Minitest::Test
74
+ def test_anything
75
+ assert_equal any_number, 42
76
+ end
77
+ end
78
+ ```
79
+
80
+ ### Composition
81
+
82
+ You can compose helpers like this:
83
+
84
+ ```ruby
85
+ acronym = upcase_string ^ string_of_length(3)
86
+
87
+ acronym == "NBA" # => true
88
+ acronym == "nba" # => false
89
+ acronym == "NASA" # => false
90
+ ```
91
+
92
+ And like that for arrays:
93
+
94
+ ```ruby
95
+ array_of_integers = array_of(any_integer)
96
+
97
+ array_of_integers == [1, 2, 3] # => true
98
+ array_of_integers == [1, nil, 3] # => false
99
+ ```
100
+
101
+ See: https://github.com/wojtekmach/anything/blob/master/test/anything_test.rb for more examples.
102
+
103
+ ## Installation
104
+
105
+ The gem is not released to rubygems.org yet, since this name is taken.
106
+
107
+ You can install it via bundler by adding `gem 'anything', github: 'wojtekmach/anything'` to your Gemfile or by cloning it and running `rake install`.
108
+
109
+ ## Contributing
110
+
111
+ 1. Fork it ( https://github.com/wojtekmach/anything/fork )
112
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
113
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
114
+ 4. Push to the branch (`git push origin my-new-feature`)
115
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.test_files = FileList['test/**/*_test.rb']
6
+ t.libs << 'test'
7
+ end
8
+
9
+ task :default => :test
data/any_value.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 "any_value/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "any_value"
8
+ spec.version = AnyValue::VERSION
9
+ spec.authors = ["Wojtek Mach"]
10
+ spec.email = ["wojtek@wojtekmach.pl"]
11
+
12
+ spec.summary = %q{Helper objects for testing nested data structures}
13
+ spec.description = spec.summary
14
+ spec.homepage = "https://github.com/wojtekmach/any_value"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.8"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest"
25
+ end
@@ -0,0 +1,3 @@
1
+ module AnyValue
2
+ VERSION = "0.1.0"
3
+ end
data/lib/any_value.rb ADDED
@@ -0,0 +1,285 @@
1
+ # Sometimes, especially when working with JSON APIs,
2
+ # when testing I found myself wanting to test the "shape" of data and only some particular elements, rather than either:
3
+ #
4
+ # - test everything - which is tricky with things like auto_increment primary keys, created_at fields etc
5
+ # - test only subset of data - do stuff like: `JSON(response.body).map { |h| h['name'] }.should == ['Item 1', 'Item 2']
6
+ #
7
+ # Here, I want to try something different. See:
8
+ # `test_why_someone_would_ever_use_it`
9
+
10
+ require "any_value/version"
11
+ require "delegate"
12
+ require "set"
13
+ require "date"
14
+ require "uri"
15
+
16
+ module AnyValue
17
+ class Anything
18
+ def initialize(*args)
19
+ @args = args
20
+ end
21
+
22
+ def ==(*)
23
+ true
24
+ end
25
+
26
+ def inspect
27
+ "#<%s>" % self.class.name.sub("Anything::", "")
28
+ end
29
+
30
+ def ^(other)
31
+ Composite.new(self, other)
32
+ end
33
+
34
+ def to_ary
35
+ self
36
+ end
37
+
38
+ def to_str
39
+ self
40
+ end
41
+ end
42
+ def anything
43
+ Anything.new
44
+ end
45
+
46
+ class Composite < SimpleDelegator
47
+ def initialize(left, right)
48
+ super(left)
49
+ @right = right
50
+ end
51
+
52
+ def ==(o)
53
+ __getobj__.==(o) && @right.==(o)
54
+ end
55
+
56
+ def ^(other)
57
+ Composite.new(self, other)
58
+ end
59
+
60
+ def inspect
61
+ "#<Composite #{__getobj__.inspect} #{@right.inspect}>"
62
+ end
63
+ end
64
+
65
+ class AnyInteger < Anything
66
+ def ==(o)
67
+ o.is_a?(Integer)
68
+ end
69
+ end
70
+ def any_integer
71
+ AnyInteger.new
72
+ end
73
+
74
+ class AnyNumber < Anything
75
+ def ==(o)
76
+ o.is_a?(Numeric)
77
+ end
78
+ end
79
+ def any_number
80
+ AnyNumber.new
81
+ end
82
+
83
+ class EvenNumber < AnyNumber
84
+ def ==(o)
85
+ super && o.even?
86
+ end
87
+ end
88
+ def even_number
89
+ EvenNumber.new
90
+ end
91
+
92
+ class OddNumber < AnyNumber
93
+ def ==(o)
94
+ super && o.odd?
95
+ end
96
+ end
97
+ def odd_number
98
+ OddNumber.new
99
+ end
100
+
101
+ class AnyString < Anything
102
+ def ==(o)
103
+ o.is_a?(String)
104
+ end
105
+
106
+ def to_str
107
+ self
108
+ end
109
+ end
110
+ def any_string
111
+ AnyString.new
112
+ end
113
+
114
+ class OneOf < Anything
115
+ def initialize(*values)
116
+ super
117
+ @values = values
118
+ end
119
+
120
+ def ==(o)
121
+ @values.include?(o)
122
+ end
123
+
124
+ def inspect
125
+ "#<OneOf #{@values.map(&:inspect).join(" ")}>"
126
+ end
127
+ end
128
+ def one_of(*values)
129
+ OneOf.new(*values)
130
+ end
131
+
132
+ class StringOfLength < AnyString
133
+ def initialize(expected_length)
134
+ super
135
+ @expected_length = expected_length
136
+ end
137
+
138
+ def ==(o)
139
+ super && o.length == @expected_length
140
+ end
141
+
142
+ def inspect
143
+ "#<StringOfLength #@expected_length>"
144
+ end
145
+ end
146
+ def string_of_length(expected_length)
147
+ StringOfLength.new(expected_length)
148
+ end
149
+
150
+ class StringMatching < AnyString
151
+ def initialize(pattern)
152
+ super
153
+ @pattern = pattern
154
+ end
155
+
156
+ def ==(o)
157
+ super && o =~ @pattern
158
+ end
159
+
160
+ def inspect
161
+ "#<StringMatching #@pattern>"
162
+ end
163
+ end
164
+ def string_matching(pattern)
165
+ StringMatching.new(pattern)
166
+ end
167
+
168
+ # It's the same as:
169
+ #
170
+ # sorted_array = array_of(increasing)
171
+ class SortedArray < Anything
172
+ def ==(o)
173
+ o == o.sort
174
+ end
175
+
176
+ def to_ary
177
+ self
178
+ end
179
+ end
180
+ def sorted_array
181
+ SortedArray.new
182
+ end
183
+
184
+ class ArrayOf < Anything
185
+ def initialize(element)
186
+ unless element.is_a?(Anything)
187
+ raise ArgumentError, "invalid argument: #{element.inspect}"
188
+ end
189
+
190
+ super
191
+ @element = element
192
+ end
193
+
194
+ def ==(o)
195
+ o.all? { |x| x == @element }
196
+ end
197
+
198
+ def inspect
199
+ "#<ArrayOf #{@element.inspect}>"
200
+ end
201
+ end
202
+ def array_of(element)
203
+ ArrayOf.new(element)
204
+ end
205
+
206
+ class AnyUnique < Anything
207
+ def initialize
208
+ @seen = Set.new
209
+ end
210
+ def ==(o)
211
+ if @seen.include?(o)
212
+ false
213
+ else
214
+ @seen << o
215
+ true
216
+ end
217
+ end
218
+ end
219
+ def any_unique
220
+ @_any_unique ||= AnyUnique.new
221
+ end
222
+
223
+ class Increasing < Anything
224
+ def initialize
225
+ @last = nil
226
+ @for_inspect = nil
227
+ end
228
+
229
+ def ==(o)
230
+ @for_inspect = @last
231
+ if @last
232
+ result = o > @last
233
+ @last = o
234
+ result
235
+ else
236
+ @last = o
237
+ super
238
+ end
239
+ end
240
+
241
+ def inspect
242
+ "#<Increasing last=#{@for_inspect.inspect}>"
243
+ end
244
+ end
245
+ def increasing
246
+ @_increasing ||= Increasing.new
247
+ end
248
+
249
+ class UpcaseString < AnyString
250
+ def ==(o)
251
+ super && o.upcase == o
252
+ end
253
+ end
254
+ def upcase_string
255
+ UpcaseString.new
256
+ end
257
+
258
+ class AnyTime < Anything
259
+ def ==(o)
260
+ o.is_a?(Time)
261
+ end
262
+ end
263
+ def any_time
264
+ AnyTime.new
265
+ end
266
+
267
+ class AnyDate < Anything
268
+ def ==(o)
269
+ o.is_a?(Date)
270
+ end
271
+ end
272
+ def any_date
273
+ AnyDate.new
274
+ end
275
+
276
+ class AnyHTTPURI < Anything
277
+ def ==(o)
278
+ uri = URI(o)
279
+ uri.is_a?(URI::HTTP)
280
+ end
281
+ end
282
+ def any_http_uri
283
+ AnyHTTPURI.new
284
+ end
285
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: any_value
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Wojtek Mach
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-01-24 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.8'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Helper objects for testing nested data structures
56
+ email:
57
+ - wojtek@wojtekmach.pl
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - any_value.gemspec
69
+ - lib/any_value.rb
70
+ - lib/any_value/version.rb
71
+ homepage: https://github.com/wojtekmach/any_value
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.5.1
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Helper objects for testing nested data structures
95
+ test_files: []