hashie 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +1 -11
- data/Gemfile.lock +23 -22
- data/Guardfile +5 -0
- data/README.rdoc +20 -19
- data/Rakefile +3 -31
- data/hashie.gemspec +17 -68
- data/lib/hashie/dash.rb +36 -1
- data/lib/hashie/mash.rb +6 -2
- data/lib/hashie/version.rb +3 -0
- data/lib/hashie.rb +1 -1
- data/spec/hashie/dash_spec.rb +59 -26
- data/spec/hashie/mash_spec.rb +39 -19
- metadata +76 -51
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,32 +1,33 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
hashie (1.1.0)
|
5
|
+
|
1
6
|
GEM
|
2
7
|
remote: http://rubygems.org/
|
3
8
|
specs:
|
4
9
|
diff-lcs (1.1.2)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
rspec (2.4
|
15
|
-
|
16
|
-
rspec-expectations (~> 2.4.0)
|
17
|
-
rspec-mocks (~> 2.4.0)
|
18
|
-
rspec-core (2.4.0)
|
19
|
-
rspec-expectations (2.4.0)
|
10
|
+
guard (0.5.1)
|
11
|
+
thor (~> 0.14.6)
|
12
|
+
guard-rspec (0.4.0)
|
13
|
+
guard (>= 0.4.0)
|
14
|
+
rake (0.9.2)
|
15
|
+
rspec (2.6.0)
|
16
|
+
rspec-core (~> 2.6.0)
|
17
|
+
rspec-expectations (~> 2.6.0)
|
18
|
+
rspec-mocks (~> 2.6.0)
|
19
|
+
rspec-core (2.6.4)
|
20
|
+
rspec-expectations (2.6.0)
|
20
21
|
diff-lcs (~> 1.1.2)
|
21
|
-
rspec-mocks (2.
|
22
|
-
|
23
|
-
json_pure (>= 1.1.7)
|
22
|
+
rspec-mocks (2.6.0)
|
23
|
+
thor (0.14.6)
|
24
24
|
|
25
25
|
PLATFORMS
|
26
26
|
ruby
|
27
27
|
|
28
28
|
DEPENDENCIES
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
guard
|
30
|
+
guard-rspec
|
31
|
+
hashie!
|
32
|
+
rake (~> 0.9.2)
|
33
|
+
rspec (~> 2.5)
|
data/Guardfile
ADDED
data/README.rdoc
CHANGED
@@ -4,7 +4,7 @@ Hashie is a growing collection of tools that extend Hashes and make
|
|
4
4
|
them more useful.
|
5
5
|
|
6
6
|
== Installation
|
7
|
-
|
7
|
+
|
8
8
|
Hashie is available as a RubyGem:
|
9
9
|
|
10
10
|
gem install hashie
|
@@ -13,11 +13,11 @@ Hashie is available as a RubyGem:
|
|
13
13
|
|
14
14
|
Mash is an extended Hash that gives simple pseudo-object functionality
|
15
15
|
that can be built from hashes and easily extended. It is designed to
|
16
|
-
be used in RESTful API libraries to provide easy object-like access
|
16
|
+
be used in RESTful API libraries to provide easy object-like access
|
17
17
|
to JSON and XML parsed hashes.
|
18
18
|
|
19
19
|
=== Example:
|
20
|
-
|
20
|
+
|
21
21
|
mash = Hashie::Mash.new
|
22
22
|
mash.name? # => false
|
23
23
|
mash.name # => nil
|
@@ -25,42 +25,42 @@ to JSON and XML parsed hashes.
|
|
25
25
|
mash.name # => "My Mash"
|
26
26
|
mash.name? # => true
|
27
27
|
mash.inspect # => <Hashie::Mash name="My Mash">
|
28
|
-
|
28
|
+
|
29
29
|
mash = Mash.new
|
30
30
|
# use bang methods for multi-level assignment
|
31
31
|
mash.author!.name = "Michael Bleigh"
|
32
32
|
mash.author # => <Hashie::Mash name="Michael Bleigh">
|
33
33
|
|
34
|
-
<b>Note:</b> The <tt>?</tt> method will return false if a key has been set
|
34
|
+
<b>Note:</b> The <tt>?</tt> method will return false if a key has been set
|
35
35
|
to false or nil. In order to check if a key has been set at all, use the
|
36
36
|
<tt>mash.key?('some_key')</tt> method instead.
|
37
|
-
|
37
|
+
|
38
38
|
== Dash
|
39
39
|
|
40
40
|
Dash is an extended Hash that has a discrete set of defined properties
|
41
41
|
and only those properties may be set on the hash. Additionally, you
|
42
|
-
can set defaults for each property.
|
42
|
+
can set defaults for each property. You can also flag a property as
|
43
|
+
required. Required properties will raise an execption if unset.
|
43
44
|
|
44
45
|
=== Example:
|
45
46
|
|
46
47
|
class Person < Hashie::Dash
|
47
|
-
property :name
|
48
|
+
property :name, :required => true
|
48
49
|
property :email
|
49
50
|
property :occupation, :default => 'Rubyist'
|
50
51
|
end
|
51
52
|
|
52
|
-
p = Person.new
|
53
|
-
|
53
|
+
p = Person.new # => ArgumentError: The property 'name' is required for this Dash.
|
54
|
+
|
55
|
+
p = Person.new(:name => "Bob")
|
56
|
+
p.name # => 'Bob'
|
57
|
+
p.name = nil # => ArgumentError: The property 'name' is required for this Dash.
|
54
58
|
p.email = 'abc@def.com'
|
55
59
|
p.occupation # => 'Rubyist'
|
56
60
|
p.email # => 'abc@def.com'
|
57
61
|
p[:awesome] # => NoMethodError
|
58
62
|
p[:occupation] # => 'Rubyist'
|
59
|
-
|
60
|
-
p = Person.new(:name => "Bob")
|
61
|
-
p.name # => 'Bob'
|
62
|
-
p.occupation # => 'Rubyist'
|
63
|
-
|
63
|
+
|
64
64
|
== Trash
|
65
65
|
|
66
66
|
A Trash is a Dash that allows you to translate keys on initialization.
|
@@ -69,12 +69,12 @@ It is used like so:
|
|
69
69
|
class Person < Hashie::Trash
|
70
70
|
property :first_name, :from => :firstName
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
This will automatically translate the <tt>firstName</tt> key to <tt>first_name</tt>
|
74
74
|
when it is initialized using a hash such as through:
|
75
|
-
|
75
|
+
|
76
76
|
Person.new(:firstName => 'Bob')
|
77
|
-
|
77
|
+
|
78
78
|
== Clash
|
79
79
|
|
80
80
|
Clash is a Chainable Lazy Hash that allows you to easily construct
|
@@ -102,8 +102,9 @@ provide.
|
|
102
102
|
c.where(:abc => 'def').where(:hgi => 123)
|
103
103
|
c # => {:where => {:abc => 'def', :hgi => 123}}
|
104
104
|
|
105
|
+
|
105
106
|
== Note on Patches/Pull Requests
|
106
|
-
|
107
|
+
|
107
108
|
* Fork the project.
|
108
109
|
* Make your feature addition or bug fix.
|
109
110
|
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
data/Rakefile
CHANGED
@@ -1,22 +1,8 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup
|
3
4
|
|
4
|
-
|
5
|
-
require 'jeweler'
|
6
|
-
Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name = "hashie"
|
8
|
-
gem.summary = %Q{Your friendly neighborhood hash toolkit.}
|
9
|
-
gem.description = %Q{Hashie is a small collection of tools that make hashes more powerful. Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).}
|
10
|
-
gem.email = "michael@intridea.com"
|
11
|
-
gem.homepage = "http://github.com/intridea/hashie"
|
12
|
-
gem.authors = ["Michael Bleigh"]
|
13
|
-
gem.add_development_dependency "rspec"
|
14
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
-
end
|
16
|
-
Jeweler::GemcutterTasks.new
|
17
|
-
rescue LoadError
|
18
|
-
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
19
|
-
end
|
5
|
+
Bundler::GemHelper.install_tasks
|
20
6
|
|
21
7
|
require 'rspec/core/rake_task'
|
22
8
|
RSpec::Core::RakeTask.new do |spec|
|
@@ -25,17 +11,3 @@ RSpec::Core::RakeTask.new do |spec|
|
|
25
11
|
end
|
26
12
|
|
27
13
|
task :default => :spec
|
28
|
-
|
29
|
-
require 'rake/rdoctask'
|
30
|
-
Rake::RDocTask.new do |rdoc|
|
31
|
-
if File.exist?('VERSION')
|
32
|
-
version = File.read('VERSION')
|
33
|
-
else
|
34
|
-
version = ""
|
35
|
-
end
|
36
|
-
|
37
|
-
rdoc.rdoc_dir = 'rdoc'
|
38
|
-
rdoc.title = "hashie #{version}"
|
39
|
-
rdoc.rdoc_files.include('README*')
|
40
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
41
|
-
end
|
data/hashie.gemspec
CHANGED
@@ -1,72 +1,21 @@
|
|
1
|
-
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
-
# -*- encoding: utf-8 -*-
|
1
|
+
require File.expand_path('../lib/hashie/version', __FILE__)
|
5
2
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.authors = ["Michael Bleigh"]
|
5
|
+
gem.email = ["michael@intridea.com"]
|
6
|
+
gem.description = %q{Hashie is a small collection of tools that make hashes more powerful. Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).}
|
7
|
+
gem.summary = %q{Your friendly neighborhood hash toolkit.}
|
8
|
+
gem.homepage = 'https://github.com/intridea/hashie'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
"LICENSE",
|
17
|
-
"README.rdoc"
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".document",
|
21
|
-
".gitignore",
|
22
|
-
".rspec",
|
23
|
-
"Gemfile",
|
24
|
-
"Gemfile.lock",
|
25
|
-
"LICENSE",
|
26
|
-
"README.rdoc",
|
27
|
-
"Rakefile",
|
28
|
-
"VERSION",
|
29
|
-
"hashie.gemspec",
|
30
|
-
"lib/hashie.rb",
|
31
|
-
"lib/hashie/clash.rb",
|
32
|
-
"lib/hashie/dash.rb",
|
33
|
-
"lib/hashie/hash.rb",
|
34
|
-
"lib/hashie/hash_extensions.rb",
|
35
|
-
"lib/hashie/mash.rb",
|
36
|
-
"lib/hashie/trash.rb",
|
37
|
-
"spec/hashie/clash_spec.rb",
|
38
|
-
"spec/hashie/dash_spec.rb",
|
39
|
-
"spec/hashie/hash_spec.rb",
|
40
|
-
"spec/hashie/mash_spec.rb",
|
41
|
-
"spec/hashie/trash_spec.rb",
|
42
|
-
"spec/spec.opts",
|
43
|
-
"spec/spec_helper.rb"
|
44
|
-
]
|
45
|
-
s.homepage = %q{http://github.com/intridea/hashie}
|
46
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
47
|
-
s.require_paths = ["lib"]
|
48
|
-
s.rubygems_version = %q{1.3.7}
|
49
|
-
s.summary = %q{Your friendly neighborhood hash toolkit.}
|
50
|
-
s.test_files = [
|
51
|
-
"spec/hashie/clash_spec.rb",
|
52
|
-
"spec/hashie/dash_spec.rb",
|
53
|
-
"spec/hashie/hash_spec.rb",
|
54
|
-
"spec/hashie/mash_spec.rb",
|
55
|
-
"spec/hashie/trash_spec.rb",
|
56
|
-
"spec/spec_helper.rb"
|
57
|
-
]
|
10
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
11
|
+
gem.files = `git ls-files`.split("\n")
|
12
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
+
gem.name = "hashie"
|
14
|
+
gem.require_paths = ['lib']
|
15
|
+
gem.version = Hashie::VERSION
|
58
16
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
64
|
-
s.add_development_dependency(%q<rspec>, [">= 0"])
|
65
|
-
else
|
66
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
67
|
-
end
|
68
|
-
else
|
69
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
70
|
-
end
|
17
|
+
gem.add_development_dependency 'rake', '~> 0.9.2'
|
18
|
+
gem.add_development_dependency 'rspec', '~> 2.5'
|
19
|
+
gem.add_development_dependency 'guard'
|
20
|
+
gem.add_development_dependency 'guard-rspec'
|
71
21
|
end
|
72
|
-
|
data/lib/hashie/dash.rb
CHANGED
@@ -23,13 +23,17 @@ module Hashie
|
|
23
23
|
# to be returned before a value is set on the property in a new
|
24
24
|
# Dash.
|
25
25
|
#
|
26
|
+
# * <tt>:required</tt> - Specify the value as required for this
|
27
|
+
# property, to raise an error if a value is unset in a new or
|
28
|
+
# existing Dash.
|
29
|
+
#
|
26
30
|
def self.property(property_name, options = {})
|
27
31
|
property_name = property_name.to_sym
|
28
32
|
|
29
33
|
self.properties << property_name
|
30
34
|
|
31
35
|
if options.has_key?(:default)
|
32
|
-
self.defaults[property_name] = options[:default]
|
36
|
+
self.defaults[property_name] = options[:default]
|
33
37
|
elsif self.defaults.has_key?(property_name)
|
34
38
|
self.defaults.delete property_name
|
35
39
|
end
|
@@ -49,19 +53,23 @@ module Hashie
|
|
49
53
|
if defined? @subclasses
|
50
54
|
@subclasses.each { |klass| klass.property(property_name, options) }
|
51
55
|
end
|
56
|
+
required_properties << property_name if options.delete(:required)
|
52
57
|
end
|
53
58
|
|
54
59
|
class << self
|
55
60
|
attr_reader :properties, :defaults
|
61
|
+
attr_reader :required_properties
|
56
62
|
end
|
57
63
|
instance_variable_set('@properties', Set.new)
|
58
64
|
instance_variable_set('@defaults', {})
|
65
|
+
instance_variable_set('@required_properties', Set.new)
|
59
66
|
|
60
67
|
def self.inherited(klass)
|
61
68
|
super
|
62
69
|
(@subclasses ||= Set.new) << klass
|
63
70
|
klass.instance_variable_set('@properties', self.properties.dup)
|
64
71
|
klass.instance_variable_set('@defaults', self.defaults.dup)
|
72
|
+
klass.instance_variable_set('@required_properties', self.required_properties.dup)
|
65
73
|
end
|
66
74
|
|
67
75
|
# Check to see if the specified property has already been
|
@@ -70,6 +78,12 @@ module Hashie
|
|
70
78
|
properties.include? name.to_sym
|
71
79
|
end
|
72
80
|
|
81
|
+
# Check to see if the specified property is
|
82
|
+
# required.
|
83
|
+
def self.required?(name)
|
84
|
+
required_properties.include? name.to_sym
|
85
|
+
end
|
86
|
+
|
73
87
|
# You may initialize a Dash with an attributes hash
|
74
88
|
# just like you would many other kinds of data objects.
|
75
89
|
def initialize(attributes = {}, &block)
|
@@ -82,6 +96,7 @@ module Hashie
|
|
82
96
|
attributes.each_pair do |att, value|
|
83
97
|
self[att] = value
|
84
98
|
end if attributes
|
99
|
+
assert_required_properties_set!
|
85
100
|
end
|
86
101
|
|
87
102
|
alias_method :_regular_reader, :[]
|
@@ -100,6 +115,7 @@ module Hashie
|
|
100
115
|
# Set a value on the Dash in a Hash-like way. Only works
|
101
116
|
# on pre-existing properties.
|
102
117
|
def []=(property, value)
|
118
|
+
assert_property_required! property, value
|
103
119
|
assert_property_exists! property
|
104
120
|
super(property.to_s, value)
|
105
121
|
end
|
@@ -111,5 +127,24 @@ module Hashie
|
|
111
127
|
raise NoMethodError, "The property '#{property}' is not defined for this Dash."
|
112
128
|
end
|
113
129
|
end
|
130
|
+
|
131
|
+
def assert_required_properties_set!
|
132
|
+
self.class.required_properties.each do |required_property|
|
133
|
+
assert_property_set!(required_property)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def assert_property_set!(property)
|
138
|
+
if send(property).nil?
|
139
|
+
raise ArgumentError, "The property '#{property}' is required for this Dash."
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def assert_property_required!(property, value)
|
144
|
+
if self.class.required?(property) && value.nil?
|
145
|
+
raise ArgumentError, "The property '#{property}' is required for this Dash."
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
114
149
|
end
|
115
150
|
end
|
data/lib/hashie/mash.rb
CHANGED
@@ -61,6 +61,10 @@ module Hashie
|
|
61
61
|
key?("id") ? self["id"] : super
|
62
62
|
end
|
63
63
|
|
64
|
+
def type #:nodoc:
|
65
|
+
key?("type") ? self["type"] : super
|
66
|
+
end
|
67
|
+
|
64
68
|
alias_method :regular_reader, :[]
|
65
69
|
alias_method :regular_writer, :[]=
|
66
70
|
|
@@ -141,11 +145,11 @@ module Hashie
|
|
141
145
|
|
142
146
|
# Will return true if the Mash has had a key
|
143
147
|
# set in addition to normal respond_to? functionality.
|
144
|
-
def respond_to?(method_name)
|
148
|
+
def respond_to?(method_name, include_private=false)
|
145
149
|
return true if key?(method_name)
|
146
150
|
super
|
147
151
|
end
|
148
|
-
|
152
|
+
|
149
153
|
def method_missing(method_name, *args, &blk)
|
150
154
|
return self.[](method_name, &blk) if key?(method_name)
|
151
155
|
match = method_name.to_s.match(/(.*?)([?=!]?)$/)
|
data/lib/hashie.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Hashie
|
2
2
|
autoload :HashExtensions, 'hashie/hash_extensions'
|
3
|
-
autoload :PrettyInspect, 'hashie/hash_extensions'
|
3
|
+
autoload :PrettyInspect, 'hashie/hash_extensions'
|
4
4
|
autoload :Hash, 'hashie/hash'
|
5
5
|
autoload :Trash, 'hashie/trash'
|
6
6
|
autoload :Mash, 'hashie/mash'
|
data/spec/hashie/dash_spec.rb
CHANGED
@@ -7,38 +7,59 @@ Hashie::Hash.class_eval do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class DashTest < Hashie::Dash
|
10
|
+
property :first_name, :required => true
|
11
|
+
property :email
|
12
|
+
property :count, :default => 0
|
13
|
+
end
|
14
|
+
|
15
|
+
class DashNoRequiredTest < Hashie::Dash
|
10
16
|
property :first_name
|
11
17
|
property :email
|
12
18
|
property :count, :default => 0
|
13
19
|
end
|
14
20
|
|
15
21
|
class Subclassed < DashTest
|
16
|
-
property :last_name
|
22
|
+
property :last_name, :required => true
|
17
23
|
end
|
18
24
|
|
19
25
|
describe DashTest do
|
20
|
-
|
26
|
+
|
27
|
+
subject { DashTest.new(:first_name => 'Bob', :email => 'bob@example.com') }
|
28
|
+
|
21
29
|
it('subclasses Hashie::Hash') { should respond_to(:to_mash) }
|
22
|
-
|
23
|
-
its(:to_s) { should == '<#DashTest count=0>' }
|
24
|
-
|
30
|
+
|
31
|
+
its(:to_s) { should == '<#DashTest count=0 email="bob@example.com" first_name="Bob">' }
|
32
|
+
|
25
33
|
it 'lists all set properties in inspect' do
|
26
34
|
subject.first_name = 'Bob'
|
27
35
|
subject.email = 'bob@example.com'
|
28
36
|
subject.inspect.should == '<#DashTest count=0 email="bob@example.com" first_name="Bob">'
|
29
37
|
end
|
30
|
-
|
38
|
+
|
31
39
|
its(:count) { should be_zero }
|
32
40
|
|
33
41
|
it { should respond_to(:first_name) }
|
34
42
|
it { should respond_to(:first_name=) }
|
35
43
|
it { should_not respond_to(:nonexistent) }
|
36
|
-
|
44
|
+
|
37
45
|
it 'errors out for a non-existent property' do
|
38
46
|
lambda { subject['nonexistent'] }.should raise_error(NoMethodError)
|
39
47
|
end
|
40
48
|
|
49
|
+
it 'errors out when attempting to set a required property to nil' do
|
50
|
+
lambda { subject.first_name = nil }.should raise_error(ArgumentError)
|
51
|
+
end
|
52
|
+
|
41
53
|
context 'writing to properties' do
|
54
|
+
|
55
|
+
it 'fails writing a required property to nil' do
|
56
|
+
lambda { subject.first_name = nil }.should raise_error(ArgumentError)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'fails writing a required property to nil using []=' do
|
60
|
+
lambda { subject['first_name'] = nil }.should raise_error(ArgumentError)
|
61
|
+
end
|
62
|
+
|
42
63
|
it 'fails writing to a non-existent property using []=' do
|
43
64
|
lambda { subject['nonexistent'] = 123 }.should raise_error(NoMethodError)
|
44
65
|
end
|
@@ -54,19 +75,19 @@ describe DashTest do
|
|
54
75
|
subject.first_name.should == 'Franklin'
|
55
76
|
end
|
56
77
|
end
|
57
|
-
|
78
|
+
|
58
79
|
context 'reading from properties' do
|
59
80
|
it 'fails reading from a non-existent property using []' do
|
60
81
|
lambda { subject['nonexistent'] }.should raise_error(NoMethodError)
|
61
82
|
end
|
62
|
-
|
83
|
+
|
63
84
|
it "should be able to retrieve properties through blocks" do
|
64
85
|
subject["first_name"] = "Aiden"
|
65
86
|
value = nil
|
66
87
|
subject.[]("first_name") { |v| value = v }
|
67
88
|
value.should == "Aiden"
|
68
89
|
end
|
69
|
-
|
90
|
+
|
70
91
|
it "should be able to retrieve properties through blocks with method calls" do
|
71
92
|
subject["first_name"] = "Frodo"
|
72
93
|
value = nil
|
@@ -84,32 +105,42 @@ describe DashTest do
|
|
84
105
|
obj = described_class.new :first_name => 'Michael'
|
85
106
|
obj.first_name.should == 'Michael'
|
86
107
|
end
|
87
|
-
|
108
|
+
|
88
109
|
it 'accepts nil' do
|
89
|
-
lambda {
|
110
|
+
lambda { DashNoRequiredTest.new(nil) }.should_not raise_error
|
90
111
|
end
|
91
|
-
|
112
|
+
|
92
113
|
it 'accepts block to define a global default' do
|
93
114
|
obj = described_class.new { |hash, key| key.to_s.upcase }
|
94
115
|
obj.first_name.should == 'FIRST_NAME'
|
95
116
|
obj.count.should be_zero
|
96
117
|
end
|
118
|
+
|
119
|
+
it "fails when required values are missing" do
|
120
|
+
expect { DashTest.new }.to raise_error(ArgumentError)
|
121
|
+
end
|
122
|
+
|
97
123
|
end
|
98
|
-
|
124
|
+
|
99
125
|
describe 'properties' do
|
100
126
|
it 'lists defined properties' do
|
101
127
|
described_class.properties.should == Set.new([:first_name, :email, :count])
|
102
128
|
end
|
103
|
-
|
129
|
+
|
104
130
|
it 'checks if a property exists' do
|
105
131
|
described_class.property?('first_name').should be_true
|
106
132
|
described_class.property?(:first_name).should be_true
|
107
133
|
end
|
108
|
-
|
134
|
+
|
135
|
+
it 'checks if a property is required' do
|
136
|
+
described_class.required?('first_name').should be_true
|
137
|
+
described_class.required?(:first_name).should be_true
|
138
|
+
end
|
139
|
+
|
109
140
|
it 'doesnt include property from subclass' do
|
110
141
|
described_class.property?(:last_name).should be_false
|
111
142
|
end
|
112
|
-
|
143
|
+
|
113
144
|
it 'lists declared defaults' do
|
114
145
|
described_class.defaults.should == { :count => 0 }
|
115
146
|
end
|
@@ -122,31 +153,31 @@ describe Hashie::Dash, 'inheritance' do
|
|
122
153
|
@middle = Class.new(@top)
|
123
154
|
@bottom = Class.new(@middle)
|
124
155
|
end
|
125
|
-
|
156
|
+
|
126
157
|
it 'reports empty properties when nothing defined' do
|
127
158
|
@top.properties.should be_empty
|
128
159
|
@top.defaults.should be_empty
|
129
160
|
end
|
130
|
-
|
161
|
+
|
131
162
|
it 'inherits properties downwards' do
|
132
163
|
@top.property :echo
|
133
164
|
@middle.properties.should include(:echo)
|
134
165
|
@bottom.properties.should include(:echo)
|
135
166
|
end
|
136
|
-
|
167
|
+
|
137
168
|
it 'doesnt inherit properties upwards' do
|
138
169
|
@middle.property :echo
|
139
170
|
@top.properties.should_not include(:echo)
|
140
171
|
@bottom.properties.should include(:echo)
|
141
172
|
end
|
142
|
-
|
173
|
+
|
143
174
|
it 'allows overriding a default on an existing property' do
|
144
175
|
@top.property :echo
|
145
176
|
@middle.property :echo, :default => 123
|
146
177
|
@bottom.properties.to_a.should == [:echo]
|
147
178
|
@bottom.new.echo.should == 123
|
148
179
|
end
|
149
|
-
|
180
|
+
|
150
181
|
it 'allows clearing an existing default' do
|
151
182
|
@top.property :echo
|
152
183
|
@middle.property :echo, :default => 123
|
@@ -163,20 +194,22 @@ describe Hashie::Dash, 'inheritance' do
|
|
163
194
|
end
|
164
195
|
|
165
196
|
describe Subclassed do
|
166
|
-
|
197
|
+
|
198
|
+
subject { Subclassed.new(:first_name => 'Bob', :last_name => 'McNob', :email => 'bob@example.com') }
|
199
|
+
|
167
200
|
its(:count) { should be_zero }
|
168
201
|
|
169
202
|
it { should respond_to(:first_name) }
|
170
203
|
it { should respond_to(:first_name=) }
|
171
204
|
it { should respond_to(:last_name) }
|
172
205
|
it { should respond_to(:last_name=) }
|
173
|
-
|
206
|
+
|
174
207
|
it 'has one additional property' do
|
175
208
|
described_class.property?(:last_name).should be_true
|
176
209
|
end
|
177
|
-
|
210
|
+
|
178
211
|
it "didn't override superclass inheritance logic" do
|
179
212
|
described_class.instance_variable_get('@inheritance_test').should be_true
|
180
213
|
end
|
181
|
-
|
214
|
+
|
182
215
|
end
|
data/spec/hashie/mash_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'delegate'
|
2
3
|
|
3
4
|
describe Hashie::Mash do
|
4
5
|
before(:each) do
|
@@ -18,14 +19,14 @@ describe Hashie::Mash do
|
|
18
19
|
@mash["test"] = "abc"
|
19
20
|
@mash.test.should == "abc"
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
it "should be able to retrieve set values through blocks" do
|
23
24
|
@mash["test"] = "abc"
|
24
25
|
value = nil
|
25
26
|
@mash.[]("test") { |v| value = v }
|
26
27
|
value.should == "abc"
|
27
28
|
end
|
28
|
-
|
29
|
+
|
29
30
|
it "should be able to retrieve set values through blocks with method calls" do
|
30
31
|
@mash["test"] = "abc"
|
31
32
|
value = nil
|
@@ -38,7 +39,7 @@ describe Hashie::Mash do
|
|
38
39
|
@mash.test = "abc"
|
39
40
|
@mash.test?.should be_true
|
40
41
|
end
|
41
|
-
|
42
|
+
|
42
43
|
it "should return false on a ? method if a value has been set to nil or false" do
|
43
44
|
@mash.test = nil
|
44
45
|
@mash.should_not be_test
|
@@ -81,6 +82,15 @@ describe Hashie::Mash do
|
|
81
82
|
@mash.author.website.should == Hashie::Mash.new(:url => "http://www.mbleigh.com/")
|
82
83
|
end
|
83
84
|
|
85
|
+
# it "should call super if type is not a key" do
|
86
|
+
# @mash.type.should == Hashie::Mash
|
87
|
+
# end
|
88
|
+
|
89
|
+
it "should return the value if type is a key" do
|
90
|
+
@mash.type = "Steve"
|
91
|
+
@mash.type.should == "Steve"
|
92
|
+
end
|
93
|
+
|
84
94
|
context "updating" do
|
85
95
|
subject {
|
86
96
|
described_class.new :first_name => "Michael", :last_name => "Bleigh",
|
@@ -95,13 +105,13 @@ describe Hashie::Mash do
|
|
95
105
|
subject.details.address.should == "Nowhere road"
|
96
106
|
subject.details.city.should == "Imagineton"
|
97
107
|
end
|
98
|
-
|
108
|
+
|
99
109
|
it "should make #update deep by default" do
|
100
110
|
subject.update(:details => {:address => "Fake street"}).should eql(subject)
|
101
111
|
subject.details.address.should == "Fake street"
|
102
112
|
subject.details.email.should == "michael@asf.com"
|
103
113
|
end
|
104
|
-
|
114
|
+
|
105
115
|
it "should clone before a #deep_merge" do
|
106
116
|
duped = subject.deep_merge(:details => {:address => "Fake street"})
|
107
117
|
duped.should_not eql(subject)
|
@@ -109,7 +119,7 @@ describe Hashie::Mash do
|
|
109
119
|
subject.details.address.should == "Nowhere road"
|
110
120
|
duped.details.email.should == "michael@asf.com"
|
111
121
|
end
|
112
|
-
|
122
|
+
|
113
123
|
it "regular #merge should be deep" do
|
114
124
|
duped = subject.merge(:details => {:email => "michael@intridea.com"})
|
115
125
|
duped.should_not eql(subject)
|
@@ -123,18 +133,18 @@ describe Hashie::Mash do
|
|
123
133
|
subject.shallow_update(:details => {
|
124
134
|
:email => "michael@intridea.com", :city => "Imagineton"
|
125
135
|
}).should eql(subject)
|
126
|
-
|
136
|
+
|
127
137
|
subject.first_name.should == "Michael"
|
128
138
|
subject.details.email.should == "michael@intridea.com"
|
129
139
|
subject.details.address.should be_nil
|
130
140
|
subject.details.city.should == "Imagineton"
|
131
141
|
end
|
132
|
-
|
142
|
+
|
133
143
|
it "should clone before a #regular_merge" do
|
134
144
|
duped = subject.shallow_merge(:details => {:address => "Fake street"})
|
135
145
|
duped.should_not eql(subject)
|
136
146
|
end
|
137
|
-
|
147
|
+
|
138
148
|
it "regular merge should be shallow" do
|
139
149
|
duped = subject.shallow_merge(:details => {:address => "Fake street"})
|
140
150
|
duped.details.address.should == "Fake street"
|
@@ -172,49 +182,59 @@ describe Hashie::Mash do
|
|
172
182
|
record.son = MyMash.new
|
173
183
|
record.son.class.should == MyMash
|
174
184
|
end
|
175
|
-
|
185
|
+
|
176
186
|
it "should not change the class of Mashes when converted" do
|
177
187
|
class SubMash < Hashie::Mash
|
178
188
|
end
|
179
|
-
|
189
|
+
|
180
190
|
record = Hashie::Mash.new
|
181
191
|
son = SubMash.new
|
182
192
|
record['submash'] = son
|
183
193
|
record['submash'].should be_kind_of(SubMash)
|
184
194
|
end
|
185
|
-
|
195
|
+
|
186
196
|
it "should respect the class when passed a bang method for a non-existent key" do
|
187
197
|
record = Hashie::Mash.new
|
188
198
|
record.non_existent!.should be_kind_of(Hashie::Mash)
|
189
|
-
|
199
|
+
|
190
200
|
class SubMash < Hashie::Mash
|
191
201
|
end
|
192
|
-
|
202
|
+
|
193
203
|
son = SubMash.new
|
194
204
|
son.non_existent!.should be_kind_of(SubMash)
|
195
205
|
end
|
196
|
-
|
206
|
+
|
197
207
|
it "should respect the class when converting the value" do
|
198
208
|
record = Hashie::Mash.new
|
199
209
|
record.details = Hashie::Mash.new({:email => "randy@asf.com"})
|
200
210
|
record.details.should be_kind_of(Hashie::Mash)
|
201
|
-
|
211
|
+
|
202
212
|
class SubMash < Hashie::Mash
|
203
213
|
end
|
204
|
-
|
214
|
+
|
205
215
|
son = SubMash.new
|
206
216
|
son.details = Hashie::Mash.new({:email => "randyjr@asf.com"})
|
207
217
|
son.details.should be_kind_of(SubMash)
|
208
218
|
end
|
209
|
-
|
219
|
+
|
210
220
|
describe '#respond_to?' do
|
211
221
|
it 'should respond to a normal method' do
|
212
222
|
Hashie::Mash.new.should be_respond_to(:key?)
|
213
223
|
end
|
214
|
-
|
224
|
+
|
215
225
|
it 'should respond to a set key' do
|
216
226
|
Hashie::Mash.new(:abc => 'def').should be_respond_to(:abc)
|
217
227
|
end
|
228
|
+
|
229
|
+
it "should delegate properly using delegate library" do
|
230
|
+
class MashDelegate < DelegateClass(Hashie::Mash)
|
231
|
+
end
|
232
|
+
|
233
|
+
delegate = MashDelegate.new(Hashie::Mash.new(:foo => 100))
|
234
|
+
delegate.foo.should == 100
|
235
|
+
delegate.should respond_to(:foo)
|
236
|
+
expect { delegate.bar }.to raise_error(NoMethodError)
|
237
|
+
end
|
218
238
|
end
|
219
239
|
|
220
240
|
context "#initialize" do
|
metadata
CHANGED
@@ -1,50 +1,75 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashie
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 1
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
version: 1.0.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Michael Bleigh
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
date: 2011-07-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70102343819800 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.2
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70102343819800
|
25
|
+
- !ruby/object:Gem::Dependency
|
21
26
|
name: rspec
|
27
|
+
requirement: &70102343818980 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.5'
|
33
|
+
type: :development
|
22
34
|
prerelease: false
|
23
|
-
|
35
|
+
version_requirements: *70102343818980
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: guard
|
38
|
+
requirement: &70102343818420 !ruby/object:Gem::Requirement
|
24
39
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
- 0
|
30
|
-
version: "0"
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
31
44
|
type: :development
|
32
|
-
|
33
|
-
|
34
|
-
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70102343818420
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: guard-rspec
|
49
|
+
requirement: &70102343817640 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70102343817640
|
58
|
+
description: Hashie is a small collection of tools that make hashes more powerful.
|
59
|
+
Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).
|
60
|
+
email:
|
61
|
+
- michael@intridea.com
|
35
62
|
executables: []
|
36
|
-
|
37
63
|
extensions: []
|
38
|
-
|
39
|
-
|
40
|
-
- LICENSE
|
41
|
-
- README.rdoc
|
42
|
-
files:
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
43
66
|
- .document
|
44
67
|
- .gitignore
|
45
68
|
- .rspec
|
69
|
+
- .travis.yml
|
46
70
|
- Gemfile
|
47
71
|
- Gemfile.lock
|
72
|
+
- Guardfile
|
48
73
|
- LICENSE
|
49
74
|
- README.rdoc
|
50
75
|
- Rakefile
|
@@ -57,6 +82,7 @@ files:
|
|
57
82
|
- lib/hashie/hash_extensions.rb
|
58
83
|
- lib/hashie/mash.rb
|
59
84
|
- lib/hashie/trash.rb
|
85
|
+
- lib/hashie/version.rb
|
60
86
|
- spec/hashie/clash_spec.rb
|
61
87
|
- spec/hashie/dash_spec.rb
|
62
88
|
- spec/hashie/hash_spec.rb
|
@@ -64,42 +90,41 @@ files:
|
|
64
90
|
- spec/hashie/trash_spec.rb
|
65
91
|
- spec/spec.opts
|
66
92
|
- spec/spec_helper.rb
|
67
|
-
|
68
|
-
homepage: http://github.com/intridea/hashie
|
93
|
+
homepage: https://github.com/intridea/hashie
|
69
94
|
licenses: []
|
70
|
-
|
71
95
|
post_install_message:
|
72
|
-
rdoc_options:
|
73
|
-
|
74
|
-
require_paths:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
75
98
|
- lib
|
76
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
100
|
none: false
|
78
|
-
requirements:
|
79
|
-
- -
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
segments:
|
82
106
|
- 0
|
83
|
-
|
84
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
hash: -1452450375686029254
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
109
|
none: false
|
86
|
-
requirements:
|
87
|
-
- -
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
segments:
|
90
115
|
- 0
|
91
|
-
|
116
|
+
hash: -1452450375686029254
|
92
117
|
requirements: []
|
93
|
-
|
94
118
|
rubyforge_project:
|
95
|
-
rubygems_version: 1.
|
119
|
+
rubygems_version: 1.8.5.1
|
96
120
|
signing_key:
|
97
121
|
specification_version: 3
|
98
122
|
summary: Your friendly neighborhood hash toolkit.
|
99
|
-
test_files:
|
123
|
+
test_files:
|
100
124
|
- spec/hashie/clash_spec.rb
|
101
125
|
- spec/hashie/dash_spec.rb
|
102
126
|
- spec/hashie/hash_spec.rb
|
103
127
|
- spec/hashie/mash_spec.rb
|
104
128
|
- spec/hashie/trash_spec.rb
|
129
|
+
- spec/spec.opts
|
105
130
|
- spec/spec_helper.rb
|