naught 2.0.0 → 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.
- checksums.yaml +4 -4
- data/lib/naught/null_class_builder/commands/mimic.rb +59 -3
- data/lib/naught/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3e4aa0e2eddca2722a669cb141655ed975ad91535158d9d0cb09566f6971de8f
|
|
4
|
+
data.tar.gz: 2872a770d1b8d58336cee9b29be4b6108511893615c1e2c621ac2e9f8a321e56
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c2cf48a809f2777cb2a39c598aac6643bc765b44d39e29c6dbf8c539a394f134f27cced5517f84ca4e7590ec43e0ee01f9b896987c5c48a5b8d08c4793128fad
|
|
7
|
+
data.tar.gz: 8eaa91494482d1a081c1fa6c95b4c54d6e2f5cf6d1cc424bcf86cfd9a09c65618ba5fb46ca7151d2c6d288806aadc578116b97bf85c6f4df14211bf20ce0c5d0
|
|
@@ -30,6 +30,14 @@ module Naught
|
|
|
30
30
|
# @return [Class] singleton class being mimicked
|
|
31
31
|
attr_reader :singleton_class
|
|
32
32
|
|
|
33
|
+
# The example instance for dynamic method discovery
|
|
34
|
+
# @return [Object, nil] example instance or nil
|
|
35
|
+
attr_reader :example_instance
|
|
36
|
+
|
|
37
|
+
# Whether to include dynamically-defined methods
|
|
38
|
+
# @return [Boolean] whether to include dynamic methods
|
|
39
|
+
attr_reader :include_dynamic
|
|
40
|
+
|
|
33
41
|
# Create a mimic command for a class or instance
|
|
34
42
|
#
|
|
35
43
|
# @param builder [NullClassBuilder]
|
|
@@ -60,14 +68,16 @@ module Naught
|
|
|
60
68
|
def parse_arguments(class_to_mimic_or_options, options)
|
|
61
69
|
if class_to_mimic_or_options.is_a?(Hash)
|
|
62
70
|
options = class_to_mimic_or_options.merge(options)
|
|
63
|
-
|
|
64
|
-
@singleton_class =
|
|
65
|
-
@class_to_mimic =
|
|
71
|
+
@example_instance = options.fetch(:example)
|
|
72
|
+
@singleton_class = @example_instance.singleton_class
|
|
73
|
+
@class_to_mimic = @example_instance.class
|
|
66
74
|
else
|
|
75
|
+
@example_instance = nil
|
|
67
76
|
@singleton_class = NULL_SINGLETON_CLASS
|
|
68
77
|
@class_to_mimic = class_to_mimic_or_options
|
|
69
78
|
end
|
|
70
79
|
@include_super = options.fetch(:include_super, true)
|
|
80
|
+
@include_dynamic = options.fetch(:include_dynamic, !@example_instance.nil?)
|
|
71
81
|
end
|
|
72
82
|
|
|
73
83
|
# Configure the builder with the mimicked class's properties
|
|
@@ -91,8 +101,54 @@ module Naught
|
|
|
91
101
|
# @return [Array<Symbol>] methods to stub
|
|
92
102
|
def methods_to_stub
|
|
93
103
|
all_methods = class_to_mimic.instance_methods(include_super) | singleton_class.instance_methods(false)
|
|
104
|
+
all_methods |= dynamic_methods if include_dynamic
|
|
94
105
|
all_methods - METHODS_TO_SKIP
|
|
95
106
|
end
|
|
107
|
+
|
|
108
|
+
# Discover dynamically-defined methods from the example instance
|
|
109
|
+
#
|
|
110
|
+
# This handles classes like Stripe that use method_missing and
|
|
111
|
+
# respond_to_missing? to define methods based on instance data.
|
|
112
|
+
#
|
|
113
|
+
# @return [Array<Symbol>] dynamic method names
|
|
114
|
+
def dynamic_methods
|
|
115
|
+
return [] unless example_instance
|
|
116
|
+
|
|
117
|
+
candidates = discover_method_candidates
|
|
118
|
+
candidates.select { |name| example_instance.respond_to?(name) }
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Discover candidate method names from the example instance
|
|
122
|
+
#
|
|
123
|
+
# Tries multiple approaches to find method names:
|
|
124
|
+
# 1. If the instance responds to :keys (like Stripe objects), use those
|
|
125
|
+
# 2. If the instance responds to :attributes, use those
|
|
126
|
+
# 3. If the instance responds to :to_h or :to_hash, use the hash keys
|
|
127
|
+
#
|
|
128
|
+
# @return [Array<Symbol>] candidate method names
|
|
129
|
+
def discover_method_candidates
|
|
130
|
+
candidates = [] #: Array[Symbol]
|
|
131
|
+
|
|
132
|
+
# Stripe-style objects expose keys
|
|
133
|
+
candidates |= example_instance.keys.map(&:to_sym) if example_instance.respond_to?(:keys)
|
|
134
|
+
|
|
135
|
+
# ActiveRecord-style objects expose attribute_names
|
|
136
|
+
if example_instance.respond_to?(:attribute_names)
|
|
137
|
+
candidates |= example_instance.attribute_names.map(&:to_sym)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# OpenStruct-style objects can be converted to hash
|
|
141
|
+
if example_instance.respond_to?(:to_h) && !example_instance.is_a?(Object.const_get(:Hash))
|
|
142
|
+
begin
|
|
143
|
+
hash = example_instance.to_h
|
|
144
|
+
candidates |= hash.keys.map(&:to_sym) if hash.is_a?(Hash)
|
|
145
|
+
rescue
|
|
146
|
+
# Ignore errors from to_h
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
candidates
|
|
151
|
+
end
|
|
96
152
|
end
|
|
97
153
|
end
|
|
98
154
|
end
|
data/lib/naught/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: naught
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Avdi Grimm
|
|
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
89
|
version: '0'
|
|
90
90
|
requirements: []
|
|
91
|
-
rubygems_version: 4.0.
|
|
91
|
+
rubygems_version: 4.0.6
|
|
92
92
|
specification_version: 4
|
|
93
93
|
summary: Naught is a toolkit for building Null Objects
|
|
94
94
|
test_files: []
|