zerobearing-hashie 0.1.9

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ *.gem
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Intridea, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ = Hashie
2
+
3
+ Hashie is a growing collection of tools that extend Hashes and make
4
+ them more useful.
5
+
6
+ == Installation
7
+
8
+ Hashie is a gem and is available on Gemcutter. If you don't have Gemcutter,
9
+ install it:
10
+
11
+ gem install gemcutter
12
+ gem tumble
13
+
14
+ Then you can install Hashie:
15
+
16
+ gem install hashie
17
+
18
+ == Mash
19
+
20
+ Mash is an extended Hash that gives simple pseudo-object functionality
21
+ that can be built from hashes and easily extended. It is designed to
22
+ be used in RESTful API libraries to provide easy object-like access
23
+ to JSON and XML parsed hashes.
24
+
25
+ === Example:
26
+
27
+ mash = Hashie::Mash.new
28
+ mash.name? # => false
29
+ mash.name # => nil
30
+ mash.name = "My Mash"
31
+ mash.name # => "My Mash"
32
+ mash.name? # => true
33
+ mash.inspect # => <Hashie::Mash name="My Mash">
34
+
35
+ mash = Mash.new
36
+ # use bang methods for multi-level assignment
37
+ mash.author!.name = "Michael Bleigh"
38
+ mash.author # => <Hashie::Mash name="Michael Bleigh">
39
+
40
+ == Dash
41
+
42
+ Dash is an extended Hash that has a discrete set of defined properties
43
+ and only those properties may be set on the hash. Additionally, you
44
+ can set defaults for each property.
45
+
46
+ === Example:
47
+
48
+ class Person < Hashie::Dash
49
+ property :name
50
+ property :email
51
+ property :occupation, :default => 'Rubyist'
52
+ end
53
+
54
+ p = Person.new
55
+ p.name # => nil
56
+ p.email = 'abc@def.com'
57
+ p.occupation # => 'Rubyist'
58
+ p.email # => 'abc@def.com'
59
+ p[:awesome] # => NoMethodError
60
+ p[:occupation] # => 'Rubyist'
61
+
62
+ p = Person.new(:name => "Bob")
63
+ p.name # => 'Bob'
64
+ p.occupation # => 'Rubyist'
65
+
66
+
67
+ == Note on Patches/Pull Requests
68
+
69
+ * Fork the project.
70
+ * Make your feature addition or bug fix.
71
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
72
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
73
+ * Send me a pull request. Bonus points for topic branches.
74
+
75
+ == Authors
76
+
77
+ * Michael Bleigh
78
+
79
+ == Copyright
80
+
81
+ Copyright (c) 2009 Intridea, Inc (http://intridea.com/). See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
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
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ if File.exist?('VERSION')
40
+ version = File.read('VERSION')
41
+ else
42
+ version = ""
43
+ end
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "hashie #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.9
data/hashie.gemspec ADDED
@@ -0,0 +1,63 @@
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 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{zerobearing-hashie}
8
+ s.version = "0.1.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{2010-01-20}
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
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "hashie.gemspec",
27
+ "lib/hashie.rb",
28
+ "lib/hashie/dash.rb",
29
+ "lib/hashie/hash.rb",
30
+ "lib/hashie/hash_extensions.rb",
31
+ "lib/hashie/mash.rb",
32
+ "spec/hashie/dash_spec.rb",
33
+ "spec/hashie/hash_spec.rb",
34
+ "spec/hashie/mash_spec.rb",
35
+ "spec/spec.opts",
36
+ "spec/spec_helper.rb"
37
+ ]
38
+ s.homepage = %q{http://github.com/intridea/hashie}
39
+ s.rdoc_options = ["--charset=UTF-8"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.3.5}
42
+ s.summary = %q{Your friendly neighborhood hash toolkit.}
43
+ s.test_files = [
44
+ "spec/hashie/dash_spec.rb",
45
+ "spec/hashie/hash_spec.rb",
46
+ "spec/hashie/mash_spec.rb",
47
+ "spec/spec_helper.rb"
48
+ ]
49
+
50
+ if s.respond_to? :specification_version then
51
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
52
+ s.specification_version = 3
53
+
54
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
55
+ s.add_development_dependency(%q<rspec>, [">= 0"])
56
+ else
57
+ s.add_dependency(%q<rspec>, [">= 0"])
58
+ end
59
+ else
60
+ s.add_dependency(%q<rspec>, [">= 0"])
61
+ end
62
+ end
63
+
data/lib/hashie.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'hashie/hash_extensions'
2
+ require 'hashie/hash'
3
+ require 'hashie/mash'
4
+ require 'hashie/dash'
@@ -0,0 +1,108 @@
1
+ require 'hashie/hash'
2
+
3
+ module Hashie
4
+ include Hashie::PrettyInspect
5
+ # A Dash is a 'defined' or 'discrete' Hash, that is, a Hash
6
+ # that has a set of defined keys that are accessible (with
7
+ # optional defaults) and only those keys may be set or read.
8
+ #
9
+ # Dashes are useful when you need to create a very simple
10
+ # lightweight data object that needs even fewer options and
11
+ # resources than something like a DataMapper resource.
12
+ #
13
+ # It is preferrable to a Struct because of the in-class
14
+ # API for defining properties as well as per-property defaults.
15
+ class Dash < Hashie::Hash
16
+ include Hashie::PrettyInspect
17
+ alias_method :to_s, :inspect
18
+
19
+ # Defines a property on the Dash. Options are
20
+ # as follows:
21
+ #
22
+ # * <tt>:default</tt> - Specify a default value for this property,
23
+ # to be returned before a value is set on the property in a new
24
+ # Dash.
25
+ #
26
+ def self.property(property_name, options = {})
27
+ property_name = property_name.to_sym
28
+
29
+ (@properties ||= []) << property_name
30
+ (@defaults ||= {})[property_name] = options.delete(:default)
31
+
32
+ class_eval <<-RUBY
33
+ def #{property_name}
34
+ self[:#{property_name}]
35
+ end
36
+
37
+ def #{property_name}=(val)
38
+ self[:#{property_name}] = val
39
+ end
40
+ RUBY
41
+ end
42
+
43
+ # Get a String array of the currently defined
44
+ # properties on this Dash.
45
+ def self.properties
46
+ properties = []
47
+ ancestors.each do |elder|
48
+ if elder.instance_variable_defined?("@properties")
49
+ properties << elder.instance_variable_get("@properties")
50
+ end
51
+ end
52
+
53
+ properties.flatten.map{|p| p.to_s}
54
+ end
55
+
56
+ # Check to see if the specified property has already been
57
+ # defined.
58
+ def self.property?(prop)
59
+ properties.include?(prop.to_s)
60
+ end
61
+
62
+ # The default values that have been set for this Dash
63
+ def self.defaults
64
+ properties = {}
65
+ ancestors.each do |elder|
66
+ if elder.instance_variable_defined?("@defaults")
67
+ properties.merge! elder.instance_variable_get("@defaults")
68
+ end
69
+ end
70
+
71
+ properties
72
+ end
73
+
74
+ # You may initialize a Dash with an attributes hash
75
+ # just like you would many other kinds of data objects.
76
+ def initialize(attributes = {})
77
+ self.class.properties.each do |prop|
78
+ self.send("#{prop}=", self.class.defaults[prop.to_sym])
79
+ end
80
+
81
+ attributes.each_pair do |att, value|
82
+ self.send("#{att}=", value)
83
+ end
84
+ end
85
+
86
+ # Retrieve a value from the Dash (will return the
87
+ # property's default value if it hasn't been set).
88
+ def [](property)
89
+ super(property.to_sym) if property_exists? property
90
+ end
91
+
92
+ # Set a value on the Dash in a Hash-like way. Only works
93
+ # on pre-existing properties.
94
+ def []=(property, value)
95
+ super if property_exists? property
96
+ end
97
+
98
+ private
99
+ # Raises an NoMethodError if the property doesn't exist
100
+ #
101
+ def property_exists?(property)
102
+ unless self.class.property?(property.to_sym)
103
+ raise NoMethodError, "The property '#{property}' is not defined for this Dash."
104
+ end
105
+ true
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,8 @@
1
+ module Hashie
2
+ # A Hashie Hash is simply a Hash that has convenience
3
+ # functions baked in such as stringify_keys that may
4
+ # not be available in all libraries.
5
+ class Hash < Hash
6
+ include Hashie::HashExtensions
7
+ end
8
+ end
@@ -0,0 +1,49 @@
1
+ module Hashie
2
+ module HashExtensions
3
+ def self.included(base)
4
+ # Don't tread on existing extensions of Hash by
5
+ # adding methods that are likely to exist.
6
+ %w(stringify_keys stringify_keys!).each do |hashie_method|
7
+ base.send :alias_method, hashie_method, "hashie_#{hashie_method}" unless base.instance_methods.include?(hashie_method)
8
+ end
9
+ end
10
+
11
+ # Destructively convert all of the keys of a Hash
12
+ # to their string representations.
13
+ def hashie_stringify_keys!
14
+ self.keys.each do |k|
15
+ unless String === k
16
+ self[k.to_s] = self.delete(k)
17
+ end
18
+ end
19
+ self
20
+ end
21
+
22
+ # Convert all of the keys of a Hash
23
+ # to their string representations.
24
+ def hashie_stringify_keys
25
+ self.dup.stringify_keys!
26
+ end
27
+
28
+ # Convert this hash into a Mash
29
+ def to_mash
30
+ Hashie::Mash.new(self)
31
+ end
32
+ end
33
+
34
+ module PrettyInspect
35
+ def self.included(base)
36
+ base.send :alias_method, :hash_inspect, :inspect
37
+ base.send :alias_method, :inspect, :hashie_inspect
38
+ end
39
+
40
+ def hashie_inspect
41
+ ret = "<##{self.class.to_s}"
42
+ stringify_keys.keys.sort.each do |key|
43
+ ret << " #{key}=#{self[key].inspect}"
44
+ end
45
+ ret << ">"
46
+ ret
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,166 @@
1
+ module Hashie
2
+ # Mash allows you to create pseudo-objects that have method-like
3
+ # accessors for hash keys. This is useful for such implementations
4
+ # as an API-accessing library that wants to fake robust objects
5
+ # without the overhead of actually doing so. Think of it as OpenStruct
6
+ # with some additional goodies.
7
+ #
8
+ # A Mash will look at the methods you pass it and perform operations
9
+ # based on the following rules:
10
+ #
11
+ # * No punctuation: Returns the value of the hash for that key, or nil if none exists.
12
+ # * Assignment (<tt>=</tt>): Sets the attribute of the given method name.
13
+ # * Existence (<tt>?</tt>): Returns true or false depending on whether that key has been set.
14
+ # * Bang (<tt>!</tt>): Forces the existence of this key, used for deep Mashes. Think of it as "touch" for mashes.
15
+ #
16
+ # == Basic Example
17
+ #
18
+ # mash = Mash.new
19
+ # mash.name? # => false
20
+ # mash.name = "Bob"
21
+ # mash.name # => "Bob"
22
+ # mash.name? # => true
23
+ #
24
+ # == Hash Conversion Example
25
+ #
26
+ # hash = {:a => {:b => 23, :d => {:e => "abc"}}, :f => [{:g => 44, :h => 29}, 12]}
27
+ # mash = Mash.new(hash)
28
+ # mash.a.b # => 23
29
+ # mash.a.d.e # => "abc"
30
+ # mash.f.first.g # => 44
31
+ # mash.f.last # => 12
32
+ #
33
+ # == Bang Example
34
+ #
35
+ # mash = Mash.new
36
+ # mash.author # => nil
37
+ # mash.author! # => <Mash>
38
+ #
39
+ # mash = Mash.new
40
+ # mash.author!.name = "Michael Bleigh"
41
+ # mash.author # => <Mash name="Michael Bleigh">
42
+ #
43
+ class Mash < Hashie::Hash
44
+ include Hashie::PrettyInspect
45
+ alias_method :to_s, :inspect
46
+
47
+ # If you pass in an existing hash, it will
48
+ # convert it to a Mash including recursively
49
+ # descending into arrays and hashes, converting
50
+ # them as well.
51
+ def initialize(source_hash = nil, default = nil, &blk)
52
+ deep_update(source_hash) if source_hash
53
+ default ? super(default) : super(&blk)
54
+ end
55
+
56
+ class << self; alias [] new; end
57
+
58
+ def id #:nodoc:
59
+ key?("id") ? self["id"] : super
60
+ end
61
+
62
+ alias_method :regular_reader, :[]
63
+ alias_method :regular_writer, :[]=
64
+
65
+ # Retrieves an attribute set in the Mash. Will convert
66
+ # any key passed in to a string before retrieving.
67
+ def [](key)
68
+ regular_reader(convert_key(key))
69
+ end
70
+
71
+ # Sets an attribute in the Mash. Key will be converted to
72
+ # a string before it is set, and Hashes will be converted
73
+ # into Mashes for nesting purposes.
74
+ def []=(key,value) #:nodoc:
75
+ regular_writer(convert_key(key), convert_value(value))
76
+ end
77
+
78
+ # This is the bang method reader, it will return a new Mash
79
+ # if there isn't a value already assigned to the key requested.
80
+ def initializing_reader(key)
81
+ ck = convert_key(key)
82
+ regular_writer(ck, Hashie::Mash.new) unless key?(ck)
83
+ regular_reader(ck)
84
+ end
85
+
86
+ alias_method :regular_dup, :dup
87
+ # Duplicates the current mash as a new mash.
88
+ def dup
89
+ Mash.new(self, self.default)
90
+ end
91
+
92
+ def key?(key)
93
+ super(convert_key(key))
94
+ end
95
+
96
+ # Performs a deep_update on a duplicate of the
97
+ # current mash.
98
+ def deep_merge(other_hash)
99
+ dup.deep_merge!(other_hash)
100
+ end
101
+
102
+ # Recursively merges this mash with the passed
103
+ # in hash, merging each hash in the hierarchy.
104
+ def deep_update(other_hash)
105
+ other_hash.each_pair do |k,v|
106
+ regular_writer(convert_key(k), convert_value(other_hash[k], true))
107
+ end
108
+ self
109
+ end
110
+ alias_method :deep_merge!, :deep_update
111
+ alias_method :update, :deep_update
112
+ alias_method :merge!, :update
113
+
114
+ # Converts a mash back to a hash (with stringified keys)
115
+ def to_hash
116
+ h = Hash.new(default).merge(self)
117
+ h.each {|key,val| h[key] = convert_value_to_hash(val)}
118
+ h
119
+ end
120
+
121
+ def method_missing(method_name, *args)
122
+ return self[method_name] if key?(method_name)
123
+ match = method_name.to_s.match(/(.*?)([?=!]?)$/)
124
+ case match[2]
125
+ when "="
126
+ self[match[1]] = args.first
127
+ when "?"
128
+ key?(match[1])
129
+ when "!"
130
+ initializing_reader(match[1])
131
+ else
132
+ default(method_name)
133
+ end
134
+ end
135
+
136
+ protected
137
+
138
+ def convert_key(key) #:nodoc:
139
+ key.to_s
140
+ end
141
+
142
+ #------------------
143
+ def convert_value_to_hash(val)
144
+ case val
145
+ when Mash
146
+ val.to_hash
147
+ when Array
148
+ val.collect(&:to_hash)
149
+ else
150
+ val
151
+ end
152
+ end
153
+
154
+ def convert_value(val, duping=false) #:nodoc:
155
+ case val
156
+ when ::Hash
157
+ val = val.dup if duping
158
+ self.class.new(val)
159
+ when Array
160
+ val.collect{ |e| convert_value(e) }
161
+ else
162
+ val
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,103 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ class DashTest < Hashie::Dash
4
+ property :first_name
5
+ property :email
6
+ property :count, :default => 0
7
+ end
8
+
9
+ class Subclassed < DashTest
10
+ property :last_name
11
+ end
12
+
13
+ describe Hashie::Dash do
14
+ it 'should be a subclass of Hashie::Hash' do
15
+ (Hashie::Dash < Hash).should be_true
16
+ end
17
+
18
+ it '#inspect should be ok!' do
19
+ dash = DashTest.new
20
+ dash.email = "abd@abc.com"
21
+ dash.inspect.should == "<#DashTest count=0 email=\"abd@abc.com\" first_name=nil>"
22
+ end
23
+
24
+ describe ' creating properties' do
25
+ it 'should add the property to the list' do
26
+ DashTest.property :not_an_att
27
+ DashTest.properties.include?('not_an_att').should be_true
28
+ end
29
+
30
+ it 'should create a method for reading the property' do
31
+ DashTest.new.respond_to?(:first_name).should be_true
32
+ end
33
+
34
+ it 'should create a method for writing the property' do
35
+ DashTest.new.respond_to?(:first_name=).should be_true
36
+ end
37
+ end
38
+
39
+ describe 'reading properties' do
40
+ it 'should raise an error when reading a non-existent property' do
41
+ lambda{@dash['abc']}.should raise_error(NoMethodError)
42
+ end
43
+ end
44
+
45
+ describe ' writing to properties' do
46
+ before do
47
+ @dash = DashTest.new
48
+ end
49
+
50
+ it 'should not be able to write to a non-existent property using []=' do
51
+ lambda{@dash['abc'] = 123}.should raise_error(NoMethodError)
52
+ end
53
+
54
+ it 'should be able to write to an existing property using []=' do
55
+ lambda{@dash['first_name'] = 'Bob'}.should_not raise_error
56
+ end
57
+
58
+ it 'should be able to read/write to an existing property using a method call' do
59
+ @dash.first_name = 'Franklin'
60
+ @dash.first_name.should == 'Franklin'
61
+ end
62
+ end
63
+
64
+ describe ' initializing with a Hash' do
65
+ it 'should not be able to initialize non-existent properties' do
66
+ lambda{DashTest.new(:bork => 'abc')}.should raise_error(NoMethodError)
67
+ end
68
+
69
+ it 'should set properties that it is able to' do
70
+ DashTest.new(:first_name => 'Michael').first_name.should == 'Michael'
71
+ end
72
+ end
73
+
74
+ describe ' defaults' do
75
+ before do
76
+ @dash = DashTest.new
77
+ end
78
+
79
+ it 'should return the default value for defaulted' do
80
+ DashTest.property :defaulted, :default => 'abc'
81
+ DashTest.new.defaulted.should == 'abc'
82
+ end
83
+ end
84
+ end
85
+
86
+ describe Subclassed do
87
+ it "should inherit all properties from DashTest" do
88
+ Subclassed.properties.size.should == 6
89
+ end
90
+
91
+ it "should inherit all defaults from DashTest" do
92
+ Subclassed.defaults.size.should == 6
93
+ end
94
+
95
+ it "should init without raising" do
96
+ lambda { Subclassed.new }.should_not raise_error
97
+ lambda { Subclassed.new(:first_name => 'Michael') }.should_not raise_error
98
+ end
99
+
100
+ it "should share defaults from DashTest" do
101
+ Subclassed.new.count.should == 0
102
+ end
103
+ end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Hash do
4
+ it "should be convertible to a Hashie::Mash" do
5
+ mash = Hashie::Hash[:some => "hash"].to_mash
6
+ mash.is_a?(Hashie::Mash).should be_true
7
+ mash.some.should == "hash"
8
+ end
9
+
10
+ it "#stringify_keys! should turn all keys into strings" do
11
+ hash = Hashie::Hash[:a => "hey", 123 => "bob"]
12
+ hash.stringify_keys!
13
+ hash.should == Hashie::Hash["a" => "hey", "123" => "bob"]
14
+ end
15
+
16
+ it "#stringify_keys should return a hash with stringified keys" do
17
+ hash = Hashie::Hash[:a => "hey", 123 => "bob"]
18
+ stringified_hash = hash.stringify_keys
19
+ hash.should == Hashie::Hash[:a => "hey", 123 => "bob"]
20
+ stringified_hash.should == Hashie::Hash["a" => "hey", "123" => "bob"]
21
+ end
22
+ end
@@ -0,0 +1,139 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Hashie::Mash do
4
+ before(:each) do
5
+ @mash = Hashie::Mash.new
6
+ end
7
+
8
+ it "should inherit from hash" do
9
+ @mash.is_a?(Hash).should be_true
10
+ end
11
+
12
+ it "should be able to set hash values through method= calls" do
13
+ @mash.test = "abc"
14
+ @mash["test"].should == "abc"
15
+ end
16
+
17
+ it "should be able to retrieve set values through method calls" do
18
+ @mash["test"] = "abc"
19
+ @mash.test.should == "abc"
20
+ end
21
+
22
+ it "should test for already set values when passed a ? method" do
23
+ @mash.test?.should be_false
24
+ @mash.test = "abc"
25
+ @mash.test?.should be_true
26
+ end
27
+
28
+ it "should make all [] and []= into strings for consistency" do
29
+ @mash["abc"] = 123
30
+ @mash.key?('abc').should be_true
31
+ @mash["abc"].should == 123
32
+ end
33
+
34
+ it "should have a to_s that is identical to its inspect" do
35
+ @mash.abc = 123
36
+ @mash.to_s.should == @mash.inspect
37
+ end
38
+
39
+ it "should return nil instead of raising an error for attribute-esque method calls" do
40
+ @mash.abc.should be_nil
41
+ end
42
+
43
+ it "should return a Hashie::Mash when passed a bang method to a non-existenct key" do
44
+ @mash.abc!.is_a?(Hashie::Mash).should be_true
45
+ end
46
+
47
+ it "should return the existing value when passed a bang method for an existing key" do
48
+ @mash.name = "Bob"
49
+ @mash.name!.should == "Bob"
50
+ end
51
+
52
+ it "#initializing_reader should return a Hashie::Mash when passed a non-existent key" do
53
+ @mash.initializing_reader(:abc).is_a?(Hashie::Mash).should be_true
54
+ end
55
+
56
+ it "should allow for multi-level assignment through bang methods" do
57
+ @mash.author!.name = "Michael Bleigh"
58
+ @mash.author.should == Hashie::Mash.new(:name => "Michael Bleigh")
59
+ @mash.author!.website!.url = "http://www.mbleigh.com/"
60
+ @mash.author.website.should == Hashie::Mash.new(:url => "http://www.mbleigh.com/")
61
+ end
62
+
63
+ it "#deep_update should recursively Hashie::Mash Hashie::Mashes and hashes together" do
64
+ @mash.first_name = "Michael"
65
+ @mash.last_name = "Bleigh"
66
+ @mash.details = Hashie::Hash[:email => "michael@asf.com"].to_mash
67
+ @mash.deep_update({:details => {:email => "michael@intridea.com"}})
68
+ @mash.details.email.should == "michael@intridea.com"
69
+ end
70
+
71
+ it "should convert hash assignments into Hashie::Mashes" do
72
+ @mash.details = {:email => 'randy@asf.com', :address => {:state => 'TX'} }
73
+ @mash.details.email.should == 'randy@asf.com'
74
+ @mash.details.address.state.should == 'TX'
75
+ end
76
+
77
+ it "should not convert the type of Hashie::Mashes childs to Hashie::Mash" do
78
+ class MyMash < Hashie::Mash
79
+ end
80
+
81
+ record = MyMash.new
82
+ record.son = MyMash.new
83
+ record.son.class.should == MyMash
84
+ end
85
+
86
+ context "#initialize" do
87
+ it "should convert an existing hash to a Hashie::Mash" do
88
+ converted = Hashie::Mash.new({:abc => 123, :name => "Bob"})
89
+ converted.abc.should == 123
90
+ converted.name.should == "Bob"
91
+ end
92
+
93
+ it "should convert hashes recursively into Hashie::Mashes" do
94
+ converted = Hashie::Mash.new({:a => {:b => 1, :c => {:d => 23}}})
95
+ converted.a.is_a?(Hashie::Mash).should be_true
96
+ converted.a.b.should == 1
97
+ converted.a.c.d.should == 23
98
+ end
99
+
100
+ it "should convert hashes in arrays into Hashie::Mashes" do
101
+ converted = Hashie::Mash.new({:a => [{:b => 12}, 23]})
102
+ converted.a.first.b.should == 12
103
+ converted.a.last.should == 23
104
+ end
105
+
106
+ it "should convert an existing Hashie::Mash into a Hashie::Mash" do
107
+ initial = Hashie::Mash.new(:name => 'randy', :address => {:state => 'TX'})
108
+ copy = Hashie::Mash.new(initial)
109
+ initial.name.should == copy.name
110
+ initial.object_id.should_not == copy.object_id
111
+ copy.address.state.should == 'TX'
112
+ copy.address.state = 'MI'
113
+ initial.address.state.should == 'TX'
114
+ copy.address.object_id.should_not == initial.address.object_id
115
+ end
116
+
117
+ it "should accept a default block" do
118
+ initial = Hashie::Mash.new { |h,i| h[i] = []}
119
+ initial.default_proc.should_not be_nil
120
+ initial.default.should be_nil
121
+ initial.test.should == []
122
+ initial.test?.should be_true
123
+ end
124
+ end
125
+
126
+ context "#to_hash" do
127
+ it "convert to hash (deeply)" do
128
+ @mash.test = 1
129
+ @mash.a = Hashie::Mash.new(:name => "testa")
130
+ @mash.b = [{:c => 1}, {:d => {:name => "hello"}}]
131
+ h = @mash.to_hash
132
+ h['test'].should == 1
133
+ h['a']['name'].should == "testa"
134
+ h['b'][0]['c'].should == 1
135
+ h['b'][1]['d']['name'].should == "hello"
136
+ end
137
+ end
138
+
139
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format progress
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ require 'hashie'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zerobearing-hashie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.9
5
+ platform: ruby
6
+ authors:
7
+ - Michael Bleigh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-20 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Hashie is a small collection of tools that make hashes more powerful. Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).
26
+ email: michael@intridea.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - hashie.gemspec
42
+ - lib/hashie.rb
43
+ - lib/hashie/dash.rb
44
+ - lib/hashie/hash.rb
45
+ - lib/hashie/hash_extensions.rb
46
+ - lib/hashie/mash.rb
47
+ - spec/hashie/dash_spec.rb
48
+ - spec/hashie/hash_spec.rb
49
+ - spec/hashie/mash_spec.rb
50
+ - spec/spec.opts
51
+ - spec/spec_helper.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/intridea/hashie
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --charset=UTF-8
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ requirements: []
74
+
75
+ rubyforge_project:
76
+ rubygems_version: 1.3.5
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: Your friendly neighborhood hash toolkit.
80
+ test_files:
81
+ - spec/hashie/dash_spec.rb
82
+ - spec/hashie/hash_spec.rb
83
+ - spec/hashie/mash_spec.rb
84
+ - spec/spec_helper.rb