astruct 1.0.0 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|