eaternet 0.2.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 +7 -0
- data/.gitignore +25 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +202 -0
- data/README.md +78 -0
- data/Rakefile +10 -0
- data/eaternet.gemspec +32 -0
- data/lib/eaternet.rb +9 -0
- data/lib/eaternet/agencies/nyc.rb +184 -0
- data/lib/eaternet/agencies/snhd.rb +118 -0
- data/lib/eaternet/agencies/snhd_config.rb +61 -0
- data/lib/eaternet/framework/lives_1_0.rb +232 -0
- data/lib/eaternet/framework/prototype.rb +109 -0
- data/lib/eaternet/util.rb +38 -0
- data/lib/eaternet/version.rb +3 -0
- data/lib/ext/lazy.rb +13 -0
- data/test/fixtures/morris-park-bake-shop.csv +23 -0
- data/test/lives_1_0/business_test.rb +84 -0
- data/test/lives_1_0/feed_info_test.rb +70 -0
- data/test/lives_1_0/inspection_test.rb +100 -0
- data/test/lives_1_0/legend_test.rb +152 -0
- data/test/nyc_adapter_test.rb +96 -0
- data/test/snhd_adapter_test.rb +99 -0
- data/test/test_helper.rb +14 -0
- metadata +203 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'zip'
|
3
|
+
|
4
|
+
module Eaternet
|
5
|
+
module Util
|
6
|
+
# A utility function to download a zip file,
|
7
|
+
# extract it into a temp directory.
|
8
|
+
#
|
9
|
+
# @return [String] the directory path
|
10
|
+
def self.download_and_extract_zipfile(url)
|
11
|
+
dir = make_temp_dir
|
12
|
+
zip_path = File.join(dir, 'zip-file.zip')
|
13
|
+
download(source: url, dest: zip_path)
|
14
|
+
extract_zipfile(path: zip_path, dest_dir: dir)
|
15
|
+
dir
|
16
|
+
end
|
17
|
+
|
18
|
+
# Create a temporary directory which is automatically
|
19
|
+
# deleted when the program exits.
|
20
|
+
def self.make_temp_dir
|
21
|
+
dir = Dir.mktmpdir
|
22
|
+
at_exit { FileUtils.remove_entry dir }
|
23
|
+
dir
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.download(source:, dest:)
|
27
|
+
open(dest, 'wb') { |file| file << open(source).read }
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.extract_zipfile(path:, dest_dir:)
|
31
|
+
open(path) do |zip_file|
|
32
|
+
Zip::File.open(zip_file, 'rb') do |zip_data|
|
33
|
+
zip_data.each { |entry| entry.extract(File.join(dest_dir, entry.name)) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/ext/lazy.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
CAMIS,DBA,BORO,BUILDING,STREET,ZIPCODE,PHONE,CUISINE DESCRIPTION,INSPECTION DATE,ACTION,VIOLATION CODE,VIOLATION DESCRIPTION,CRITICAL FLAG,SCORE,GRADE,GRADE DATE,RECORD DATE,INSPECTION TYPE
|
2
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,02/09/2015,Violations were cited in the following area(s).,06C,"Food not protected from potential source of contamination during storage, preparation, transportation, display or service.",Critical,6,A,02/09/2015,03/06/2015,Cycle Inspection / Initial Inspection
|
3
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,03/03/2014,Violations were cited in the following area(s).,10F,"Non-food contact surface improperly constructed. Unacceptable material used. Non-food contact surface or equipment improperly maintained and/or not properly sealed, raised, spaced or movable to allow accessibility for cleaning on all sides, above and underneath the unit.",Not Critical,2,A,03/03/2014,03/06/2015,Cycle Inspection / Initial Inspection
|
4
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,10/10/2013,No violations were recorded at the time of this inspection.,,,Not Applicable,,,,03/06/2015,Trans Fat / Second Compliance Inspection
|
5
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,09/11/2013,Violations were cited in the following area(s).,04L,Evidence of mice or live mice present in facility's food and/or non-food areas.,Critical,6,A,09/11/2013,03/06/2015,Cycle Inspection / Re-inspection
|
6
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,09/11/2013,Violations were cited in the following area(s).,04N,"Filth flies or food/refuse/sewage-associated (FRSA) flies present in facilitys food and/or non-food areas. Filth flies include house flies, little house flies, blow flies, bottle flies and flesh flies. Food/refuse/sewage-associated flies include fruit flies, drain flies and Phorid flies.",Critical,6,A,09/11/2013,03/06/2015,Cycle Inspection / Re-inspection
|
7
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,08/14/2013,Violations were cited in the following area(s).,04C,Food worker does not use proper utensil to eliminate bare hand contact with food that will not receive adequate additional heat treatment.,Critical,32,,,03/06/2015,Cycle Inspection / Initial Inspection
|
8
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,08/14/2013,Violations were cited in the following area(s).,04L,Evidence of mice or live mice present in facility's food and/or non-food areas.,Critical,32,,,03/06/2015,Cycle Inspection / Initial Inspection
|
9
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,08/14/2013,Violations were cited in the following area(s).,06A,Personal cleanliness inadequate. Outer garment soiled with possible contaminant. Effective hair restraint not worn in an area where food is prepared.,Critical,32,,,03/06/2015,Cycle Inspection / Initial Inspection
|
10
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,08/14/2013,Violations were cited in the following area(s).,06C,"Food not protected from potential source of contamination during storage, preparation, transportation, display or service.",Critical,32,,,03/06/2015,Cycle Inspection / Initial Inspection
|
11
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,08/14/2013,Violations were cited in the following area(s).,08A,Facility not vermin proof. Harborage or conditions conducive to attracting vermin to the premises and/or allowing vermin to exist.,Not Critical,32,,,03/06/2015,Cycle Inspection / Initial Inspection
|
12
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,08/14/2013,Violations were cited in the following area(s).,10F,"Non-food contact surface improperly constructed. Unacceptable material used. Non-food contact surface or equipment improperly maintained and/or not properly sealed, raised, spaced or movable to allow accessibility for cleaning on all sides, above and underneath the unit.",Not Critical,32,,,03/06/2015,Cycle Inspection / Initial Inspection
|
13
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,06/01/2013,Violations were cited in the following area(s).,16B,"The original nutritional fact labels and/or ingredient label for a cooking oil, shortening or margarine or food item sold in bulk, or acceptable manufacturers documentation not maintained on site.",Not Critical,,,,03/06/2015,Trans Fat / Compliance Inspection
|
14
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,01/24/2013,Violations were cited in the following area(s).,02G,Cold food item held above 41º F (smoked fish and reduced oxygen packaged foods above 38 ºF) except during necessary preparation.,Critical,10,A,01/24/2013,03/06/2015,Cycle Inspection / Re-inspection
|
15
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,01/24/2013,Violations were cited in the following area(s).,10F,"Non-food contact surface improperly constructed. Unacceptable material used. Non-food contact surface or equipment improperly maintained and/or not properly sealed, raised, spaced or movable to allow accessibility for cleaning on all sides, above and underneath the unit.",Not Critical,10,A,01/24/2013,03/06/2015,Cycle Inspection / Re-inspection
|
16
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,01/24/2013,No violations were recorded at the time of this inspection.,,,Not Applicable,,,,03/06/2015,Trans Fat / Re-inspection
|
17
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,12/31/2012,Violations were cited in the following area(s).,02G,Cold food item held above 41º F (smoked fish and reduced oxygen packaged foods above 38 ºF) except during necessary preparation.,Critical,25,,,03/06/2015,Cycle Inspection / Initial Inspection
|
18
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,12/31/2012,Violations were cited in the following area(s).,04L,Evidence of mice or live mice present in facility's food and/or non-food areas.,Critical,25,,,03/06/2015,Cycle Inspection / Initial Inspection
|
19
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,12/31/2012,Violations were cited in the following area(s).,06C,"Food not protected from potential source of contamination during storage, preparation, transportation, display or service.",Critical,25,,,03/06/2015,Cycle Inspection / Initial Inspection
|
20
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,12/31/2012,Violations were cited in the following area(s).,08A,Facility not vermin proof. Harborage or conditions conducive to attracting vermin to the premises and/or allowing vermin to exist.,Not Critical,25,,,03/06/2015,Cycle Inspection / Initial Inspection
|
21
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,12/31/2012,Violations were cited in the following area(s).,10F,"Non-food contact surface improperly constructed. Unacceptable material used. Non-food contact surface or equipment improperly maintained and/or not properly sealed, raised, spaced or movable to allow accessibility for cleaning on all sides, above and underneath the unit.",Not Critical,25,,,03/06/2015,Cycle Inspection / Initial Inspection
|
22
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,12/31/2012,Violations were cited in the following area(s).,16B,"The original nutritional fact labels and/or ingredient label for a cooking oil, shortening or margarine or food item sold in bulk, or acceptable manufacturers documentation not maintained on site.",Not Critical,,,,03/06/2015,Trans Fat / Initial Inspection
|
23
|
+
30075445,MORRIS PARK BAKE SHOP,BRONX,1007,MORRIS PARK AVE,10462,7188924968,Bakery,05/03/2012,No violations were recorded at the time of this inspection.,,,Not Applicable,,,,03/06/2015,Trans Fat / Second Compliance Inspection
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'eaternet/framework/lives_1_0'
|
4
|
+
include Eaternet::Framework
|
5
|
+
|
6
|
+
class BusinessTest < Minitest::Test
|
7
|
+
|
8
|
+
#
|
9
|
+
# Business#latitude and Business#longitude
|
10
|
+
#
|
11
|
+
|
12
|
+
PORTLAND_OR_US = { lat: 45.5236111, lon: -122.675 }
|
13
|
+
|
14
|
+
def test_business_without_lat_and_lon
|
15
|
+
business = Lives_1_0::Business.new do |i|
|
16
|
+
i.business_id = '789123hjd'
|
17
|
+
i.name = 'Starbucks'
|
18
|
+
i.address = '123 Happy Lane'
|
19
|
+
end
|
20
|
+
refute_nil business
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_business_rejects_lat_and_lon_which_are_not_numbers
|
24
|
+
assert_raises(ArgumentError) {
|
25
|
+
business = Lives_1_0::Business.new do |i|
|
26
|
+
i.business_id = '789123hjd'
|
27
|
+
i.name = 'Starbucks'
|
28
|
+
i.address = '123 Happy Lane'
|
29
|
+
i.latitude = 'north'
|
30
|
+
i.longitude = '45.2'
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_business_with_lat_and_lon
|
36
|
+
business = Lives_1_0::Business.new do |i|
|
37
|
+
i.business_id = '789123hjd'
|
38
|
+
i.name = 'Starbucks'
|
39
|
+
i.address = '123 Happy Lane'
|
40
|
+
i.latitude = PORTLAND_OR_US[:lat]
|
41
|
+
i.longitude = PORTLAND_OR_US[:lon]
|
42
|
+
end
|
43
|
+
refute_nil business
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_business_rejects_invalid_latitude
|
47
|
+
assert_raises(ArgumentError) {
|
48
|
+
business = Lives_1_0::Business.new do |i|
|
49
|
+
i.business_id = '789123hjd'
|
50
|
+
i.name = 'Starbucks'
|
51
|
+
i.address = '123 Happy Lane'
|
52
|
+
i.latitude = 91
|
53
|
+
i.longitude = PORTLAND_OR_US[:lon]
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_business_rejects_invalid_longitude
|
59
|
+
assert_raises(ArgumentError) {
|
60
|
+
business = Lives_1_0::Business.new do |i|
|
61
|
+
i.business_id = '789123hjd'
|
62
|
+
i.name = 'Starbucks'
|
63
|
+
i.address = '123 Happy Lane'
|
64
|
+
i.latitude = PORTLAND_OR_US[:lat]
|
65
|
+
i.longitude = -181
|
66
|
+
end
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Business#name
|
72
|
+
#
|
73
|
+
|
74
|
+
def test_business_rejects_blank_name
|
75
|
+
assert_raises(ArgumentError) {
|
76
|
+
business = Lives_1_0::Business.new do |i|
|
77
|
+
i.business_id = '789123hjd'
|
78
|
+
i.name = ''
|
79
|
+
i.address = '123 Happy Lane'
|
80
|
+
end
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'eaternet/framework/lives_1_0'
|
4
|
+
include Eaternet::Framework::Lives_1_0
|
5
|
+
|
6
|
+
class FeedInfoTest < Minitest::Test
|
7
|
+
|
8
|
+
def set_required_attrs(feed_info)
|
9
|
+
feed_info.feed_date = Date.new(2015, 1, 1)
|
10
|
+
feed_info.feed_version = '1.0'
|
11
|
+
feed_info.municipality_name = 'Dallas'
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@dallas = FeedInfo.new { |i| set_required_attrs(i) }
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
#
|
20
|
+
# FeedInfo#date
|
21
|
+
#
|
22
|
+
|
23
|
+
def test_rejects_when_missing_feed_date
|
24
|
+
assert_raises(ArgumentError) {
|
25
|
+
FeedInfo.new do |i|
|
26
|
+
i.feed_version = '1.0'
|
27
|
+
i.municipality_name = 'NYC'
|
28
|
+
end
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_rejects_incorrect_feed_date_type
|
33
|
+
@dallas.feed_date = '2015-01-01'
|
34
|
+
refute @dallas.valid?
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_rejects_nil_feed_date
|
38
|
+
@dallas.feed_date = nil
|
39
|
+
refute @dallas.valid?
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# FeedInfo#municipality_url
|
44
|
+
#
|
45
|
+
|
46
|
+
def test_with_url
|
47
|
+
@dallas.municipality_url = 'http://www.nyc.gov/html/doh/html/services/restaurant-inspection.shtml'
|
48
|
+
assert @dallas.valid?
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_rejects_malformed_url
|
52
|
+
@dallas.municipality_url = 'www.nyc.gov'
|
53
|
+
refute @dallas.valid?
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# FeedInfo#contact_email
|
58
|
+
#
|
59
|
+
|
60
|
+
def test_with_email
|
61
|
+
@dallas.contact_email = 'Pressoffice@health.nyc.gov'
|
62
|
+
assert @dallas.valid?
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_rejects_malformed_email
|
66
|
+
@dallas.contact_email = 'myaddress.com'
|
67
|
+
refute @dallas.valid?
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'eaternet/framework/lives_1_0'
|
4
|
+
include Eaternet::Framework
|
5
|
+
|
6
|
+
class InspectionTest < Minitest::Test
|
7
|
+
|
8
|
+
#
|
9
|
+
# Inspection#type
|
10
|
+
#
|
11
|
+
|
12
|
+
def test_with_a_valid_type
|
13
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
14
|
+
i.business_id = 'abcdef1'
|
15
|
+
i.score = 98
|
16
|
+
i.date = Date.new(2012, 2, 3)
|
17
|
+
i.type = 'initial'
|
18
|
+
end
|
19
|
+
refute_nil inspection
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_rejects_unspecified_types
|
23
|
+
assert_raises(ArgumentError) {
|
24
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
25
|
+
i.business_id = 'abcdef1'
|
26
|
+
i.score = 98
|
27
|
+
i.date = Date.new(2012, 2, 3)
|
28
|
+
i.type = 'auto inspection'
|
29
|
+
end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_without_a_type
|
34
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
35
|
+
i.business_id = 'abcdef1'
|
36
|
+
i.score = 98
|
37
|
+
i.date = Date.new(2012, 2, 3)
|
38
|
+
end
|
39
|
+
refute_nil inspection
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
#
|
44
|
+
# Inspection#score
|
45
|
+
#
|
46
|
+
|
47
|
+
def test_accepts_a_blank_score
|
48
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
49
|
+
i.score = ''
|
50
|
+
i.business_id = 'abcdef1'
|
51
|
+
i.date = Date.new(2012, 2, 3)
|
52
|
+
end
|
53
|
+
refute_nil inspection
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_accepts_a_numeric_score
|
57
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
58
|
+
i.score = 96
|
59
|
+
i.business_id = 'abcdef1'
|
60
|
+
i.date = Date.new(2012, 2, 3)
|
61
|
+
end
|
62
|
+
refute_nil inspection
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_rejects_a_score_out_of_bounds
|
66
|
+
assert_raises(ArgumentError) {
|
67
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
68
|
+
i.score = 101
|
69
|
+
i.business_id = 'abcdef1'
|
70
|
+
i.date = Date.new(2012, 2, 3)
|
71
|
+
end
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_rejects_a_non_numeric_score
|
76
|
+
assert_raises(ArgumentError) {
|
77
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
78
|
+
i.score = '100'
|
79
|
+
i.business_id = 'abcdef1'
|
80
|
+
i.date = Date.new(2012, 2, 3)
|
81
|
+
end
|
82
|
+
}
|
83
|
+
assert_raises(ArgumentError) {
|
84
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
85
|
+
i.score = 'A'
|
86
|
+
i.business_id = 'abcdef1'
|
87
|
+
i.date = Date.new(2012, 2, 3)
|
88
|
+
end
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_with_no_score_sets_it_to_blank
|
93
|
+
inspection = Lives_1_0::Inspection.new do |i|
|
94
|
+
i.business_id = 'abcdef1'
|
95
|
+
i.date = Date.new(2012, 2, 3)
|
96
|
+
end
|
97
|
+
assert_equal('', inspection.score)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'eaternet/framework/lives_1_0'
|
4
|
+
include Eaternet::Framework::Lives_1_0
|
5
|
+
|
6
|
+
class LegendTest < Minitest::Test
|
7
|
+
|
8
|
+
def set_required_attrs(legend_record)
|
9
|
+
legend_record.minimum_score = 98
|
10
|
+
legend_record.maximum_score = 100
|
11
|
+
legend_record.description = 'A+'
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@a_plus = Legend.new { |l| set_required_attrs(l) }
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def test_with_all_required_attributes
|
20
|
+
assert @a_plus.valid?
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_rejects_incorrect_minimum_type
|
24
|
+
@a_plus.minimum_score = '98'
|
25
|
+
refute @a_plus.valid?
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_rejects_incorrect_maximum_type
|
29
|
+
@a_plus.maximum_score = '100'
|
30
|
+
refute @a_plus.valid?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_rejects_when_missing_maximum_score
|
34
|
+
assert_raises(ArgumentError) {
|
35
|
+
Legend.new do |legend_record|
|
36
|
+
legend_record.minimum_score = 100
|
37
|
+
legend_record.description = 'A+'
|
38
|
+
end
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_rejects_when_missing_minimum_score
|
43
|
+
assert_raises(ArgumentError) {
|
44
|
+
Legend.new do |legend_record|
|
45
|
+
legend_record.maximum_score = 100
|
46
|
+
legend_record.description = 'A+'
|
47
|
+
end
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_rejects_when_missing_description
|
52
|
+
assert_raises(ArgumentError) {
|
53
|
+
Legend.new do |legend_record|
|
54
|
+
legend_record.minimum_score = 95
|
55
|
+
legend_record.maximum_score = 100
|
56
|
+
end
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_rejects_when_description_not_a_string
|
61
|
+
@a_plus.description = ['the', 'highest', 'score']
|
62
|
+
refute @a_plus.valid?
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# LegendGroup
|
67
|
+
#
|
68
|
+
|
69
|
+
def test_group_accepts_comprehensive_records
|
70
|
+
group = LegendGroup.new do |lg|
|
71
|
+
lg.legends = [
|
72
|
+
Legend.new do |l|
|
73
|
+
l.minimum_score = 95
|
74
|
+
l.maximum_score = 100
|
75
|
+
l.description = 'A+'
|
76
|
+
end,
|
77
|
+
Legend.new do |l|
|
78
|
+
l.minimum_score = 0
|
79
|
+
l.maximum_score = 94
|
80
|
+
l.description = 'F'
|
81
|
+
end,
|
82
|
+
]
|
83
|
+
end
|
84
|
+
refute_nil group
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_group_accepts_records_overlapping_by_1
|
88
|
+
group = LegendGroup.new do |lg|
|
89
|
+
lg.legends = [
|
90
|
+
Legend.new do |l|
|
91
|
+
l.minimum_score = 95
|
92
|
+
l.maximum_score = 100
|
93
|
+
l.description = 'A+'
|
94
|
+
end,
|
95
|
+
Legend.new do |l|
|
96
|
+
l.minimum_score = 70
|
97
|
+
l.maximum_score = 95
|
98
|
+
l.description = 'B'
|
99
|
+
end,
|
100
|
+
Legend.new do |l|
|
101
|
+
l.minimum_score = 0
|
102
|
+
l.maximum_score = 69
|
103
|
+
l.description = 'F'
|
104
|
+
end,
|
105
|
+
]
|
106
|
+
end
|
107
|
+
refute_nil group
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_legend_group_rejects_non_comprehensive_records
|
111
|
+
assert_raises(ArgumentError) {
|
112
|
+
group = LegendGroup.new do |lg|
|
113
|
+
lg.legends = [ @a_plus ]
|
114
|
+
end
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_legend_group_rejects_overlapping_records
|
119
|
+
assert_raises(ArgumentError) {
|
120
|
+
group = LegendGroup.new do |lg|
|
121
|
+
lg.legends = [
|
122
|
+
Legend.new do |l|
|
123
|
+
l.minimum_score = 90
|
124
|
+
l.maximum_score = 100
|
125
|
+
l.description = 'A'
|
126
|
+
end,
|
127
|
+
Legend.new do |l|
|
128
|
+
l.minimum_score = 0
|
129
|
+
l.maximum_score = 91
|
130
|
+
l.description = 'B'
|
131
|
+
end
|
132
|
+
]
|
133
|
+
end
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_legend_group_rejects_non_legend_objects
|
138
|
+
assert_raises(ArgumentError) {
|
139
|
+
group = LegendGroup.new do |lg|
|
140
|
+
lg.legends = [
|
141
|
+
Legend.new do |l|
|
142
|
+
l.minimum_score = 90
|
143
|
+
l.maximum_score = 100
|
144
|
+
l.description = 'A'
|
145
|
+
end,
|
146
|
+
'0-91, B'
|
147
|
+
]
|
148
|
+
end
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|