hash_with_struct_access 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ Gemfile.lock
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source("http://rubygems.org")
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Kostiantyn Kahanskyi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ Hash object with struct access.
2
+ Main purpose is to be a configuration object.
3
+
4
+ *Warning*: It can't be modified after initialization.
5
+
6
+ ```ruby
7
+ # Simple example
8
+ hash = HashWithStructAccess.new(:foo => {:bar => 42})
9
+ hash.foo #=> {:bar => 42}
10
+ hash.foo.bar #=> 42
11
+
12
+ # More complex example
13
+ hash = HashWithStructAccess.new(:foo => {(o = Object.new) => {"bar" => {1 => :baz}}})
14
+ hash.foo #=> {o => {"bar" => {1 => :baz}}}
15
+ hash.foo[o] #=> {"bar" => {1 => :baz}}
16
+ hash.foo[o].bar #=> {1 => :baz}
17
+ hash.foo[o].bar[1] #=> :baz
18
+ ```
19
+
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.test_files = FileList["test/*.rb"]
8
+ t.verbose = true
9
+ end
10
+
11
+ task(:default => :test)
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path("../lib/hash_with_struct_access", __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "hash_with_struct_access"
7
+ gem.version = HashWithStructAccess::VERSION
8
+ gem.description = %q{Hash object with struct access}
9
+ gem.summary = %q{Hash object with struct access. Main purpose is to be a configuration object.}
10
+ gem.homepage = "https://github.com/kostia/hash_with_struct_access"
11
+ gem.authors = ["Kostiantyn Kahanskyi"]
12
+ gem.email = %w(kostiantyn.kahanskyi@googlemail.com)
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ gem.require_paths = %w(lib)
16
+ gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
17
+ gem.add_development_dependency("rake")
18
+ end
@@ -0,0 +1,14 @@
1
+ class HashWithStructAccess < Hash
2
+ VERSION = "0.0.1"
3
+
4
+ def initialize(hash = {})
5
+ hash.each_pair do |key, value|
6
+ self[key] = value.kind_of?(Hash) ? self.class.new(value) : value
7
+ end
8
+ self.freeze
9
+ end
10
+
11
+ def method_missing(method_name)
12
+ self[method_name] || self[method_name.to_s] || super
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class HashLike < Hash
2
+ def self.call_me_with_options(options)
3
+ options
4
+ end
5
+ end
@@ -0,0 +1,75 @@
1
+ require "./test/test_helper"
2
+
3
+
4
+ class HashWithStructAccessTest < Test::Unit::TestCase
5
+ def test_should_be_kind_of_hash
6
+ assert(HashWithStructAccess.new(:foo => :bar).kind_of?(Hash))
7
+ end
8
+
9
+ def test_should_be_initializable_by_hash_object
10
+ hash = HashWithStructAccess.new({:foo => {:bar => :baz}})
11
+ assert_equal(hash.to_hash, {:foo => {:bar => :baz}})
12
+ end
13
+
14
+ def test_should_be_initializable_by_options
15
+ hash = HashWithStructAccess.new(:foo => {:bar => :baz})
16
+ assert_equal(hash.to_hash, {:foo => {:bar => :baz}})
17
+ end
18
+
19
+ def test_should_be_initializable_with_hash_like_objects
20
+ hash_like = HashLike.new
21
+ hash_like[:foo] = {:bar => :baz}
22
+ hash = HashWithStructAccess.new(hash_like)
23
+ assert_equal(hash.to_hash, {:foo => {:bar => :baz}})
24
+ end
25
+
26
+ def test_should_be_initializable_with_nothing_given
27
+ hash = HashWithStructAccess.new
28
+ assert_equal(hash.keys, [])
29
+ assert_equal(hash.values, [])
30
+ end
31
+
32
+ def test_should_convert_to_hash_properly
33
+ o = Object.new
34
+ hash = {:foo => {1 => {o => "bar"}}}
35
+ assert_equal(HashWithStructAccess.new(hash).to_hash, hash)
36
+ end
37
+
38
+ def test_should_be_able_to_handle_numerical_keys
39
+ hash = HashWithStructAccess.new(:foo => {1 => {:bar => :baz}})
40
+ assert_equal(hash.foo[1].bar, :baz)
41
+ end
42
+
43
+ def test_should_be_able_to_hadle_object_keys
44
+ o1, o2 = Object.new, Object.new
45
+ hash = HashWithStructAccess.new(o1 => {:foo => {o2 => {:bar => :baz}}})
46
+ assert_equal(hash[o1].foo[o2].bar, :baz)
47
+ end
48
+
49
+ def test_should_behave_like_deep_struct
50
+ hash = HashWithStructAccess.new(:foo => {"bar" => {:baz => 42}})
51
+ assert_equal(hash.foo.bar.baz, 42)
52
+ end
53
+
54
+ def test_should_convert_subhashes_to_hashes_with_struct_access
55
+ hash = HashWithStructAccess.new(:foo => {"bar" => {:baz => 42}})
56
+ assert(hash.foo.kind_of?(HashWithStructAccess))
57
+ assert(hash.foo.bar.kind_of?(HashWithStructAccess))
58
+ end
59
+
60
+ # The main purpose of HashWithStructAccess is to be a configuration object,
61
+ # so it would be not such a good idea to modify a configuration object at the runtime.
62
+ def test_should_not_allow_modifications_after_initialization
63
+ hash = HashWithStructAccess.new(:foo => :bar)
64
+ begin
65
+ hash[:foo] = :baz
66
+ rescue RuntimeError => e
67
+ assert_equal(e.message, "can't modify frozen HashWithStructAccess")
68
+ end
69
+ end
70
+
71
+ def test_should_be_able_to_act_as_method_options
72
+ assert_equal(HashLike.call_me_with_options(HashWithStructAccess.new(:foo => {:bar => :baz})),
73
+ HashLike.call_me_with_options(:foo => {:bar => :baz}))
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ require "test/unit"
2
+
3
+
4
+ FileList["lib/*"].each { |f| load f }
5
+ FileList["test/fixtures/*"].each { |f| load f }
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hash_with_struct_access
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kostiantyn Kahanskyi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &70247841423260 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70247841423260
25
+ description: Hash object with struct access
26
+ email:
27
+ - kostiantyn.kahanskyi@googlemail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - .rbenv-version
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - hash_with_struct_access.gemspec
39
+ - lib/hash_with_struct_access.rb
40
+ - test/fixtures/hash_like.rb
41
+ - test/hash_with_struct_access_test.rb
42
+ - test/test_helper.rb
43
+ homepage: https://github.com/kostia/hash_with_struct_access
44
+ licenses: []
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.11
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Hash object with struct access. Main purpose is to be a configuration object.
67
+ test_files:
68
+ - test/fixtures/hash_like.rb
69
+ - test/hash_with_struct_access_test.rb
70
+ - test/test_helper.rb