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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64a3fdc5e88962936613bf54a490e1b04342d083a5be7818045036c607fbb5fd
4
- data.tar.gz: 6bb051df21c2809e9ee3596d5f9cb571111032876c3480e07691a0fb44ad610c
3
+ metadata.gz: 8b64e7bb0ef88ead17af2b5d1bca5ea4dc3a19c566a441ee8fe519afe7ac47c3
4
+ data.tar.gz: 4dedaf9317e816780dc86427b99a2b070a1ec46da22ca56446e8ceb120ba615a
5
5
  SHA512:
6
- metadata.gz: 4dc8c01c9763ddb8ed545cb3a45357c2de743f83e9cc002e5cc52329bf2909e8de4ee38255bebd6a87e09f811d20244c16fff49d63b2e40f53b9ef73faf33639
7
- data.tar.gz: fc24b0ce11427a6fece8911e9fa1021ab5bfb5b1edd63b1ac699cd1866c3919903d97f04652bbd432b8b645e08a3cc674fddf1c3e02fc55263ac0761b2a5ccbd
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
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in {gemname}.gemspec
4
4
  gemspec
5
+
6
+ gem "rubocop", "~> 0.87.1"
data/Makefile CHANGED
@@ -1,7 +1,11 @@
1
1
  default: test
2
2
 
3
+ .PHONY: test
4
+
3
5
  test:
4
- ruby lib/simple/immutable.rb
6
+ ruby test/immutable_test.rb
7
+ ruby test/immutable_w_null_record_test.rb
8
+ bin/rubocop
5
9
 
6
10
  release:
7
11
  scripts/release.rb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.2
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")
@@ -1 +1,3 @@
1
- require "simple/immutable"
1
+ # rubocop:disable Naming/FileName
2
+
3
+ require_relative "simple/immutable"
@@ -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 = 5)
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
- begin
31
- value = @hsh.fetch(sym.to_sym) { @hsh.fetch(sym.to_s) }
32
- return SELF.create(value)
33
- rescue KeyError
34
- # STDERR.puts "Missing attribute #{sym} for Immutable w/#{@hsh.inspect}"
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.2
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: 2020-03-03 00:00:00.000000000 Z
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.0.6
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