eaternet 0.2.2 → 0.3.0
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 +4 -4
- data/.gitignore +0 -1
- data/.inch.yml +5 -0
- data/Guardfile +36 -0
- data/README.md +23 -23
- data/Rakefile +1 -1
- data/eaternet.gemspec +13 -11
- data/lib/eaternet.rb +8 -4
- data/lib/eaternet/agencies/nyc.rb +44 -20
- data/lib/eaternet/agencies/snhd.rb +24 -21
- data/lib/eaternet/lives_1_0.rb +240 -0
- data/lib/eaternet/loggable.rb +16 -0
- data/lib/eaternet/prototype.rb +112 -0
- data/lib/eaternet/version.rb +1 -1
- data/test/lives_1_0/business_test.rb +7 -10
- data/test/lives_1_0/feed_info_test.rb +3 -6
- data/test/lives_1_0/inspection_test.rb +10 -13
- data/test/lives_1_0/legend_test.rb +23 -26
- data/test/loggable_test.rb +15 -0
- data/test/nyc_adapter_test.rb +8 -11
- data/test/snhd_adapter_test.rb +39 -7
- data/test/test_helper.rb +3 -0
- metadata +38 -4
- data/lib/eaternet/framework/lives_1_0.rb +0 -232
- data/lib/eaternet/framework/prototype.rb +0 -109
@@ -0,0 +1,16 @@
|
|
1
|
+
module Eaternet
|
2
|
+
module Loggable
|
3
|
+
|
4
|
+
def logger
|
5
|
+
@logger ||= create_logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_logger
|
9
|
+
logger = Logger.new(ENV['EATERNET_LOG_FILE'] || $stderr)
|
10
|
+
logger.datetime_format = '%Y-%m-%d %H:%M:%S'
|
11
|
+
logger.progname = 'Eaternet'
|
12
|
+
logger
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Eaternet
|
2
|
+
# A first pass at a health scores mini-framework which
|
3
|
+
# is denormalized and provides some more information than
|
4
|
+
# LIVES.
|
5
|
+
#:nodoc:
|
6
|
+
module Prototype
|
7
|
+
|
8
|
+
module AbstractAdapter
|
9
|
+
# @return [Enumerable<BusinessData>]
|
10
|
+
def businesses
|
11
|
+
fail 'Override this to return an Enumerable of BusinessData'
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Enumerable<InspectionData>]
|
15
|
+
def inspections
|
16
|
+
fail 'Override this to return an Enumerable of InspectionData'
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Enumerable<ViolationData>]
|
20
|
+
def violations
|
21
|
+
fail 'Override this to return an Enumerable of ViolationData'
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Enumerable<ViolationData>]
|
25
|
+
def violation_kinds
|
26
|
+
fail 'Override this to return an Enumerable of ViolationKindData'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class BusinessData
|
31
|
+
# @return [String]
|
32
|
+
attr_reader :name, :address, :city, :zipcode, :orig_key
|
33
|
+
|
34
|
+
#:nodoc:
|
35
|
+
def initialize(name:, address:, city:, zipcode:, orig_key:)
|
36
|
+
@name = name
|
37
|
+
@address = address
|
38
|
+
@city = city
|
39
|
+
@zipcode = zipcode
|
40
|
+
@orig_key = orig_key
|
41
|
+
end
|
42
|
+
|
43
|
+
def ==(other)
|
44
|
+
@orig_key == other.orig_key
|
45
|
+
end
|
46
|
+
|
47
|
+
def eql?(other)
|
48
|
+
self == other
|
49
|
+
end
|
50
|
+
|
51
|
+
def hash
|
52
|
+
@orig_key.hash
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [String]
|
56
|
+
def to_s
|
57
|
+
"Business #{@orig_key}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
#:nodoc:
|
62
|
+
class InspectionData
|
63
|
+
# @return [String]
|
64
|
+
attr_reader :orig_key, :business_orig_key, :score, :date
|
65
|
+
|
66
|
+
def initialize(orig_key:, business_orig_key:, score:, date:)
|
67
|
+
@orig_key = orig_key
|
68
|
+
@business_orig_key = business_orig_key
|
69
|
+
@score = score
|
70
|
+
@date = date
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
"Inspection #{@orig_key}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#:nodoc:
|
79
|
+
class ViolationData
|
80
|
+
# @return [String]
|
81
|
+
attr_reader :orig_key, :inspection_id, :violation_kind_id
|
82
|
+
|
83
|
+
def initialize(orig_key:, inspection_id:, violation_kind_id:)
|
84
|
+
@orig_key = orig_key
|
85
|
+
@inspection_id = inspection_id
|
86
|
+
@violation_kind_id = violation_kind_id
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_s
|
90
|
+
"Violation #{@orig_key}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#:nodoc:
|
95
|
+
class ViolationKindData
|
96
|
+
# @return [String]
|
97
|
+
attr_reader :orig_key, :code, :demerits, :description
|
98
|
+
|
99
|
+
def initialize(orig_key:, code:, demerits:, description:)
|
100
|
+
@orig_key = orig_key
|
101
|
+
@code = code
|
102
|
+
@demerits = demerits
|
103
|
+
@description = description
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_s
|
107
|
+
"ViolationKind #{@orig_key}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
data/lib/eaternet/version.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
require 'eaternet/
|
3
|
+
require 'eaternet/lives_1_0'
|
4
4
|
|
5
5
|
class BusinessTest < Minitest::Test
|
6
|
-
include Eaternet::Framework
|
7
|
-
|
8
6
|
#
|
9
7
|
# Business#latitude and Business#longitude
|
10
8
|
#
|
@@ -12,7 +10,7 @@ class BusinessTest < Minitest::Test
|
|
12
10
|
PORTLAND_OR_US = { lat: 45.5236111, lon: -122.675 }
|
13
11
|
|
14
12
|
def test_business_without_lat_and_lon
|
15
|
-
business = Lives_1_0::Business.new do |i|
|
13
|
+
business = Eaternet::Lives_1_0::Business.new do |i|
|
16
14
|
i.business_id = '789123hjd'
|
17
15
|
i.name = 'Starbucks'
|
18
16
|
i.address = '123 Happy Lane'
|
@@ -22,7 +20,7 @@ class BusinessTest < Minitest::Test
|
|
22
20
|
|
23
21
|
def test_business_rejects_lat_and_lon_which_are_not_numbers
|
24
22
|
assert_raises(ArgumentError) {
|
25
|
-
|
23
|
+
Eaternet::Lives_1_0::Business.new do |i|
|
26
24
|
i.business_id = '789123hjd'
|
27
25
|
i.name = 'Starbucks'
|
28
26
|
i.address = '123 Happy Lane'
|
@@ -33,7 +31,7 @@ class BusinessTest < Minitest::Test
|
|
33
31
|
end
|
34
32
|
|
35
33
|
def test_business_with_lat_and_lon
|
36
|
-
business = Lives_1_0::Business.new do |i|
|
34
|
+
business = Eaternet::Lives_1_0::Business.new do |i|
|
37
35
|
i.business_id = '789123hjd'
|
38
36
|
i.name = 'Starbucks'
|
39
37
|
i.address = '123 Happy Lane'
|
@@ -45,7 +43,7 @@ class BusinessTest < Minitest::Test
|
|
45
43
|
|
46
44
|
def test_business_rejects_invalid_latitude
|
47
45
|
assert_raises(ArgumentError) {
|
48
|
-
|
46
|
+
Eaternet::Lives_1_0::Business.new do |i|
|
49
47
|
i.business_id = '789123hjd'
|
50
48
|
i.name = 'Starbucks'
|
51
49
|
i.address = '123 Happy Lane'
|
@@ -57,7 +55,7 @@ class BusinessTest < Minitest::Test
|
|
57
55
|
|
58
56
|
def test_business_rejects_invalid_longitude
|
59
57
|
assert_raises(ArgumentError) {
|
60
|
-
|
58
|
+
Eaternet::Lives_1_0::Business.new do |i|
|
61
59
|
i.business_id = '789123hjd'
|
62
60
|
i.name = 'Starbucks'
|
63
61
|
i.address = '123 Happy Lane'
|
@@ -73,12 +71,11 @@ class BusinessTest < Minitest::Test
|
|
73
71
|
|
74
72
|
def test_business_rejects_blank_name
|
75
73
|
assert_raises(ArgumentError) {
|
76
|
-
|
74
|
+
Eaternet::Lives_1_0::Business.new do |i|
|
77
75
|
i.business_id = '789123hjd'
|
78
76
|
i.name = ''
|
79
77
|
i.address = '123 Happy Lane'
|
80
78
|
end
|
81
79
|
}
|
82
80
|
end
|
83
|
-
|
84
81
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
require 'eaternet/
|
3
|
+
require 'eaternet/lives_1_0'
|
4
4
|
|
5
5
|
class FeedInfoTest < Minitest::Test
|
6
|
-
include Eaternet::Framework::Lives_1_0
|
7
|
-
|
8
6
|
def set_required_attrs(feed_info)
|
9
7
|
feed_info.feed_date = Date.new(2015, 1, 1)
|
10
8
|
feed_info.feed_version = '1.0'
|
@@ -12,7 +10,7 @@ class FeedInfoTest < Minitest::Test
|
|
12
10
|
end
|
13
11
|
|
14
12
|
def setup
|
15
|
-
@dallas = FeedInfo.new { |i| set_required_attrs(i) }
|
13
|
+
@dallas = Eaternet::Lives_1_0::FeedInfo.new { |i| set_required_attrs(i) }
|
16
14
|
end
|
17
15
|
|
18
16
|
|
@@ -22,7 +20,7 @@ class FeedInfoTest < Minitest::Test
|
|
22
20
|
|
23
21
|
def test_rejects_when_missing_feed_date
|
24
22
|
assert_raises(ArgumentError) {
|
25
|
-
FeedInfo.new do |i|
|
23
|
+
Eaternet::Lives_1_0::FeedInfo.new do |i|
|
26
24
|
i.feed_version = '1.0'
|
27
25
|
i.municipality_name = 'NYC'
|
28
26
|
end
|
@@ -66,5 +64,4 @@ class FeedInfoTest < Minitest::Test
|
|
66
64
|
@dallas.contact_email = 'myaddress.com'
|
67
65
|
refute @dallas.valid?
|
68
66
|
end
|
69
|
-
|
70
67
|
end
|
@@ -1,16 +1,14 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
require 'eaternet/
|
3
|
+
require 'eaternet/lives_1_0'
|
4
4
|
|
5
5
|
class InspectionTest < Minitest::Test
|
6
|
-
include Eaternet::Framework
|
7
|
-
|
8
6
|
#
|
9
7
|
# Inspection#type
|
10
8
|
#
|
11
9
|
|
12
10
|
def test_with_a_valid_type
|
13
|
-
inspection = Lives_1_0::Inspection.new do |i|
|
11
|
+
inspection = Eaternet::Lives_1_0::Inspection.new do |i|
|
14
12
|
i.business_id = 'abcdef1'
|
15
13
|
i.score = 98
|
16
14
|
i.date = Date.new(2012, 2, 3)
|
@@ -21,7 +19,7 @@ class InspectionTest < Minitest::Test
|
|
21
19
|
|
22
20
|
def test_rejects_unspecified_types
|
23
21
|
assert_raises(ArgumentError) {
|
24
|
-
inspection = Lives_1_0::Inspection.new do |i|
|
22
|
+
inspection = Eaternet::Lives_1_0::Inspection.new do |i|
|
25
23
|
i.business_id = 'abcdef1'
|
26
24
|
i.score = 98
|
27
25
|
i.date = Date.new(2012, 2, 3)
|
@@ -31,7 +29,7 @@ class InspectionTest < Minitest::Test
|
|
31
29
|
end
|
32
30
|
|
33
31
|
def test_without_a_type
|
34
|
-
inspection = Lives_1_0::Inspection.new do |i|
|
32
|
+
inspection = Eaternet::Lives_1_0::Inspection.new do |i|
|
35
33
|
i.business_id = 'abcdef1'
|
36
34
|
i.score = 98
|
37
35
|
i.date = Date.new(2012, 2, 3)
|
@@ -45,7 +43,7 @@ class InspectionTest < Minitest::Test
|
|
45
43
|
#
|
46
44
|
|
47
45
|
def test_accepts_a_blank_score
|
48
|
-
inspection = Lives_1_0::Inspection.new do |i|
|
46
|
+
inspection = Eaternet::Lives_1_0::Inspection.new do |i|
|
49
47
|
i.score = ''
|
50
48
|
i.business_id = 'abcdef1'
|
51
49
|
i.date = Date.new(2012, 2, 3)
|
@@ -54,7 +52,7 @@ class InspectionTest < Minitest::Test
|
|
54
52
|
end
|
55
53
|
|
56
54
|
def test_accepts_a_numeric_score
|
57
|
-
inspection = Lives_1_0::Inspection.new do |i|
|
55
|
+
inspection = Eaternet::Lives_1_0::Inspection.new do |i|
|
58
56
|
i.score = 96
|
59
57
|
i.business_id = 'abcdef1'
|
60
58
|
i.date = Date.new(2012, 2, 3)
|
@@ -64,7 +62,7 @@ class InspectionTest < Minitest::Test
|
|
64
62
|
|
65
63
|
def test_rejects_a_score_out_of_bounds
|
66
64
|
assert_raises(ArgumentError) {
|
67
|
-
|
65
|
+
Eaternet::Lives_1_0::Inspection.new do |i|
|
68
66
|
i.score = 101
|
69
67
|
i.business_id = 'abcdef1'
|
70
68
|
i.date = Date.new(2012, 2, 3)
|
@@ -74,14 +72,14 @@ class InspectionTest < Minitest::Test
|
|
74
72
|
|
75
73
|
def test_rejects_a_non_numeric_score
|
76
74
|
assert_raises(ArgumentError) {
|
77
|
-
|
75
|
+
Eaternet::Lives_1_0::Inspection.new do |i|
|
78
76
|
i.score = '100'
|
79
77
|
i.business_id = 'abcdef1'
|
80
78
|
i.date = Date.new(2012, 2, 3)
|
81
79
|
end
|
82
80
|
}
|
83
81
|
assert_raises(ArgumentError) {
|
84
|
-
|
82
|
+
Eaternet::Lives_1_0::Inspection.new do |i|
|
85
83
|
i.score = 'A'
|
86
84
|
i.business_id = 'abcdef1'
|
87
85
|
i.date = Date.new(2012, 2, 3)
|
@@ -90,11 +88,10 @@ class InspectionTest < Minitest::Test
|
|
90
88
|
end
|
91
89
|
|
92
90
|
def test_with_no_score_sets_it_to_blank
|
93
|
-
inspection = Lives_1_0::Inspection.new do |i|
|
91
|
+
inspection = Eaternet::Lives_1_0::Inspection.new do |i|
|
94
92
|
i.business_id = 'abcdef1'
|
95
93
|
i.date = Date.new(2012, 2, 3)
|
96
94
|
end
|
97
95
|
assert_equal('', inspection.score)
|
98
96
|
end
|
99
|
-
|
100
97
|
end
|
@@ -1,18 +1,16 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
require 'eaternet/
|
3
|
+
require 'eaternet/lives_1_0'
|
4
4
|
|
5
5
|
class LegendTest < Minitest::Test
|
6
|
-
|
7
|
-
|
8
|
-
def set_required_attrs(legend_record)
|
6
|
+
def setup_required_attrs(legend_record)
|
9
7
|
legend_record.minimum_score = 98
|
10
8
|
legend_record.maximum_score = 100
|
11
9
|
legend_record.description = 'A+'
|
12
10
|
end
|
13
11
|
|
14
12
|
def setup
|
15
|
-
@a_plus = Legend.new { |l|
|
13
|
+
@a_plus = Eaternet::Lives_1_0::Legend.new { |l| setup_required_attrs(l) }
|
16
14
|
end
|
17
15
|
|
18
16
|
|
@@ -32,7 +30,7 @@ class LegendTest < Minitest::Test
|
|
32
30
|
|
33
31
|
def test_rejects_when_missing_maximum_score
|
34
32
|
assert_raises(ArgumentError) {
|
35
|
-
Legend.new do |legend_record|
|
33
|
+
Eaternet::Lives_1_0::Legend.new do |legend_record|
|
36
34
|
legend_record.minimum_score = 100
|
37
35
|
legend_record.description = 'A+'
|
38
36
|
end
|
@@ -41,7 +39,7 @@ class LegendTest < Minitest::Test
|
|
41
39
|
|
42
40
|
def test_rejects_when_missing_minimum_score
|
43
41
|
assert_raises(ArgumentError) {
|
44
|
-
Legend.new do |legend_record|
|
42
|
+
Eaternet::Lives_1_0::Legend.new do |legend_record|
|
45
43
|
legend_record.maximum_score = 100
|
46
44
|
legend_record.description = 'A+'
|
47
45
|
end
|
@@ -50,7 +48,7 @@ class LegendTest < Minitest::Test
|
|
50
48
|
|
51
49
|
def test_rejects_when_missing_description
|
52
50
|
assert_raises(ArgumentError) {
|
53
|
-
Legend.new do |legend_record|
|
51
|
+
Eaternet::Lives_1_0::Legend.new do |legend_record|
|
54
52
|
legend_record.minimum_score = 95
|
55
53
|
legend_record.maximum_score = 100
|
56
54
|
end
|
@@ -58,7 +56,7 @@ class LegendTest < Minitest::Test
|
|
58
56
|
end
|
59
57
|
|
60
58
|
def test_rejects_when_description_not_a_string
|
61
|
-
@a_plus.description =
|
59
|
+
@a_plus.description = %w(the highest score)
|
62
60
|
refute @a_plus.valid?
|
63
61
|
end
|
64
62
|
|
@@ -67,41 +65,41 @@ class LegendTest < Minitest::Test
|
|
67
65
|
#
|
68
66
|
|
69
67
|
def test_group_accepts_comprehensive_records
|
70
|
-
group = LegendGroup.new do |lg|
|
68
|
+
group = Eaternet::Lives_1_0::LegendGroup.new do |lg|
|
71
69
|
lg.legends = [
|
72
|
-
Legend.new do |l|
|
70
|
+
Eaternet::Lives_1_0::Legend.new do |l|
|
73
71
|
l.minimum_score = 95
|
74
72
|
l.maximum_score = 100
|
75
73
|
l.description = 'A+'
|
76
74
|
end,
|
77
|
-
Legend.new do |l|
|
75
|
+
Eaternet::Lives_1_0::Legend.new do |l|
|
78
76
|
l.minimum_score = 0
|
79
77
|
l.maximum_score = 94
|
80
78
|
l.description = 'F'
|
81
|
-
end
|
79
|
+
end
|
82
80
|
]
|
83
81
|
end
|
84
82
|
refute_nil group
|
85
83
|
end
|
86
84
|
|
87
85
|
def test_group_accepts_records_overlapping_by_1
|
88
|
-
group = LegendGroup.new do |lg|
|
86
|
+
group = Eaternet::Lives_1_0::LegendGroup.new do |lg|
|
89
87
|
lg.legends = [
|
90
|
-
Legend.new do |l|
|
88
|
+
Eaternet::Lives_1_0::Legend.new do |l|
|
91
89
|
l.minimum_score = 95
|
92
90
|
l.maximum_score = 100
|
93
91
|
l.description = 'A+'
|
94
92
|
end,
|
95
|
-
Legend.new do |l|
|
93
|
+
Eaternet::Lives_1_0::Legend.new do |l|
|
96
94
|
l.minimum_score = 70
|
97
95
|
l.maximum_score = 95
|
98
96
|
l.description = 'B'
|
99
97
|
end,
|
100
|
-
Legend.new do |l|
|
98
|
+
Eaternet::Lives_1_0::Legend.new do |l|
|
101
99
|
l.minimum_score = 0
|
102
100
|
l.maximum_score = 69
|
103
101
|
l.description = 'F'
|
104
|
-
end
|
102
|
+
end
|
105
103
|
]
|
106
104
|
end
|
107
105
|
refute_nil group
|
@@ -109,22 +107,22 @@ class LegendTest < Minitest::Test
|
|
109
107
|
|
110
108
|
def test_legend_group_rejects_non_comprehensive_records
|
111
109
|
assert_raises(ArgumentError) {
|
112
|
-
|
113
|
-
lg.legends = [
|
110
|
+
Eaternet::Lives_1_0::LegendGroup.new do |lg|
|
111
|
+
lg.legends = [@a_plus]
|
114
112
|
end
|
115
113
|
}
|
116
114
|
end
|
117
115
|
|
118
116
|
def test_legend_group_rejects_overlapping_records
|
119
117
|
assert_raises(ArgumentError) {
|
120
|
-
|
118
|
+
Eaternet::Lives_1_0::LegendGroup.new do |lg|
|
121
119
|
lg.legends = [
|
122
|
-
Legend.new do |l|
|
120
|
+
Eaternet::Lives_1_0::Legend.new do |l|
|
123
121
|
l.minimum_score = 90
|
124
122
|
l.maximum_score = 100
|
125
123
|
l.description = 'A'
|
126
124
|
end,
|
127
|
-
Legend.new do |l|
|
125
|
+
Eaternet::Lives_1_0::Legend.new do |l|
|
128
126
|
l.minimum_score = 0
|
129
127
|
l.maximum_score = 91
|
130
128
|
l.description = 'B'
|
@@ -136,9 +134,9 @@ class LegendTest < Minitest::Test
|
|
136
134
|
|
137
135
|
def test_legend_group_rejects_non_legend_objects
|
138
136
|
assert_raises(ArgumentError) {
|
139
|
-
|
137
|
+
Eaternet::Lives_1_0::LegendGroup.new do |lg|
|
140
138
|
lg.legends = [
|
141
|
-
Legend.new do |l|
|
139
|
+
Eaternet::Lives_1_0::Legend.new do |l|
|
142
140
|
l.minimum_score = 90
|
143
141
|
l.maximum_score = 100
|
144
142
|
l.description = 'A'
|
@@ -148,5 +146,4 @@ class LegendTest < Minitest::Test
|
|
148
146
|
end
|
149
147
|
}
|
150
148
|
end
|
151
|
-
|
152
149
|
end
|