eaternet 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ require 'eaternet/loggable'
4
+
5
+ class LoggableTest < Minitest::Test
6
+ # Test with include because this is how the module
7
+ # is intended to be used.
8
+ include Eaternet::Loggable
9
+
10
+ def test_creates_and_sends_log_messages_to_stderr
11
+ assert_output(nil, /Border Collie/) do
12
+ logger.info('Border Collie')
13
+ end
14
+ end
15
+ end
@@ -1,22 +1,20 @@
1
1
  require 'test_helper'
2
2
 
3
3
  require 'eaternet'
4
- require 'eaternet/framework/lives_1_0'
4
+ require 'eaternet/lives_1_0'
5
5
 
6
6
  CASSETTE = 'nyc'
7
7
  MORRIS_PARK_CSV = 'test/fixtures/morris-park-bake-shop.csv'
8
8
 
9
9
  class NycAdapterTest < Minitest::Test
10
- include Eaternet::Framework::Lives_1_0
11
-
12
- @@nyc = Nyc.new(csv_path: MORRIS_PARK_CSV)
10
+ @@nyc = Eaternet::Nyc.new(csv_path: MORRIS_PARK_CSV)
13
11
 
14
12
  #
15
13
  # Businesses
16
14
  #
17
15
 
18
16
  def test_businesses_returns_an_enumerator_of_business
19
- assert enumerable_of? Business, @@nyc.businesses
17
+ assert enumerable_of? Eaternet::Lives_1_0::Business, @@nyc.businesses
20
18
  end
21
19
 
22
20
  def test_businesses_returns_lives_attributes
@@ -37,7 +35,7 @@ class NycAdapterTest < Minitest::Test
37
35
  #
38
36
 
39
37
  def test_inspections_returns_an_enumerable_of_inspection
40
- assert enumerable_of? Inspection, @@nyc.inspections
38
+ assert enumerable_of? Eaternet::Lives_1_0::Inspection, @@nyc.inspections
41
39
  end
42
40
 
43
41
  # Use the wiki analysis document as a test.
@@ -49,7 +47,7 @@ class NycAdapterTest < Minitest::Test
49
47
  09/11/2013
50
48
  08/14/2013
51
49
  01/24/2013
52
- 12/31/2012).map{ |d| Date.strptime(d, '%m/%d/%Y')}
50
+ 12/31/2012).map { |d| Date.strptime(d, '%m/%d/%Y') }
53
51
  actual_dates = @@nyc.inspections.map(&:date).to_a
54
52
  assert_equal expected_dates, actual_dates
55
53
  end
@@ -67,7 +65,7 @@ class NycAdapterTest < Minitest::Test
67
65
  #
68
66
 
69
67
  def test_violations_returns_an_enumerable_of_violation
70
- assert enumerable_of? Violation, @@nyc.violations
68
+ assert enumerable_of? Eaternet::Lives_1_0::Violation, @@nyc.violations
71
69
  end
72
70
 
73
71
  def test_violations_returns_lives_attributes
@@ -88,11 +86,10 @@ class NycAdapterTest < Minitest::Test
88
86
  #
89
87
 
90
88
  def test_implements_feed_info
91
- assert_instance_of FeedInfo, @@nyc.feed_info
89
+ assert_instance_of Eaternet::Lives_1_0::FeedInfo, @@nyc.feed_info
92
90
  end
93
91
 
94
92
  def test_has_legends
95
- assert_instance_of LegendGroup, @@nyc.legends
93
+ assert_instance_of Eaternet::Lives_1_0::LegendGroup, @@nyc.legends
96
94
  end
97
-
98
95
  end
@@ -6,7 +6,19 @@ require 'eaternet'
6
6
  SNHD_CASSETTE = 'snhd'
7
7
 
8
8
  class SnhdAdapterTest < Minitest::Test
9
- @@snhd = Snhd.new
9
+ @@snhd = Eaternet::Snhd.new
10
+
11
+ #
12
+ # Namespace and access
13
+ #
14
+
15
+ def test_global_namespace_not_polluted
16
+ assert_raises(NameError) { Snhd }
17
+ end
18
+
19
+ #
20
+ # #businesses
21
+ #
10
22
 
11
23
  def test_businesses_returns_an_enumerator
12
24
  VCR.use_cassette(SNHD_CASSETTE) do
@@ -16,7 +28,7 @@ class SnhdAdapterTest < Minitest::Test
16
28
 
