worlddb-models 2.1.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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/HISTORY.md +4 -0
  4. data/Manifest.txt +43 -0
  5. data/README.md +85 -0
  6. data/Rakefile +44 -0
  7. data/lib/worlddb/deleter.rb +32 -0
  8. data/lib/worlddb/matcher.rb +143 -0
  9. data/lib/worlddb/models/city.rb +240 -0
  10. data/lib/worlddb/models/city_comp.rb +27 -0
  11. data/lib/worlddb/models/continent.rb +41 -0
  12. data/lib/worlddb/models/continent_comp.rb +24 -0
  13. data/lib/worlddb/models/country.rb +328 -0
  14. data/lib/worlddb/models/country_code.rb +41 -0
  15. data/lib/worlddb/models/country_comp.rb +35 -0
  16. data/lib/worlddb/models/forward.rb +57 -0
  17. data/lib/worlddb/models/lang.rb +18 -0
  18. data/lib/worlddb/models/lang_comp.rb +23 -0
  19. data/lib/worlddb/models/name.rb +13 -0
  20. data/lib/worlddb/models/place.rb +16 -0
  21. data/lib/worlddb/models/region.rb +176 -0
  22. data/lib/worlddb/models/region_comp.rb +26 -0
  23. data/lib/worlddb/models/tagdb/tag.rb +16 -0
  24. data/lib/worlddb/models/tagdb/tagging.rb +15 -0
  25. data/lib/worlddb/models/usage.rb +17 -0
  26. data/lib/worlddb/models.rb +200 -0
  27. data/lib/worlddb/patterns.rb +54 -0
  28. data/lib/worlddb/reader.rb +224 -0
  29. data/lib/worlddb/reader_file.rb +86 -0
  30. data/lib/worlddb/reader_zip.rb +160 -0
  31. data/lib/worlddb/readers/city.rb +81 -0
  32. data/lib/worlddb/readers/country.rb +78 -0
  33. data/lib/worlddb/readers/lang.rb +107 -0
  34. data/lib/worlddb/readers/region.rb +79 -0
  35. data/lib/worlddb/readers/usage.rb +98 -0
  36. data/lib/worlddb/schema.rb +202 -0
  37. data/lib/worlddb/stats.rb +31 -0
  38. data/lib/worlddb/version.rb +23 -0
  39. data/test/helper.rb +26 -0
  40. data/test/test_fixture_matchers.rb +112 -0
  41. data/test/test_model_city.rb +60 -0
  42. data/test/test_model_comp.rb +48 -0
  43. data/test/test_model_country.rb +53 -0
  44. data/test/test_model_region.rb +50 -0
  45. data/test/test_models.rb +35 -0
  46. metadata +252 -0
