simple-immutable 1.0.2 → 1.0.6
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +35 -0
- data/Gemfile +2 -0
- data/Makefile +5 -1
- data/VERSION +1 -1
- data/bin/rubocop +29 -0
- data/lib/simple-immutable.rb +3 -1
- data/lib/simple/immutable.rb +50 -98
- data/test/immutable_test.rb +93 -0
- data/test/immutable_w_null_record_test.rb +63 -0
- metadata +13 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b64e7bb0ef88ead17af2b5d1bca5ea4dc3a19c566a441ee8fe519afe7ac47c3
|
4
|
+
data.tar.gz: 4dedaf9317e816780dc86427b99a2b070a1ec46da22ca56446e8ceb120ba615a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0029d88bfa9788f39948eacc0707af394d2702b31800ec86ef83e76f9e1b4dbeb672ce619877a5f0e9f09da93b9b1edcdf3a0dc471c84b73fd1fd8415f168a6e'
|
7
|
+
data.tar.gz: abd71b228155f72f7953868cd445722c013b3ce9067d9ecc2075cd5c518a12905a0cd3ed768d7adec505291b53f6f383ce0fc6b63e2b1181ff0887f2fdf7c09c
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- bin/**/*
|
4
|
+
- test/**/*
|
5
|
+
- scripts/**/*
|
6
|
+
- ./*.gemspec
|
7
|
+
- Gemfile
|
8
|
+
NewCops: enable
|
9
|
+
|
10
|
+
Style/StringLiterals:
|
11
|
+
EnforcedStyle: double_quotes
|
12
|
+
|
13
|
+
Style/Documentation:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/FrozenStringLiteralComment:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Lint/MissingCopEnableDirective:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/ClassAndModuleChildren:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Style/NumericPredicate:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Metrics/MethodLength:
|
32
|
+
Max: 20
|
33
|
+
|
34
|
+
Lint/IneffectiveAccessModifier:
|
35
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/Makefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.6
|
data/bin/rubocop
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/lib/simple-immutable.rb
CHANGED
data/lib/simple/immutable.rb
CHANGED
@@ -6,34 +6,73 @@ class Simple::Immutable
|
|
6
6
|
|
7
7
|
# turns an object, which can be a hash or array of hashes, arrays, and scalars
|
8
8
|
# into an object which you can use to access with dot methods.
|
9
|
-
def self.create(object, max_depth
|
9
|
+
def self.create(object, max_depth: 8, null_record: nil)
|
10
10
|
case object
|
11
11
|
when Array
|
12
12
|
raise ArgumentError, "Object nested too deep (or inner loop?)" if max_depth < 0
|
13
13
|
|
14
|
-
object.map { |obj| create obj, max_depth - 1 }
|
14
|
+
object.map { |obj| create obj, null_record: null_record, max_depth: max_depth - 1 }
|
15
15
|
when Hash
|
16
|
-
new(object)
|
16
|
+
new(object, null_record)
|
17
17
|
else
|
18
18
|
object
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
def self.raw_data(immutable)
|
23
|
+
case immutable
|
24
|
+
when SELF
|
25
|
+
hsh = immutable.instance_variable_get :@hsh
|
26
|
+
null_record = immutable.instance_variable_get :@null_record
|
27
|
+
|
28
|
+
if null_record
|
29
|
+
null_record.merge(hsh)
|
30
|
+
else
|
31
|
+
hsh
|
32
|
+
end
|
33
|
+
when Array
|
34
|
+
immutable.map { |e| raw_data(e) }
|
35
|
+
else
|
36
|
+
immutable
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# adds to_json support.
|
41
|
+
def as_json(opts)
|
42
|
+
@hsh.as_json(opts)
|
43
|
+
end
|
44
|
+
|
22
45
|
private
|
23
46
|
|
24
|
-
def initialize(hsh)
|
47
|
+
def initialize(hsh, null_record = nil)
|
25
48
|
@hsh = hsh
|
49
|
+
@null_record = null_record
|
50
|
+
end
|
51
|
+
|
52
|
+
# rubycop:disable Lint/IneffectiveAccessModifier
|
53
|
+
|
54
|
+
# fetches key from a hsh, regardless of it being a Symbol or a String.
|
55
|
+
# Yields the block if the key cannot be found.
|
56
|
+
def self.fetch_symbol_or_string_from_hash(hsh, key, &block)
|
57
|
+
if hsh
|
58
|
+
hsh.fetch(key.to_sym) do
|
59
|
+
hsh.fetch(key.to_s, &block)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
yield
|
63
|
+
end
|
26
64
|
end
|
27
65
|
|
28
66
|
def method_missing(sym, *args, &block)
|
29
67
|
if args.empty? && !block
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
nil
|
68
|
+
value = SELF.fetch_symbol_or_string_from_hash(@hsh, sym) do
|
69
|
+
SELF.fetch_symbol_or_string_from_hash(@null_record, sym) do
|
70
|
+
# STDERR.puts "Missing attribute #{sym} for Immutable w/#{@hsh.inspect}"
|
71
|
+
super
|
72
|
+
end
|
36
73
|
end
|
74
|
+
|
75
|
+
return SELF.create(value)
|
37
76
|
end
|
38
77
|
|
39
78
|
super
|
@@ -51,7 +90,7 @@ class Simple::Immutable
|
|
51
90
|
super
|
52
91
|
end
|
53
92
|
|
54
|
-
def respond_to?(sym)
|
93
|
+
def respond_to?(sym, include_all = false)
|
55
94
|
super || @hsh.key?(sym.to_s) || @hsh.key?(sym.to_sym)
|
56
95
|
end
|
57
96
|
|
@@ -59,90 +98,3 @@ class Simple::Immutable
|
|
59
98
|
@hsh == other
|
60
99
|
end
|
61
100
|
end
|
62
|
-
|
63
|
-
if $PROGRAM_NAME == __FILE__
|
64
|
-
|
65
|
-
# rubocop:disable Metrics/AbcSize
|
66
|
-
|
67
|
-
require "test-unit"
|
68
|
-
|
69
|
-
class Simple::Immutable::TestCase < Test::Unit::TestCase
|
70
|
-
Immutable = ::Simple::Immutable
|
71
|
-
|
72
|
-
def hsh
|
73
|
-
{
|
74
|
-
a: "a-value",
|
75
|
-
"b": "b-value",
|
76
|
-
"child": {
|
77
|
-
name: "childname",
|
78
|
-
grandchild: {
|
79
|
-
name: "grandchildname"
|
80
|
-
}
|
81
|
-
},
|
82
|
-
"children": [
|
83
|
-
"anna",
|
84
|
-
"arthur",
|
85
|
-
{
|
86
|
-
action: {
|
87
|
-
keep_your_mouth_shut: true
|
88
|
-
}
|
89
|
-
}
|
90
|
-
]
|
91
|
-
}
|
92
|
-
end
|
93
|
-
|
94
|
-
def immutable
|
95
|
-
Immutable.create hsh
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_hash_access
|
99
|
-
assert_equal "a-value", immutable.a
|
100
|
-
assert_equal "b-value", immutable.b
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_comparison
|
104
|
-
immutable = Immutable.create hsh
|
105
|
-
|
106
|
-
assert_equal immutable, hsh
|
107
|
-
assert_not_equal({}, immutable)
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_child_access
|
111
|
-
child = immutable.child
|
112
|
-
assert_kind_of(Immutable, child)
|
113
|
-
assert_equal "childname", immutable.child.name
|
114
|
-
assert_equal "grandchildname", immutable.child.grandchild.name
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_array_access
|
118
|
-
assert_kind_of(Array, immutable.children)
|
119
|
-
assert_equal 3, immutable.children.length
|
120
|
-
assert_equal "anna", immutable.children[0]
|
121
|
-
|
122
|
-
assert_kind_of(Immutable, immutable.children[2])
|
123
|
-
assert_equal true, immutable.children[2].action.keep_your_mouth_shut
|
124
|
-
end
|
125
|
-
|
126
|
-
def test_base_class
|
127
|
-
assert_nothing_raised do
|
128
|
-
immutable.object_id
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def test_missing_keys
|
133
|
-
assert_raise(NoMethodError) do
|
134
|
-
immutable.foo
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def test_skip_when_args_or_block
|
139
|
-
assert_raise(NoMethodError) do
|
140
|
-
immutable.a(1, 2, 3)
|
141
|
-
end
|
142
|
-
assert_raise(NoMethodError) do
|
143
|
-
immutable.a { :dummy }
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# rubocop:disable Metrics/AbcSize
|
2
|
+
|
3
|
+
require "test-unit"
|
4
|
+
require_relative "../lib/simple-immutable"
|
5
|
+
|
6
|
+
class Simple::Immutable::TestCase < Test::Unit::TestCase
|
7
|
+
Immutable = ::Simple::Immutable
|
8
|
+
|
9
|
+
def hsh
|
10
|
+
{
|
11
|
+
a: "a-value",
|
12
|
+
"b": "b-value",
|
13
|
+
"child": {
|
14
|
+
name: "childname",
|
15
|
+
grandchild: {
|
16
|
+
name: "grandchildname"
|
17
|
+
}
|
18
|
+
},
|
19
|
+
"children": [
|
20
|
+
"anna",
|
21
|
+
"arthur",
|
22
|
+
{
|
23
|
+
action: {
|
24
|
+
keep_your_mouth_shut: true
|
25
|
+
}
|
26
|
+
}
|
27
|
+
]
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def immutable
|
32
|
+
Immutable.create hsh
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_hash_access
|
36
|
+
assert_equal "a-value", immutable.a
|
37
|
+
assert_equal "b-value", immutable.b
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_comparison
|
41
|
+
immutable = Immutable.create hsh
|
42
|
+
|
43
|
+
assert_equal immutable, hsh
|
44
|
+
assert_not_equal({}, immutable)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_child_access
|
48
|
+
child = immutable.child
|
49
|
+
assert_kind_of(Immutable, child)
|
50
|
+
assert_equal "childname", immutable.child.name
|
51
|
+
assert_equal "grandchildname", immutable.child.grandchild.name
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_array_access
|
55
|
+
assert_kind_of(Array, immutable.children)
|
56
|
+
assert_equal 3, immutable.children.length
|
57
|
+
assert_equal "anna", immutable.children[0]
|
58
|
+
|
59
|
+
assert_kind_of(Immutable, immutable.children[2])
|
60
|
+
assert_equal true, immutable.children[2].action.keep_your_mouth_shut
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_base_class
|
64
|
+
assert_nothing_raised do
|
65
|
+
immutable.object_id
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_missing_keys
|
70
|
+
assert_raise(NoMethodError) do
|
71
|
+
immutable.foo
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_skip_when_args_or_block
|
76
|
+
# raise NoMethodError when called with arguments
|
77
|
+
assert_raise(NoMethodError) do
|
78
|
+
immutable.a(1, 2, 3)
|
79
|
+
end
|
80
|
+
|
81
|
+
# raise NoMethodError when called with a block argument
|
82
|
+
assert_raise(NoMethodError) do
|
83
|
+
immutable.a { :dummy }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_raw_data
|
88
|
+
expected = hsh
|
89
|
+
|
90
|
+
assert_equal(expected, Immutable.raw_data(immutable))
|
91
|
+
assert_equal(expected[:children], Immutable.raw_data(immutable.children))
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# rubocop:disable Metrics/AbcSize
|
2
|
+
|
3
|
+
require "test-unit"
|
4
|
+
require_relative "../lib/simple-immutable"
|
5
|
+
|
6
|
+
class Simple::Immutable::WithNullRecordTestCase < Test::Unit::TestCase
|
7
|
+
Immutable = ::Simple::Immutable
|
8
|
+
|
9
|
+
def hsh
|
10
|
+
{
|
11
|
+
a: "a-value",
|
12
|
+
"b": "b-value",
|
13
|
+
"child": {
|
14
|
+
name: "childname",
|
15
|
+
grandchild: {
|
16
|
+
name: "grandchildname"
|
17
|
+
}
|
18
|
+
},
|
19
|
+
"children": [
|
20
|
+
"anna",
|
21
|
+
"arthur",
|
22
|
+
{
|
23
|
+
action: {
|
24
|
+
keep_your_mouth_shut: true
|
25
|
+
}
|
26
|
+
}
|
27
|
+
]
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def null_record
|
32
|
+
{
|
33
|
+
foo: "foo-value",
|
34
|
+
"bar" => "bar-value"
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def immutable
|
39
|
+
Immutable.create hsh, null_record: null_record
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_hash_access
|
43
|
+
assert_equal "a-value", immutable.a
|
44
|
+
assert_equal "b-value", immutable.b
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_null_record_access
|
48
|
+
assert_equal "foo-value", immutable.foo
|
49
|
+
assert_equal "bar-value", immutable.bar
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_missing_keys
|
53
|
+
assert_raise(NoMethodError) do
|
54
|
+
immutable.unknown
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_raw_data
|
59
|
+
# raw data does contain null_record
|
60
|
+
expected = hsh.merge(null_record)
|
61
|
+
assert_equal(expected, Immutable.raw_data(immutable))
|
62
|
+
end
|
63
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-immutable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
8
8
|
- mediapeers GmbH
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-07-13 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Immutable ruby objects implementing dot and [] accessors.
|
15
15
|
email: eno@radiospiel.org
|
@@ -18,6 +18,7 @@ extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
20
|
- ".gitignore"
|
21
|
+
- ".rubocop.yml"
|
21
22
|
- ".tm_properties"
|
22
23
|
- Gemfile
|
23
24
|
- Makefile
|
@@ -25,15 +26,18 @@ files:
|
|
25
26
|
- VERSION
|
26
27
|
- bin/bundle
|
27
28
|
- bin/console
|
29
|
+
- bin/rubocop
|
28
30
|
- lib/simple-immutable.rb
|
29
31
|
- lib/simple/immutable.rb
|
30
32
|
- scripts/release
|
31
33
|
- scripts/release.rb
|
32
34
|
- simple-immutable.gemspec
|
35
|
+
- test/immutable_test.rb
|
36
|
+
- test/immutable_w_null_record_test.rb
|
33
37
|
homepage: http://github.com/radiospiel/simple-immutable
|
34
38
|
licenses: []
|
35
39
|
metadata: {}
|
36
|
-
post_install_message:
|
40
|
+
post_install_message:
|
37
41
|
rdoc_options: []
|
38
42
|
require_paths:
|
39
43
|
- lib
|
@@ -48,8 +52,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
52
|
- !ruby/object:Gem::Version
|
49
53
|
version: '0'
|
50
54
|
requirements: []
|
51
|
-
rubygems_version: 3.
|
52
|
-
signing_key:
|
55
|
+
rubygems_version: 3.1.4
|
56
|
+
signing_key:
|
53
57
|
specification_version: 4
|
54
58
|
summary: Immutable ruby objects
|
55
|
-
test_files:
|
59
|
+
test_files:
|
60
|
+
- test/immutable_test.rb
|
61
|
+
- test/immutable_w_null_record_test.rb
|