17
29
  def test_businesses_returns_business_data_objects
18
30
  VCR.use_cassette(SNHD_CASSETTE) do
19
- assert_kind_of Eaternet::Framework::Prototype::BusinessData, @@snhd.businesses.first
31
+ assert_kind_of Eaternet::Prototype::BusinessData, @@snhd.businesses.first
20
32
  end
21
33
  end
22
34
 
@@ -31,6 +43,10 @@ class SnhdAdapterTest < Minitest::Test
31
43
  end
32
44
  end
33
45
 
46
+ #
47
+ # #inspections
48
+ #
49
+
34
50
  def test_inspections_returns_an_enumerable
35
51
  VCR.use_cassette(SNHD_CASSETTE) do
36
52
  assert_kind_of Enumerable, @@snhd.inspections
@@ -39,7 +55,10 @@ class SnhdAdapterTest < Minitest::Test
39
55
 
40
56
  def test_inspections_returns_inspection_data_objects
41
57
  VCR.use_cassette(SNHD_CASSETTE) do
42
- assert_kind_of Eaternet::Framework::Prototype::InspectionData, @@snhd.inspections.first
58
+ assert_kind_of(
59
+ Eaternet::Prototype::InspectionData,
60
+ @@snhd.inspections.first
61
+ )
43
62
  end
44
63
  end
45
64
 
@@ -53,6 +72,10 @@ class SnhdAdapterTest < Minitest::Test
53
72
  end
54
73
  end
55
74
 
75
+ #
76
+ # #violations
77
+ #
78
+
56
79
  def test_violations_returns_an_enumerable
57
80
  VCR.use_cassette(SNHD_CASSETTE) do
58
81
  assert_kind_of Enumerable, @@snhd.violations
@@ -61,7 +84,7 @@ class SnhdAdapterTest < Minitest::Test
61
84
 
62
85
  def test_violations_returns_violation_data_objects
63
86
  VCR.use_cassette(SNHD_CASSETTE) do
64
- assert_kind_of Eaternet::Framework::Prototype::ViolationData, @@snhd.violations.first
87
+ assert_kind_of Eaternet::Prototype::ViolationData, @@snhd.violations.first
65
88
  end
66
89
  end
67
90
 
@@ -74,6 +97,10 @@ class SnhdAdapterTest < Minitest::Test
74
97
  end
75
98
  end
76
99
 
100
+ #
101
+ # #violation_kinds
102
+ #
103
+
77
104
  def test_violation_kinds_returns_an_enumerable
78
105
  VCR.use_cassette(SNHD_CASSETTE) do
79
106
  assert_kind_of Enumerable, @@snhd.violation_kinds
@@ -82,7 +109,10 @@ class SnhdAdapterTest < Minitest::Test
82
109
 
83
110
  def test_violation_kinds_returns_violation_kind_data_objects
84
111
  VCR.use_cassette(SNHD_CASSETTE) do
85
- assert_kind_of Eaternet::Framework::Prototype::ViolationKindData, @@snhd.violation_kinds.first
112
+ assert_kind_of(
113
+ Eaternet::Prototype::ViolationKindData,
114
+ @@snhd.violation_kinds.first
115
+ )
86
116
  end
87
117
  end
88
118
 
@@ -92,8 +122,10 @@ class SnhdAdapterTest < Minitest::Test
92
122
  assert_equal '1', v.orig_key
93
123
  assert_equal '1', v.code
94
124
  assert_equal '6', v.demerits
95
- assert_equal 'Food not obtained from approved sources and/or improperly identified.',
96
- v.description
125
+ assert_equal(
126
+ 'Food not obtained from approved sources and/or improperly identified.',
127
+ v.description
128
+ )
97
129
  end
98
130
  end
99
131
  end
data/test/test_helper.rb CHANGED
@@ -8,6 +8,9 @@ VCR.configure do |c|
8
8
  end
9
9
 
10
10
 
11
+ #
12
+ # Testing helpers
13
+ #
11
14
  def enumerable_of?(a_class, obj)
12
15
  assert_kind_of Enumerable, obj
13
16
  assert_kind_of a_class, obj.first
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eaternet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robb Shecter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-04 00:00:00.000000000 Z
11
+ date: 2015-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: guard
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: guard-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'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: minitest
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -145,8 +173,10 @@ extensions: []
145
173
  extra_rdoc_files: []
146
174
  files:
147
175
  - ".gitignore"
