rare_map 1.3.2 → 2.0.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.
- data/README.rdoc +49 -124
- data/lib/rare_map/config_loader.rb +4 -2
- data/lib/rare_map/errors.rb +4 -0
- data/lib/rare_map/model_builder.rb +1 -5
- data/lib/rare_map/model_generator.rb +21 -17
- data/lib/rare_map/version.rb +3 -3
- data/lib/rare_map.rb +9 -24
- metadata +28 -27
data/README.rdoc
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
= rare_map >=
|
1
|
+
= rare_map >= 2.0.0
|
2
2
|
|
3
3
|
Relational db to ActiveREcord models MAPper
|
4
4
|
|
5
5
|
RareMap can be used for BOTH standalone application & Rails
|
6
6
|
|
7
|
-
WARN: rare_map >= 1.0.0 is totally not compatible with 0.9.x
|
8
|
-
|
9
7
|
* Installation:
|
10
8
|
|
11
9
|
gem install rare_map
|
@@ -13,63 +11,58 @@ WARN: rare_map >= 1.0.0 is totally not compatible with 0.9.x
|
|
13
11
|
== Basic RareMap use
|
14
12
|
|
15
13
|
==== Standalone:
|
16
|
-
Create a new
|
14
|
+
Create a new rare_map.yml with following lines in the root of your application
|
17
15
|
|
18
16
|
==== Rails:
|
19
|
-
|
17
|
+
Create a new config/rare_map.yml with following lines in rails
|
20
18
|
|
21
|
-
*
|
19
|
+
* rare_map.yml
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
database: db/db1.sqlite3
|
21
|
+
legacy:
|
22
|
+
adapter: sqlite3
|
23
|
+
database: db/db1.sqlite3
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
old_db:
|
26
|
+
adapter: mysql2
|
27
|
+
host: localhost
|
28
|
+
database: db_name
|
29
|
+
port: 3306
|
30
|
+
username: user
|
31
|
+
password: pw
|
35
32
|
|
36
33
|
* Run following command in the root of your application or rails
|
37
34
|
|
38
35
|
$ raremap
|
39
36
|
|
40
|
-
* Standalone: A demo.rb example is generated for you in the root of your
|
41
|
-
|
42
|
-
* Rails: Add following line to your config/application.rb
|
43
|
-
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
|
37
|
+
* Standalone: A demo.rb example is generated for you in the root of your application
|
44
38
|
|
45
39
|
== Advanced RareMap use
|
46
40
|
|
47
|
-
==== Seperate databases
|
41
|
+
==== Seperate databases into groups (highly recommended)
|
48
42
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
database: db/db4.sqlite3
|
43
|
+
her_group:
|
44
|
+
-
|
45
|
+
db1:
|
46
|
+
adapter: sqlite3
|
47
|
+
database: db/db1.sqlite3
|
48
|
+
-
|
49
|
+
db2:
|
50
|
+
adapter: sqlite3
|
51
|
+
database: db/db1.sqlite3
|
52
|
+
|
53
|
+
his_group:
|
54
|
+
-
|
55
|
+
db1:
|
56
|
+
adapter: sqlite3
|
57
|
+
database: db/db3.sqlite3
|
58
|
+
-
|
59
|
+
db2:
|
60
|
+
adapter: sqlite3
|
61
|
+
database: db/db4.sqlite3
|
69
62
|
|
70
63
|
There are benefits by separating databases into groups
|
71
64
|
1. Associations are built between databases within a group
|
72
|
-
2.
|
65
|
+
2. Group name is treated as a module namespace
|
73
66
|
3. Models of a group are organized within a folder
|
74
67
|
|
75
68
|
If all your data reside in several legacy databases, it is important to build back those associations across databases
|
@@ -97,92 +90,24 @@ If there are tons of tables, it is better to organize them well
|
|
97
90
|
|
98
91
|
You can place rare_map options in 3 ways
|
99
92
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
db1:
|
109
|
-
...
|
110
|
-
legacy_db:
|
111
|
-
adapter: sqlite3
|
112
|
-
database: db/db.sqlite3
|
113
|
-
rare_map_opts: # DB options
|
93
|
+
rare_map_opts: # Global options
|
94
|
+
...
|
95
|
+
group1:
|
96
|
+
-
|
97
|
+
rare_map_opts: # Group options
|
98
|
+
...
|
99
|
+
-
|
100
|
+
db1:
|
114
101
|
...
|
102
|
+
legacy_db:
|
103
|
+
adapter: sqlite3
|
104
|
+
database: db/db.sqlite3
|
105
|
+
rare_map_opts: # DB options
|
106
|
+
...
|
115
107
|
|
116
108
|
* Precedence: DB > Group > Global
|
117
109
|
|
118
110
|
|
119
|
-
= rare_map ~> 0.9.x(deprecated)
|
120
|
-
|
121
|
-
Relational DB to ActiveRecord models Mapper
|
122
|
-
|
123
|
-
* Installation:
|
124
|
-
|
125
|
-
gem install rare_map
|
126
|
-
|
127
|
-
== Basic RareMap use
|
128
|
-
|
129
|
-
Set up your legacay db under your Rails applicaiton
|
130
|
-
|
131
|
-
* database.yml
|
132
|
-
|
133
|
-
mylegacy_db1:
|
134
|
-
adapter: sqlite3
|
135
|
-
database: db/db1.sqlite3
|
136
|
-
|
137
|
-
mylegacy_db2:
|
138
|
-
adapter: sqlite3
|
139
|
-
database: db/db2/sqlite3
|
140
|
-
|
141
|
-
hislegacy_db1:
|
142
|
-
adapter: sqlite3
|
143
|
-
database: db/db1.sqlite3
|
144
|
-
|
145
|
-
"mylegacy" is treated as a group name.
|
146
|
-
|
147
|
-
You MUST give all your legacy databases a group name.
|
148
|
-
|
149
|
-
The associations of databases with the same group name will be built together.
|
150
|
-
|
151
|
-
|
152
|
-
* Create a {RAILS_ROOT}/demo.rb file with following content under your Rails application
|
153
|
-
|
154
|
-
RareMap.mapping
|
155
|
-
|
156
|
-
* Under terminal
|
157
|
-
|
158
|
-
ruby demo.rb
|
159
|
-
|
160
|
-
* Add following line to your config/application.rb
|
161
|
-
|
162
|
-
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
|
163
|
-
|
164
|
-
== Advanced RareMap use
|
165
|
-
|
166
|
-
If the foreign key of your legacy db is not end with '_id', you can change it manually.
|
167
|
-
|
168
|
-
foreign_keys = { :mylegacy => 'id', :hislegacy => 'id' }
|
169
|
-
|
170
|
-
If the foreign key is not started with regular table names, you can create aliases for them.
|
171
|
-
|
172
|
-
aliases = { :mylegacy => { :pclid => :protocol, personid => people }, :hislegacy => { :measid => measurement } }
|
173
|
-
|
174
|
-
Some of the databases like Oracle won't show the primary key on the dump of schema. If your primary key of a table is not 'id' and it didn't show the schema either. You can specify your special primary key beside 'id' if you want.
|
175
|
-
|
176
|
-
primary_keys = { :mylegacy => { :table1 => 'table1id' }, :hislegacy => { :table2 => 'table2id' } }
|
177
|
-
|
178
|
-
When you using the RareMap
|
179
|
-
|
180
|
-
info = RareMap.mapping(:foreign_key => foreign_keys, :alias => aliases, :primary_key => primary_keys)
|
181
|
-
|
182
|
-
[info]
|
183
|
-
It contains all details of your tables.
|
184
|
-
|
185
|
-
|
186
111
|
== Contributing to rare_map
|
187
112
|
|
188
113
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'rare_map/errors'
|
2
3
|
|
3
4
|
module RareMap
|
4
5
|
module ConfigLoader
|
5
6
|
OPTS_KEY = 'rare_map_opts'
|
6
7
|
|
7
|
-
def load_config(path, file_name = '
|
8
|
+
def load_config(path, file_name = 'rare_map.yml')
|
9
|
+
raise ConfigNotFoundError unless File.exist? "#{path}#{file_name}"
|
8
10
|
config = YAML.load_file "#{path}#{file_name}"
|
9
|
-
organize_config_properties config['rare_map'] || {}
|
11
|
+
organize_config_properties config['rare_map'] || config || {}
|
10
12
|
end
|
11
13
|
|
12
14
|
private
|
@@ -13,44 +13,46 @@ module RareMap
|
|
13
13
|
models.each do |model|
|
14
14
|
output = ''
|
15
15
|
output <<
|
16
|
-
"
|
17
|
-
"
|
18
|
-
"
|
19
|
-
"
|
20
|
-
"
|
16
|
+
"module #{model.group.camelize}\n" <<
|
17
|
+
" class #{model.classify} < #{group_db2conn[[model.group, model.db_name]]}\n" <<
|
18
|
+
" self.table_name = '#{model.table.name}'\n" <<
|
19
|
+
" self.inheritance_column = 'ruby_type'\n" <<
|
20
|
+
" #{ "self.primary_key = '#{model.table.primary_key}'\n" if model.table.primary_key }\n" <<
|
21
|
+
" attr_accessible #{model.table.columns.map { |col| ":#{col.name}" }.join(', ')}\n\n"
|
21
22
|
|
22
23
|
belongs_to = model.relations.select { |rel| rel.type == :belongs_to }
|
23
24
|
unless belongs_to.empty?
|
24
25
|
output << belongs_to.
|
25
|
-
map { |rel| "
|
26
|
+
map { |rel| " belongs_to :#{rel.table.pluralize.singularize}, :foreign_key => '#{rel.foreign_key}', :class_name => '#{classify_by_table(rel.table, model, models)}'" }.
|
26
27
|
join("\n") << "\n"
|
27
28
|
end
|
28
29
|
|
29
30
|
has_one = model.relations.select { |rel| rel.type == :has_one }
|
30
31
|
unless has_one.empty?
|
31
32
|
output << has_one.
|
32
|
-
map { |rel| "
|
33
|
+
map { |rel| " has_one :#{rel.table.pluralize.singularize}, :foreign_key => '#{rel.foreign_key}', :class_name => '#{classify_by_table(rel.table, model, models)}'" }.
|
33
34
|
join("\n") << "\n"
|
34
35
|
end
|
35
36
|
|
36
37
|
has_many = model.relations.select { |rel| rel.type == :has_many }
|
37
38
|
unless has_many.empty?
|
38
39
|
output << has_many.
|
39
|
-
map { |rel| "
|
40
|
+
map { |rel| " has_many :#{rel.table.pluralize}, :foreign_key => '#{rel.foreign_key}', :class_name => '#{classify_by_table(rel.table, model, models)}'" }.
|
40
41
|
join("\n") << "\n"
|
41
42
|
end
|
42
43
|
|
43
44
|
has_many_through = model.relations.select { |rel| rel.type == :has_many_through }
|
44
45
|
unless has_many_through.empty?
|
45
46
|
output << has_many_through.
|
46
|
-
map { |rel| "
|
47
|
+
map { |rel| " has_many :#{rel.table.pluralize}#{"_by_#{rel.through}, :source => :#{rel.table.pluralize.singularize}" if has_many_through.count { |hmt| hmt.table == rel.table } > 1 || has_many.count { |hm| hm.table == rel.table } > 0 }, :through => :#{rel.through.pluralize}, :foreign_key => '#{rel.foreign_key}', :class_name => '#{classify_by_table(rel.table, model, models)}'" }.
|
47
48
|
join("\n") << "\n"
|
48
49
|
end
|
49
50
|
|
51
|
+
output << " end\n"
|
50
52
|
output << 'end'
|
51
53
|
|
52
|
-
Dir.mkdir path + "#{model.group}" unless Dir.exist? path + "#{model.group}"
|
53
|
-
f = File.new(path + "#{model.group}/#{model.classify.underscore}.rb", 'w')
|
54
|
+
Dir.mkdir path + "#{model.group.underscore}" unless Dir.exist? path + "#{model.group}"
|
55
|
+
f = File.new(path + "#{model.group.underscore}/#{model.classify.underscore}.rb", 'w')
|
54
56
|
f.write output
|
55
57
|
f.close
|
56
58
|
end
|
@@ -71,18 +73,20 @@ module RareMap
|
|
71
73
|
|
72
74
|
group2connection = Hash[models.map { |model| [[model.group, model.db_name], [model.connection, model.table.name]] }]
|
73
75
|
group2connection.each do |(group, db_name), (connection, table_name)|
|
74
|
-
model = "#{
|
76
|
+
model = "#{db_name}".camelize + 'Base'
|
75
77
|
|
76
78
|
output = ''
|
77
79
|
output <<
|
78
|
-
"
|
79
|
-
"
|
80
|
-
"
|
80
|
+
"module #{group.camelize}\n" <<
|
81
|
+
" class #{model} < ActiveRecord::Base\n" <<
|
82
|
+
" establish_connection #{connection.map { |k, v| ":#{k} => #{v.inspect}" }.join(', ')}\n" <<
|
83
|
+
" self.table_name = '#{table_name}'\n" <<
|
84
|
+
" end\n" <<
|
81
85
|
'end'
|
82
86
|
|
83
87
|
|
84
|
-
Dir.mkdir path + "#{group}" unless Dir.exist? path + "#{group}"
|
85
|
-
f = File.new(path + "#{group}/#{model.underscore}.rb", 'w')
|
88
|
+
Dir.mkdir path + "#{group.underscore}" unless Dir.exist? path + "#{group}"
|
89
|
+
f = File.new(path + "#{group.underscore}/#{model.underscore}.rb", 'w')
|
86
90
|
f.write output
|
87
91
|
f.close
|
88
92
|
|
data/lib/rare_map/version.rb
CHANGED
data/lib/rare_map.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# $:.unshift File.dirname(__FILE__)
|
2
|
-
|
3
1
|
require 'rare_map/rails_locator'
|
4
2
|
require 'rare_map/config_loader'
|
5
3
|
require 'rare_map/schema_reader'
|
@@ -28,17 +26,19 @@ module RareMap
|
|
28
26
|
@models = build_models @db_profiles
|
29
27
|
generate_models @models, @rails_root
|
30
28
|
if @rails_root
|
31
|
-
puts '
|
32
|
-
puts '
|
33
|
-
puts '
|
34
|
-
create_initializer
|
29
|
+
puts '*****************************************************************'
|
30
|
+
puts ' Activerecord models are generated. Enjoy it!'
|
31
|
+
puts '*****************************************************************'
|
35
32
|
else
|
36
|
-
puts '
|
37
|
-
puts ' A demo.rb is generated'
|
38
|
-
puts '
|
33
|
+
puts '*****************************************************************'
|
34
|
+
puts ' A demo.rb is generated.'
|
35
|
+
puts '*****************************************************************'
|
39
36
|
generate_demo unless File.exist?('demo.rb')
|
40
37
|
end
|
41
38
|
@models
|
39
|
+
|
40
|
+
rescue ConfigNotFoundError => e
|
41
|
+
puts "Please put your database config in `#{'config/' if @rails_root}rare_map.yml`."
|
42
42
|
end
|
43
43
|
|
44
44
|
private
|
@@ -50,21 +50,6 @@ module RareMap
|
|
50
50
|
f.write "Dir[File.dirname(__FILE__) + '/app/models/**/*.rb'].each { |file| require file }\n"
|
51
51
|
f.close
|
52
52
|
end
|
53
|
-
|
54
|
-
def create_initializer
|
55
|
-
f = File.new(@rails_root + 'config/initializers/rare_map.rb', 'w')
|
56
|
-
f.write "bases = []; models = []\n"
|
57
|
-
f.write "Dir[Rails.root + 'app/models/**/*.rb'].each do |file|\n"
|
58
|
-
f.write " if file =~ /models\\/[^\\/]+\\/[^\\/]+_base.rb$/\n"
|
59
|
-
f.write " bases << file\n"
|
60
|
-
f.write " elsif file =~ /models\\/[^\\/]+\\/[^\\/]+.rb$/\n"
|
61
|
-
f.write " models << file\n"
|
62
|
-
f.write " end\n"
|
63
|
-
f.write "end\n"
|
64
|
-
f.write "bases.map { |b| require b }\n"
|
65
|
-
f.write "models.map { |m| require m }\n"
|
66
|
-
f.close
|
67
|
-
end
|
68
53
|
end
|
69
54
|
end
|
70
55
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rare_map
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -16,39 +16,39 @@ dependencies:
|
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 3.2.
|
21
|
+
version: 3.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 3.2.
|
29
|
+
version: 3.2.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: activesupport
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 3.2.
|
37
|
+
version: 3.2.0
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 3.2.
|
45
|
+
version: 3.2.0
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: shoulda
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: 3.3.2
|
54
54
|
type: :development
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 3.3.2
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -64,7 +64,7 @@ dependencies:
|
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '3.12'
|
70
70
|
type: :development
|
@@ -72,7 +72,7 @@ dependencies:
|
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '3.12'
|
78
78
|
- !ruby/object:Gem::Dependency
|
@@ -80,33 +80,33 @@ dependencies:
|
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
81
81
|
none: false
|
82
82
|
requirements:
|
83
|
-
- -
|
83
|
+
- - ~>
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: 1.
|
85
|
+
version: '1.3'
|
86
86
|
type: :development
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
91
|
-
- -
|
91
|
+
- - ~>
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: 1.
|
93
|
+
version: '1.3'
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: rake
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
97
97
|
none: false
|
98
98
|
requirements:
|
99
|
-
- -
|
99
|
+
- - '>='
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
101
|
+
version: '0'
|
102
102
|
type: :development
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
|
-
- -
|
107
|
+
- - '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
109
|
+
version: '0'
|
110
110
|
description: Relational db to ActiveREcord models MAPper
|
111
111
|
email: wnameless@gmail.com
|
112
112
|
executables:
|
@@ -115,6 +115,7 @@ extensions: []
|
|
115
115
|
extra_rdoc_files: []
|
116
116
|
files:
|
117
117
|
- lib/rare_map/config_loader.rb
|
118
|
+
- lib/rare_map/errors.rb
|
118
119
|
- lib/rare_map/model_builder.rb
|
119
120
|
- lib/rare_map/model_generator.rb
|
120
121
|
- lib/rare_map/rails_locator.rb
|
@@ -138,27 +139,27 @@ require_paths:
|
|
138
139
|
required_ruby_version: !ruby/object:Gem::Requirement
|
139
140
|
none: false
|
140
141
|
requirements:
|
141
|
-
- -
|
142
|
+
- - '>='
|
142
143
|
- !ruby/object:Gem::Version
|
143
144
|
version: '0'
|
144
145
|
segments:
|
145
146
|
- 0
|
146
|
-
hash:
|
147
|
+
hash: 2598832910408143833
|
147
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
149
|
none: false
|
149
150
|
requirements:
|
150
|
-
- -
|
151
|
+
- - '>='
|
151
152
|
- !ruby/object:Gem::Version
|
152
153
|
version: '0'
|
153
154
|
segments:
|
154
155
|
- 0
|
155
|
-
hash:
|
156
|
+
hash: 2598832910408143833
|
156
157
|
requirements: []
|
157
158
|
rubyforge_project:
|
158
|
-
rubygems_version: 1.8.
|
159
|
+
rubygems_version: 1.8.25
|
159
160
|
signing_key:
|
160
161
|
specification_version: 3
|
161
|
-
summary: rare_map-
|
162
|
+
summary: rare_map-2.0.0
|
162
163
|
test_files:
|
163
164
|
- test/helper.rb
|
164
165
|
- test/test_rare_map.rb
|