class-table-inheritance 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ test/cti_plugin.sqlite3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in correios.gemspec
4
+ gemspec
data/README CHANGED
@@ -1,9 +1,17 @@
1
+ Change log
2
+ ==========
3
+
4
+ * Now you can inherits from and to modules like inherits_from 'Module::Model', see the the name of field
5
+ must be module_model_id:integer thanks for Marc Remolt (https://github.com/mremolt).
6
+ * Unit test
7
+
8
+
1
9
  Versions
2
10
  ========
3
11
 
4
12
  If you are using Rails 2.3.8 or other version < 3, you have to use the version 1.1.x of this plugin, for Rails 3 you need to use the version 1.2.x or master of this plugin.
5
13
 
6
- ClassTableInheritance 1.2.0
14
+ ClassTableInheritance 1.2.1
7
15
  ===========================
8
16
 
9
17
  This is an ActiveRecord plugin designed to allow
@@ -23,14 +31,14 @@ Example
23
31
 
24
32
  # Migrations
25
33
 
26
- create_table :product do |t|
34
+ create_table :products do |t|
27
35
  t.string :description, :null => false
28
36
  t.string :subtype # Only if you need access of both side see example
29
37
  t.decimal :price
30
38
  t.timestamps
31
39
  end
32
40
 
33
- create_table :book, :inherits => :product do |t|
41
+ create_table :books, :inherits => :product do |t|
34
42
  t.string :author, :null => false
35
43
  end
36
44
 
@@ -39,6 +47,7 @@ Example
39
47
  t.string :genre, :null => false
40
48
  end
41
49
 
50
+
42
51
  # Models
43
52
 
44
53
  class Product < ActiveRecord::Base
@@ -69,6 +78,28 @@ Example
69
78
  book.author = "Shakespeare, William"
70
79
  book.price => 14.00
71
80
  book.save
81
+
82
+
83
+ Module inheritance
84
+ ==================
85
+ # Migrations
86
+
87
+ create_table :mod_users do |t|
88
+ t.string :name, :null => false
89
+ end
90
+
91
+ create_table :managers, :inherits => 'Mod::User' do |t|
92
+ t.string :salary, :null => false
93
+ end
94
+
95
+ # Models
96
+
97
+ class Mod::User < ActiveRecord::Base
98
+ end
99
+
100
+ class Manager < ActiveRecord::Base
101
+ inherits_from 'Mod::User'
102
+ end
72
103
 
73
104
  Top-down access (Polymorphic)
74
105
  =============================
data/Rakefile CHANGED
@@ -1,23 +1,11 @@
1
- require 'rake'
1
+ require 'bundler'
2
2
  require 'rake/testtask'
3
- require 'rake/rdoctask'
3
+ Bundler::GemHelper.install_tasks
4
4
 
5
- desc 'Default: run unit tests.'
6
- task :default => :test
7
-
8
- desc 'Test the class_table_inheritance plugin.'
9
- Rake::TestTask.new(:test) do |t|
5
+ # just 'rake test'
6
+ Rake::TestTask.new do |t|
10
7
  t.libs << 'lib'
11
8
  t.libs << 'test'
12
9
  t.pattern = 'test/**/*_test.rb'
13
10
  t.verbose = true
14
- end
15
-
16
- desc 'Generate documentation for the class_table_inheritance plugin.'
17
- Rake::RDocTask.new(:rdoc) do |rdoc|
18
- rdoc.rdoc_dir = 'rdoc'
19
- rdoc.title = 'ClassTableInheritance'
20
- rdoc.options << '--line-numbers' << '--inline-source'
21
- rdoc.rdoc_files.include('README')
22
- rdoc.rdoc_files.include('lib/**/*.rb')
23
- end
11
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'class-table-inheritance/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "class-table-inheritance"
7
+ s.version = ClassTableInheritance::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Bruno Frank"]
10
+ s.email = ["bfscordeiro@gmail.com"]
11
+ s.homepage = "https://github.com/brunofrank/class-table-inheritance"
12
+ s.summary = %q{ActiveRecord plugin designed to allow simple multiple table (class) inheritance.}
13
+ s.description = %q{ActiveRecord plugin designed to allow simple multiple table (class) inheritance.}
14
+
15
+ s.rubyforge_project = "class-table-inheritance"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -1,141 +1,3 @@
1
1
  require 'active_record'
2
- require 'inherits-migration'
3
-
4
- # ClassTableInheritance is an ActiveRecord plugin designed to allow
5
- # simple multiple table (class) inheritance.
6
- class ActiveRecord::Base
7
- attr_reader :reflection
8
-
9
- def self.acts_as_superclass
10
- if self.column_names.include?("subtype")
11
- def self.find(*args)
12
- super_classes = super
13
- begin
14
- if super_classes.kind_of? Array
15
- super_classes.map do |item|
16
- if !item.subtype.nil? && !item.subtype.blank?
17
- inherits_type = Object.const_get(item.subtype.to_s)
18
- inherits_type.send(:find, item.id)
19
- else
20
- super_classes
21
- end
22
- end
23
- else
24
- if !super_classes.subtype.nil? && !super_classes.subtype.blank?
25
- inherits_type = Object.const_get(super_classes.subtype.to_s)
26
- inherits_type.send(:find, *args)
27
- else
28
- super_classes
29
- end
30
- end
31
- rescue
32
- super_classes
33
- end
34
- end
35
- end
36
- end
37
-
38
- def self.inherits_from(association_id)
39
-
40
- # add an association, and set the foreign key.
41
- has_one association_id, :foreign_key => :id, :dependent => :destroy
42
-
43
-
44
- # set the primary key, it' need because the generalized table doesn't have
45
- # a field ID.
46
- set_primary_key "#{association_id}_id"
47
-
48
-
49
- # Autobuild method to make a instance of association
50
- define_method("#{association_id}_with_autobuild") do
51
- send("#{association_id}_without_autobuild") || send("build_#{association_id}")
52
- end
53
-
54
-
55
- # Set a method chain whith autobuild.
56
- alias_method_chain association_id, :autobuild
57
-
58
-
59
- # bind the before save, this method call the save of association, and
60
- # get our generated ID an set to association_id field.
61
- before_save :save_inherit
62
-
63
-
64
- # Bind the validation of association.
65
- validate :inherit_association_must_be_valid
66
-
67
- # Generate a method to validate the field of association.
68
- define_method("inherit_association_must_be_valid") do
69
- association = send(association_id)
70
-
71
- unless valid = association.valid?
72
- association.errors.each do |attr, message|
73
- errors.add(attr, message)
74
- end
75
- end
76
-
77
- valid
78
- end
79
-
80
-
81
-
82
- # get the class of association by reflection, this is needed because
83
- # i need to get the methods and attributes to make a proxy methods.
84
- reflection = create_reflection(:has_one, association_id, {}, self)
85
- association_class = Object.const_get(reflection.class_name)
86
- # Get the colluns of association class.
87
- inherited_columns = association_class.column_names
88
- # Make a filter in association colluns to exclude the colluns that
89
- # the generalized class already have.
90
- inherited_columns = inherited_columns.reject { |c| self.column_names.grep(c).length > 0 || c == "type" || c == "subtype"}
91
- # Get the methods of the association class and tun it to an Array of Strings.
92
- inherited_methods = association_class.reflections.map { |key,value| key.to_s }
93
- # Make a filter in association methods to exclude the methods that
94
- # the generalizae class already have.
95
- inherited_methods = inherited_methods.reject { |c| self.reflections.map {|key, value| key.to_s }.include?(c) }
96
-
97
-
98
- # create the proxy methods to get and set the properties and methods
99
- # in association class.
100
- (inherited_columns + inherited_methods).each do |name|
101
- define_method name do
102
- # if the field is ID than i only bind that with the association field.
103
- # this is needed to bypass the overflow problem when the ActiveRecord
104
- # try to get the id to find the association.
105
- if name == 'id'
106
- self["#{association_id}_id"]
107
- else
108
- assoc = send(association_id)
109
- assoc.send(name)
110
- end
111
- end
112
-
113
-
114
- define_method "#{name}=" do |new_value|
115
- # if the field is ID than i only bind that with the association field.
116
- # this is needed to bypass the overflow problem when the ActiveRecord
117
- # try to get the id to find the association.
118
- if name == 'id'
119
- self["#{association_id}_id"] = new_value
120
- else
121
- assoc = send(association_id)
122
- assoc.send("#{name}=", new_value)
123
- end
124
- end
125
- end
126
-
127
-
128
- # Create a method do bind in before_save callback, this method
129
- # only call the save of association class and set the id in the
130
- # generalized class.
131
- define_method("save_inherit") do |*args|
132
- association = send(association_id)
133
- if association.attribute_names.include?("subtype")
134
- association.subtype = self.class.to_s
135
- end
136
- association.save
137
- self["#{association_id}_id"] = association.id
138
- true
139
- end
140
- end
141
- end
2
+ require 'class-table-inheritance/inherits-migration'
3
+ require 'class-table-inheritance/class-table-inheritance'
@@ -0,0 +1,145 @@
1
+
2
+ # ClassTableInheritance is an ActiveRecord plugin designed to allow
3
+ # simple multiple table (class) inheritance.
4
+ class ActiveRecord::Base
5
+ attr_reader :reflection
6
+
7
+ def self.acts_as_superclass
8
+ if self.column_names.include?("subtype")
9
+ def self.find(*args)
10
+ super_classes = super
11
+ begin
12
+ if super_classes.kind_of? Array
13
+ super_classes.map do |item|
14
+ if !item.subtype.nil? && !item.subtype.blank?
15
+ inherits_type = super_classes.subtype.to_s.classify.constantize
16
+ inherits_type.send(:find, item.id)
17
+ else
18
+ super_classes
19
+ end
20
+ end
21
+ else
22
+ if !super_classes.subtype.nil? && !super_classes.subtype.blank?
23
+ inherits_type = super_classes.subtype.to_s.classify.constantize
24
+ inherits_type.send(:find, *args)
25
+ else
26
+ super_classes
27
+ end
28
+ end
29
+ rescue
30
+ super_classes
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def self.inherits_from(association_id)
37
+ # Subst the module simbol to dash and if this is string
38
+ if association_id.kind_of?(String)
39
+ class_name = association_id
40
+ association_id = association_id.to_s.gsub(/::/, '_').downcase.to_sym
41
+ else
42
+ class_name = association_id.to_s.classify
43
+ end
44
+
45
+ # add an association, and set the foreign key.
46
+ has_one association_id, :class_name => class_name, :foreign_key => :id, :dependent => :destroy
47
+
48
+
49
+ # set the primary key, it' need because the generalized table doesn't have
50
+ # a field ID.
51
+ set_primary_key "#{association_id}_id"
52
+
53
+
54
+ # Autobuild method to make a instance of association
55
+ define_method("#{association_id}_with_autobuild") do
56
+ send("#{association_id}_without_autobuild") || send("build_#{association_id}")
57
+ end
58
+
59
+
60
+ # Set a method chain whith autobuild.
61
+ alias_method_chain association_id, :autobuild
62
+
63
+
64
+ # bind the before save, this method call the save of association, and
65
+ # get our generated ID an set to association_id field.
66
+ before_save :save_inherit
67
+
68
+
69
+ # Bind the validation of association.
70
+ validate :inherit_association_must_be_valid
71
+
72
+ # Generate a method to validate the field of association.
73
+ define_method("inherit_association_must_be_valid") do
74
+ association = send(association_id)
75
+
76
+ unless valid = association.valid?
77
+ association.errors.each do |attr, message|
78
+ errors.add(attr, message)
79
+ end
80
+ end
81
+
82
+ valid
83
+ end
84
+
85
+
86
+
87
+ # get the class of association by reflection, this is needed because
88
+ # i need to get the methods and attributes to make a proxy methods.
89
+ association_class = class_name.constantize
90
+ # Get the colluns of association class.
91
+ inherited_columns = association_class.column_names
92
+ # Make a filter in association colluns to exclude the colluns that
93
+ # the generalized class already have.
94
+ inherited_columns = inherited_columns.reject { |c| self.column_names.grep(c).length > 0 || c == "type" || c == "subtype"}
95
+ # Get the methods of the association class and tun it to an Array of Strings.
96
+ inherited_methods = association_class.reflections.map { |key,value| key.to_s }
97
+ # Make a filter in association methods to exclude the methods that
98
+ # the generalizae class already have.
99
+ inherited_methods = inherited_methods.reject { |c| self.reflections.map {|key, value| key.to_s }.include?(c) }
100
+
101
+
102
+ # create the proxy methods to get and set the properties and methods
103
+ # in association class.
104
+ (inherited_columns + inherited_methods).each do |name|
105
+ define_method name do
106
+ # if the field is ID than i only bind that with the association field.
107
+ # this is needed to bypass the overflow problem when the ActiveRecord
108
+ # try to get the id to find the association.
109
+ if name == 'id'
110
+ self["#{association_id}_id"]
111
+ else
112
+ assoc = send(association_id)
113
+ assoc.send(name)
114
+ end
115
+ end
116
+
117
+
118
+ define_method "#{name}=" do |new_value|
119
+ # if the field is ID than i only bind that with the association field.
120
+ # this is needed to bypass the overflow problem when the ActiveRecord
121
+ # try to get the id to find the association.
122
+ if name == 'id'
123
+ self["#{association_id}_id"] = new_value
124
+ else
125
+ assoc = send(association_id)
126
+ assoc.send("#{name}=", new_value)
127
+ end
128
+ end
129
+ end
130
+
131
+
132
+ # Create a method do bind in before_save callback, this method
133
+ # only call the save of association class and set the id in the
134
+ # generalized class.
135
+ define_method("save_inherit") do |*args|
136
+ association = send(association_id)
137
+ if association.attribute_names.include?("subtype")
138
+ association.subtype = self.class.to_s
139
+ end
140
+ association.save
141
+ self["#{association_id}_id"] = association.id
142
+ true
143
+ end
144
+ end
145
+ end
@@ -1,4 +1,3 @@
1
- require 'active_record'
2
1
 
3
2
  module InheritsMigration
4
3
 
@@ -14,19 +13,24 @@ module InheritsMigration
14
13
 
15
14
  create_table_without_inherits(table_name, options) do |table_defintion|
16
15
  if options[:inherits]
17
- association_type = Object.const_get(options[:inherits].to_s.capitalize)
16
+ if options[:inherits].kind_of?(String)
17
+ column_to_create = options[:inherits].gsub(/::/, '_').downcase
18
+ association_type = options[:inherits].constantize
19
+ else
20
+ column_to_create = options[:inherits]
21
+ association_type = options[:inherits].to_s.classify.constantize
22
+ end
18
23
  association_inst = association_type.send(:new)
19
24
  attr_column = association_inst.column_for_attribute(association_type.primary_key)
20
25
 
21
26
  field_option = {:primary_key => true, :null => false}
22
27
  field_option[:limit] = attr_column.limit if attr_column.limit
23
- table_defintion.column "#{options[:inherits]}_id", attr_column.type, field_option
28
+ table_defintion.column "#{column_to_create}_id", attr_column.type, field_option
24
29
  end
25
30
  yield table_defintion
26
31
  end
27
32
  end
28
33
  end
29
34
 
30
- #ActiveRecord::ConnectionAdapters::SchemaStatements::send(:include, InheritsMigration)
31
35
  ActiveRecord::Base
32
36
  ActiveRecord::ConnectionAdapters::SchemaStatements::send(:include, InheritsMigration)
@@ -0,0 +1,3 @@
1
+ class ClassTableInheritance
2
+ VERSION = "1.3.0"
3
+ end
@@ -0,0 +1,71 @@
1
+ require 'test_helper'
2
+
3
+ class ClassTableInheritanceTest < Test::Unit::TestCase
4
+
5
+ def test_create
6
+ name = 'Bike'
7
+
8
+ product = Product.new
9
+ product.name = name
10
+ assert_equal true, product.save
11
+
12
+ product = Product.find product.id
13
+ assert_equal name, product.name
14
+ end
15
+
16
+
17
+ def test_inheritance_book
18
+ title = 'Atlas Shrugged'
19
+ isbn = '9780451191144'
20
+
21
+ book = Book.new
22
+ book.name = title
23
+ book.isbn = isbn
24
+ assert_equal true, book.save
25
+
26
+ book = Book.find book.id
27
+ assert_equal title, book.name
28
+ assert_equal isbn, book.isbn
29
+ end
30
+
31
+ def test_inheritance_video
32
+ name = 'Amy Whinehouse - Rehab'
33
+ url = 'http://www.youtube.com/watch?v=3QI8RjKibyc'
34
+
35
+ video = Mod::Video.new
36
+ video.name = name
37
+ video.url = url
38
+ assert_equal true, video.save
39
+
40
+ video = Mod::Video.find video.id
41
+ assert_equal name, video.name
42
+ assert_equal url, video.url
43
+ end
44
+
45
+ def test_inheritance_user_save
46
+ name = 'bfscordeiro'
47
+
48
+ user = Mod::User.new
49
+ user.name = name
50
+ assert_equal true, user.save
51
+
52
+ user = Mod::User.find user.id
53
+ assert_equal name, user.name
54
+ end
55
+
56
+ def test_inheritance_manager_save
57
+ name = 'bfscordeiro'
58
+ salary = '6000'
59
+
60
+ manager = Manager.new
61
+ manager.name = name
62
+ manager.salary = salary
63
+ assert_equal true, manager.save
64
+
65
+ manager = Manager.find manager.id
66
+ assert_equal name, manager.name
67
+ assert_equal salary, manager.salary
68
+ end
69
+
70
+
71
+ end
@@ -0,0 +1,4 @@
1
+ sqlite3:
2
+ :adapter: sqlite3
3
+ :database: test/cti_plugin.sqlite3
4
+
@@ -0,0 +1,3 @@
1
+ class Book < ActiveRecord::Base
2
+ inherits_from :product
3
+ end
@@ -0,0 +1,3 @@
1
+ class Manager < ActiveRecord::Base
2
+ inherits_from 'Mod::User'
3
+ end
@@ -0,0 +1,5 @@
1
+ module Mod
2
+ def self.table_name_prefix
3
+ 'mod_'
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ class Mod::User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,3 @@
1
+ class Mod::Video < ActiveRecord::Base
2
+ inherits_from :product
3
+ end
@@ -0,0 +1,2 @@
1
+ class Product < ActiveRecord::Base
2
+ end
@@ -0,0 +1,24 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :products, :force => true do |t|
3
+ t.string :name
4
+ end
5
+
6
+ create_table :books, :force => true do |t|
7
+ t.string :isbn
8
+ t.integer :product_id
9
+ end
10
+
11
+ create_table :mod_videos, :force => true do |t|
12
+ t.integer :product_id
13
+ t.string :url
14
+ end
15
+
16
+ create_table :mod_users, :force => true do |t|
17
+ t.string :name
18
+ end
19
+
20
+ create_table :managers, :force => true do |t|
21
+ t.integer :mod_user_id
22
+ t.string :salary
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_record'
4
+ require 'class-table-inheritance'
5
+ require 'yaml'
6
+
7
+ database = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
8
+ ActiveRecord::Base.establish_connection(database['sqlite3'])
9
+ load(File.dirname(__FILE__) + "/schema.rb") if !File.exists?(database['sqlite3'][:database])
10
+
11
+ require 'models/product'
12
+ require 'models/book'
13
+ require 'models/mod'
14
+ require 'models/mod/video'
15
+ require 'models/mod/user'
16
+ require 'models/manager'
metadata CHANGED
@@ -1,45 +1,51 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class-table-inheritance
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 2
9
- - 1
10
- version: 1.2.1
4
+ prerelease:
5
+ version: 1.3.0
11
6
  platform: ruby
12
7
  authors:
13
- - Bruno Frank Cordeiro
8
+ - Bruno Frank
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2010-12-03 00:00:00 -02:00
13
+ date: 2011-07-25 00:00:00 -03:00
19
14
  default_executable:
20
15
  dependencies: []
21
16
 
22
- description: ActiveRecord plugin designed to allow simple multiple table inheritance CTI.
23
- email: bfscordeiro@gmail.com
17
+ description: ActiveRecord plugin designed to allow simple multiple table (class) inheritance.
18
+ email:
19
+ - bfscordeiro@gmail.com
24
20
  executables: []
25
21
 
26
22
  extensions: []
27
23
 
28
- extra_rdoc_files:
29
- - README
24
+ extra_rdoc_files: []
25
+
30
26
  files:
31
- - class-table-inheritance-1.0.0.gem
32
- - class-table-inheritance-1.1.0.gem
33
- - class-table-inheritance-1.1.1.gem
34
- - class-table-inheritance-1.2.0.gem
35
- - class-table-inheritance-1.2.1.gem
27
+ - .gitignore
28
+ - Gemfile
29
+ - README
30
+ - Rakefile
31
+ - class-table-inheritance.gemspec
36
32
  - init.rb
37
33
  - lib/class-table-inheritance.rb
38
- - lib/inherits-migration.rb
39
- - Rakefile
40
- - README
34
+ - lib/class-table-inheritance/class-table-inheritance.rb
35
+ - lib/class-table-inheritance/inherits-migration.rb
36
+ - lib/class-table-inheritance/version.rb
37
+ - test/class_table_inheritance_test.rb
38
+ - test/database.yml
39
+ - test/models/book.rb
40
+ - test/models/manager.rb
41
+ - test/models/mod.rb
42
+ - test/models/mod/user.rb
43
+ - test/models/mod/video.rb
44
+ - test/models/product.rb
45
+ - test/schema.rb
46
+ - test/test_helper.rb
41
47
  has_rdoc: true
42
- homepage:
48
+ homepage: https://github.com/brunofrank/class-table-inheritance
43
49
  licenses: []
44
50
 
45
51
  post_install_message:
@@ -52,25 +58,28 @@ required_ruby_version: !ruby/object:Gem::Requirement
52
58
  requirements:
53
59
  - - ">="
54
60
  - !ruby/object:Gem::Version
55
- hash: 3
56
- segments:
57
- - 0
58
61
  version: "0"
59
62
  required_rubygems_version: !ruby/object:Gem::Requirement
60
63
  none: false
61
64
  requirements:
62
65
  - - ">="
63
66
  - !ruby/object:Gem::Version
64
- hash: 3
65
- segments:
66
- - 0
67
67
  version: "0"
68
68
  requirements: []
69
69
 
70
- rubyforge_project:
71
- rubygems_version: 1.3.7
70
+ rubyforge_project: class-table-inheritance
71
+ rubygems_version: 1.6.2
72
72
  signing_key:
73
73
  specification_version: 3
74
- summary: ActiveRecord plugin designed to allow simple multiple table (class) inheritance.
75
- test_files: []
76
-
74
+ summary: ActiveRecord plugin designed to allow simple multiple table (class) inheritance.
75
+ test_files:
76
+ - test/class_table_inheritance_test.rb
77
+ - test/database.yml
78
+ - test/models/book.rb
79
+ - test/models/manager.rb
80
+ - test/models/mod.rb
81
+ - test/models/mod/user.rb
82
+ - test/models/mod/video.rb
83
+ - test/models/product.rb
84
+ - test/schema.rb
85
+ - test/test_helper.rb