structure 1.1.1 → 1.2.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 +4 -4
- data/lib/structure.rb +30 -16
- data/lib/structure/class_methods.rb +27 -21
- data/lib/structure/double.rb +10 -9
- data/lib/structure/version.rb +1 -1
- metadata +2 -3
- data/lib/structure/utils.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b08d68f313a052ecf51e5ddae25a9c01b2fa97f4d62faffd0886036f2143569
|
4
|
+
data.tar.gz: '0330855f5dbce7826cbdc2c845e719c81e6b1e60e17fcf5bc3a58a496ffa2944'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c4bfbe6e6cbeaaf3440b71894f469e03b71eb272a570bd127923960eddec434750badd66d5258a79ee559b4c59f5be9141ab9595eb7f82b27108f5e26340751
|
7
|
+
data.tar.gz: 48fa29e4f97245598a2af38667e32b4bee11e87c65944c9570219fb764e0383a3d4bdaf5b71d403cde00f0e4dcff7bdb68f25566d2cb8f866b1f9c8ee1ae2913
|
data/lib/structure.rb
CHANGED
@@ -1,20 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'structure/class_methods'
|
4
|
-
require 'structure/utils'
|
5
4
|
|
6
5
|
module Structure
|
6
|
+
def self.inspect(value)
|
7
|
+
if value.is_a?(::Array)
|
8
|
+
inspection = value.take(3)
|
9
|
+
.map { |subvalue| inspect(subvalue) }
|
10
|
+
.join(', ')
|
11
|
+
inspection += '...' if value.size > 3
|
12
|
+
|
13
|
+
"[#{inspection}]"
|
14
|
+
else
|
15
|
+
value.inspect
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.serialize(value)
|
20
|
+
if value.respond_to?(:attributes)
|
21
|
+
value.attributes
|
22
|
+
elsif value.is_a?(::Array)
|
23
|
+
value.map { |subvalue| serialize(subvalue) }
|
24
|
+
else
|
25
|
+
value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
7
29
|
def self.included(base)
|
8
30
|
base.extend ClassMethods
|
9
|
-
base.__overwrite_initialize__
|
10
31
|
end
|
11
32
|
|
33
|
+
# Returns a hash of all the attributes with their names as keys and the
|
34
|
+
# values of the attributes as values
|
12
35
|
def attributes
|
13
36
|
attribute_names.each_with_object({}) do |key, hash|
|
14
|
-
hash[key] =
|
37
|
+
hash[key] = Structure.serialize(send(key))
|
15
38
|
end
|
16
39
|
end
|
17
40
|
|
41
|
+
# Returns an array of attribute names as strings
|
18
42
|
def attribute_names
|
19
43
|
self.class.attribute_names
|
20
44
|
end
|
@@ -27,19 +51,9 @@ module Structure
|
|
27
51
|
|
28
52
|
def inspect
|
29
53
|
name = self.class.name || self.class.to_s.gsub(/[^\w:]/, '')
|
30
|
-
values =
|
31
|
-
|
32
|
-
|
33
|
-
value = send(key)
|
34
|
-
if value.is_a?(::Array)
|
35
|
-
description = value.take(3).map(&:inspect).join(', ')
|
36
|
-
description += '...' if value.size > 3
|
37
|
-
"#{key}=[#{description}]"
|
38
|
-
else
|
39
|
-
"#{key}=#{value.inspect}"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
.join(', ')
|
54
|
+
values = attribute_names
|
55
|
+
.map { |key| "#{key}=#{Structure.inspect(send(key))}" }
|
56
|
+
.join(', ')
|
43
57
|
|
44
58
|
"#<#{name} #{values}>"
|
45
59
|
end
|
@@ -2,16 +2,19 @@
|
|
2
2
|
|
3
3
|
module Structure
|
4
4
|
module ClassMethods
|
5
|
+
# Returns an array of attribute names as strings
|
5
6
|
attr_reader :attribute_names
|
6
7
|
|
7
8
|
def self.extended(base)
|
8
9
|
base.instance_variable_set :@attribute_names, []
|
10
|
+
base.send :__overwrite_initialize
|
9
11
|
end
|
10
12
|
|
11
13
|
def attribute(name, &block)
|
12
14
|
name = name.to_s
|
13
15
|
|
14
|
-
if name.
|
16
|
+
if name.end_with?('?')
|
17
|
+
name = name.chop
|
15
18
|
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
16
19
|
def #{name}?
|
17
20
|
#{name}
|
@@ -21,48 +24,51 @@ module Structure
|
|
21
24
|
|
22
25
|
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
23
26
|
def #{name}
|
24
|
-
@
|
25
|
-
|
27
|
+
@__mutex.synchronize {
|
28
|
+
break if @__table.key?("#{name}")
|
26
29
|
|
27
|
-
|
28
|
-
|
30
|
+
@__table["#{name}"] = __#{name}
|
31
|
+
@__table["#{name}"].freeze
|
29
32
|
|
30
|
-
|
33
|
+
@__table["#{name}"]
|
31
34
|
}
|
35
|
+
|
36
|
+
@__table["#{name}"]
|
32
37
|
end
|
33
38
|
CODE
|
34
39
|
|
35
|
-
define_method "__#{name}
|
36
|
-
private "__#{name}
|
40
|
+
define_method "__#{name}", block
|
41
|
+
private "__#{name}"
|
37
42
|
|
38
43
|
@attribute_names << name
|
39
44
|
|
40
45
|
name.to_sym
|
41
46
|
end
|
42
47
|
|
43
|
-
|
48
|
+
private
|
49
|
+
|
50
|
+
def __overwrite_initialize
|
44
51
|
class_eval do
|
45
|
-
unless method_defined?(:
|
46
|
-
define_method :
|
47
|
-
@
|
48
|
-
|
52
|
+
unless method_defined?(:__custom_initialize)
|
53
|
+
define_method :__custom_initialize do |*arguments, &block|
|
54
|
+
@__mutex = ::Thread::Mutex.new
|
55
|
+
@__table = {}
|
56
|
+
__original_initialize(*arguments, &block)
|
57
|
+
freeze
|
49
58
|
end
|
50
59
|
end
|
51
60
|
|
52
61
|
return if instance_method(:initialize) ==
|
53
|
-
instance_method(:
|
62
|
+
instance_method(:__custom_initialize)
|
54
63
|
|
55
|
-
alias_method :
|
56
|
-
alias_method :initialize, :
|
64
|
+
alias_method :__original_initialize, :initialize
|
65
|
+
alias_method :initialize, :__custom_initialize
|
66
|
+
private :__custom_initialize, :__original_initialize
|
57
67
|
end
|
58
68
|
end
|
59
69
|
|
60
|
-
private
|
61
|
-
|
62
70
|
def method_added(name)
|
63
|
-
|
64
|
-
|
65
|
-
__overwrite_initialize__
|
71
|
+
__overwrite_initialize if name == :initialize
|
66
72
|
end
|
67
73
|
|
68
74
|
def inherited(subclass)
|
data/lib/structure/double.rb
CHANGED
@@ -2,31 +2,32 @@
|
|
2
2
|
|
3
3
|
module Structure
|
4
4
|
module ClassMethods
|
5
|
+
# Creates a double that mocks a value object built with Structure during a
|
6
|
+
# test
|
7
|
+
#
|
8
|
+
# The double has an alternative constructor that takes a hash to set values.
|
9
|
+
# Otherwise, it shares the public API of the mocked value object.
|
5
10
|
def double
|
6
11
|
klass = Class.new(self)
|
7
12
|
|
8
|
-
(
|
9
|
-
|
10
|
-
protected_instance_methods(false) -
|
11
|
-
[:initialize]
|
12
|
-
).each do |name|
|
13
|
+
(private_instance_methods(false) + protected_instance_methods(false) -
|
14
|
+
[:initialize]).each do |name|
|
13
15
|
klass.send :undef_method, name
|
14
16
|
end
|
15
17
|
|
16
18
|
klass.module_eval do
|
17
|
-
def initialize(
|
18
|
-
|
19
|
+
def initialize(values = {})
|
20
|
+
values.each do |key, value|
|
19
21
|
instance_variable_set :"@#{key}", value
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
attribute_names.each do |name|
|
24
26
|
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
25
|
-
def __#{name}
|
27
|
+
private def __#{name}
|
26
28
|
@#{name}
|
27
29
|
end
|
28
30
|
CODE
|
29
|
-
private "__#{name}__"
|
30
31
|
end
|
31
32
|
|
32
33
|
module_eval(&Proc.new) if block_given?
|
data/lib/structure/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: structure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hakan Ensari
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -19,7 +19,6 @@ files:
|
|
19
19
|
- lib/structure.rb
|
20
20
|
- lib/structure/class_methods.rb
|
21
21
|
- lib/structure/double.rb
|
22
|
-
- lib/structure/utils.rb
|
23
22
|
- lib/structure/version.rb
|
24
23
|
homepage:
|
25
24
|
licenses:
|
data/lib/structure/utils.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Structure
|
4
|
-
module Utils
|
5
|
-
def self.serialize(value)
|
6
|
-
if value.respond_to?(:attributes)
|
7
|
-
value.attributes
|
8
|
-
elsif value.is_a?(::Array)
|
9
|
-
value.map { |subvalue| serialize(subvalue) }
|
10
|
-
else
|
11
|
-
value
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|