176
+ - ".inch.yml"
148
177
  - ".travis.yml"
149
178
  - Gemfile
179
+ - Guardfile
150
180
  - LICENSE.txt
151
181
  - README.md
152
182
  - Rakefile
@@ -155,8 +185,9 @@ files:
155
185
  - lib/eaternet/agencies/nyc.rb
156
186
  - lib/eaternet/agencies/snhd.rb
157
187
  - lib/eaternet/agencies/snhd_config.rb
158
- - lib/eaternet/framework/lives_1_0.rb
159
- - lib/eaternet/framework/prototype.rb
188
+ - lib/eaternet/lives_1_0.rb
189
+ - lib/eaternet/loggable.rb
190
+ - lib/eaternet/prototype.rb
160
191
  - lib/eaternet/util.rb
161
192
  - lib/eaternet/version.rb
162
193
  - lib/ext/lazy.rb
@@ -166,6 +197,7 @@ files:
166
197
  - test/lives_1_0/feed_info_test.rb
167
198
  - test/lives_1_0/inspection_test.rb
168
199
  - test/lives_1_0/legend_test.rb
200
+ - test/loggable_test.rb
169
201
  - test/nyc_adapter_test.rb
170
202
  - test/snhd_adapter_test.rb
171
203
  - test/test_helper.rb
@@ -200,6 +232,8 @@ test_files:
200
232
  - test/lives_1_0/feed_info_test.rb
201
233
  - test/lives_1_0/inspection_test.rb
202
234
  - test/lives_1_0/legend_test.rb
235
+ - test/loggable_test.rb
203
236
  - test/nyc_adapter_test.rb
204
237
  - test/snhd_adapter_test.rb
205
238
  - test/test_helper.rb
