hashie 0.2.2 → 0.3.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/README.rdoc CHANGED
@@ -30,6 +30,10 @@ to JSON and XML parsed hashes.
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
+
34
+ <b>Note:</b> The <tt>?</tt> method will return false if a key has been set
35
+ to false or nil. In order to check if a key has been set at all, use the
36
+ <tt>mash.key?('some_key')</tt> method instead.
33
37
 
34
38
  == Dash
35
39
 
@@ -57,6 +61,20 @@ can set defaults for each property.
57
61
  p.name # => 'Bob'
58
62
  p.occupation # => 'Rubyist'
59
63
 
64
+ == Trash
65
+
66
+ A Trash is a Dash that allows you to translate keys on initialization.
67
+ It is used like so:
68
+
69
+ class Person < Hashie::Trash
70
+ property :first_name, :from => :firstName
71
+ end
72
+
73
+ This will automatically translate the <tt>firstName</tt> key to <tt>first_name</tt>
74
+ when it is initialized using a hash such as through:
75
+
76
+ Person.new(:firstName => 'Bob')
77
+
60
78
  == Clash
61
79
 
62
80
  Clash is a Chainable Lazy Hash that allows you to easily construct
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.3.0
data/hashie.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{hashie}
8
- s.version = "0.2.2"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Michael Bleigh"]
12
- s.date = %q{2010-07-28}
12
+ s.date = %q{2010-08-10}
13
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
14
  s.email = %q{michael@intridea.com}
15
15
  s.extra_rdoc_files = [
@@ -32,10 +32,12 @@ Gem::Specification.new do |s|
32
32
  "lib/hashie/hash.rb",
33
33
  "lib/hashie/hash_extensions.rb",
34
34
  "lib/hashie/mash.rb",
35
+ "lib/hashie/trash.rb",
35
36
  "spec/hashie/clash_spec.rb",
36
37
  "spec/hashie/dash_spec.rb",
37
38
  "spec/hashie/hash_spec.rb",
38
39
  "spec/hashie/mash_spec.rb",
40
+ "spec/hashie/trash_spec.rb",
39
41
  "spec/spec.opts",
40
42
  "spec/spec_helper.rb"
41
43
  ]
@@ -49,6 +51,7 @@ Gem::Specification.new do |s|
49
51
  "spec/hashie/dash_spec.rb",
50
52
  "spec/hashie/hash_spec.rb",
51
53
  "spec/hashie/mash_spec.rb",
54
+ "spec/hashie/trash_spec.rb",
52
55
  "spec/spec_helper.rb"
53
56
  ]
54
57
 
data/lib/hashie.rb CHANGED
@@ -2,4 +2,8 @@ require 'hashie/hash_extensions'
2
2
  require 'hashie/hash'
3
3
  require 'hashie/mash'
4
4
  require 'hashie/dash'
5
- require 'hashie/clash'
5
+ require 'hashie/clash'
6
+
7
+ module Hashie
8
+ autoload :Trash, 'hashie/trash'
9
+ end
data/lib/hashie/dash.rb CHANGED
@@ -44,7 +44,7 @@ module Hashie
44
44
  # properties on this Dash.
45
45
  def self.properties
46
46
  properties = []
47
- ancestors.each do |elder|
47
+ ancestors.each do |elder|
48
48
  if elder.instance_variable_defined?("@properties")
49
49
  properties << elder.instance_variable_get("@properties")
50
50
  end
@@ -67,7 +67,7 @@ module Hashie
67
67
  properties.merge! elder.instance_variable_get("@defaults")
68
68
  end
69
69
  end
70
-
70
+
71
71
  properties
72
72
  end
73
73
 
@@ -80,7 +80,7 @@ module Hashie
80
80
 
81
81
  attributes.each_pair do |att, value|
82
82
  self.send("#{att}=", value)
83
- end
83
+ end if attributes
84
84
  end
85
85
 
86
86
  # Retrieve a value from the Dash (will return the
@@ -94,8 +94,8 @@ module Hashie
94
94
  def []=(property, value)
95
95
  super if property_exists? property
96
96
  end
97
-
98
- private
97
+
98
+ private
99
99
  # Raises an NoMethodError if the property doesn't exist
100
100
  #
101
101
  def property_exists?(property)
data/lib/hashie/mash.rb CHANGED
@@ -125,7 +125,7 @@ module Hashie
125
125
  when "="
126
126
  self[match[1]] = args.first
127
127
  when "?"
128
- key?(match[1])
128
+ !!self[match[1]]
129
129
  when "!"
130
130
  initializing_reader(match[1])
131
131
  else
