astruct 1.0.0 → 2.7.1
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/.gitignore +34 -17
- data/.rvmrc +48 -0
- data/Rakefile +31 -2
- data/astruct.gemspec +5 -8
- data/benchmark/basic_vs_ostruct.rb +7 -26
- data/benchmark/deep_inspect_vs_ostruct.rb +34 -0
- data/benchmark/delete_vs_ostruct.rb +19 -0
- data/benchmark/dump_vs_ostruct.rb +25 -0
- data/benchmark/dynamic_vs_ostruct +23 -0
- data/benchmark/inspect_vs_ostruct.rb +19 -0
- data/benchmark/load_vs_ostruct.rb +19 -0
- data/lib/astruct.rb +93 -29
- data/lib/astruct/module.rb +151 -0
- data/lib/astruct/version.rb +3 -2
- data/test/helper.rb +1 -0
- data/test/lib/astruct_test.rb +236 -0
- metadata +46 -50
- data/test/test_astruct.rb +0 -76
- data/test/test_helper.rb +0 -6
data/.gitignore
CHANGED
@@ -1,17 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
.
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile ~/.gitignore
|
6
|
+
|
7
|
+
# Ignore all of the generated gem stuff
|
8
|
+
/pkg
|
9
|
+
/*.gem
|
10
|
+
|
11
|
+
# Ignore bundler config
|
12
|
+
/.bundle
|
13
|
+
/Gemfile.lock
|
14
|
+
|
15
|
+
# Ignore all bundler caching
|
16
|
+
/vendor/cache
|
17
|
+
/vendor/ruby
|
18
|
+
|
19
|
+
# Ignore all tempfiles
|
20
|
+
/tmp
|
21
|
+
|
22
|
+
# Ignores that should be in the global gitignore
|
23
|
+
# /*.rbc
|
24
|
+
# /.config
|
25
|
+
/.yardoc
|
26
|
+
# /InstalledFiles
|
27
|
+
# /_yardoc
|
28
|
+
# /coverage/
|
29
|
+
/doc/
|
30
|
+
# /lib/bundler/man/
|
31
|
+
# /rdoc/
|
32
|
+
# /spec/reports/
|
33
|
+
# /test/tmp/
|
34
|
+
# /test/version_tmp/
|
data/.rvmrc
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
+
# Only full ruby name is supported here, for short names use:
|
8
|
+
# echo "rvm use 1.9.3" > .rvmrc
|
9
|
+
environment_id="ruby-1.9.3-p194@astruct"
|
10
|
+
|
11
|
+
# Uncomment the following lines if you want to verify rvm version per project
|
12
|
+
# rvmrc_rvm_version="1.13.8 (master)" # 1.10.1 seams as a safe start
|
13
|
+
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
14
|
+
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
15
|
+
# return 1
|
16
|
+
# }
|
17
|
+
|
18
|
+
# First we attempt to load the desired environment directly from the environment
|
19
|
+
# file. This is very fast and efficient compared to running through the entire
|
20
|
+
# CLI and selector. If you want feedback on which environment was used then
|
21
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
22
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
23
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
24
|
+
then
|
25
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
26
|
+
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
|
27
|
+
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
|
28
|
+
else
|
29
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
30
|
+
rvm --create "$environment_id" || {
|
31
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
32
|
+
return 1
|
33
|
+
}
|
34
|
+
fi
|
35
|
+
|
36
|
+
# If you use bundler, this might be useful to you:
|
37
|
+
# if [[ -s Gemfile ]] && {
|
38
|
+
# ! builtin command -v bundle >/dev/null ||
|
39
|
+
# builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
|
40
|
+
# }
|
41
|
+
# then
|
42
|
+
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
|
43
|
+
# gem install bundler
|
44
|
+
# fi
|
45
|
+
# if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
|
46
|
+
# then
|
47
|
+
# bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
|
48
|
+
# fi
|
data/Rakefile
CHANGED
@@ -1,2 +1,31 @@
|
|
1
|
-
#!/usr/bin/env
|
2
|
-
require
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'yard'
|
6
|
+
|
7
|
+
begin
|
8
|
+
Bundler.setup :default, :development
|
9
|
+
rescue Bundler::BundlerError => error
|
10
|
+
$stderr.puts error.message
|
11
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
12
|
+
exit error.status_code
|
13
|
+
end
|
14
|
+
|
15
|
+
Bundler::GemHelper.install_tasks
|
16
|
+
|
17
|
+
desc "Run all of the tests"
|
18
|
+
Rake::TestTask.new do |config|
|
19
|
+
config.libs << 'test'
|
20
|
+
config.pattern = 'test/**/*_test*'
|
21
|
+
config.verbose = true
|
22
|
+
config.warning = true
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Generate all of the docs"
|
26
|
+
YARD::Rake::YardocTask.new do |config|
|
27
|
+
config.files = Dir['lib/**/*.rb']
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Default: run tests, and generate docs'
|
31
|
+
task :default => [ :test, :yard ]
|
data/astruct.gemspec
CHANGED
@@ -4,9 +4,9 @@ require File.expand_path('../lib/astruct/version', __FILE__)
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Kurtis Rainbolt-Greene"]
|
6
6
|
gem.email = ["kurtisrainboltgreene@gmail.com"]
|
7
|
-
gem.description = %q{An alternative to OpenStruct}
|
8
7
|
gem.summary = %q{An alternative to OpenStruct}
|
9
|
-
gem.
|
8
|
+
gem.description = gem.summary
|
9
|
+
gem.homepage = "http://krainboltgreene.github.com/astruct"
|
10
10
|
|
11
11
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
12
|
gem.files = `git ls-files`.split("\n")
|
@@ -16,10 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = AltStruct::VERSION
|
17
17
|
|
18
18
|
gem.add_development_dependency 'rake', '~> 0.9'
|
19
|
-
gem.add_development_dependency '
|
20
|
-
gem.add_development_dependency '
|
21
|
-
gem.add_development_dependency '
|
22
|
-
gem.add_development_dependency 'guard', '~> 0.10'
|
23
|
-
gem.add_development_dependency 'guard-minitest', '~> 0.4'
|
24
|
-
gem.add_development_dependency 'guard-rocco', '~> 0.0.3'
|
19
|
+
gem.add_development_dependency 'yard'
|
20
|
+
gem.add_development_dependency 'kramdown'
|
21
|
+
gem.add_development_dependency 'benchmark-ips'
|
25
22
|
end
|
@@ -1,36 +1,17 @@
|
|
1
|
-
require 'benchmark'
|
2
|
-
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require_relative '../lib/astruct'
|
3
3
|
require 'ostruct'
|
4
4
|
|
5
|
-
|
6
|
-
ADATA = (1..10_000).map { |i| { :"item#{i}" => i } }.inject :merge!
|
5
|
+
DATA = (1..1_000).map { |i| { :"item#{i}" => i } }.inject :merge!
|
7
6
|
|
8
|
-
|
7
|
+
Benchmark.ips do |x|
|
9
8
|
x.report "OStruct creation" do
|
10
9
|
class OProfile < OpenStruct; end
|
11
|
-
OProfile.new
|
10
|
+
OProfile.new DATA.dup
|
12
11
|
end
|
13
12
|
|
14
13
|
x.report "AStruct creation" do
|
15
|
-
class AProfile
|
16
|
-
AProfile.new
|
14
|
+
class AProfile < AltStruct; end
|
15
|
+
AProfile.new DATA.dup
|
17
16
|
end
|
18
17
|
end
|
19
|
-
|
20
|
-
puts "Astruct is #{report.map(&:to_s).map(&:split).map(&:last).map(&:to_f).inject(:/) * 100 - 100}% faster"
|
21
|
-
|
22
|
-
report = Benchmark.bmbm do |x|
|
23
|
-
x.report "OStruct load" do
|
24
|
-
class OProfile < OpenStruct; end
|
25
|
-
op = OProfile.new
|
26
|
-
op.load ODATA
|
27
|
-
end
|
28
|
-
|
29
|
-
x.report "AStruct load" do
|
30
|
-
class AProfile; include AltStruct; end
|
31
|
-
ap = AProfile.new
|
32
|
-
ap.load ADATA
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
puts "Astruct is #{report.map(&:to_s).map(&:split).map(&:last).map(&:to_f).inject(:/) * 100 - 100}% faster"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require_relative '../lib/astruct'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
DATA = (1..1_000).map { |i| { :"item#{i}" => i } }.inject :merge!
|
6
|
+
|
7
|
+
Benchmark.ips do |x|
|
8
|
+
x.report "OStruct load" do
|
9
|
+
class OProfile < OpenStruct; end
|
10
|
+
op = OProfile.new DATA.dup
|
11
|
+
op.op2 = OProfile.new DATA.dup
|
12
|
+
op.op2.op3 = OProfile.new DATA.dup
|
13
|
+
op.inspect
|
14
|
+
end
|
15
|
+
|
16
|
+
x.report "AStruct load" do
|
17
|
+
class AProfile < AltStruct; end
|
18
|
+
ap = AProfile.new DATA.dup
|
19
|
+
ap.ap2 = AProfile.new DATA.dup
|
20
|
+
ap.ap2.ap3 = AProfile.new DATA.dup
|
21
|
+
ap.inspect
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
op = OProfile.new DATA.dup
|
26
|
+
op.op2 = OProfile.new DATA.dup
|
27
|
+
op.op2.op3 = OProfile.new DATA.dup
|
28
|
+
ap = AProfile.new DATA.dup
|
29
|
+
ap.ap2 = AProfile.new DATA.dup
|
30
|
+
ap.ap2.ap3 = AProfile.new DATA.dup
|
31
|
+
p ap.inspect
|
32
|
+
p op.inspect
|
33
|
+
puts "The output of each is the same: #{ap.inspect == op.inspect}"
|
34
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require_relative '../lib/astruct'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
DATA = (1..1_000).map { |i| { :"item#{i}" => i } }.inject :merge!
|
6
|
+
|
7
|
+
Benchmark.ips do |x|
|
8
|
+
x.report "OStruct load" do
|
9
|
+
class OProfile < OpenStruct; end
|
10
|
+
op = OProfile.new DATA.dup
|
11
|
+
op.delete_field :item1
|
12
|
+
end
|
13
|
+
|
14
|
+
x.report "AStruct load" do
|
15
|
+
class AProfile < AltStruct; end
|
16
|
+
ap = AProfile.new DATA.dup
|
17
|
+
ap.delete :item1
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require_relative '../lib/astruct'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
DATA = (1..1_000).map { |i| { :"item#{i}" => i } }.inject :merge!
|
6
|
+
|
7
|
+
Benchmark.ips do |x|
|
8
|
+
x.report "OStruct load" do
|
9
|
+
class OProfile < OpenStruct; end
|
10
|
+
op = OProfile.new DATA.dup
|
11
|
+
op.marshal_dump
|
12
|
+
end
|
13
|
+
|
14
|
+
x.report "AStruct load" do
|
15
|
+
class AProfile < AltStruct; end
|
16
|
+
ap = AProfile.new DATA.dup
|
17
|
+
ap.dump
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class OProfile < OpenStruct; end
|
22
|
+
op = OProfile.new DATA.dup
|
23
|
+
class AProfile < AltStruct; end
|
24
|
+
ap = AProfile.new DATA.dup
|
25
|
+
puts "The output of each is the same: #{ap.dump == op.marshal_dump}"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require_relative '../lib/astruct'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
DATA = (1..1_000).map { |i| { :"item#{i}" => i } }.inject :merge!
|
6
|
+
|
7
|
+
Benchmark.ips do |x|
|
8
|
+
x.report "OStruct creation" do
|
9
|
+
class OProfile < OpenStruct; end
|
10
|
+
op = OProfile.new DATA.dup
|
11
|
+
op.example1 = "red"
|
12
|
+
op.example2 = "blue"
|
13
|
+
op.example3 = "green"
|
14
|
+
end
|
15
|
+
|
16
|
+
x.report "AStruct creation" do
|
17
|
+
class AProfile < AltStruct; end
|
18
|
+
ap = AProfile.new DATA.dup
|
19
|
+
ap.example1 = "red"
|
20
|
+
ap.example2 = "blue"
|
21
|
+
ap.example3 = "green"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require_relative '../lib/astruct'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
DATA = (1..1_000).map { |i| { :"item#{i}" => i } }.inject :merge!
|
6
|
+
|
7
|
+
Benchmark.ips do |x|
|
8
|
+
x.report "OStruct load" do
|
9
|
+
class OProfile < OpenStruct; end
|
10
|
+
op = OProfile.new DATA.dup
|
11
|
+
op.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
x.report "AStruct load" do
|
15
|
+
class AProfile < AltStruct; end
|
16
|
+
ap = AProfile.new DATA.dup
|
17
|
+
ap.inspect
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require_relative '../lib/astruct'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
DATA = (1..1_000).map { |i| { :"item#{i}" => i } }.inject :merge!
|
6
|
+
|
7
|
+
Benchmark.ips do |x|
|
8
|
+
x.report "OStruct load" do
|
9
|
+
class OProfile < OpenStruct; end
|
10
|
+
op = OProfile.new
|
11
|
+
op.marshal_load DATA.dup
|
12
|
+
end
|
13
|
+
|
14
|
+
x.report "AStruct load" do
|
15
|
+
class AProfile < AltStruct; end
|
16
|
+
ap = AProfile.new
|
17
|
+
ap.load DATA.dup
|
18
|
+
end
|
19
|
+
end
|
data/lib/astruct.rb
CHANGED
@@ -1,30 +1,94 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
1
|
+
require_relative 'astruct/module'
|
2
|
+
|
3
|
+
#
|
4
|
+
# = astruct.rb: AltStruct implementation
|
5
|
+
#
|
6
|
+
# Author:: Kurtis Rainbolt-Greene
|
7
|
+
# Documentation:: Kurtis Rainbolt-Greene
|
8
|
+
#
|
9
|
+
# AltStruct is an Class and Module (AltStruct::M) that can be used to
|
10
|
+
# create hash-like classes. Allowing you to create an object that can
|
11
|
+
# dynamically accept accessors and behaves very much like a Hash.
|
12
|
+
#
|
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
|
+
class AltStruct
|
90
|
+
# We include all of the AltStruct::M Module in order to give AltStruct
|
91
|
+
# the same behavior as OpenStruct. It's better, however, to simply
|
92
|
+
# include AltStruct::M into your own class.
|
93
|
+
include AltStruct::M
|
30
94
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
class AltStruct
|
2
|
+
module M
|
3
|
+
ThreadKey = :__inspect_astruct_ids__ # :nodoc:
|
4
|
+
attr_reader :table
|
5
|
+
|
6
|
+
# Create a new field for each of the key/value pairs passed.
|
7
|
+
# By default the resulting OpenStruct object will have no
|
8
|
+
# attributes. If no pairs are passed avoid any work.
|
9
|
+
#
|
10
|
+
# require 'ostruct'
|
11
|
+
# hash = { "country" => "Australia", :population => 20_000_000 }
|
12
|
+
# data = OpenStruct.new hash
|
13
|
+
#
|
14
|
+
# p data # => <OpenStruct country="Australia" population=20000000>
|
15
|
+
#
|
16
|
+
# If you happen to be inheriting then you can define your own
|
17
|
+
# @table ivar before the `super()` call. AltStruct will respect
|
18
|
+
# your @table.
|
19
|
+
#
|
20
|
+
def initialize(pairs = {})
|
21
|
+
@table ||= {}
|
22
|
+
for key, value in pairs
|
23
|
+
__new_field__ key, value
|
24
|
+
end unless pairs.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
# This is the `load()` method, which works like initialize in that it
|
28
|
+
# will create new fields for each pair passed. Notice that it
|
29
|
+
# also is a double-underbar method, making it really hard to
|
30
|
+
# overwrite. It also mimics the behavior of a Hash#merge and
|
31
|
+
# Hash#merge!
|
32
|
+
def __load__(pairs)
|
33
|
+
for key, value in pairs
|
34
|
+
__new_field__ key, value
|
35
|
+
end unless pairs.empty?
|
36
|
+
end
|
37
|
+
alias_method :marshal_load, :__load__
|
38
|
+
alias_method :load, :__load__
|
39
|
+
alias_method :merge, :__load__
|
40
|
+
alias_method :merge!, :__load__
|
41
|
+
|
42
|
+
# The `dump()` takes the table and out puts in it's natural hash
|
43
|
+
# format. In addition you can pass along a specific set of keys to
|
44
|
+
# dump.
|
45
|
+
def __dump__(*keys)
|
46
|
+
keys.empty? ? table : __dump_specific__(keys)
|
47
|
+
end
|
48
|
+
alias_method :marshal_dump, :__dump__
|
49
|
+
alias_method :dump, :__dump__
|
50
|
+
alias_method :to_hash, :__dump__
|
51
|
+
|
52
|
+
def __inspect__
|
53
|
+
"#<#{self.class}#{__dump_inspect__}>"
|
54
|
+
end
|
55
|
+
alias_method :inspect, :__inspect__
|
56
|
+
alias_method :to_s, :__inspect__
|
57
|
+
|
58
|
+
# The delete_field() method removes a key/value pair on the @table
|
59
|
+
# and on the singleton class. It also mimics the Hash#delete method.
|
60
|
+
def __delete_field__(key)
|
61
|
+
singleton_class.send :remove_method, key
|
62
|
+
singleton_class.send :remove_method, :"#{key}="
|
63
|
+
@table.delete key
|
64
|
+
end
|
65
|
+
alias_method :delete_field, :__delete_field__
|
66
|
+
alias_method :delete, :__delete_field__
|
67
|
+
|
68
|
+
# The `method_missing()` method catches all non-tabled method calls.
|
69
|
+
# The AltStruct object will return two specific errors depending on
|
70
|
+
# the call.
|
71
|
+
def method_missing(method, *args)
|
72
|
+
name = method.to_s
|
73
|
+
case
|
74
|
+
when !name.include?('=')
|
75
|
+
# This is to catch non-assignment methods
|
76
|
+
message = "undefined method `#{name}' for #{self}"
|
77
|
+
raise NoMethodError, message, caller(1)
|
78
|
+
when args.size != 1
|
79
|
+
# This is to catch the []= method
|
80
|
+
message = "wrong number of arguments (#{args.size} for 1)"
|
81
|
+
raise ArgumentError, message, caller(1)
|
82
|
+
else
|
83
|
+
__new_field__ name.chomp!('='), args.first
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def ==(object)
|
88
|
+
if object.respond_to? :table
|
89
|
+
table == object.table
|
90
|
+
else
|
91
|
+
false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def freeze
|
96
|
+
super
|
97
|
+
@table.freeze
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def __dump_inspect__
|
103
|
+
__create_id_list__
|
104
|
+
unless __id_exists_in_id_list?
|
105
|
+
__add_id_to_id_list__
|
106
|
+
string = __dump__.any? ? " #{__dump_string__.join ', '}" : ""
|
107
|
+
else
|
108
|
+
__remove_last_id_from_id_list__
|
109
|
+
string = __dump__.any? ? " ..." : ""
|
110
|
+
end
|
111
|
+
__remove_last_id_from_id_list__
|
112
|
+
string
|
113
|
+
end
|
114
|
+
|
115
|
+
def __define_accessor__(key, value)
|
116
|
+
define_singleton_method(key) { @table[key] }
|
117
|
+
define_singleton_method(:"#{key}=") { |v| @table[key] = v }
|
118
|
+
{ key => value }.freeze
|
119
|
+
end
|
120
|
+
|
121
|
+
def __new_field__(key, value)
|
122
|
+
table.merge! __define_accessor__ key.to_sym, value
|
123
|
+
end
|
124
|
+
|
125
|
+
def __dump_specific__(keys)
|
126
|
+
@table.keep_if { |key| keys.include? key }
|
127
|
+
end
|
128
|
+
|
129
|
+
def __dump_string__
|
130
|
+
__dump__.map do |key, value|
|
131
|
+
"#{key}=#{value.inspect}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def __add_id_to_id_list__
|
136
|
+
Thread.current[ThreadKey] << object_id
|
137
|
+
end
|
138
|
+
|
139
|
+
def __create_id_list__
|
140
|
+
Thread.current[ThreadKey] ||= []
|
141
|
+
end
|
142
|
+
|
143
|
+
def __id_exists_in_id_list?
|
144
|
+
Thread.current[ThreadKey].include?(object_id)
|
145
|
+
end
|
146
|
+
|
147
|
+
def __remove_last_id_from_id_list__
|
148
|
+
Thread.current[ThreadKey].pop
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/lib/astruct/version.rb
CHANGED
data/test/helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'astruct'
|
@@ -0,0 +1,236 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require_relative '../helper'
|
3
|
+
|
4
|
+
class TestAltStruct < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@empty = AltStruct.new
|
7
|
+
@example = AltStruct.new name: "Kurtis", age: 24
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_equality_with_two_empty_astructs
|
11
|
+
empty2 = AltStruct.new
|
12
|
+
assert_equal @empty, empty2
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_equality_vs_astruct_with_fields
|
16
|
+
refute_equal @example, @empty
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_equality_vs_object_with_fake_table
|
20
|
+
empty_object = Object.new
|
21
|
+
empty_object.instance_eval { @table = { name: "Kurtis", age: 24 } }
|
22
|
+
expected = @example
|
23
|
+
actual = empty_object
|
24
|
+
refute_equal expected, actual
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_inspect_with_no_fields
|
28
|
+
expected = "#<AltStruct>"
|
29
|
+
actual = @empty.inspect
|
30
|
+
assert_equal expected, actual
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_inspect_with_fields
|
34
|
+
@empty.example1 = 1
|
35
|
+
@empty.example2 = 2
|
36
|
+
expected = "#<AltStruct example1=1, example2=2>"
|
37
|
+
actual = @empty.inspect
|
38
|
+
assert_equal expected, actual
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_inspect_with_sub_struct_duplicate
|
42
|
+
@empty.struct2 = AltStruct.new
|
43
|
+
@empty.struct2.struct3 = @empty
|
44
|
+
expected = '#<AltStruct struct2=#<AltStruct struct3=#<AltStruct ...>>>'
|
45
|
+
actual = @empty.inspect
|
46
|
+
assert_equal expected, actual
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_inspect_with_sub_struct
|
50
|
+
@example.friends = AltStruct.new name: "Jason", age: 24
|
51
|
+
@example.friends.friends = AltStruct.new name: "John", age: 15
|
52
|
+
@example.friends.friends.friends = AltStruct.new name: "Ally", age: 32
|
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
|
+
actual = @example.inspect
|
55
|
+
assert_equal expected, actual
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_inspect_with_twice_inspected_struct
|
59
|
+
@example.inspect
|
60
|
+
@example.inspect
|
61
|
+
expected = '#<AltStruct name="Kurtis", age=24>'
|
62
|
+
actual = @example.inspect
|
63
|
+
assert_equal expected, actual
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_inspect_with_empty_sub_struct
|
67
|
+
@empty.struct2 = AltStruct.new
|
68
|
+
expected = '#<AltStruct struct2=#<AltStruct>>'
|
69
|
+
actual = @empty.inspect
|
70
|
+
assert_equal expected, actual
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_freeze_stops_new_assignments
|
74
|
+
@example.freeze
|
75
|
+
assert_raises(RuntimeError) { @example.age = 24 }
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_freeze_still_returns_values
|
79
|
+
@example.freeze
|
80
|
+
expecteds = "Kurtis"
|
81
|
+
actual = @example.name
|
82
|
+
assert_equal expecteds, actual
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_freeze_stops_reassignments
|
86
|
+
@example.freeze
|
87
|
+
assert_raises(RuntimeError) { @example.name = "Jazzy" }
|
88
|
+
end
|
89
|
+
|
90
|
+
# def test_freeze_stops_reassign_even_if_frozen_redefined
|
91
|
+
# @example.freeze
|
92
|
+
# def @example.frozen?; nil end
|
93
|
+
# @example.freeze
|
94
|
+
# message = '[ruby-core:22559]'
|
95
|
+
# assert_raises(RuntimeError, message) { @example.name = "Jazzy" }
|
96
|
+
# # assert_raises(TypeError, message) { @example.name = "Jazzy" }
|
97
|
+
# end
|
98
|
+
|
99
|
+
def test_astruct_doesn_respond_to_non_existant_keys_getter
|
100
|
+
refute_respond_to @empty, :akey
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_astruct_doesn_respond_to_non_existant_keys_setter
|
104
|
+
refute_respond_to @empty, :akey=
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_delete_field_removes_getter_method
|
108
|
+
bug = '[ruby-core:33010]'
|
109
|
+
@example.delete_field :name
|
110
|
+
refute_respond_to @example, :name, bug
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_delete_field_removes_setter_method
|
114
|
+
bug = '[ruby-core:33010]'
|
115
|
+
@example.delete_field :name
|
116
|
+
refute_respond_to @example, :name=, bug
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_delete_field_removes_table_key_value
|
120
|
+
@example.delete_field :name
|
121
|
+
expected = nil
|
122
|
+
actual = @example.table[:name]
|
123
|
+
assert_equal expected, actual
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_delete_field_returns_value_of_deleted_key
|
127
|
+
expected = "Kurtis"
|
128
|
+
actual = @example.delete_field :name
|
129
|
+
assert_equal expected, actual
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_method_missing_handles_square_bracket_equals
|
133
|
+
assert_raises(ArgumentError) { @empty[:foo] = :bar }
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_method_missing_handles_square_brackets
|
137
|
+
assert_raises(NoMethodError) { @empty[:foo] }
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_to_hash_returns_hash
|
141
|
+
expected = { name: "John Smith", age: 70, pension: 300 }
|
142
|
+
actual = AltStruct.new(expected).to_hash
|
143
|
+
assert_equal expected, actual
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_to_hash_modified_modifies_astruct
|
147
|
+
@example.to_hash[:age] = 70
|
148
|
+
expected = 70
|
149
|
+
actual = @example.age
|
150
|
+
assert_equal expected, actual
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_example_has_table_method
|
154
|
+
assert_respond_to @example, :table
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_empty_example_has_empty_table
|
158
|
+
expected = {}
|
159
|
+
actual = @empty.table
|
160
|
+
assert_equal expected, actual
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_example_has_name_method
|
164
|
+
assert_respond_to @example, :name
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_example_has_given_name
|
168
|
+
expected = "Kurtis"
|
169
|
+
actual = @example.name
|
170
|
+
assert_equal expected, actual
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_example_takes_name
|
174
|
+
assert_send [@example, :name=, "Dave"]
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_example_has_taken_name
|
178
|
+
@example.name = "Dave"
|
179
|
+
expected = "Dave"
|
180
|
+
actual = @example.name
|
181
|
+
assert_equal expected, actual
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_load_takes_a_hash
|
185
|
+
assert_send [@example, :load, { nickname: "Kurt" }]
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_load_sets_methods
|
189
|
+
@example.load nickname: "Kurt"
|
190
|
+
assert_respond_to @example, :nickname
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_astruct_has_getter_methods_with_non_alpha_numeric_characters
|
194
|
+
@example.load "Length (In Inchs)" => 72
|
195
|
+
assert_send [@example, :"Length (In Inchs)"]
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_astruct_has_getter_methods_with_non_alpha_numeric_characters
|
199
|
+
@example.load "Length (In Inchs)" => 72
|
200
|
+
assert_send [@example, :"Length (In Inchs)=", 73]
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_load_sets_correct_value
|
204
|
+
@example.load nickname: "Kurt"
|
205
|
+
expected = "Kurt"
|
206
|
+
actual = @example.nickname
|
207
|
+
assert_equal expected, actual
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_example_has_dump_method
|
211
|
+
assert_respond_to @example, :dump
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_dump_contains_values
|
215
|
+
expected = { name: "Kurtis", age: 24 }
|
216
|
+
actual = @example.dump
|
217
|
+
assert_equal expected, actual
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_selective_dump_contains_selective_values
|
221
|
+
expected = { age: 24 }
|
222
|
+
actual = @example.dump :age
|
223
|
+
assert_equal expected, actual
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_inspect_has_values_delimited_by_comma
|
227
|
+
expected = /name="Kurtis", age=24/
|
228
|
+
actual = @example.inspect
|
229
|
+
assert_match expected, actual
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_other_object_isnt_affected
|
233
|
+
refute_respond_to @empty, :name
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: astruct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.7.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,73 +21,60 @@ dependencies:
|
|
21
21
|
version: '0.9'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: rocco
|
27
|
-
requirement: &2161260360 !ruby/object:Gem::Requirement
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
25
|
none: false
|
29
26
|
requirements:
|
30
27
|
- - ~>
|
31
28
|
- !ruby/object:Gem::Version
|
32
|
-
version: '0.
|
33
|
-
type: :development
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *2161260360
|
29
|
+
version: '0.9'
|
36
30
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement:
|
31
|
+
name: yard
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
39
33
|
none: false
|
40
34
|
requirements:
|
41
|
-
- -
|
35
|
+
- - ! '>='
|
42
36
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
37
|
+
version: '0'
|
44
38
|
type: :development
|
45
39
|
prerelease: false
|
46
|
-
version_requirements:
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: awesome_print
|
49
|
-
requirement: &2161259300 !ruby/object:Gem::Requirement
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
41
|
none: false
|
51
42
|
requirements:
|
52
|
-
- -
|
43
|
+
- - ! '>='
|
53
44
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
type: :development
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: *2161259300
|
45
|
+
version: '0'
|
58
46
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
60
|
-
requirement:
|
47
|
+
name: kramdown
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
61
49
|
none: false
|
62
50
|
requirements:
|
63
|
-
- -
|
51
|
+
- - ! '>='
|
64
52
|
- !ruby/object:Gem::Version
|
65
|
-
version: '0
|
53
|
+
version: '0'
|
66
54
|
type: :development
|
67
55
|
prerelease: false
|
68
|
-
version_requirements:
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: guard-minitest
|
71
|
-
requirement: &2161238500 !ruby/object:Gem::Requirement
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
57
|
none: false
|
73
58
|
requirements:
|
74
|
-
- -
|
59
|
+
- - ! '>='
|
75
60
|
- !ruby/object:Gem::Version
|
76
|
-
version: '0
|
77
|
-
type: :development
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: *2161238500
|
61
|
+
version: '0'
|
80
62
|
- !ruby/object:Gem::Dependency
|
81
|
-
name:
|
82
|
-
requirement:
|
63
|
+
name: benchmark-ips
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
83
65
|
none: false
|
84
66
|
requirements:
|
85
|
-
- -
|
67
|
+
- - ! '>='
|
86
68
|
- !ruby/object:Gem::Version
|
87
|
-
version: 0
|
69
|
+
version: '0'
|
88
70
|
type: :development
|
89
71
|
prerelease: false
|
90
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
91
78
|
description: An alternative to OpenStruct
|
92
79
|
email:
|
93
80
|
- kurtisrainboltgreene@gmail.com
|
@@ -96,6 +83,7 @@ extensions: []
|
|
96
83
|
extra_rdoc_files: []
|
97
84
|
files:
|
98
85
|
- .gitignore
|
86
|
+
- .rvmrc
|
99
87
|
- Gemfile
|
100
88
|
- Guardfile
|
101
89
|
- LICENSE
|
@@ -103,11 +91,18 @@ files:
|
|
103
91
|
- Rakefile
|
104
92
|
- astruct.gemspec
|
105
93
|
- benchmark/basic_vs_ostruct.rb
|
94
|
+
- benchmark/deep_inspect_vs_ostruct.rb
|
95
|
+
- benchmark/delete_vs_ostruct.rb
|
96
|
+
- benchmark/dump_vs_ostruct.rb
|
97
|
+
- benchmark/dynamic_vs_ostruct
|
98
|
+
- benchmark/inspect_vs_ostruct.rb
|
99
|
+
- benchmark/load_vs_ostruct.rb
|
106
100
|
- lib/astruct.rb
|
101
|
+
- lib/astruct/module.rb
|
107
102
|
- lib/astruct/version.rb
|
108
|
-
- test/
|
109
|
-
- test/
|
110
|
-
homepage:
|
103
|
+
- test/helper.rb
|
104
|
+
- test/lib/astruct_test.rb
|
105
|
+
homepage: http://krainboltgreene.github.com/astruct
|
111
106
|
licenses: []
|
112
107
|
post_install_message:
|
113
108
|
rdoc_options: []
|
@@ -121,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
116
|
version: '0'
|
122
117
|
segments:
|
123
118
|
- 0
|
124
|
-
hash:
|
119
|
+
hash: -3476508434562981874
|
125
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
121
|
none: false
|
127
122
|
requirements:
|
@@ -130,13 +125,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
125
|
version: '0'
|
131
126
|
segments:
|
132
127
|
- 0
|
133
|
-
hash:
|
128
|
+
hash: -3476508434562981874
|
134
129
|
requirements: []
|
135
130
|
rubyforge_project:
|
136
|
-
rubygems_version: 1.8.
|
131
|
+
rubygems_version: 1.8.24
|
137
132
|
signing_key:
|
138
133
|
specification_version: 3
|
139
134
|
summary: An alternative to OpenStruct
|
140
135
|
test_files:
|
141
|
-
- test/
|
142
|
-
- test/
|
136
|
+
- test/helper.rb
|
137
|
+
- test/lib/astruct_test.rb
|
138
|
+
has_rdoc:
|
data/test/test_astruct.rb
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require_relative 'test_helper'
|
3
|
-
|
4
|
-
class TestAltStruct < MiniTest::Unit::TestCase
|
5
|
-
def setup
|
6
|
-
@empty_example = Profile.new
|
7
|
-
@example = Profile.new name: "Kurtis", age: 24
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_that_example_is_kind_of_altstruct
|
11
|
-
assert_kind_of(AltStruct, @example)
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_that_example_has_table_imethod
|
15
|
-
assert_respond_to(@example, :table)
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_that_empty_example_has_empty_table
|
19
|
-
assert_equal({}, @empty_example.table)
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_that_example_has_name_method
|
23
|
-
assert_respond_to(@example, :name)
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_that_example_has_given_name
|
27
|
-
assert_equal("Kurtis", @example.name)
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_that_example_takes_name
|
31
|
-
assert_send([@example, :name=, "Dave"])
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_that_example_has_taken_name
|
35
|
-
@example.name = "Dave"
|
36
|
-
assert_equal("Dave", @example.name)
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_that_example_has_load_imethod
|
40
|
-
assert_respond_to(@example, :load)
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_that_load_takes_a_hash
|
44
|
-
assert_send([@example, :load, { nickname: "Kurt" }])
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_that_load_sets_imethods
|
48
|
-
@example.load nickname: "Kurt"
|
49
|
-
assert_respond_to(@example, :nickname)
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_that_load_sets_correct_value
|
53
|
-
@example.load nickname: "Kurt"
|
54
|
-
assert_equal("Kurt", @example.nickname)
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_that_example_has_dump_imethod
|
58
|
-
assert_respond_to(@example, :dump)
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_that_dump_contains_values
|
62
|
-
assert_equal({ name: "Kurtis", age: 24 }, @example.dump)
|
63
|
-
end
|
64
|
-
|
65
|
-
def test_that_selective_dump_contains_selective_values
|
66
|
-
assert_equal({ age: 24 }, @example.dump(:age))
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_inspect_has_values
|
70
|
-
assert_match(/name="Kurtis" age=24/, @example.inspect)
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_that_other_class_isnt_affected
|
74
|
-
refute_respond_to(Profile.new, :name)
|
75
|
-
end
|
76
|
-
end
|