hashie 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ rdoc
5
5
  pkg
6
6
  *.gem
7
7
  .bundle
8
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - rbx
5
+ - ree
6
+ - ruby-head
data/Gemfile CHANGED
@@ -1,12 +1,2 @@
1
- # A sample Gemfile
2
1
  source 'http://rubygems.org'
3
-
4
- group :development do
5
- gem 'rake'
6
- gem 'json'
7
- gem 'jeweler'
8
- end
9
-
10
- group :test do
11
- gem 'rspec', '~> 2.0'
12
- end
2
+ gemspec
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
- gemcutter (0.6.1)
6
- git (1.2.5)
7
- jeweler (1.4.0)
8
- gemcutter (>= 0.1.0)
9
- git (>= 1.2.5)
10
- rubyforge (>= 2.0.0)
11
- json (1.4.3)
12
- json_pure (1.4.3)
13
- rake (0.8.7)
14
- rspec (2.4.0)
15
- rspec-core (~> 2.4.0)
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.4.0)
22
- rubyforge (2.0.4)
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
- jeweler
30
- json
31
- rake
32
- rspec (~> 2.0)
29
+ guard
30
+ guard-rspec
31
+ hashie!
32
+ rake (~> 0.9.2)
33
+ rspec (~> 2.5)
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb})
3
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
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
- p.name # => nil
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 'rake'
2
+ require 'bundler'
3
+ Bundler.setup
3
4
 
4
- begin
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
- # Generated by jeweler
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 |s|
7
- s.name = %q{hashie}
8
- s.version = "1.0.0"
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
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Michael Bleigh"]
12
- s.date = %q{2011-01-27}
13
- s.description = %q{Hashie is a small collection of tools that make hashes more powerful. Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).}
14
- s.email = %q{michael@intridea.com}
15
- s.extra_rdoc_files = [
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
- if s.respond_to? :specification_version then
60
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
61
- s.specification_version = 3
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(/(.*?)([?=!]?)$/)
@@ -0,0 +1,3 @@
1
+ module Hashie
2
+ VERSION = '1.1.0'
3
+ end
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'
@@ -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 { described_class.new(nil) }.should_not raise_error
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
@@ -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
- prerelease: false
5
- segments:
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
- date: 2011-01-27 00:00:00 -06:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
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
- requirement: &id001 !ruby/object:Gem::Requirement
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
- segments:
29
- - 0
30
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
31
44
  type: :development
32
- version_requirements: *id001
33
- description: Hashie is a small collection of tools that make hashes more powerful. Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).
34
- email: michael@intridea.com
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
- extra_rdoc_files:
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
- has_rdoc: true
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
- - --charset=UTF-8
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
- segments:
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ segments:
82
106
  - 0
83
- version: "0"
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
- segments:
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ segments:
90
115
  - 0
91
- version: "0"
116
+ hash: -1452450375686029254
92
117
  requirements: []
93
-
94
118
  rubyforge_project:
95
- rubygems_version: 1.3.7
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