239
+ has_rdoc:
@@ -1,232 +0,0 @@
1
- module Eaternet
2
- module Framework
3
-
4
- # Framework for creating LIVES 1.0 apps.
5
- #
6
- # The goal is to make it as easy as possible to create
7
- # compliant implementations. And so, the Business, Inspection
8
- # and Violation data objects use validations to ensure that they
9
- # correctly produce the entities listed in the spec.
10
- #
11
- # @see http://www.yelp.com/healthscores
12
- # @see http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/
13
- # @see http://www.rubyinside.com/rails-3-0s-activemodel-how-to-give-ruby-classes-some-activerecord-magic-2937.html
14
- module Lives_1_0
15
- require 'active_model'
16
-
17
-
18
- class Adapter
19
- # Required.
20
- # @return [Enumerable<Business>]
21
- def businesses
22
- fail 'Override this to return an Enumerable of Business'
23
- end
24
-
25
- # Required.
26
- # @return [Enumerable<Inspection>]
27
- def inspections
28
- fail 'Override this to return an Enumerable of Inspection'
29
- end
30
-
31
- # Optional.
32
- # @return [Enumerable<Violation>]
33
- def violations
34
- fail 'Optionally override this to return an Enumerable of Violation'
35
- end
36
-
37
- # Optional.
38
- # @return [FeedInfo]
39
- def feed_info
40
- fail 'Optionally override this to return a FeedInfo'
41
- end
42
- end
43
-
44
-
45
- class DataTransferObject
46
- include ActiveModel::Validations
47
-
48
- def initialize(&block)
49
- block.call(self)
50
- check_validations!
51
- end
52
-
53
- def check_validations!
54
- fail ArgumentError, errors.messages.inspect if invalid?
55
- end
56
-
57
- class TypeValidator < ActiveModel::EachValidator
58
- def validate_each(record, attribute, value)
59
- record.errors.add attribute, (options[:message] || "is not of class #{options[:with]}") unless
60
- value.class == options[:with]
61
- end
62
- end
63
- end
64
-
65
-
66
- # @see http://www.yelp.com/healthscores#businesses
67
- class Business < DataTransferObject
68
- attr_accessor :business_id, :name, :address, :city, :state,
69
- :postal_code, :latitude, :longitude, :phone_number
70
-
71
- validates :business_id, :name, :address,
72
- type: String,
73
- presence: true
74
- validates :city, :state, :postal_code, :phone_number,
75
- type: String,
76
- allow_nil: true
77
- validates :latitude,
78
- numericality:
79
- {
80
- greater_than_or_equal_to: -90,
81
- less_than_or_equal_to: 90
82
- },
83
- allow_nil: true
84
- validates :longitude,
85
- numericality:
86
- {
87
- greater_than_or_equal_to: -180,
88
- less_than_or_equal_to: 180
89
- },
90
- allow_nil: true
91
-
92
- def ==(other)
93
- @business_id == other.business_id
94
- end
95
-
96
- def eql?(other)
97
- self == other
98
- end
99
-
100
- def hash
101
- @business_id.hash
102
- end
103
-
104
- # @return [String]
105
- def to_s
106
- "Business #{@business_id}"
107
- end
108
- end
109
-
110
-
111
- # @see http://www.yelp.com/healthscores#inspections
112
- class Inspection < DataTransferObject
113
- attr_accessor :business_id, :score, :date, :description, :type
114
-
115
- ZERO_TO_ONE_HUNDRED_AND_BLANK = (0..100).to_a + ['']
116
-
117
- validates :business_id,
118
- type: String,
119
- presence: true
120
- validates :score,
121
- inclusion: { in: ZERO_TO_ONE_HUNDRED_AND_BLANK },
122
- allow_nil: true
123
- validates :date,
124
- type: Date,
125
- presence: true
126
- validates :type,
127
- inclusion: { in: %w(initial routine followup complaint) },
128
- allow_nil: true
129
-
130
- def score
131
- @score.nil? ? '' : @score
132
- end
133
-
134
- def to_s
135
- "Inspection #{@business_id}/#{@date}/#{@score}"
136
- end
137
- end
138
-
139
-
140
- # @see http://www.yelp.com/healthscores#violations
141
- class Violation < DataTransferObject
142
- attr_accessor :business_id, :date, :code, :description
143
-
144
- validates :business_id,
145
- type: String,
146
- presence: true
147
- validates :date,
148
- type: Date,
149
- presence: true
150
- validates :code, :description,
151
- type: String,
152
- allow_nil: true
153
- end
154
-
155
-
156
- # @see http://www.yelp.com/healthscores#feed_info
157
- class FeedInfo < DataTransferObject
158
- attr_accessor :feed_date, :feed_version, :municipality_name,
159
- :municipality_url, :contact_email
160
-
161
- HAS_AN_AT_SOMEWHERE_IN_THE_MIDDLE = /\A[^@]+@[^@]+\z/
162
-
163
- validates :feed_date,
164
- type: Date,
165
- presence: true
166
- validates :feed_version,
167
- type: String,
168
- presence: true
169
- validates :municipality_name,
170
- type: String,
171
- presence: true
172
- validates :municipality_url,
173
- type: String,
174
- format: { with: %r(\Ahttps?:/) },
175
- allow_nil: true
176
- validates :contact_email,
177
- type: String,
178
- format: { with: HAS_AN_AT_SOMEWHERE_IN_THE_MIDDLE },
179
- allow_nil: true
180
- end
181
-
182
-
183
- # @see http://www.yelp.com/healthscores#legend
184
- class Legend < DataTransferObject
185
- attr_accessor :minimum_score, :maximum_score, :description
186
-
187
- validates :minimum_score, :maximum_score,
188
- inclusion: { in: (0..100) }
189
- validates :description,
190
- presence: true,
191
- type: String
192
- end
193
-
194
-
195
- # A container for all the Legends in the data set. Performs
196
- # validation on the whole set of Legends ensure they cover
197
- # the entire range of scores and do not overlap.
198
- class LegendGroup < DataTransferObject
199
- attr_accessor :legends
200
-
201
- # Check that all the items in this LegendGroup:
202
- #
203
- # 1. Are of the class, Legend
204
- # 2. Cover the range of scores from 0-100 without overlap
205
- class ComprehensiveValidator < ActiveModel::EachValidator
206
- def validate_each(record, attribute, legends)
207
- scores = (0..100).to_a
208
- legends.each do |legend|
209
- unless legend.class == Legend
210
- record.errors.add attribute, 'must be a Legend'
211
- return
212
- end
213
- range = (legend.minimum_score..legend.maximum_score)
214
- range.each do |score|
215
- if scores.delete(score).nil?
216
- unless score == legend.minimum_score || score == legend.maximum_score
217
- record.errors.add attribute, 'may not overlap'
218
- return
219
- end
220
- end
221
- end
222
- end
223
- record.errors.add attribute, 'do not cover entire span from 0–100' unless scores.empty?
224
- end
225
- end
226
-
227
- validates :legends, comprehensive: true
228
- end
229
-
230
- end
231
- end
232
- end