activerecord-null 0.1.3 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61c6b213e7c4c8f5cbeab18700a2eebc46803592fb34b3677ed93da0a6c49c92
4
- data.tar.gz: 698f74dbdf03af5dbdc7e35111f20a478363c832028258c77cc14fdf0061b8b0
3
+ metadata.gz: a56f2bfbaf5d498a54f2698e96dc1d460b6a9036ed1c6946e54bcbf724a782c9
4
+ data.tar.gz: 4575ab2f7ffabae11b05bf8429acb57c0810840fd7e996902691f4758d63ce81
5
5
  SHA512:
6
- metadata.gz: 3e8fd9f3d1c8c130a997e3c66c6560b82e18b2ff782a2772832de7e4344abb59f0a6ef0efcaae67cb2a47dd221076b1113be2a0f520bc0c267a6ecb137c3b7eb
7
- data.tar.gz: 9848bd89df1f1cb2ded9dcecd27f478aacbac6ed1586f56ecd7b17446b3755bceec6fbef8b0858b58be7996da11617c1d2f056517c0a55a03aff26a79ee483e5
6
+ metadata.gz: 5f737ae853ffbdf31b4ef323e313f9a844f7b549d2bb3a7aa8d5547af94bfb0779b5d2f099a47b11f6ff4b3a48f163e842d68e8c3efb8b52e519a08ae30dc620
7
+ data.tar.gz: e0af61bf86c190fb5e5ccf05eb7d8ec13f0cbb51e59b48e36eb3e0be1b29f3925ea69e778e391c2b0b700d7e1e053ab801db4840fe4e1ae91a130772b98c3132
data/CHANGELOG.md CHANGED
@@ -5,24 +5,28 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [0.1.3] - 2025-11-18
8
+ ## [0.1.5] - 2025-11-19
9
9
 
10
- ### Changed
10
+ ### Added
11
11
 
12
- - Use git trailers to track changelog entries. (d296851)
13
- - Implement [] method to access attributes with string/symbol keys (1dc4f95)
12
+ - Void() method for defining non-singleton null objects (0e89194)
13
+ - Model.void(attributes) for creating instances with attribute overrides (0e89194)
14
14
 
15
- ### Removed
15
+ ### Changed
16
16
 
17
- - CodeClimate access on CI runs. (2dbf5bc)
17
+ - Mimic module now delegates table_name to parent model (c6f3956)
18
+ - Extracted create_null_class, setup_singleton_attributes, setup_instance_attributes helpers (b0a77f8)
19
+ - Pass class_name to the Null() or Void() methods with an alternative class name. (d3284c4)
18
20
 
19
- ## [0.1.3] - 2025-11-18
21
+ ## [0.1.5] - 2025-11-19
20
22
 
21
- ### Changed
23
+ ### Added
22
24
 
23
- - Use git trailers to track changelog entries. (d296851)
24
- - Implement [] method to access attributes with string/symbol keys (1dc4f95)
25
+ - Void() method for defining non-singleton null objects (0e89194)
26
+ - Model.void(attributes) for creating instances with attribute overrides (0e89194)
25
27
 
26
- ### Removed
28
+ ### Changed
27
29
 
28
- - CodeClimate access on CI runs. (2dbf5bc)
30
+ - Mimic module now delegates table_name to parent model (c6f3956)
31
+ - Extracted create_null_class, setup_singleton_attributes, setup_instance_attributes helpers (b0a77f8)
32
+ - Pass class_name to the Null() or Void() methods with an alternative class name. (d3284c4)
data/README.md CHANGED
@@ -68,6 +68,81 @@ class User < ApplicationRecord
68
68
  end
