msmg_public 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 81762cbf5c6a373790c9b3377ce5b1371e769f45
4
+ data.tar.gz: 5e05a3462ede5afc08a8e6ecd42162a2caf32f66
5
+ SHA512:
6
+ metadata.gz: 9f9f0219e41a521560b06a41de8a70eb43af9a7ccf9ccff6a0d938844010f1ad7471cb6327f29d479b3a0a4282e5fbfee18dd88e43b470af8882c1a6565f6f87
7
+ data.tar.gz: 0fd81f23a94643717688aec13815e3befdc8fa64aca41b2510cc5f0b992b4a66aa575b17b0fd29dc0dc543cf6644b05f2e13c1591c1494ba867fa6de833ecfec
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ *.gem
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ # Tests
2
+
3
+ require 'rake/testtask'
4
+ require 'rubocop/rake_task'
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs |= %w[
8
+ test
9
+ lib
10
+ ]
11
+ t.test_files = FileList['test/unit/**/test_*.rb']
12
+ end
13
+
14
+ RuboCop::RakeTask.new(:rubocop) do |t|
15
+ t.fail_on_error = true
16
+ end
17
+
18
+ task default: %i[test rubocop]
@@ -0,0 +1,43 @@
1
+ # Allow simple definitions for object comparisons
2
+ module ComparableByAttr
3
+ include Comparable
4
+
5
+ # rubocop:disable Metrics/MethodLength class_eval wrapper
6
+ def self.included(klass)
7
+ klass.class_eval do
8
+ @__attr_precedence = nil
9
+
10
+ # attr_compare allows selection of specific instance variables and order
11
+ # to use within the comparison of objects created off the class
12
+ #
13
+ # Example:
14
+ # class IgnoreC
15
+ # include ComparableByAttr
16
+ # attr_compare :a, :b
17
+ #
18
+ # def initialize(a, b, c)
19
+ # @a = a
20
+ # @b = b
21
+ # @c = c
22
+ # end
23
+ # end
24
+ #
25
+ # Arguments:
26
+ # *prec = (Optional Precedence Map)
27
+ def self.attr_compare(*prec)
28
+ attr_prec = prec.map do |attr|
29
+ "@#{attr}".to_sym
30
+ end
31
+ @__attr_precedence = attr_prec
32
+ end
33
+
34
+ def <=>(other)
35
+ prec = self.class.instance_variable_get(:@__attr_precedence)
36
+ comp_order = prec || instance_variables.sort
37
+ this = comp_order.map { |field| instance_variable_get(field) }
38
+ that = comp_order.map { |field| other.instance_variable_get(field) }
39
+ this <=> that
40
+ end
41
+ end
42
+ end
43
+ end
data/lib/dig.rb ADDED
@@ -0,0 +1,21 @@
1
+ # Hash/Array #dig backport from Ruby 2.3.0
2
+ # Dig method is common to Array and Hash
3
+ [[], {}].each do |obj|
4
+ next if obj.respond_to?(:dig)
5
+ obj.class.class_eval do
6
+ # dig for values in Array/Hash
7
+ #
8
+ # Example:
9
+ # g = { foo: [10, 11, 12] }
10
+ # g.dig(:foo, 1) #=> 11
11
+ #
12
+ # Arguments:
13
+ # *keys: (Accessor List)
14
+ def dig(*keys)
15
+ elem = self[keys.shift]
16
+ return elem if keys.empty? || elem.nil?
17
+ return elem.dig(*keys) if elem.respond_to?(:dig)
18
+ raise TypeError, "#{elem.class} does not have a #dig method"
19
+ end
20
+ end
21
+ end
data/lib/to_hash.rb ADDED
@@ -0,0 +1,46 @@
1
+ # Generic ToHash mixin
2
+ module ToHash
3
+ # to_hash generic implementation, generates a hash from object Mixing in this
4
+ # module from instance variables of the object
5
+ #
6
+ # Example:
7
+ # class Foo
8
+ # include ToHash
9
+ # def initialize
10
+ # @a = 1
11
+ # @b = 2
12
+ # @c = 3
13
+ # end
14
+ # end
15
+ #
16
+ # Foo.new.to_hash #=> { :a => 1, :b => 2, :c => 3}
17
+ # Foo.new.to_hash(:c, 'a') #=> { 'a' => 1, :c => 3 }
18
+ #
19
+ # Arguments:
20
+ # *keys: (Optional key list)
21
+ def to_hash(*keys)
22
+ keys = keys.any? ? __named_map(keys) : __instance_map
23
+ keys = keys.map do |key, val|
24
+ [key, instance_variable_get(val)]
25
+ end
26
+ Hash[keys]
27
+ end
28
+
29
+ private
30
+
31
+ def __named_map(keys)
32
+ keys = keys.map do |key|
33
+ [key, "@#{key}".to_sym]
34
+ end
35
+ Hash[keys]
36
+ end
37
+
38
+ def __instance_map
39
+ keys = instance_variables.map do |var|
40
+ # Eliminate @ in naming key
41
+ key = var.to_s.delete('@').to_sym
42
+ [key, var]
43
+ end
44
+ Hash[keys]
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ class << $LOAD_PATH
2
+ def merge!(other)
3
+ replace(self | other)
4
+ end
5
+ end
6
+
7
+ $LOAD_PATH.merge! [File.expand_path('../lib', __FILE__)]
8
+
9
+ Gem::Specification.new do |spec|
10
+ raise 'RubyGems 2.0 or newer is required.' unless spec.respond_to?(:metadata)
11
+ spec.name = 'msmg_public'
12
+ spec.version = '0.1.0'
13
+ spec.authors = ['Andrew Smith']
14
+ spec.email = ['andrew.smith at moneysupermarket.com']
15
+
16
+ spec.summary = 'Various Ruby Sources'
17
+ spec.description = 'MSM pubicly available Ruby'
18
+ # spec.homepage = ''
19
+ spec.license = 'Apache-2.0'
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ end
data/readme.md ADDED
@@ -0,0 +1,78 @@
1
+ # Generic mixins
2
+
3
+ Released by MSM DevOps group under Apache 2.0 license
4
+
5
+ ## ToHash
6
+
7
+ Add a to_hash method to any class that will produce a hash from all instance variables or that can be called with a parameter set of instance variables in string or symbol form.
8
+ By default the keys produced are symbols but when called with parameters it will use the parameter form passed for the keys (which can be mixed symbols and strings).
9
+ In order to make an alternate default of to_hash with a specific set of attributes one may consider implementing to_hash can calling a super method to pass the params i.e.
10
+
11
+ class Foo
12
+ include ToHash
13
+
14
+ def initialize
15
+ @foo = 1
16
+ @bar = 2
17
+ @boo = 3
18
+ end
19
+
20
+ def to_hash
21
+ super(:foo, 'bar')
22
+ end
23
+ end
24
+
25
+ Foo.new.to_hash == {
26
+ :foo => 1,
27
+ 'bar' => 2
28
+ }
29
+
30
+ ## ComparableByAttr
31
+
32
+
33
+ Adds a default behaviour for <=> based upon instance variables within the class and includes Comparable to produce other comparison operators.
34
+ Instance variables by default are enumerated, sorted and stored in an array and the arrays are compared with their own l to r behaviour.
35
+ One may override the instance variables used in the comparison and the order by specifying an attr_compare override in the class definition.
36
+
37
+ # instances will be comparable by [@a, @b, @c]
38
+ class Bar
39
+ include ComparableByAttr
40
+
41
+ def initialize(a, b, c)
42
+ @a = a
43
+ @b = b
44
+ @c = c
45
+ end
46
+ end
47
+
48
+ # instances will be comparable by [@c, @a]
49
+ class Bar
50
+ include ComparableByAttr
51
+ attr_compare :c, :a
52
+
53
+ def initialize(a, b, c)
54
+ @a = a
55
+ @b = b
56
+ @c = c
57
+ end
58
+ end
59
+
60
+ ## dig
61
+
62
+ A backport of the Ruby 2.3.0 dig instance method for Hash and Array written in Ruby.
63
+
64
+ Since this code aims not to introduce unnecessary modules into the namespace and is targetted at extending Hash and Array directly it is not implemented as a Mixin but rather extends those classes directly using class_eval.
65
+
66
+ The Ruby module aims for compatibility based upon the specification stated in the C library comments (which are recorded within the unit test for convenience).
67
+
68
+ Documentation from Ruby 2.3.0 states..
69
+
70
+ Extracts the nested value specified by the sequence of idx objects by calling dig at each step, returning nil if any intermediate step is nil.
71
+
72
+ h = { foo: {bar: {baz: 1}}}
73
+
74
+ h.dig(:foo, :bar, :baz) #=> 1
75
+ h.dig(:foo, :zot, :xyz) #=> nil
76
+
77
+ g = { foo: [10, 11, 12] }
78
+ g.dig(:foo, 1) #=> 11
@@ -0,0 +1,7 @@
1
+ require 'simplecov'
2
+ SimpleCov.command_name 'test:unit'
3
+ SimpleCov.start do
4
+ add_group 'Libs', 'lib/'
5
+ track_files 'lib/*.rb'
6
+ add_filter '/test/'
7
+ end
@@ -0,0 +1,63 @@
1
+ # Test classes
2
+
3
+ require 'comparable_by_attr'
4
+
5
+ # Test class
6
+ class APrecB
7
+ include ComparableByAttr
8
+
9
+ def initialize(a, b)
10
+ @a = a
11
+ @b = b
12
+ end
13
+ end
14
+
15
+ # Test class
16
+ class BPrecA
17
+ include ComparableByAttr
18
+ attr_compare :b, :a
19
+
20
+ def initialize(a, b)
21
+ @a = a
22
+ @b = b
23
+ end
24
+ end
25
+
26
+ # Test class
27
+ class IgnoreC
28
+ include ComparableByAttr
29
+ attr_compare :a, :b
30
+
31
+ def initialize(a, b, c)
32
+ @a = a
33
+ @b = b
34
+ @c = c
35
+ end
36
+ end
37
+
38
+ # Unit Test
39
+ require 'minitest/autorun'
40
+
41
+ # rubocop:disable Lint/UselessComparison Unit Test
42
+ # Unit test
43
+ class TestComparableByAttr < Minitest::Test
44
+ def test_a_gt_b_aprecb
45
+ assert(APrecB.new(2, 1) > APrecB.new(1, 2))
46
+ end
47
+
48
+ def test_a_lt_b_aprecb
49
+ assert(APrecB.new(1, 2) < APrecB.new(2, 1))
50
+ end
51
+
52
+ def test_a_n_gt_b_aprecb
53
+ refute(APrecB.new(1, 2) > APrecB.new(1, 2))
54
+ end
55
+
56
+ def test_a_gt_b_bpreca
57
+ assert(BPrecA.new(1, 2) > BPrecA.new(2, 1))
58
+ end
59
+
60
+ def test_a_eq_b_ignorec
61
+ assert(IgnoreC.new(1, 1, 2) == IgnoreC.new(1, 1, 2))
62
+ end
63
+ end
@@ -0,0 +1,54 @@
1
+ # Unit test for #dig
2
+
3
+ # Contract from hash.c in Ruby 2.3.0 and later..
4
+ # rubocop:disable Metrics/LineLength original documentation
5
+ # /*
6
+ # * call-seq:
7
+ # * hsh.dig(key, ...) -> object
8
+ # *
9
+ # * Extracts the nested value specified by the sequence of <i>key</i>
10
+ # * objects by calling +dig+ at each step, returning +nil+ if any
11
+ # * intermediate step is +nil+.
12
+ # *
13
+ # * h = { foo: {bar: {baz: 1}}}
14
+ # *
15
+ # * h.dig(:foo, :bar, :baz) #=> 1
16
+ # * h.dig(:foo, :zot, :xyz) #=> nil
17
+ # *
18
+ # * g = { foo: [10, 11, 12] }
19
+ # * g.dig(:foo, 1) #=> 11
20
+ # * g.dig(:foo, 1, 0) #=> TypeError: Integer does not have #dig method
21
+ # * g.dig(:foo, :bar) #=> TypeError: no implicit conversion of Symbol into Integer
22
+ # */
23
+ # rubocop:enable all
24
+
25
+ require 'minitest/autorun'
26
+ require 'dig'
27
+
28
+ # Unit Test
29
+ class TestDig < Minitest::Test
30
+ def setup
31
+ @h = { foo: { bar: { baz: 1 } } }
32
+ @g = { foo: [10, 11, 12] }
33
+ end
34
+
35
+ def test_hash_hash_hash
36
+ assert_equal(1, @h.dig(:foo, :bar, :baz))
37
+ end
38
+
39
+ def test_hash_miss_miss
40
+ assert_nil(@h.dig(:foo, :zot, :xyz))
41
+ end
42
+
43
+ def test_hash_array_fixnum_typerror
44
+ assert_raises(TypeError) do
45
+ @g.dig(:foo, 1, 0)
46
+ end
47
+ end
48
+
49
+ def test_hash_array_symbol_typerror
50
+ assert_raises(TypeError) do
51
+ @g.dig(:foo, :bar)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,46 @@
1
+ # Test Classes
2
+ require 'to_hash'
3
+
4
+ # Test Class
5
+ class TestClass
6
+ include ToHash
7
+
8
+ def initialize
9
+ @foo = 1
10
+ @bar = 2
11
+ @moo = 'three'
12
+ end
13
+ end
14
+
15
+ require 'minitest/autorun'
16
+
17
+ # Unit test
18
+ class TestToHash < Minitest::Test
19
+ def test_no_param
20
+ expected = {
21
+ foo: 1,
22
+ bar: 2,
23
+ moo: 'three'
24
+ }
25
+ assert_equal expected, TestClass.new.to_hash
26
+ end
27
+
28
+ def test_limited_text
29
+ expected = {
30
+ 'foo' => 1,
31
+ 'moo' => 'three'
32
+ }
33
+ assert_equal expected, TestClass.new.to_hash('foo', 'moo')
34
+ end
35
+
36
+ # Of course with hash ordering is not important and neith should be
37
+ # the order provided to the parameterisation
38
+ def test_mixed_keys
39
+ expected = {
40
+ 'moo' => 'three',
41
+ foo: 1,
42
+ bar: 2
43
+ }
44
+ assert_equal expected, TestClass.new.to_hash(:foo, 'moo', :bar)
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: msmg_public
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-01-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: MSM pubicly available Ruby
14
+ email:
15
+ - andrew.smith at moneysupermarket.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - Rakefile
22
+ - lib/comparable_by_attr.rb
23
+ - lib/dig.rb
24
+ - lib/to_hash.rb
25
+ - msmg_public.gemspec
26
+ - readme.md
27
+ - test/test_helper.rb
28
+ - test/unit/test_comparable_by_attr.rb
29
+ - test/unit/test_dig.rb
30
+ - test/unit/test_to_hash.rb
31
+ homepage:
32
+ licenses:
33
+ - Apache-2.0
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 2.2.5
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Various Ruby Sources
55
+ test_files: []