hashie 0.2.2 → 0.3.0

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