69
69
  ```
70
70
 
71
+ Customize the null class name:
72
+
73
+ ```ruby
74
+ class User < ApplicationRecord
75
+ Null(class_name: "Guest")
76
+ class << self
77
+ alias_method :null, :guest
78
+ end
79
+ end
80
+
81
+ User.guest # returns a User::Guest instance
82
+ ```
83
+
84
+ ### Void Objects
85
+
86
+ While `Null` objects are singletons (one instance per model), `Void` objects are instantiable null objects that allow creating multiple instances with different attribute values.
87
+
88
+ Define a void object for the model:
89
+
90
+ ```ruby
91
+ class Product < ApplicationRecord
92
+ Void([:name] => "Unknown Product") do
93
+ def display_name
94
+ "Product: #{name}"
95
+ end
96
+ end
97
+ end
98
+ ```
99
+
100
+ Create instances with custom attributes:
101
+
102
+ ```ruby
103
+ product1 = Product.void(name: "Widget")
104
+ product2 = Product.void(name: "Gadget")
105
+
106
+ product1.name # => "Widget"
107
+ product2.name # => "Gadget"
108
+ ```
109
+
110
+ Each call to `.void` returns a new instance:
111
+
112
+ ```ruby
113
+ Product.void.object_id != Product.void.object_id # => true
114
+ ```
115
+
116
+ Instance attributes override defaults:
117
+
118
+ ```ruby
119
+ product = Product.void(name: "Custom")
120
+ product.name # => "Custom" (overrides default "Unknown Product")
121
+
122
+ default_product = Product.void
123
+ default_product.name # => "Unknown Product" (uses default)
124
+ ```
125
+
126
+ Void objects support the same features as Null objects:
127
+ - Callable defaults (lambdas/procs)
128
+ - Custom methods via block syntax
129
+ - Association handling
130
+ - All ActiveRecord query methods (`null?`, `persisted?`, etc.)
131
+ - Custom class names via `class_name:` parameter
132
+
133
+ ```ruby
134
+ class Product < ApplicationRecord
135
+ Void(class_name: "Placeholder")
136
+ class << self
137
+ alias_method :void, :placeholder
138
+ end
139
+ end
140
+
141
+ Product.placeholder # returns a Product::Placeholder instance
142
+ ```
143
+
144
+ Use `Null` when you need a single shared null object instance. Use `Void` when you need multiple null object instances with different attribute values.
145
+
71
146
  ## Development
72
147
 
73
148
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -14,7 +14,7 @@ module ActiveRecord
14
14
 
15
15
  def self.mimic_model_class = @mimic_model_class
16
16
 
17
- def self.table_name = @mimic_model_class.to_s.tableize
17
+ def self.table_name = @mimic_model_class.table_name
18
18
 
19
19
  def self.primary_key = @mimic_model_class.primary_key
20
20
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Null
5
- VERSION = "0.1.3"
5
+ VERSION = "0.1.5"
6
6
  end
7
7
  end
@@ -12,6 +12,129 @@ module ActiveRecord
12
12
  # extend ActiveRecord::Null
13
13
  # end
14
14
  module Null
15
+ private
16
+
17
+ # Shared method to create Null or Void classes
18
+ def create_null_class(inherit, assignments, singleton:)
19
+ null_class = Class.new do
20
+ include ::ActiveRecord::Null::Mimic
21
+
22
+ mimics inherit
23
+
24
+ # Store assignments
25
+ instance_variable_set(:@_assignments, assignments)
26
+
27
+ class << self
28
+ attr_reader :_assignments
29
+
30
+ def method_missing(method, ...)
31
+ mimic_model_class.respond_to?(method) ? mimic_model_class.send(method, ...) : super
32
+ end
33
+
34
+ def respond_to_missing?(method, include_private = false)
35
+ mimic_model_class.respond_to?(method, include_private) || super
36
+ end
37
+ end
38
+ end
39
+
40
+ if singleton
41
+ null_class.include(Singleton)
42
+ setup_singleton_attributes(null_class)
43
+ else
44
+ setup_instance_attributes(null_class)
45
+ end
46
+
47
+ null_class
48
+ end
49
+
50
+ def setup_singleton_attributes(null_class)
51
+ null_class.class_eval do
52
+ class << self
53
+ # Override instance to initialize attributes lazily
54
+ def instance
55
+ initialize_attribute_methods unless @_attributes_initialized
56
+ super
57
+ end
58
+
59
+ private
60
+
61
+ def initialize_attribute_methods
62
+ return unless mimic_model_class.table_exists?
63
+
64
+ if _assignments.any?
65
+ _assignments.each do |attributes, value|
66
+ define_attribute_methods(attributes, value:)
67
+ end
68
+ end
69
+
70
+ nil_assignments = mimic_model_class.attribute_names
71
+ if _assignments.any?
72
+ _assignments.each do |attributes, _|
73
+ nil_assignments -= attributes
74
+ end
75
+ end
76
+ define_attribute_methods(nil_assignments) if nil_assignments.any?
77
+
78
+ @_attributes_initialized = true
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def setup_instance_attributes(null_class)
85
+ null_class.class_eval do
86
+ def initialize(attributes = {})
87
+ @_instance_attributes = attributes
88
+ initialize_attribute_methods
89
+ end
90
+
91
+ private
92
+
93
+ def initialize_attribute_methods
94
+ return unless self.class.mimic_model_class.table_exists?
95
+
96
+ assignments = self.class._assignments
97
+
98
+ if assignments.any?
99
+ assignments.each do |attributes, default_value|
100
+ attributes.each do |attr|
101
+ attr_sym = attr.to_sym
102
+ next if respond_to?(attr_sym)
103
+
104
+ define_singleton_method(attr_sym) do
105
+ if @_instance_attributes.key?(attr_sym)
106
+ @_instance_attributes[attr_sym]
107
+ elsif default_value.is_a?(Proc)
108
+ instance_exec(&default_value)
109
+ else
110
+ default_value
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ nil_assignments = self.class.mimic_model_class.attribute_names
118
+ if assignments.any?
119
+ assignments.each do |attributes, _|
120
+ nil_assignments -= attributes.map(&:to_s)
121
+ end
122
+ end
123
+
124
+ nil_assignments.each do |attr|
125
+ attr_sym = attr.to_sym
126
+ next if respond_to?(attr_sym)
127
+
128
+ define_singleton_method(attr_sym) do
129
+ @_instance_attributes.key?(attr_sym) ? @_instance_attributes[attr_sym] : nil
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ public
137
+
15
138
  # Define a Null class for the given class.
16
139
  #
17
140
  # @example
@@ -33,41 +156,46 @@ module ActiveRecord
33
156
  #
34
157
  # @param inherit [Class] The class from which the Null object inherits attributes
35
158
  # @param assignments [Array] The attributes to assign to the null object
36
- def Null(inherit = self, assignments = {}, &)
159
+ def Null(inherit = self, class_name: :Null, **assignments, &)
37
160
  if inherit.is_a?(Hash)
38
161
  assignments = inherit
39
162
  inherit = self
40
163
  end
41
- null_class = Class.new do
42
- include ::ActiveRecord::Null::Mimic
43
-
44
- mimics inherit
45
164
 
46
- include Singleton
165
+ null_class = create_null_class(inherit, assignments, singleton: true)
166
+ null_class.class_eval(&) if block_given?
47
167
 
48
- class << self
49
- def method_missing(method, ...)
50
- mimic_model_class.respond_to?(method) ? mimic_model_class.send(method, ...) : super
51
- end
168
+ inherit.const_set(class_name, null_class)
169
+ inherit.define_singleton_method(:null) { null_class.instance }
170
+ end
52
171
 
53
- def respond_to_missing?(method, include_private = false)
54
- mimic_model_class.respond_to?(method, include_private) || super
55
- end
56
- end
172
+ # Define a Void class for the given class.
173
+ # Unlike Null, Void objects are not singletons and can be instantiated
174
+ # multiple times with different attribute values.
175
+ #
176
+ # @example
177
+ # class Product < ApplicationRecord
178
+ # Void do
179
+ # def display_name = "Product: #{name}"
180
+ # end
181
+ # end
182
+ #
183
+ # product1 = Product.void(name: "Widget")
184
+ # product2 = Product.void(name: "Gadget")
185
+ #
186
+ # @param inherit [Class] The class from which the Void object inherits attributes
187
+ # @param assignments [Hash] The default attributes to assign to void objects
188
+ def Void(inherit = self, class_name: :Void, **assignments, &)
189
+ if inherit.is_a?(Hash)
190
+ assignments = inherit
191
+ inherit = self
57
192
  end
58
- null_class.class_eval(&) if block_given?
59
193
 
60
- nil_assignments = inherit.attribute_names
61
- if assignments.any?
62
- assignments.each do |attributes, value|
63
- nil_assignments -= attributes
64
- null_class.define_attribute_methods(attributes, value:)
65
- end
66
- end
67
- null_class.define_attribute_methods(nil_assignments)
68
- inherit.const_set(:Null, null_class)
194
+ void_class = create_null_class(inherit, assignments, singleton: false)
195
+ void_class.class_eval(&) if block_given?
69
196
 
70
- inherit.define_singleton_method(:null) { null_class.instance }
197
+ inherit.const_set(class_name, void_class)
198
+ inherit.define_singleton_method(:void) { |attributes = {}| void_class.new(attributes) }
71
199
  end
72
200
 
73
201
  def self.extended(base)
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ # Test that Null classes can be defined without database access
6
+ class LazyLoadingTest < Minitest::Spec
7
+ describe "Lazy attribute loading" do
8
+ it "allows Null class definition without database access" do
9
+ # Create a new model class with a fake table_exists? check
10
+ table_available = false
11
+
12
+ test_class = Class.new(ApplicationRecord) do
13
+ def self.name
14
+ "TestModel"
15
+ end
16
+
17
+ define_singleton_method(:table_exists?) do
18
+ table_available
19
+ end
20
+
21
+ define_singleton_method(:attribute_names) do
22
+ ["id", "name", "email"]
23
+ end
24
+ end
25
+
26
+ # Extend with Null - this should NOT require database
27
+ test_class.extend ActiveRecord::Null
28
+
29
+ # Define the Null class - this should also NOT require database
30
+ # This is the key fix - Null() doesn't call attribute_names
31
+ assert_silent do
32
+ test_class.Null([:name] => "Unknown")
33
+ end
34
+
35
+ # The Null class constant should exist
36
+ assert test_class.const_defined?(:Null)
37
+
38
+ # Now make table available
39
+ table_available = true
40
+
41
+ # When we call .null with table available, attributes get loaded
42
+ null_instance = test_class.null
43
+ assert_instance_of test_class::Null, null_instance
44
+ assert_equal "Unknown", null_instance.name
45
+ assert_nil null_instance.email
46
+ end
47
+
48
+ it "initializes attributes only once" do
49
+ call_count = 0
50
+ test_class = Class.new(ApplicationRecord) do
51
+ def self.name
52
+ "CountingModel"
53
+ end
54
+
55
+ define_singleton_method(:table_exists?) do
56
+ true
57
+ end
58
+
59
+ define_singleton_method(:attribute_names) do
60
+ call_count += 1
61
+ ["id", "value"]
62
+ end
63
+ end
64
+
65
+ test_class.extend ActiveRecord::Null
66
+ test_class.Null
67
+
68
+ # Calling .null multiple times should only initialize once
69
+ assert_equal 0, call_count
70
+ test_class.null
71
+ assert_equal 1, call_count
72
+ test_class.null
73
+ assert_equal 1, call_count
74
+ test_class.null
75
+ assert_equal 1, call_count
76
+ end
77
+
78
+ it "handles missing database gracefully" do
79
+ # Create a model that simulates a missing database
80
+ test_class = Class.new(ApplicationRecord) do
81
+ def self.name
82
+ "MissingDbModel"
83
+ end
84
+
85
+ define_singleton_method(:table_exists?) do
86
+ false
87
+ end
88
+
89
+ define_singleton_method(:attribute_names) do
90
+ raise ActiveRecord::NoDatabaseError, "Database 'test' does not exist"
91
+ end
92
+ end
93
+
94
+ test_class.extend ActiveRecord::Null
95
+
96
+ # Should be able to define Null class without database
97
+ assert_silent do
98
+ test_class.Null([:name] => "Unknown")
99
+ end
100
+
101
+ # Accessing .null returns the instance (but no attributes are defined yet)
102
+ null_instance = test_class.null
103
+ assert_instance_of test_class::Null, null_instance
104
+
105
+ # Without a table, no attributes work (not even custom ones)
106
+ # This is fine - in CI, you wouldn't call .null before running migrations
107
+ assert_raises(NoMethodError) { null_instance.name }
108
+ end
109
+
110
+ it "handles missing table gracefully" do
111
+ # Create a model that simulates a missing table
112
+ test_class = Class.new(ApplicationRecord) do
113
+ def self.name
114
+ "MissingTableModel"
115
+ end
116
+
117
+ define_singleton_method(:table_exists?) do
118
+ false
119
+ end
120
+
121
+ define_singleton_method(:attribute_names) do
122
+ raise ActiveRecord::StatementInvalid, "Table 'missing_table_models' doesn't exist"
123
+ end
124
+ end
125
+
126
+ test_class.extend ActiveRecord::Null
127
+
128
+ # Should be able to define Null class without table
129
+ assert_silent do
130
+ test_class.Null([:status] => "inactive")
131
+ end
132
+
133
+ # Accessing .null returns the instance
134
+ null_instance = test_class.null
135
+ assert_instance_of test_class::Null, null_instance
136
+
137
+ # Without a table, attributes don't work
138
+ assert_raises(NoMethodError) { null_instance.status }
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,245 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class ApplicationRecord < ActiveRecord::Base
6
+ primary_abstract_class
7
+ extend ActiveRecord::Null
8
+ end
9
+
10
+ class Product < ApplicationRecord
11
+ self.table_name = "businesses" # Reuse existing table
12
+
13
+ Void([:name] => "Unknown Product") do
14
+ def display_name
15
+ "Product: #{name}"
16
+ end
17
+ end
18
+ end
19
+
20
+ class Comment < ApplicationRecord
21
+ self.table_name = "posts" # Reuse existing table
22
+
23
+ Void()
24
+ end
25
+
26
+ class ActiveRecord::TestVoid < Minitest::Spec
27
+ describe "Void class definition" do
28
+ it "creates Void constant on model" do
29
+ assert Product.const_defined?(:Void)
30
+ end
31
+
32
+ it "Void class includes Mimic" do
33
+ assert Product::Void.include?(ActiveRecord::Null::Mimic)
34
+ end
35
+
36
+ it "Void class does not include Singleton" do
37
+ refute Product::Void.include?(Singleton)
38
+ end
39
+
40
+ it "defines .void method on model" do
41
+ assert Product.respond_to?(:void)
42
+ end
43
+
44
+ it "Void can be defined without arguments" do
45
+ assert Comment.const_defined?(:Void)
46
+ end
47
+ end
48
+
49
+ describe ".void instantiation" do
50
+ it "returns new instance each time" do
51
+ void1 = Product.void
52
+ void2 = Product.void
53
+
54
+ assert_instance_of Product::Void, void1
55
+ assert_instance_of Product::Void, void2
56
+ refute_equal void1.object_id, void2.object_id
57
+ end
58
+
59
+ it "creates instance with no arguments" do
60
+ void_obj = Product.void
61
+
62
+ assert_instance_of Product::Void, void_obj
63
+ end
64
+
65
+ it "creates instance with empty hash" do
66
+ void_obj = Product.void({})
67
+
68
+ assert_instance_of Product::Void, void_obj
69
+ end
70
+ end
71
+
72
+ describe "attribute handling" do
73
+ it "returns default value from hash syntax" do
74
+ void_obj = Product.void
75
+
76
+ assert_equal "Unknown Product", void_obj.name
77
+ end
78
+
79
+ it "allows instance attributes to override defaults" do
80
+ void_obj = Product.void(name: "Custom Product")
81
+
82
+ assert_equal "Custom Product", void_obj.name
83
+ end
84
+
85
+ it "database attributes default to nil" do
86
+ # Assuming businesses table doesn't have a 'price' column
87
+ void_obj = Product.void
88
+
89
+ # Name has a default, so it should return that
90
+ assert_equal "Unknown Product", void_obj.name
91
+ end
92
+
93
+ it "supports multiple instances with different attributes" do
94
+ void1 = Product.void(name: "Product A")
95
+ void2 = Product.void(name: "Product B")
96
+
97
+ assert_equal "Product A", void1.name
98
+ assert_equal "Product B", void2.name
99
+ end
100
+
101
+ it "instance attributes don't affect class defaults" do
102
+ void1 = Product.void(name: "Modified")
103
+ void2 = Product.void
104
+
105
+ assert_equal "Modified", void1.name
106
+ assert_equal "Unknown Product", void2.name
107
+ end
108
+ end
109
+
110
+ describe "custom methods from block" do
111
+ it "block-defined methods are accessible" do
112
+ void_obj = Product.void
113
+
114
+ assert_respond_to void_obj, :display_name
115
+ end
116
+
117
+ it "block methods can access attributes" do
118
+ void_obj = Product.void(name: "Special")
119
+
120
+ assert_equal "Product: Special", void_obj.display_name
121
+ end
122
+
123
+ it "block methods work with defaults" do
124
+ void_obj = Product.void
125
+
126
+ assert_equal "Product: Unknown Product", void_obj.display_name
127
+ end
128
+ end
129
+
130
+ describe "type checking" do
131
+ it "is_a?(Model) returns true" do
132
+ void_obj = Product.void
133
+
134
+ assert void_obj.is_a?(Product)
135
+ end
136
+
137
+ it "is_a?(Model::Void) returns true" do
138
+ void_obj = Product.void
139
+
140
+ assert void_obj.is_a?(Product::Void)
141
+ end
142
+
143
+ it "null? returns true" do
144
+ void_obj = Product.void
145
+
146
+ assert void_obj.null?
147
+ end
148
+
149
+ it "persisted? returns false" do
150
+ void_obj = Product.void
151
+
152
+ refute void_obj.persisted?
153
+ end
154
+
155
+ it "new_record? returns false" do
156
+ void_obj = Product.void
157
+
158
+ refute void_obj.new_record?
159
+ end
160
+
161
+ it "destroyed? returns false" do
162
+ void_obj = Product.void
163
+
164
+ refute void_obj.destroyed?
165
+ end
166
+ end
167
+
168
+ describe "callable attribute values" do
169
+ it "supports callable defaults" do
170
+ test_class = Class.new(ApplicationRecord) do
171
+ def self.name
172
+ "CallableTest"
173
+ end
174
+
175
+ self.table_name = "users"
176
+
177
+ Void([:name] => -> { "Computed Name" })
178
+ end
179
+
180
+ void_obj = test_class.void
181
+
182
+ assert_equal "Computed Name", void_obj.name
183
+ end
184
+
185
+ it "callable defaults can access instance context" do
186
+ test_class = Class.new(ApplicationRecord) do
187
+ def self.name
188
+ "ContextTest"
189
+ end
190
+
191
+ self.table_name = "users"
192
+
193
+ Void([:name] => -> { "Hello" })
194
+
195
+ def greeting
196
+ "Welcome"
197
+ end
198
+ end
199
+
200
+ void_obj = test_class.void
201
+
202
+ assert_equal "Hello", void_obj.name
203
+ end
204
+ end
205
+
206
+ describe "integration with Null" do
207
+ it "Null and Void can coexist on same model" do
208
+ # Define both on a test class
209
+ test_class = Class.new(ApplicationRecord) do
210
+ def self.name
211
+ "TestModel"
212
+ end
213
+
214
+ self.table_name = "users"
215
+
216
+ Null([:name] => "Null Default")
217
+ Void([:name] => "Void Default")
218
+ end
219
+
220
+ null_obj = test_class.null
221
+ void_obj = test_class.void
222
+
223
+ assert_equal "Null Default", null_obj.name
224
+ assert_equal "Void Default", void_obj.name
225
+ assert_equal null_obj.object_id, test_class.null.object_id # Singleton
226
+ refute_equal void_obj.object_id, test_class.void.object_id # Not singleton
227
+ end
228
+ end
229
+
230
+ describe "model integration" do
231
+ it "respects table_name from parent model" do
232
+ assert_equal Product.table_name, Product::Void.table_name
233
+ end
234
+
235
+ it "respects primary_key from parent model" do
236
+ assert_equal "id", Product::Void.primary_key
237
+ end
238
+
239
+ it "has mimic_model_class reference" do
240
+ void_obj = Product.void
241
+
242
+ assert_equal Product, void_obj.mimic_model_class
243
+ end
244
+ end
245
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-null
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Gay
@@ -39,7 +39,9 @@ files:
39
39
  - lib/activerecord/null.rb
40
40
  - lib/activerecord/null/mimic.rb
41
41
  - lib/activerecord/null/version.rb
42
+ - test/activerecord/test_lazy_loading.rb
42
43
  - test/activerecord/test_null.rb
44
+ - test/activerecord/test_void.rb
43
45
  - test/support/schema.rb
44
46
  - test/test_helper.rb
45
47
  homepage: https://github.com/SOFware/activerecord-null