astruct 2.11.0 → 3.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.
- checksums.yaml +7 -0
- data/lib/astruct.rb +6 -81
- data/lib/astruct/behavior.rb +251 -0
- data/lib/astruct/version.rb +1 -2
- data/spec/lib/astruct/behavior_spec.rb +10 -0
- data/spec/lib/astruct/version_spec.rb +7 -0
- data/spec/lib/astruct_spec.rb +13 -0
- data/spec/spec_helper.rb +30 -0
- data/test/lib/{astruct_test.rb → astruct/test_behavior.rb} +13 -13
- data/test/test_helper.rb +2 -0
- metadata +91 -78
- data/.gitignore +0 -34
- data/.rvmrc +0 -49
- data/.travis.yml +0 -1
- data/Gemfile +0 -4
- data/Guardfile +0 -14
- data/LICENSE +0 -22
- data/README.md +0 -32
- data/Rakefile +0 -43
- data/astruct.gemspec +0 -23
- data/bench/add_more_vs_ostruct.rb +0 -34
- data/bench/delete_vs_ostruct.rb +0 -33
- data/bench/dump_vs_ostruct.rb +0 -33
- data/bench/dynamic_vs_ostruct.rb +0 -37
- data/bench/inspect_vs_ostruct.rb +0 -33
- data/bench/load_vs_ostruct.rb +0 -33
- data/bench/nested_vs_ostruct.rb +0 -37
- data/bench/new_vs_ostruct.rb +0 -31
- data/bench/some_updates_vs_ostruct.rb +0 -34
- data/lib/astruct/module.rb +0 -162
- data/test/helper.rb +0 -3
- data/test/lib/ostruct_test.rb +0 -227
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6990e238c22d0d907f210e88381630a930b20355
|
4
|
+
data.tar.gz: 028d8e80cc9b222c3383c511f514426a3d888eea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 64a93ec3749af729bd2d2bce28a225f22ec46e8ad415e4ba8004f69ad82dd81a0cf9b925a6040b76fb316a4bbf6e954542bce07540503d5ce6f9a29289e418fd
|
7
|
+
data.tar.gz: 5708d234e2e1cea7f644dc7be147ebc267d3c931aacc5a93b7a4386a2cb588ed1949eb4acfaf0d360871843dbe1a0eefba09f4ba6d258fd897be26639ff43e67
|
data/lib/astruct.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "astruct/behavior"
|
2
2
|
|
3
|
-
#
|
4
3
|
# = astruct.rb: AltStruct implementation
|
5
4
|
#
|
6
5
|
# Author:: Kurtis Rainbolt-Greene
|
@@ -10,85 +9,11 @@ require_relative 'astruct/module'
|
|
10
9
|
# create hash-like classes. Allowing you to create an object that can
|
11
10
|
# dynamically accept accessors and behaves very much like a Hash.
|
12
11
|
#
|
13
|
-
|
14
|
-
#
|
15
|
-
# An AltStruct is a data structure, similar to a Hash, that allows the
|
16
|
-
# definition of arbitrary attributes with their accompanying values. This is
|
17
|
-
# accomplished by using Ruby's metaprogramming to define methods on the class
|
18
|
-
# itself.
|
19
|
-
#
|
20
|
-
|
21
|
-
#
|
22
|
-
# == Examples:
|
23
|
-
#
|
24
|
-
# require 'astruct'
|
25
|
-
#
|
26
|
-
# class Profile < AltStruct
|
27
|
-
#
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# person = Profile.new name: "John Smith"
|
31
|
-
# person.age = 70
|
32
|
-
#
|
33
|
-
# puts person.name # => "John Smith"
|
34
|
-
# puts person.age # => 70
|
35
|
-
# puts person.dump # => { :name => "John Smith", :age => 70 }
|
36
|
-
#
|
37
|
-
|
38
|
-
#
|
39
|
-
# An AltStruct employs a Hash internally to store the methods and values and
|
40
|
-
# can even be initialized with one:
|
41
|
-
#
|
42
|
-
# australia = AltStruct.new country: "Australia", population: 20_000_000
|
43
|
-
# puts australia.inspect # => <AltStruct country="Australia", population=20000000>
|
44
|
-
#
|
45
|
-
|
46
|
-
#
|
47
|
-
# Hash keys with spaces or characters that would normally not be able to use for
|
48
|
-
# method calls (e.g. ()[]*) will not be immediately available on the
|
49
|
-
# AltStruct object as a method for retrieval or assignment, but can be still be
|
50
|
-
# reached through the Object#send method.
|
51
|
-
#
|
52
|
-
# measurements = AltStruct.new "length (in inches)" => 24
|
53
|
-
# measurements.send "length (in inches)" # => 24
|
54
|
-
#
|
55
|
-
# data_point = AltStruct.new :queued? => true
|
56
|
-
# data_point.queued? # => true
|
57
|
-
# data_point.send "queued?=", false
|
58
|
-
# data_point.queued? # => false
|
59
|
-
#
|
60
|
-
|
61
|
-
#
|
62
|
-
# Removing the presence of a method requires the execution the delete_field
|
63
|
-
# or delete (like a hash) method as setting the property value to +nil+
|
64
|
-
# will not remove the method.
|
65
|
-
#
|
66
|
-
# first_pet = AltStruct.new :name => 'Rowdy', :owner => 'John Smith'
|
67
|
-
# first_pet.owner = nil
|
68
|
-
# second_pet = AltStruct.new :name => 'Rowdy'
|
69
|
-
#
|
70
|
-
# first_pet == second_pet # -> false
|
71
|
-
#
|
72
|
-
# first_pet.delete_field(:owner)
|
73
|
-
# first_pet == second_pet # -> true
|
74
|
-
#
|
75
|
-
|
76
|
-
#
|
77
|
-
# == Implementation:
|
78
|
-
#
|
79
|
-
# An AltStruct utilizes Ruby's method lookup structure to and find and define
|
80
|
-
# the necessary methods for properties. This is accomplished through the method
|
81
|
-
# method_missing and define_method.
|
82
|
-
#
|
83
|
-
|
84
|
-
#
|
85
|
-
# This should be a consideration if there is a concern about the performance of
|
86
|
-
# the objects that are created, as there is much more overhead in the setting
|
87
|
-
# of these properties compared to using a Hash or a Struct.
|
88
|
-
#
|
89
12
|
class AltStruct
|
90
|
-
# We include all of the AltStruct::
|
13
|
+
# We include all of the AltStruct::Behavior Module in order to give AltStruct
|
91
14
|
# the same behavior as OpenStruct. It's better, however, to simply
|
92
|
-
# include AltStruct::
|
93
|
-
include AltStruct::
|
15
|
+
# include AltStruct::Behavior into your own class.
|
16
|
+
include AltStruct::Behavior
|
94
17
|
end
|
18
|
+
|
19
|
+
require_relative "astruct/version"
|
@@ -0,0 +1,251 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
class AltStruct
|
4
|
+
# An AltStruct is a data structure, similar to a Hash, that allows the
|
5
|
+
# definition of arbitrary attributes with their accompanying values. This is
|
6
|
+
# accomplished by using Ruby's meta-programming to define methods on the
|
7
|
+
# class itself.
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# == Examples:
|
11
|
+
#
|
12
|
+
# require 'astruct'
|
13
|
+
#
|
14
|
+
# class Profile < AltStruct
|
15
|
+
#
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# person = Profile.new name: "John Smith"
|
19
|
+
# person.age = 70
|
20
|
+
#
|
21
|
+
# puts person.name # => "John Smith"
|
22
|
+
# puts person.age # => 70
|
23
|
+
# puts person.dump # => { :name => "John Smith", :age => 70 }
|
24
|
+
#
|
25
|
+
# An AltStruct employs a Hash internally to store the methods and values and
|
26
|
+
# can even be initialized with one:
|
27
|
+
#
|
28
|
+
# australia = AltStruct.new(
|
29
|
+
# country: "Australia",
|
30
|
+
# population: 20_000_000
|
31
|
+
# )
|
32
|
+
# puts australia.inspect
|
33
|
+
# # => <AltStruct country="Australia", population=20000000>
|
34
|
+
#
|
35
|
+
# Hash keys with spaces or characters that would normally not be able to use
|
36
|
+
# for method calls (e.g. ()[]*) will not be immediately available on the
|
37
|
+
# AltStruct object as a method for retrieval or assignment, but can be still
|
38
|
+
# be reached through the `Object#send` method.
|
39
|
+
#
|
40
|
+
# measurements = AltStruct.new "length (in inches)" => 24
|
41
|
+
# measurements.send "length (in inches)" # => 24
|
42
|
+
#
|
43
|
+
# data_point = AltStruct.new :queued? => true
|
44
|
+
# data_point.queued? # => true
|
45
|
+
# data_point.send "queued?=", false
|
46
|
+
# data_point.queued? # => false
|
47
|
+
#
|
48
|
+
# Removing the presence of a method requires the execution the delete_field
|
49
|
+
# or delete (like a hash) method as setting the property value to +nil+
|
50
|
+
# will not remove the method.
|
51
|
+
#
|
52
|
+
# first_pet = AltStruct.new :name => 'Rowdy', :owner => 'John Smith'
|
53
|
+
# first_pet.owner = nil
|
54
|
+
# second_pet = AltStruct.new :name => 'Rowdy'
|
55
|
+
#
|
56
|
+
# first_pet == second_pet # -> false
|
57
|
+
#
|
58
|
+
# first_pet.delete_field(:owner)
|
59
|
+
# first_pet == second_pet # -> true
|
60
|
+
#
|
61
|
+
#
|
62
|
+
# == Implementation:
|
63
|
+
#
|
64
|
+
# An AltStruct utilizes Ruby's method lookup structure to and find and define
|
65
|
+
# the necessary methods for properties. This is accomplished through the
|
66
|
+
# method `method_missing` and `define_singleton_method`.
|
67
|
+
#
|
68
|
+
# This should be a consideration if there is a concern about the performance
|
69
|
+
# of the objects that are created, as there is much more overhead in the
|
70
|
+
# setting of these properties compared to using a Hash or a Struct.
|
71
|
+
module Behavior
|
72
|
+
THREAD_KEY = :__as_ids__ # :nodoc:
|
73
|
+
NESTED_INSPECT = "...".freeze
|
74
|
+
INSPECT_DELIMITER = ", ".freeze
|
75
|
+
WRAP_PATTERN = /__/.freeze
|
76
|
+
UNSETABLE_PATTERN = /\@|\[|\]|\=\=|\~|\>|\<|\!\=/.freeze
|
77
|
+
SUFFIX_PATTERN = /(\?|\!)$/.freeze
|
78
|
+
|
79
|
+
# We want to give easy access to the table
|
80
|
+
attr_reader :table
|
81
|
+
|
82
|
+
# We want to automatically wrap important Ruby object methods
|
83
|
+
Object.instance_methods.each do |meth|
|
84
|
+
case meth
|
85
|
+
|
86
|
+
# Don't bother with already wrapped methods
|
87
|
+
when WRAP_PATTERN then next
|
88
|
+
|
89
|
+
# Skip methods that can't be set anyways
|
90
|
+
when UNSETABLE_PATTERN then next
|
91
|
+
|
92
|
+
# Get around Ruby's stupid method signature problems with ? and !
|
93
|
+
# suffixes
|
94
|
+
when SUFFIX_PATTERN then alias_method("__#{meth[0...-1]}__#{meth[-1]}".to_sym, meth)
|
95
|
+
|
96
|
+
# Finally, wrap regular methods
|
97
|
+
else alias_method("__#{meth}__".to_sym, meth)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Create a new field for each of the key/value pairs passed.
|
102
|
+
# By default the resulting OpenStruct object will have no
|
103
|
+
# attributes. If no pairs are passed avoid any work.
|
104
|
+
#
|
105
|
+
# require "astruct"
|
106
|
+
# hash = { "country" => "Australia", :population => 20_000_000 }
|
107
|
+
# data = AltStruct.new hash
|
108
|
+
#
|
109
|
+
# p data # => <AltStruct country="Australia" population=20000000>
|
110
|
+
#
|
111
|
+
# If you happen to be inheriting then you can define your own
|
112
|
+
# `@table` ivar before the `super()` call. AltStruct will respect
|
113
|
+
# your `@table`.
|
114
|
+
#
|
115
|
+
def initialize(pairs = {})
|
116
|
+
@table ||= {}
|
117
|
+
__iterate_set_over__(pairs) unless pairs.empty?
|
118
|
+
end
|
119
|
+
|
120
|
+
# This is the `load()` method, which works like initialize in that it
|
121
|
+
# will create new fields for each pair passed. It mimics the behavior of a
|
122
|
+
# Hash#merge.
|
123
|
+
def __load__(pairs)
|
124
|
+
__iterate_set_over__(pairs) unless pairs.empty?
|
125
|
+
end
|
126
|
+
alias_method :marshal_load, :__load__
|
127
|
+
alias_method :load, :__load__
|
128
|
+
alias_method :merge, :__load__
|
129
|
+
|
130
|
+
# This is the `load!()` method, which works like Hash#merge!
|
131
|
+
# See: `AltStruct#load()`
|
132
|
+
def __load__!(pairs)
|
133
|
+
__iterate_set_over__(pairs, true)
|
134
|
+
end
|
135
|
+
alias_method :marshal_load!, :__load__!
|
136
|
+
alias_method :load!, :__load__!
|
137
|
+
alias_method :merge!, :__load__!
|
138
|
+
|
139
|
+
# The `dump()` takes the table and out puts in it's natural hash
|
140
|
+
# format. In addition you can pass along a specific set of keys to
|
141
|
+
# dump.
|
142
|
+
def __dump__(*keys)
|
143
|
+
if keys.empty? then @table else __dump_specific__(keys) end
|
144
|
+
end
|
145
|
+
alias_method :marshal_dump, :__dump__
|
146
|
+
alias_method :dump, :__dump__
|
147
|
+
alias_method :to_hash, :__dump__
|
148
|
+
|
149
|
+
def __inspect__
|
150
|
+
"#<#{__class__}#{__dump_inspect__}>"
|
151
|
+
end
|
152
|
+
alias_method :inspect, :__inspect__
|
153
|
+
alias_method :to_sym, :__inspect__
|
154
|
+
|
155
|
+
# The `delete()` method removes a key/value pair on the @table
|
156
|
+
# and on the singleton class. It also mimics the Hash#delete method.
|
157
|
+
def __delete__(key)
|
158
|
+
__singleton_class__.send(:remove_method, key)
|
159
|
+
__singleton_class__.send(:remove_method, "#{key}=")
|
160
|
+
@table.delete(key.to_sym)
|
161
|
+
end
|
162
|
+
alias_method :delete_field, :__delete__
|
163
|
+
alias_method :delete, :__delete__
|
164
|
+
|
165
|
+
# The `method_missing()` method catches all non-tabled method calls.
|
166
|
+
# The AltStruct object will return two specific errors depending on
|
167
|
+
# the call.
|
168
|
+
def method_missing(method, *arguments)
|
169
|
+
name = method.to_s
|
170
|
+
if name.split("").last == "=" && arguments.size == 1
|
171
|
+
__define_field__(name.chomp!("="), arguments.first)
|
172
|
+
else
|
173
|
+
if name.split.last != "="
|
174
|
+
super
|
175
|
+
else arguments.size > 1
|
176
|
+
raise(ArgumentError,"wrong number of arguments (#{arguments.size} for 1)")
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def ==(other)
|
182
|
+
if other.respond_to?(:table)
|
183
|
+
table == other.table
|
184
|
+
else
|
185
|
+
false
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def freeze
|
190
|
+
super
|
191
|
+
@table.freeze
|
192
|
+
end
|
193
|
+
alias_method :__freeze__, :freeze
|
194
|
+
alias_method :__frozen?, :frozen?
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def __dump_inspect__
|
199
|
+
Thread.current[THREAD_KEY] ||= Set.new
|
200
|
+
|
201
|
+
if __dump__.any? then " #{__dump_subinspect__}" else "" end.tap do
|
202
|
+
__thread_ids__.delete(__object_id__)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def __dump_subinspect__
|
207
|
+
if __thread_ids__.add?(__object_id__)
|
208
|
+
__dump_string__.join(INSPECT_DELIMITER)
|
209
|
+
else
|
210
|
+
NESTED_INSPECT
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def __thread_ids__
|
215
|
+
Thread.current[THREAD_KEY]
|
216
|
+
end
|
217
|
+
|
218
|
+
def __define_field__(key, value)
|
219
|
+
__define_accessor__(key)
|
220
|
+
__set_table__(key, value)
|
221
|
+
end
|
222
|
+
|
223
|
+
def __define_accessor__(key)
|
224
|
+
singleton_class.send(:define_method, key) { @table[key] }
|
225
|
+
singleton_class.send(:define_method, "#{key}=") { |v| @table[key] = v }
|
226
|
+
end
|
227
|
+
|
228
|
+
def __set_table__(key, value)
|
229
|
+
@table.merge!(key => value) unless key.nil?
|
230
|
+
end
|
231
|
+
|
232
|
+
def __dump_specific__(keys)
|
233
|
+
@table.keep_if { |key| keys.include?(key.to_sym) }
|
234
|
+
end
|
235
|
+
|
236
|
+
def __dump_string__
|
237
|
+
__dump__.map { |key, value| "#{key}=#{value.inspect}" }
|
238
|
+
end
|
239
|
+
|
240
|
+
def __iterate_set_over__(pairs, force = false)
|
241
|
+
pairs.each do |key, value|
|
242
|
+
if force && respond_to?(key)
|
243
|
+
__set_table__(key, value)
|
244
|
+
else
|
245
|
+
__define_accessor__(key)
|
246
|
+
__set_table__(key, value)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
data/lib/astruct/version.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe AltStruct do
|
4
|
+
let(:astruct) { described_class.new }
|
5
|
+
|
6
|
+
it "should behave like AltStruct::Behavior" do
|
7
|
+
expect(astruct).to respond_to(*AltStruct::Behavior.instance_methods)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have aliases for standard methods" do
|
11
|
+
expect(astruct).to respond_to(:__object_id__)
|
12
|
+
end
|
13
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
require "pry"
|
3
|
+
require "rspec"
|
4
|
+
require "astruct"
|
5
|
+
|
6
|
+
RSpec.configure do |let|
|
7
|
+
let.before("suite") do
|
8
|
+
CodeClimate::TestReporter.start
|
9
|
+
end
|
10
|
+
|
11
|
+
# Exit the spec after the first failure
|
12
|
+
let.fail_fast = true
|
13
|
+
|
14
|
+
# Only run a specific file, using the ENV variable
|
15
|
+
# Example: FILE=spec/blankgem/version_spec.rb bundle exec rake spec
|
16
|
+
let.pattern = ENV["FILE"]
|
17
|
+
|
18
|
+
# Show the slowest examples in the suite
|
19
|
+
let.profile_examples = true
|
20
|
+
|
21
|
+
# Colorize the output
|
22
|
+
let.color = true
|
23
|
+
|
24
|
+
# Output as a document string
|
25
|
+
let.default_formatter = "doc"
|
26
|
+
end
|
27
|
+
|
28
|
+
class ExampleAltStruct
|
29
|
+
include AltStruct::Behavior
|
30
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "test_helper"
|
2
|
+
require "minitest/autorun"
|
3
3
|
|
4
4
|
class TestAltStruct < MiniTest::Unit::TestCase
|
5
5
|
def setup
|
6
6
|
@empty = AltStruct.new
|
7
|
-
@example = AltStruct.new
|
7
|
+
@example = AltStruct.new(name: "Kurtis", age: 24)
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_equality_with_two_empty_astructs
|
@@ -39,9 +39,9 @@ class TestAltStruct < MiniTest::Unit::TestCase
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def test_inspect_with_sub_struct_duplicate
|
42
|
-
@empty.
|
43
|
-
@empty.
|
44
|
-
expected =
|
42
|
+
@empty.substruct = AltStruct.new
|
43
|
+
@empty.substruct.subsubstruct = @empty
|
44
|
+
expected = "#<AltStruct substruct=#<AltStruct subsubstruct=#<AltStruct ...>>>"
|
45
45
|
actual = @empty.inspect
|
46
46
|
assert_equal expected, actual
|
47
47
|
end
|
@@ -50,7 +50,7 @@ class TestAltStruct < MiniTest::Unit::TestCase
|
|
50
50
|
@example.friends = AltStruct.new name: "Jason", age: 24
|
51
51
|
@example.friends.friends = AltStruct.new name: "John", age: 15
|
52
52
|
@example.friends.friends.friends = AltStruct.new name: "Ally", age: 32
|
53
|
-
expected =
|
53
|
+
expected = "#<AltStruct name=\"Kurtis\", age=24, friends=#<AltStruct name=\"Jason\", age=24, friends=#<AltStruct name=\"John\", age=15, friends=#<AltStruct name=\"Ally\", age=32>>>>"
|
54
54
|
actual = @example.inspect
|
55
55
|
assert_equal expected, actual
|
56
56
|
end
|
@@ -58,14 +58,14 @@ class TestAltStruct < MiniTest::Unit::TestCase
|
|
58
58
|
def test_inspect_with_twice_inspected_struct
|
59
59
|
@example.inspect
|
60
60
|
@example.inspect
|
61
|
-
expected =
|
61
|
+
expected = "#<AltStruct name=\"Kurtis\", age=24>"
|
62
62
|
actual = @example.inspect
|
63
63
|
assert_equal expected, actual
|
64
64
|
end
|
65
65
|
|
66
66
|
def test_inspect_with_empty_sub_struct
|
67
67
|
@empty.struct2 = AltStruct.new
|
68
|
-
expected =
|
68
|
+
expected = "#<AltStruct struct2=#<AltStruct>>"
|
69
69
|
actual = @empty.inspect
|
70
70
|
assert_equal expected, actual
|
71
71
|
end
|
@@ -91,7 +91,7 @@ class TestAltStruct < MiniTest::Unit::TestCase
|
|
91
91
|
# @example.freeze
|
92
92
|
# def @example.frozen?; nil end
|
93
93
|
# @example.freeze
|
94
|
-
# message =
|
94
|
+
# message = "[ruby-core:22559]"
|
95
95
|
# assert_raises(RuntimeError, message) { @example.name = "Jazzy" }
|
96
96
|
# # assert_raises(TypeError, message) { @example.name = "Jazzy" }
|
97
97
|
# end
|
@@ -105,13 +105,13 @@ class TestAltStruct < MiniTest::Unit::TestCase
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def test_delete_field_removes_getter_method
|
108
|
-
bug =
|
108
|
+
bug = "[ruby-core:33010]"
|
109
109
|
@example.delete_field :name
|
110
110
|
refute_respond_to @example, :name, bug
|
111
111
|
end
|
112
112
|
|
113
113
|
def test_delete_field_removes_setter_method
|
114
|
-
bug =
|
114
|
+
bug = "[ruby-core:33010]"
|
115
115
|
@example.delete_field :name
|
116
116
|
refute_respond_to @example, :name=, bug
|
117
117
|
end
|
@@ -130,7 +130,7 @@ class TestAltStruct < MiniTest::Unit::TestCase
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def test_method_missing_handles_square_bracket_equals
|
133
|
-
assert_raises(
|
133
|
+
assert_raises(NoMethodError) { @empty[:foo] = :bar }
|
134
134
|
end
|
135
135
|
|
136
136
|
def test_method_missing_handles_square_brackets
|