@@ -0,0 +1,107 @@
1
+ # encoding: UTF-8
2
+
3
+ module WorldDb
4
+
5
+ class LangReader
6
+
7
+ include LogUtils::Logging
8
+
9
+ ## make models available by default with namespace
10
+ # e.g. lets you use Usage instead of Model::Usage
11
+ include Models
12
+
13
+ ## value helpers e.g. is_year?, is_taglist? etc.
14
+ include TextUtils::ValueHelper
15
+
16
+
17
+ ## todo: add opts={} etc.
18
+ def self.from_zip( zip_file, entry_path )
19
+ ## get text content from zip
20
+
21
+ entry = zip_file.find_entry( entry_path )
22
+
23
+ ## todo/fix: add force encoding to utf-8 ??
24
+ ## check!!!
25
+ ## clean/prepprocess lines
26
+ ## e.g. CR/LF (/r/n) to LF (e.g. /n)
27
+ text = entry.get_input_stream().read()
28
+
29
+ ## NOTE: needs logger ref; only available in instance methods; use global logger for now
30
+ logger = LogUtils::Logger.root
31
+ logger.debug "text.encoding.name (before): #{text.encoding.name}"
32
+ #####
33
+ # NB: ASCII-8BIT == BINARY == Encoding Unknown; Raw Bytes Here
34
+ ## NB:
35
+ # for now "hardcoded" to utf8 - what else can we do?
36
+ # - note: force_encoding will NOT change the chars only change the assumed encoding w/o translation
37
+ text = text.force_encoding( Encoding::UTF_8 )
38
+ logger.debug "text.encoding.name (after): #{text.encoding.name}"
39
+
40
+ ## todo:
41
+ # NB: for convenience: convert fancy unicode dashes/hyphens to plain ascii hyphen-minus
42
+ ## text = TextUtils.convert_unicode_dashes_to_plain_ascii( text, path: path )
43
+
44
+ self.from_string( text )
45
+ end
46
+
47
+ def self.from_file( path, opts={} )
48
+ ## note: assume/enfore utf-8 encoding (with or without BOM - byte order mark)
49
+ ## - see textutils/utils.rb
50
+ text = File.read_utf8( path )
51
+ self.from_string( text, opts )
52
+ end
53
+
54
+ def self.from_string( text, opts={} )
55
+ LangReader.new( text, opts )
56
+ end
57
+
58
+
59
+ def skip_tags?() @skip_tags == true; end
60
+ def strict?() @strict == true; end
61
+
62
+ def initialize( text, opts={} )
63
+ @text = text
64
+
65
+ ## option: do NOT generate/add any tags for countries/regions/cities
66
+ @skip_tags = opts[:skip_tags].present? ? true : false
67
+ ## option: for now issue warning on update, that is, if key/record (country,region,city) already exists
68
+ @strict = opts[:strict].present? ? true : false
69
+ end
70
+
71
+ def read()
72
+ reader = HashReader.from_string( @text )
73
+
74
+ reader.each do |key, value|
75
+
76
+ ### fix:
77
+ ## move to Lang.read() for (re)use
78
+
79
+ logger.debug "adding lang >>#{key}<< >>#{value}<<..."
80
+
81
+ lang_key = key.strip
82
+ lang_title = value.strip
83
+
84
+ lang_attribs = {}
85
+
86
+ ## check if it exists
87
+ lang = Lang.find_by_key( lang_key )
88
+ if lang.present?
89
+ logger.debug "update lang #{lang.id}-#{lang.key}:"
90
+ else
91
+ logger.debug "create lang:"
92
+ lang = Lang.new
93
+ lang_attribs[ :key ] = lang_key
94
+ end
95
+
96
+ lang_attribs[ :title ] = lang_title
97
+
98
+ logger.debug lang_attribs.to_json
99
+
100
+ lang.update_attributes!( lang_attribs )
101
+ end # each key,value
102
+
103
+ end # method load_langs
104
+
105
+
106
+ end # class LangReader
107
+ end # module WorldDb
@@ -0,0 +1,79 @@
1
+ # encoding: UTF-8
2
+
3
+ module WorldDb
4
+
5
+ class RegionReader
6
+
7
+ include LogUtils::Logging
8
+
9
+ ## make models available by default with namespace
10
+ # e.g. lets you use Usage instead of Model::Usage
11
+ include Models
12
+
13
+ ## value helpers e.g. is_year?, is_taglist? etc.
14
+ include TextUtils::ValueHelper
15
+
16
+
17
+ def self.from_zip( zip_file, entry_path, more_attribs={} )
18
+ ## get text content from zip
19
+
20
+ entry = zip_file.find_entry( entry_path )
21
+
22
+ ## todo/fix: add force encoding to utf-8 ??
23
+ ## check!!!
24
+ ## clean/prepprocess lines
25
+ ## e.g. CR/LF (/r/n) to LF (e.g. /n)
26
+ text = entry.get_input_stream().read()
27
+
28
+ ## NOTE: needs logger ref; only available in instance methods; use global logger for now
29
+ logger = LogUtils::Logger.root
30
+ logger.debug "text.encoding.name (before): #{text.encoding.name}"
31
+ #####
32
+ # NB: ASCII-8BIT == BINARY == Encoding Unknown; Raw Bytes Here
33
+ ## NB:
34
+ # for now "hardcoded" to utf8 - what else can we do?
35
+ # - note: force_encoding will NOT change the chars only change the assumed encoding w/o translation
36
+ text = text.force_encoding( Encoding::UTF_8 )
37
+ logger.debug "text.encoding.name (after): #{text.encoding.name}"
38
+
39
+ ## todo:
40
+ # NB: for convenience: convert fancy unicode dashes/hyphens to plain ascii hyphen-minus
41
+ ## text = TextUtils.convert_unicode_dashes_to_plain_ascii( text, path: path )
42
+
43
+ self.from_string( text, more_attribs )
44
+ end
45
+
46
+ def self.from_file( path, more_attribs={} )
47
+ ## note: assume/enfore utf-8 encoding (with or without BOM - byte order mark)
48
+ ## - see textutils/utils.rb
49
+ text = File.read_utf8( path )
50
+ self.from_string( text, more_attribs )
51
+ end
52
+
53
+ def self.from_string( text, more_attribs={} )
54
+ RegionReader.new( text, more_attribs )
55
+ end
56
+
57
+
58
+ def skip_tags?() @skip_tags == true; end
59
+ def strict?() @strict == true; end
60
+
61
+ def initialize( text, more_attribs={} )
62
+ ## todo/fix: how to add opts={} ???
63
+
64
+ @text = text
65
+ @more_attribs = more_attribs
66
+ end
67
+
68
+
69
+ def read()
70
+ reader = ValuesReader.from_string( @text, @more_attribs )
71
+
72
+ reader.each_line do |attribs, values|
73
+ opts = { skip_tags: skip_tags? }
74
+ Region.create_or_update_from_attribs( attribs, values, opts )
75
+ end
76
+ end
77
+
78
+ end # class RegionReader
79
+ end # module WorldDb
@@ -0,0 +1,98 @@
1
+ # encoding: UTF-8
2
+
3
+ module WorldDb
4
+
5
+ class UsageReader
6
+
7
+ include LogUtils::Logging
8
+
9
+ ## make models available by default with namespace
10
+ # e.g. lets you use Usage instead of Model::Usage
11
+ include Models
12
+
13
+ ## value helpers e.g. is_year?, is_taglist? etc.
14
+ include TextUtils::ValueHelper
15
+
16
+ ## todo: add opts
17
+ def self.from_zip( zip_file, entry_path )
18
+ ## get text content from zip
19
+
20
+ entry = zip_file.find_entry( entry_path )
21
+
22
+ ## todo/fix: add force encoding to utf-8 ??
23
+ ## check!!!
24
+ ## clean/prepprocess lines
25
+ ## e.g. CR/LF (/r/n) to LF (e.g. /n)
26
+ text = entry.get_input_stream().read()
27
+
28
+ ## NOTE: needs logger ref; only available in instance methods; use global logger for now
29
+ logger = LogUtils::Logger.root
30
+ logger.debug "text.encoding.name (before): #{text.encoding.name}"
31
+ #####
32
+ # NB: ASCII-8BIT == BINARY == Encoding Unknown; Raw Bytes Here
33
+ ## NB:
34
+ # for now "hardcoded" to utf8 - what else can we do?
35
+ # - note: force_encoding will NOT change the chars only change the assumed encoding w/o translation
36
+ text = text.force_encoding( Encoding::UTF_8 )
37
+ logger.debug "text.encoding.name (after): #{text.encoding.name}"
38
+
39
+ ## todo:
40
+ # NB: for convenience: convert fancy unicode dashes/hyphens to plain ascii hyphen-minus
41
+ ## text = TextUtils.convert_unicode_dashes_to_plain_ascii( text, path: path )
42
+
43
+ self.from_string( text )
44
+ end
45
+
46
+ def self.from_file( path, opts={} )
47
+ ## note: assume/enfore utf-8 encoding (with or without BOM - byte order mark)
48
+ ## - see textutils/utils.rb
49
+ text = File.read_utf8( path )
50
+ self.from_string( text, opts )
51
+ end
52
+
53
+ def self.from_string( text, opts={} )
54
+ UsageReader.new( text, opts )
55
+ end
56
+
57
+
58
+ def skip_tags?() @skip_tags == true; end
59
+ def strict?() @strict == true; end
60
+
61
+ def initialize( text, opts={} )
62
+ @text = text
63
+
64
+ ## option: do NOT generate/add any tags for countries/regions/cities
65
+ @skip_tags = opts[:skip_tags].present? ? true : false
66
+ ## option: for now issue warning on update, that is, if key/record (country,region,city) already exists
67
+ @strict = opts[:strict].present? ? true : false
68
+ end
69
+
70
+ def read()
71
+ reader = HashReader.from_string( @text )
72
+
73
+ reader.each do |key, value|
74
+
75
+ ### fix:
76
+ ## move to Usage.read() for (re)use
77
+
78
+ logger.debug " adding langs >>#{value}<<to country >>#{key}<<"
79
+
80
+ country = Country.find_by_key!( key )
81
+
82
+ lang_keys = value.split(',')
83
+ lang_keys.each do |lang_key|
84
+
85
+ ### remove (optional comment) from key (e.g. carribean (islands))
86
+ lang_key = lang_key.gsub( /\(.+\)/, '' )
87
+ ## remove leading n trailing space
88
+ lang_key = lang_key.strip
89
+
90
+ lang = Lang.find_by_key!( lang_key )
91
+ Usage.create!( country_id: country.id, lang_id: lang.id, official: true, minor: false )
92
+ end
93
+ end
94
+ end
95
+
96
+
97
+ end # class UsageReader
98
+ end # module WorldDb
@@ -0,0 +1,202 @@
1
+
2
+ module WorldDb
3
+
4
+ class CreateDb
5
+
6
+ def up
7
+
8
+ ActiveRecord::Schema.define do
9
+
10
+ create_table :places do |t|
11
+ t.string :name, null: false
12
+ t.string :kind, null: false # -- kind/feature (note: type reserved for activerecord sti)
13
+ #####
14
+ # continent:
15
+ # CONT - continent (use CNTI or CENT why??)
16
+ # country:
17
+ # SUPR - supra (e.g. European Union)
18
+ # CNTY - country
19
+ # TERR - terr
20
+ # region:
21
+ # ADM1 - e.g. region/state/province
22
+ # ADM2 - e.g. county/district/
23
+ # ADM3 - e.g.
24
+ # city:
25
+ # MTRO - metro
26
+ # CITY - city/town/
27
+ # DIST - district/
28
+ #
29
+ # add new table for zones (e.g. informal regions e.g. tourism, wine regions, etc.) ??
30
+ # why? why not??
31
+
32
+
33
+ t.float :lat # optional for now (latitude)
34
+ t.float :lng # optional for now (longitude)
35
+
36
+ ## todo: add parent for hierachy ?? or keep it in country/region/city etc. table ??
37
+
38
+ ## timestamp at last
39
+ t.timestamps
40
+ end
41
+
42
+
43
+ #############
44
+ # todo: use many-to-many assoc w/ join table for name and place ???
45
+ # why? why not?
46
+ # - wien -> city n region n metro ? collect more samples of names used more than once
47
+
48
+ ### alternative names for places
49
+ create_table :names do |t|
50
+ t.string :name, null: false
51
+ t.references :place, null: false
52
+ ### todo/fix: add lang_id to reference lang from lang table!!! (for now make it a duplicate; e.g. keep stirng lang for now)
53
+ t.string :lang, null: false, default: 'en' # default to english for now (or use unknown/undeterminded/unspecified???)
54
+
55
+ ## todo: add kind/type ? e.g. postal for postal code ??
56
+ ## or wikipedia for wikipedia? or use separate table ?? (linkable/links) etc.??
57
+
58
+ ## timestamp at last
59
+ t.timestamps
60
+ end
61
+
62
+
63
+
64
+ create_table :continents do |t|
65
+ t.string :name, null: false
66
+ t.string :slug, null: false # auto-generate default
67
+ t.string :key, null: false
68
+ t.references :place, null: false
69
+ t.string :alt_names # comma separated list of alternate names (synonyms)
70
+
71
+ ## timestamp at last
72
+ t.timestamps
73
+ end
74
+
75
+ add_index :continents, :key, unique: true
76
+
77
+
78
+ create_table :country_codes do |t|
79
+ t.string :name, null: false
80
+ t.string :kind, null: false # e.g. ALPHA2,NUM,FIFA,IOC,FIPS,NET,etc.
81
+ t.references :country, null: false
82
+ end
83
+
84
+ add_index :country_codes, [:name, :kind], unique: true
85
+
86
+
87
+ create_table :countries do |t|
88
+ t.string :name, null: false
89
+ t.string :slug, null: false # auto-generate default
90
+ t.string :key, null: false
91
+ t.references :place, null: false
92
+ t.string :code, null: false # short three letter code (FIFA country code e.g. ITA)
93
+ t.string :alt_names # comma separated list of alternate names (synonyms)
94
+ t.string :hist_names # comma separated list of historic names (no longer in use)
95
+ t.integer :pop, null: false # population count
96
+ t.integer :area, null: false # area in square km (sq. km)
97
+ t.references :continent
98
+ t.references :country # for supra(nationals) n depend(encies)
99
+
100
+ ## flags (use single int named flags - why? why not?
101
+ t.boolean :s, null: false, default: false # supra(national) flag e.g. eu
102
+ t.boolean :c, null: false, default: false # country flag (is this needed?)
103
+ t.boolean :d, null: false, default: false # dependency flag
104
+
105
+ t.boolean :m, null: false, default: false # misc(ellaneous) flag
106
+ # misc use for territories w/ shared or disputed claims
107
+ # e.g. Antartica/Western Sahara/Paracel Islands/Spratly Islands/etc.
108
+
109
+ # extras - country codes
110
+ t.string :motor # optional motor (vehicle) licene plate code (bumper sticker)
111
+ t.string :alpha2 # optional iso two letter country code
112
+ t.string :alpha3 # optional iso three letter country code
113
+ t.string :num # optional iso numeric country code - NOTE: same numeric code as string!!! e.g. 043 etc.
114
+ t.string :fifa # optional fifa country code
115
+ t.string :ioc
116
+ t.string :fips
117
+ t.string :net # optional internet top level domain (tld)
118
+
119
+ t.string :wikipedia # optional wikipedia page name -- en.wikipedia.org/wiki/<name>
120
+
121
+ ## timestamp at last
122
+ t.timestamps
123
+ end
124
+
125
+
126
+ add_index :countries, :key, unique: true
127
+ add_index :countries, :code, unique: true
128
+
129
+
130
+ ######
131
+ # NB: rename to adms/admins ??
132
+ #
133
+ # used for state/provice/land/regioni/etc.
134
+ create_table :regions do |t|
135
+ t.string :name, null: false
136
+ t.string :key, null: false
137
+ t.references :place, null: false
138
+ t.string :code # short two or three letter code e.g. NY, OAX, etc.
139
+ t.string :abbr # optional conventional abbrevation (e.g. Stmk., Gto., etc.)
140
+ t.string :iso # iso code
141
+ t.string :nuts # nuts code (europe/eu only)
142
+ t.string :alt_names # comma separated list of alternate names (synonyms)
143
+ t.references :country, null: false
144
+ t.integer :pop # optional population count
145
+ t.integer :area # optional area in square km (sq. km)
146
+ t.timestamps
147
+ end
148
+
149
+ add_index :regions, [:key, :country_id], unique: true
150
+
151
+
152
+ create_table :cities do |t|
153
+ t.string :name, null: false
154
+ t.string :key, null: false
155
+ t.references :place, null: false
156
+ t.string :code # short three letter code (ITAT/airport code e.g. NYC or VIE)
157
+ t.string :alt_names # comma separated list of alternate names (synonyms)
158
+ t.references :country, null: false
159
+ t.references :region # optional for now
160
+ t.references :city # optional parent (e.g. metro for city, or city for district)
161
+ t.integer :pop # optional population count (city proper)
162
+ t.integer :popm # optional population count (metropolitan/aglomeration)
163
+ t.integer :area # optional area in square km (sq. km)
164
+
165
+ ## t.float :lat # optional for now -- FIX: remove?? moved to places
166
+ ## t.float :lng # optional for now -- FIX: remove?? moved to places
167
+
168
+ ## flags (use single int named flags - why? why not?
169
+ t.boolean :m, null: false, default: false # metro flag
170
+ t.boolean :c, null: false, default: false # city flag (is this needed?)
171
+ t.boolean :d, null: false, default: false # district flag
172
+
173
+ ### t.boolean :capital, null: false, default: false # is national captial?
174
+
175
+ t.timestamps
176
+ end
177
+
178
+
179
+ create_table :langs do |t| # langs == languages (e.g. en/English, de/Deutsch, etc.)
180
+ t.string :key, null: false
181
+ t.string :name, null: false
182
+ t.timestamps
183
+ end
184
+
185
+
186
+ create_table :usages do |t| # join table for countries_langs
187
+ t.references :country, null: false
188
+ t.references :lang, null: false
189
+ t.boolean :official, null: false, default: true # is_official language in country
190
+ t.boolean :minor, null: false, default: false # spoken by minority
191
+ t.float :percent # usage in percent e.g. 90.0, 0.55, etc.
192
+ t.timestamps
193
+ end
194
+
195
+ end # block Schema.define
196
+
197
+ end # method up
198
+
199
+
200
+ end # class CreateDb
201
+
202
+ end # module WorldDb
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ module WorldDb
4
+
5
+ class Stats
6
+ include Models
7
+
8
+ def tables
9
+ puts "Stats:"
10
+ puts " #{'%5d' % Continent.count} continents"
11
+ puts " #{'%5d' % Country.count} countries (#{Country.where(s: true).count} supras, #{Country.where(d:true).count} deps), #{Country.where(m:true).count} miscs)"
12
+ puts " #{'%5d' % Region.count} regions"
13
+ puts " #{'%5d' % City.where(m: true).where(c: false).count} metros"
14
+ puts " #{'%5d' % City.where(c: true).count} cities (#{City.where(c: true).where(m: true).count} metros)"
15
+ puts " #{'%5d' % City.where(d: true).count} districts"
16
+ puts " #{'%5d' % Place.count} places"
17
+ puts " #{'%5d' % Name.count} names"
18
+
19
+ puts " #{'%5d' % Lang.count} langs"
20
+ puts " #{'%5d' % Usage.count} usages"
21
+
22
+ puts " #{'%5d' % CountryCode.count} (country) codes"
23
+
24
+ # puts " #{'%5d' % Tag.count} tags"
25
+ # puts " #{'%5d' % Tagging.count} taggings"
26
+ end
27
+
28
+ end # class Stats
29
+
30
+ end # module WorldDb
31
+
@@ -0,0 +1,23 @@
1
+
2
+ module WorldDb
3
+
4
+ # sync version w/ sport.db n friends - why? why not?
5
+ MAJOR = 2 ## todo: namespace inside version or something - why? why not??
6
+ MINOR = 1
7
+ PATCH = 0
8
+ VERSION = [MAJOR,MINOR,PATCH].join('.')
9
+
10
+ def self.version
11
+ VERSION
12
+ end
13
+
14
+ def self.banner
15
+ "worlddb-models/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
16
+ end
17
+
18
+ def self.root
19
+ "#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
20
+ end
21
+
22
+ end
23
+
data/test/helper.rb ADDED
@@ -0,0 +1,26 @@
1
+
2
+ ## $:.unshift(File.dirname(__FILE__))
3
+
4
+ ## minitest setup
5
+ require 'minitest/autorun'
6
+
7
+
8
+ # our own code
9
+
10
+ require 'worlddb/models'
11
+
12
+
13
+ Name = WorldDb::Model::Name
14
+ Place = WorldDb::Model::Place
15
+ Continent = WorldDb::Model::Continent
16
+ Country = WorldDb::Model::Country
17
+ Region = WorldDb::Model::Region
18
+ City = WorldDb::Model::City
19
+
20
+ Lang = WorldDb::Model::Lang
21
+ Usage = WorldDb::Model::Usage
22
+
23
+
24
+
25
+ WorldDb.setup_in_memory_db
26
+
@@ -0,0 +1,112 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+
6
+ class TestFixtureMatchers < MiniTest::Test
7
+
8
+ include WorldDb::Matcher
9
+
10
+
11
+ def test_cities_for_country
12
+
13
+ cities_at = [
14
+ 'europe/at/cities',
15
+ 'europe/at-austria/cities',
16
+ 'at-austria/cities',
17
+ 'at-austria!/cities',
18
+ 'at-austria!/1--niederoesterreich--eastern--cities',
19
+ 'at-austria!/1--niederoesterreich--eastern/cities', # region w/o code/abbrev
20
+ 'at-austria!/1--niederoesterreich--eastern/1--waldviertel--cities'
21
+ ]
22
+
23
+ cities_at.each do |name|
24
+ found = match_cities_for_country( name ) do |country_key|
25
+ assert_equal country_key, 'at'
26
+ end
27
+ assert found
28
+ end
29
+ end # method test_cities_for_country
30
+
31
+ def test_country
32
+
33
+ beers_at = [
34
+ 'europe/at/beers',
35
+ 'europe/at-austria/beers',
36
+ 'europe/at-austria--beers',
37
+ 'at-austria/beers',
38
+ 'at-austria!/beers',
39
+ '1--at-austria--central/beers',
40
+ '1--at-austria--central/1--niederoesterreich--eastern--beers',
41
+ 'europe/1--at-austria--central/beers',
42
+ 'europe/1--at-austria--central/1--niederosterreich--eastern--beers',
43
+ 'at-austria!/1--niederoesterreich--eastern--beers',
44
+ 'at-austria!/1--niederoesterreich--eastern/beers', # region w/o code/abbrev
45
+ 'at-austria!/1--niederoesterreich--eastern/1--waldviertel--beers'
46
+ ]
47
+
48
+ beers_at.each do |name|
49
+ found = match_xxx_for_country( name, 'beers' ) do |country_key|
50
+ assert_equal country_key, 'at'
51
+ end
52
+ assert found, "no match found for '#{name}'"
53
+ end
54
+
55
+ breweries_at = [
56
+ 'europe/at/breweries',
57
+ 'europe/at-austria/breweries',
58
+ 'at-austria/breweries',
59
+ 'at-austria!/breweries'
60
+ ]
61
+
62
+ breweries_at.each do |name|
63
+ found = match_xxx_for_country( name, 'breweries' ) do |country_key|
64
+ assert_equal country_key, 'at'
65
+ end
66
+ assert found
67
+ end
68
+ end # method test_country
69
+
70
+
71
+ def test_country_n_region
72
+
73
+ beers_at = [
74
+ 'europe/at-austria/w-wien/beers',
75
+ 'at-austria/w-wien/beers',
76
+ 'at-austria/w-wien/2--leopoldstadt--beers',
77
+ 'at-austria!/w-wien/beers',
78
+ '1--at-austria--central/1--w-wien--eastern/beers',
79
+ '1--at-austria--central/1--w-wien--eastern/2--leopoldstadt--beers',
80
+ 'europe/1--at-austria--central/1--w-wien--eastern/beers',
81
+ 'at-austria/1--w-wien--eastern/beers',
82
+ 'europe/at-austria!/1--w-wien--eastern/beers',
83
+ '1--at-austria--central/w-wien/beers',
84
+ 'europe/1--at-austria--central/w-wien/beers',
85
+ 'europe/1--at-austria--central/w-wien/2--leopoldstadt--beers'
86
+ ]
87
+
88
+ beers_at.each do |name|
89
+ found = match_xxx_for_country_n_region( name, 'beers' ) do |country_key,region_key|
90
+ assert_equal country_key, 'at'
91
+ assert_equal region_key, 'w'
92
+ end
93
+ assert found
94
+ end
95
+
96
+ breweries_at = [
97
+ 'europe/at-austria/w-wien/breweries',
98
+ 'at-austria/w-wien/breweries',
99
+ 'at-austria!/w-wien/breweries'
100
+ ]
101
+
102
+ breweries_at.each do |name|
103
+ found = match_xxx_for_country_n_region( name, 'breweries' ) do |country_key,region_key|
104
+ assert_equal country_key, 'at'
105
+ assert_equal region_key, 'w'
106
+ end
107
+ assert found
108
+ end
109
+ end # method test_country_n_region
110
+
111
+
112
+ end # class TestFixtureMatchers