@@ -0,0 +1,55 @@
1
+ require 'hashie/dash'
2
+
3
+ module Hashie
4
+ # A Trash is a 'translated' Dash where the keys can be remapped from a source
5
+ # hash.
6
+ #
7
+ # Trashes are useful when you need to read data from another application,
8
+ # such as a Java api, where the keys are named differently from how we would
9
+ # in Ruby.
10
+ class Trash < Hashie::Dash
11
+
12
+ # Defines a property on the Trash. Options are as follows:
13
+ #
14
+ # * <tt>:default</tt> - Specify a default value for this property, to be
15
+ # returned before a value is set on the property in a new Dash.
16
+ # * <tt>:from</tt> - Specify the original key name that will be write only.
17
+ def self.property(property_name, options = {})
18
+ super
19
+
20
+ if options[:from]
21
+ translations << options[:from].to_sym
22
+ class_eval <<-RUBY
23
+ def #{options[:from]}=(val)
24
+ self[:#{property_name}] = val
25
+ end
26
+ RUBY
27
+ end
28
+ end
29
+
30
+ # Set a value on the Dash in a Hash-like way. Only works
31
+ # on pre-existing properties.
32
+ def []=(property, value)
33
+ if self.class.translations.include? property.to_sym
34
+ send("#{property}=", value)
35
+ elsif property_exists? property
36
+ super
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def self.translations
43
+ @translations ||= []
44
+ end
45
+
46
+ # Raises an NoMethodError if the property doesn't exist
47
+ #
48
+ def property_exists?(property)
49
+ unless self.class.property?(property.to_sym)
50
+ raise NoMethodError, "The property '#{property}' is not defined for this Trash."
51
+ end
52
+ true
53
+ end
54
+ end
55
+ end
@@ -14,68 +14,74 @@ describe Hashie::Dash do
14
14
  it 'should be a subclass of Hashie::Hash' do
15
15
  (Hashie::Dash < Hash).should be_true
16
16
  end
17
-
17
+
18
18
  it '#inspect should be ok!' do
19
19
  dash = DashTest.new
20
20
  dash.email = "abd@abc.com"
21
21
  dash.inspect.should == "<#DashTest count=0 email=\"abd@abc.com\" first_name=nil>"
22
22
  end
23
-
23
+
24
24
  describe ' creating properties' do
25
25
  it 'should add the property to the list' do
26
26
  DashTest.property :not_an_att
27
27
  DashTest.properties.include?('not_an_att').should be_true
28
28
  end
29
-
29
+
30
30
  it 'should create a method for reading the property' do
31
31
  DashTest.new.respond_to?(:first_name).should be_true
32
32
  end
33
-
33
+
34
34
  it 'should create a method for writing the property' do
35
35
  DashTest.new.respond_to?(:first_name=).should be_true
36
36
  end
37
37
  end
38
-
38
+
39
39
  describe 'reading properties' do
40
- it 'should raise an error when reading a non-existent property' do
40
+ it 'should raise an error when reading a non-existent property' do
41
41
  lambda{@dash['abc']}.should raise_error(NoMethodError)
42
42
  end
43
43
  end
44
-
44
+
45
45
  describe ' writing to properties' do
46
46
  before do
47
47
  @dash = DashTest.new
48
48
  end
49
-
49
+
50
50
  it 'should not be able to write to a non-existent property using []=' do
51
51
  lambda{@dash['abc'] = 123}.should raise_error(NoMethodError)
52
52
  end
53
-
53
+
54
54
  it 'should be able to write to an existing property using []=' do
55
55
  lambda{@dash['first_name'] = 'Bob'}.should_not raise_error
56
56
  end
57
-
57
+
58
58
  it 'should be able to read/write to an existing property using a method call' do
59
59
  @dash.first_name = 'Franklin'
60
60
  @dash.first_name.should == 'Franklin'
61
61
  end
62
62
  end
63
-
63
+
64
64
  describe ' initializing with a Hash' do
65
65
  it 'should not be able to initialize non-existent properties' do
66
66
  lambda{DashTest.new(:bork => 'abc')}.should raise_error(NoMethodError)
67
67
  end
68
-
68
+
69
69
  it 'should set properties that it is able to' do
70
70
  DashTest.new(:first_name => 'Michael').first_name.should == 'Michael'
71
71
  end
72
72
  end
73
-
73
+
74
+ describe 'initializing with a nil' do
75
+ it 'accepts nil' do
76
+ lambda { DashTest.new(nil) }.should_not raise_error
77
+ end
78
+ end
79
+
74
80
  describe ' defaults' do
75
81
  before do
76
82
  @dash = DashTest.new
77
83
  end
78
-
84
+
79
85
  it 'should return the default value for defaulted' do
80
86
  DashTest.property :defaulted, :default => 'abc'
81
87
  DashTest.new.defaulted.should == 'abc'
@@ -87,17 +93,17 @@ describe Subclassed do
87
93
  it "should inherit all properties from DashTest" do
88
94
  Subclassed.properties.size.should == 6
89
95
  end
90
-
96
+
91
97
  it "should inherit all defaults from DashTest" do
92
98
  Subclassed.defaults.size.should == 6
93
99
  end
94
-
100
+
95
101
  it "should init without raising" do
96
102
  lambda { Subclassed.new }.should_not raise_error
97
103
  lambda { Subclassed.new(:first_name => 'Michael') }.should_not raise_error
98
104
  end
99
-
105
+
100
106
  it "should share defaults from DashTest" do
101
107
  Subclassed.new.count.should == 0
102
108
  end
103
- end
109
+ end
@@ -24,6 +24,13 @@ describe Hashie::Mash do
24
24
  @mash.test = "abc"
25
25
  @mash.test?.should be_true
26
26
  end
27
+
28
+ it "should return false on a ? method if a value has been set to nil or false" do
29
+ @mash.test = nil
30
+ @mash.should_not be_test
31
+ @mash.test = false
32
+ @mash.should_not be_test
33
+ end
27
34
 
28
35
  it "should make all [] and []= into strings for consistency" do
29
36
  @mash["abc"] = 123
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hashie::Trash do
4
+ class TrashTest < Hashie::Trash
5
+ property :first_name, :from => :firstName
6
+ end
7
+
8
+ let(:trash) { TrashTest.new }
9
+
10
+ describe 'translating properties' do
11
+ it 'adds the property to the list' do
12
+ TrashTest.property :not_an_att, :from => :notAnAtt
13
+ TrashTest.properties.should include('not_an_att')
14
+ end
15
+
16
+ it 'creates a method for reading the property' do
17
+ trash.should respond_to(:first_name)
18
+ end
19
+
20
+ it 'creates a method for writing the property' do
21
+ trash.should respond_to(:first_name=)
22
+ end
23
+
24
+ it 'creates a method for writing the translated property' do
25
+ trash.should respond_to(:firstName=)
26
+ end
27
+
28
+ it 'does not create a method for reading the translated property' do
29
+ trash.should_not respond_to(:firstName)
30
+ end
31
+ end
32
+
33
+ describe 'writing to properties' do
34
+
35
+ it 'does not write to a non-existent property using []=' do
36
+ lambda{trash['abc'] = 123}.should raise_error(NoMethodError)
37
+ end
38
+
39
+ it 'writes to an existing property using []=' do
40
+ lambda{trash['first_name'] = 'Bob'}.should_not raise_error
41
+ end
42
+
43
+ it 'writes to a translated property using []=' do
44
+ lambda{trash['firstName'] = 'Bob'}.should_not raise_error
45
+ end
46
+
47
+ it 'reads/writes to an existing property using a method call' do
48
+ trash.first_name = 'Franklin'
49
+ trash.first_name.should == 'Franklin'
50
+ end
51
+
52
+ it 'writes to an translated property using a method call' do
53
+ trash.firstName = 'Franklin'
54
+ trash.first_name.should == 'Franklin'
55
+ end
56
+ end
57
+
58
+ describe ' initializing with a Hash' do
59
+ it 'does not initialize non-existent properties' do
60
+ lambda{TrashTest.new(:bork => 'abc')}.should raise_error(NoMethodError)
61
+ end
62
+
63
+ it 'sets the desired properties' do
64
+ TrashTest.new(:first_name => 'Michael').first_name.should == 'Michael'
65
+ end
66
+
67
+ it 'sets the translated properties' do
68
+ TrashTest.new(:firstName => 'Michael').first_name.should == 'Michael'
69
+ end
70
+ end
71
+ end
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 2
10
- version: 0.2.2
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Michael Bleigh
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-28 00:00:00 -05:00
18
+ date: 2010-08-10 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -57,10 +57,12 @@ files:
57
57
  - lib/hashie/hash.rb
58
58
  - lib/hashie/hash_extensions.rb
59
59
  - lib/hashie/mash.rb
60
+ - lib/hashie/trash.rb
60
61
  - spec/hashie/clash_spec.rb
61
62
  - spec/hashie/dash_spec.rb
62
63
  - spec/hashie/hash_spec.rb
63
64
  - spec/hashie/mash_spec.rb
65
+ - spec/hashie/trash_spec.rb
64
66
  - spec/spec.opts
65
67
  - spec/spec_helper.rb
66
68
  has_rdoc: true
@@ -102,4 +104,5 @@ test_files:
102
104
  - spec/hashie/dash_spec.rb
103
105
  - spec/hashie/hash_spec.rb
104
106
  - spec/hashie/mash_spec.rb
107
+ - spec/hashie/trash_spec.rb
105
108
  - spec/spec_helper.rb