nrser 0.0.25 → 0.0.26
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/README.md +39 -11
- data/lib/nrser.rb +5 -1
- data/lib/nrser/array.rb +10 -53
- data/lib/nrser/enumerable.rb +21 -0
- data/lib/nrser/hash.rb +13 -476
- data/lib/nrser/hash/bury.rb +154 -0
- data/lib/nrser/hash/deep_merge.rb +57 -0
- data/lib/nrser/hash/except_keys.rb +42 -0
- data/lib/nrser/hash/guess_label_key_type.rb +37 -0
- data/lib/nrser/hash/slice_keys.rb +41 -0
- data/lib/nrser/hash/stringify_keys.rb +37 -0
- data/lib/nrser/hash/symbolize_keys.rb +41 -0
- data/lib/nrser/hash/transform_keys.rb +45 -0
- data/lib/nrser/merge_by.rb +26 -0
- data/lib/nrser/message.rb +125 -0
- data/lib/nrser/meta/props.rb +2 -2
- data/lib/nrser/meta/props/prop.rb +5 -2
- data/lib/nrser/object.rb +5 -0
- data/lib/nrser/object/as_array.rb +37 -0
- data/lib/nrser/object/as_hash.rb +101 -0
- data/lib/nrser/{truthy.rb → object/truthy.rb} +0 -0
- data/lib/nrser/proc.rb +132 -0
- data/lib/nrser/refinements.rb +1 -2
- data/lib/nrser/refinements/array.rb +94 -5
- data/lib/nrser/refinements/enumerable.rb +5 -0
- data/lib/nrser/refinements/hash.rb +43 -6
- data/lib/nrser/refinements/object.rb +22 -2
- data/lib/nrser/refinements/symbol.rb +12 -0
- data/lib/nrser/refinements/tree.rb +41 -0
- data/lib/nrser/rspex.rb +329 -0
- data/lib/nrser/string.rb +3 -0
- data/lib/nrser/string/looks_like.rb +51 -0
- data/lib/nrser/temp/where.rb +52 -0
- data/lib/nrser/tree.rb +86 -0
- data/lib/nrser/tree/leaves.rb +92 -0
- data/lib/nrser/tree/map_leaves.rb +63 -0
- data/lib/nrser/tree/transform.rb +30 -0
- data/lib/nrser/types.rb +9 -4
- data/lib/nrser/types/any.rb +1 -1
- data/lib/nrser/types/array.rb +167 -25
- data/lib/nrser/types/{hash.rb → hashes.rb} +19 -5
- data/lib/nrser/types/in.rb +47 -0
- data/lib/nrser/types/is_a.rb +2 -2
- data/lib/nrser/types/labels.rb +49 -0
- data/lib/nrser/types/numbers.rb +63 -27
- data/lib/nrser/types/pairs.rb +109 -0
- data/lib/nrser/types/responds.rb +2 -3
- data/lib/nrser/types/strings.rb +17 -18
- data/lib/nrser/types/symbols.rb +39 -0
- data/lib/nrser/types/trees.rb +93 -0
- data/lib/nrser/types/tuples.rb +116 -0
- data/lib/nrser/types/type.rb +26 -2
- data/lib/nrser/version.rb +1 -1
- data/spec/nrser/hash/{guess_name_type_spec.rb → guess_label_key_type_spec.rb} +3 -3
- data/spec/nrser/hash_spec.rb +0 -20
- data/spec/nrser/merge_by_spec.rb +73 -0
- data/spec/nrser/meta/props_spec.rb +136 -43
- data/spec/nrser/op/message_spec.rb +62 -0
- data/spec/nrser/refinements/array_spec.rb +36 -0
- data/spec/nrser/refinements/hash_spec.rb +34 -0
- data/spec/nrser/string/looks_like_spec.rb +31 -0
- data/spec/nrser/tree/each_branch_spec.rb +82 -0
- data/spec/nrser/tree/leaves_spec.rb +112 -0
- data/spec/nrser/tree/transform_spec.rb +165 -0
- data/spec/nrser/types/array_spec.rb +82 -0
- data/spec/nrser/types/attrs_spec.rb +4 -4
- data/spec/nrser/types/pairs_spec.rb +41 -0
- data/spec/nrser/types/paths_spec.rb +3 -3
- data/spec/nrser/types/strings_spec.rb +66 -0
- data/spec/nrser/types/symbols_spec.rb +38 -0
- data/spec/nrser/types/tuples_spec.rb +37 -0
- data/spec/nrser/types_spec.rb +0 -13
- data/spec/spec_helper.rb +71 -22
- metadata +58 -10
- data/lib/nrser/spex.rb +0 -68
- data/lib/nrser/types/symbol.rb +0 -23
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'nrser/refinements'
|
2
|
+
require 'nrser/types/is'
|
3
|
+
require 'nrser/types/is_a'
|
4
|
+
|
5
|
+
require 'nrser/refinements'
|
6
|
+
using NRSER
|
7
|
+
|
8
|
+
module NRSER::Types
|
9
|
+
|
10
|
+
def self.sym **options
|
11
|
+
if options.empty?
|
12
|
+
# if there are no options can point to the constant for efficiency
|
13
|
+
SYM
|
14
|
+
else
|
15
|
+
IsA.new(
|
16
|
+
Symbol,
|
17
|
+
from_s: :to_sym.to_proc,
|
18
|
+
**options
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end # sym
|
22
|
+
|
23
|
+
singleton_class.send :alias_method, :symbol, :sym
|
24
|
+
|
25
|
+
SYM = sym( name: 'SymType' ).freeze
|
26
|
+
|
27
|
+
|
28
|
+
def self.non_empty_sym **options
|
29
|
+
return NON_EMPTY_SYM if options.empty?
|
30
|
+
|
31
|
+
intersection \
|
32
|
+
SYM,
|
33
|
+
attrs( {to_s: non_empty_str} ),
|
34
|
+
**options
|
35
|
+
end
|
36
|
+
|
37
|
+
NON_EMPTY_SYM = non_empty_sym( name: 'NonEmptySym' ).freeze
|
38
|
+
|
39
|
+
end # NRSER::Types
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# Requirements
|
2
|
+
# =======================================================================
|
3
|
+
|
4
|
+
# Stdlib
|
5
|
+
# -----------------------------------------------------------------------
|
6
|
+
|
7
|
+
# Deps
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Project / Package
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
require_relative './combinators'
|
13
|
+
require_relative './responds'
|
14
|
+
|
15
|
+
|
16
|
+
# Refinements
|
17
|
+
# =======================================================================
|
18
|
+
|
19
|
+
require 'nrser/refinements'
|
20
|
+
using NRSER
|
21
|
+
|
22
|
+
|
23
|
+
# Definitions
|
24
|
+
# =======================================================================
|
25
|
+
|
26
|
+
module NRSER::Types
|
27
|
+
|
28
|
+
# @todo Document array_like method.
|
29
|
+
#
|
30
|
+
# @param [type] arg_name
|
31
|
+
# @todo Add name param description.
|
32
|
+
#
|
33
|
+
# @return [return_type]
|
34
|
+
# @todo Document return value.
|
35
|
+
#
|
36
|
+
def self.array_like **options
|
37
|
+
if options.empty?
|
38
|
+
ARRAY_LIKE
|
39
|
+
else
|
40
|
+
intersection \
|
41
|
+
is_a( Enumerable ),
|
42
|
+
respond_to( :each_index ),
|
43
|
+
**options
|
44
|
+
end
|
45
|
+
end # .array_like
|
46
|
+
|
47
|
+
ARRAY_LIKE = array_like( name: 'ArrayLikeType' ).freeze
|
48
|
+
|
49
|
+
|
50
|
+
# @todo Document hash_like method.
|
51
|
+
#
|
52
|
+
# @param [type] arg_name
|
53
|
+
# @todo Add name param description.
|
54
|
+
#
|
55
|
+
# @return [return_type]
|
56
|
+
# @todo Document return value.
|
57
|
+
#
|
58
|
+
def self.hash_like **options
|
59
|
+
if options.empty?
|
60
|
+
HASH_LIKE
|
61
|
+
else
|
62
|
+
intersection \
|
63
|
+
is_a( Enumerable ),
|
64
|
+
respond_to( :each_pair ),
|
65
|
+
**options
|
66
|
+
end
|
67
|
+
end # .hash_like
|
68
|
+
|
69
|
+
HASH_LIKE = hash_like( name: 'HashLikeType' ).freeze
|
70
|
+
|
71
|
+
|
72
|
+
# @todo Document tree method.
|
73
|
+
#
|
74
|
+
# @param [type] arg_name
|
75
|
+
# @todo Add name param description.
|
76
|
+
#
|
77
|
+
# @return [return_type]
|
78
|
+
# @todo Document return value.
|
79
|
+
#
|
80
|
+
def self.tree **options
|
81
|
+
if options.empty?
|
82
|
+
TREE
|
83
|
+
else
|
84
|
+
union \
|
85
|
+
array_like,
|
86
|
+
hash_like,
|
87
|
+
**options
|
88
|
+
end
|
89
|
+
end # .tree
|
90
|
+
|
91
|
+
TREE = tree( name: 'TreeType' ).freeze
|
92
|
+
|
93
|
+
end # module NRSER::Types
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# Requirements
|
2
|
+
# =======================================================================
|
3
|
+
|
4
|
+
# Stdlib
|
5
|
+
# -----------------------------------------------------------------------
|
6
|
+
|
7
|
+
# Deps
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Project / Package
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
|
13
|
+
|
14
|
+
# Refinements
|
15
|
+
# =======================================================================
|
16
|
+
|
17
|
+
require 'nrser/refinements'
|
18
|
+
using NRSER
|
19
|
+
|
20
|
+
|
21
|
+
# Definitions
|
22
|
+
# =======================================================================
|
23
|
+
|
24
|
+
module NRSER::Types
|
25
|
+
|
26
|
+
# Tuple type - array of fixed length and types (though those could be
|
27
|
+
# {NRSER::Types::ANY}).
|
28
|
+
#
|
29
|
+
class TupleType < NRSER::Types::ArrayType
|
30
|
+
|
31
|
+
# Constants
|
32
|
+
# ======================================================================
|
33
|
+
|
34
|
+
|
35
|
+
# Class Methods
|
36
|
+
# ======================================================================
|
37
|
+
|
38
|
+
|
39
|
+
# Attributes
|
40
|
+
# ======================================================================
|
41
|
+
|
42
|
+
|
43
|
+
# Constructor
|
44
|
+
# ======================================================================
|
45
|
+
|
46
|
+
# Instantiate a new `TupleType`.
|
47
|
+
def initialize *types, **options
|
48
|
+
super **options
|
49
|
+
@types = types.map &NRSER::Types.method(:make)
|
50
|
+
end # #initialize
|
51
|
+
|
52
|
+
|
53
|
+
# Instance Methods
|
54
|
+
# ======================================================================
|
55
|
+
|
56
|
+
# @todo Document test method.
|
57
|
+
#
|
58
|
+
# @param [type] arg_name
|
59
|
+
# @todo Add name param description.
|
60
|
+
#
|
61
|
+
# @return [return_type]
|
62
|
+
# @todo Document return value.
|
63
|
+
#
|
64
|
+
def test value
|
65
|
+
# Test the super class first
|
66
|
+
return false unless super( value )
|
67
|
+
|
68
|
+
# If it's not the right length then it doesn't pass
|
69
|
+
return false unless value.length == @types.length
|
70
|
+
|
71
|
+
# Test each item type
|
72
|
+
@types.each_with_index.all? { |type, index|
|
73
|
+
type.test value[index]
|
74
|
+
}
|
75
|
+
end # #test
|
76
|
+
|
77
|
+
|
78
|
+
# @return [Boolean]
|
79
|
+
# `true` if this type can load values from a string, which is true if
|
80
|
+
# *all* it's types can load values from strings.
|
81
|
+
#
|
82
|
+
def has_from_s?
|
83
|
+
@types.all? &:has_from_s?
|
84
|
+
end # #has_from_s?
|
85
|
+
|
86
|
+
|
87
|
+
# Load each value in an array of strings split out by
|
88
|
+
# {NRSER::Types::ArrayType#from_s} by passing each value to `#from_s` in
|
89
|
+
# the type of the corresponding index.
|
90
|
+
#
|
91
|
+
# @param [Array<String>] strings
|
92
|
+
#
|
93
|
+
# @return [Array]
|
94
|
+
#
|
95
|
+
def items_from_strings strings
|
96
|
+
@types.each_with_index.map { |type, index|
|
97
|
+
type.from_s strings[index]
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
end # class TupleType
|
102
|
+
|
103
|
+
|
104
|
+
# @todo Document tuple method.
|
105
|
+
#
|
106
|
+
# @param [type] arg_name
|
107
|
+
# @todo Add name param description.
|
108
|
+
#
|
109
|
+
# @return [return_type]
|
110
|
+
# @todo Document return value.
|
111
|
+
#
|
112
|
+
def self.tuple *types, **options
|
113
|
+
TupleType.new *types, **options
|
114
|
+
end # .tuple
|
115
|
+
|
116
|
+
end # module NRSER::Types
|
data/lib/nrser/types/type.rb
CHANGED
@@ -194,12 +194,36 @@ module NRSER::Types
|
|
194
194
|
end # #to_data
|
195
195
|
|
196
196
|
|
197
|
+
# Language Inter-Op
|
198
|
+
# =====================================================================
|
199
|
+
|
200
|
+
|
197
201
|
# @return [String]
|
198
|
-
# a brief string description of the type
|
202
|
+
# a brief string description of the type - just it's {#name} surrounded
|
203
|
+
# by some back-ticks to make it easy to see where it starts and stops.
|
199
204
|
#
|
200
205
|
def to_s
|
201
|
-
"
|
206
|
+
"`#{ name }`"
|
202
207
|
end
|
203
208
|
|
209
|
+
|
210
|
+
# Inspecting
|
211
|
+
# ---------------------------------------------------------------------
|
212
|
+
#
|
213
|
+
# Due to their combinatoric nature, types can quickly become large data
|
214
|
+
# hierarchies, and the built-in {#inspect} will produce a massive dump
|
215
|
+
# that's distracting and hard to decipher.
|
216
|
+
#
|
217
|
+
# {#inspect} is readily used in tools like `pry` and `rspec`, significantly
|
218
|
+
# impacting their usefulness when working with types.
|
219
|
+
#
|
220
|
+
# As a solution, we alias the built-in `#inspect` as {#builtin_inspect},
|
221
|
+
# so it's available in situations where you really want all those gory
|
222
|
+
# details, and point {#inspect} to {#to_s}.
|
223
|
+
#
|
224
|
+
|
225
|
+
alias_method :builtin_inspect, :inspect
|
226
|
+
alias_method :inspect, :to_s
|
227
|
+
|
204
228
|
end # Type
|
205
229
|
end # NRSER::Types
|
data/lib/nrser/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "NRSER.
|
4
|
-
subject { NRSER.method :
|
3
|
+
describe "NRSER.guess_label_key_type" do
|
4
|
+
subject { NRSER.method :guess_label_key_type }
|
5
5
|
|
6
6
|
it "can't guess about an empty hash" do
|
7
7
|
expect( subject.call( {} ) ).to be nil
|
@@ -44,4 +44,4 @@ describe "NRSER.guess_name_type" do
|
|
44
44
|
).to be nil
|
45
45
|
end
|
46
46
|
|
47
|
-
end # NRSER.
|
47
|
+
end # NRSER.guess_label_key_type
|
data/spec/nrser/hash_spec.rb
CHANGED
@@ -5,26 +5,6 @@ require 'spec_helper'
|
|
5
5
|
|
6
6
|
using NRSER
|
7
7
|
|
8
|
-
describe NRSER.method(:leaves) do
|
9
|
-
it do
|
10
|
-
expect(NRSER.leaves({a: 1, b: 2})).to eq ({[:a] => 1, [:b] => 2})
|
11
|
-
expect(
|
12
|
-
NRSER.leaves({
|
13
|
-
a: {
|
14
|
-
x: 'ex',
|
15
|
-
y: {
|
16
|
-
z: 'zee'
|
17
|
-
}
|
18
|
-
},
|
19
|
-
b: 'bee',
|
20
|
-
})
|
21
|
-
).to eq({
|
22
|
-
[:a, :x] => 'ex',
|
23
|
-
[:a, :y, :z] => 'zee',
|
24
|
-
[:b] => 'bee',
|
25
|
-
})
|
26
|
-
end
|
27
|
-
end # NRSER.leaves
|
28
8
|
|
29
9
|
describe NRSER.method(:map_values) do
|
30
10
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
|
7
|
+
# NRSER.merge_by
|
8
|
+
# ========================================================================
|
9
|
+
#
|
10
|
+
describe "NRSER.merge_by" do
|
11
|
+
subject { NRSER.method :merge_by }
|
12
|
+
|
13
|
+
context "line items example" do
|
14
|
+
let( :current ) {
|
15
|
+
[
|
16
|
+
{
|
17
|
+
line_item_id: 123,
|
18
|
+
item_id: 1,
|
19
|
+
quantity: 1,
|
20
|
+
},
|
21
|
+
|
22
|
+
{
|
23
|
+
line_item_id: 456,
|
24
|
+
item_id: 2,
|
25
|
+
quantity: 4,
|
26
|
+
},
|
27
|
+
]
|
28
|
+
}
|
29
|
+
|
30
|
+
let( :update ) {
|
31
|
+
[
|
32
|
+
{
|
33
|
+
item_id: 1,
|
34
|
+
quantity: 4,
|
35
|
+
},
|
36
|
+
|
37
|
+
{
|
38
|
+
item_id: 3,
|
39
|
+
quantity: 1,
|
40
|
+
}
|
41
|
+
]
|
42
|
+
}
|
43
|
+
|
44
|
+
subject {
|
45
|
+
super().call current, update, &[:item_id].digger
|
46
|
+
}
|
47
|
+
|
48
|
+
it {
|
49
|
+
is_expected.to include(
|
50
|
+
{
|
51
|
+
line_item_id: 123,
|
52
|
+
item_id: 1,
|
53
|
+
quantity: 4,
|
54
|
+
},
|
55
|
+
|
56
|
+
{
|
57
|
+
line_item_id: 456,
|
58
|
+
item_id: 2,
|
59
|
+
quantity: 4,
|
60
|
+
},
|
61
|
+
|
62
|
+
{
|
63
|
+
item_id: 3,
|
64
|
+
quantity: 1,
|
65
|
+
}
|
66
|
+
)
|
67
|
+
}
|
68
|
+
|
69
|
+
end # line items example
|
70
|
+
|
71
|
+
end # NRSER.merge_by
|
72
|
+
|
73
|
+
# ************************************************************************
|
@@ -1,67 +1,160 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
require 'nrser/refinements/types'
|
3
7
|
using NRSER::Types
|
4
8
|
|
9
|
+
|
5
10
|
describe NRSER::Meta::Props do
|
6
11
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
context "simple Point class" do
|
13
|
+
|
14
|
+
# Setup
|
15
|
+
# =====================================================================
|
16
|
+
|
17
|
+
let(:point_class) {
|
18
|
+
Class.new(NRSER::Meta::Props::Base) do
|
19
|
+
# include NRSER::Meta::Props
|
20
|
+
|
21
|
+
prop :x, type: t.int
|
22
|
+
prop :y, type: t.int
|
23
|
+
prop :blah, type: t.str, source: :blah
|
24
|
+
|
25
|
+
def blah
|
26
|
+
"blah!"
|
27
|
+
end
|
20
28
|
end
|
21
|
-
|
22
|
-
}
|
23
|
-
|
24
|
-
it "has the props" do
|
25
|
-
props = point.props
|
29
|
+
}
|
26
30
|
|
27
|
-
expect(props).to be_a Hash
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
describe ".props" do
|
33
|
+
# ========================================================================
|
34
|
+
|
35
|
+
subject { point_class.props }
|
36
|
+
|
37
|
+
it {
|
38
|
+
is_expected.to be_a( Hash ).and have_attributes \
|
39
|
+
keys: eq( [:x, :y, :blah] ),
|
40
|
+
values: all( be_a NRSER::Meta::Props::Prop )
|
41
|
+
}
|
42
|
+
|
43
|
+
describe 'primary props `x` and `y`' do
|
44
|
+
[:x, :y].each do |name|
|
45
|
+
describe "prop `#{ name }`" do
|
46
|
+
subject { super()[name] }
|
47
|
+
|
48
|
+
include_examples "expect subject", to: {
|
49
|
+
be_a: NRSER::Meta::Props::Prop,
|
50
|
+
have_attributes: {
|
51
|
+
source?: false,
|
52
|
+
primary?: true,
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end # primary props `x` and `y`'
|
58
|
+
|
59
|
+
describe "derived (sourced) prop `blah`" do
|
60
|
+
subject { super()[:blah] }
|
61
|
+
|
62
|
+
include_examples "expect subject", to: {
|
63
|
+
be_a: NRSER::Meta::Props::Prop,
|
64
|
+
have_attributes: {
|
65
|
+
source?: true,
|
66
|
+
primary?: false,
|
67
|
+
}
|
68
|
+
}
|
69
|
+
end # derived (sourced) prop :blah
|
70
|
+
|
71
|
+
end # .props
|
72
|
+
|
73
|
+
# ************************************************************************
|
32
74
|
|
33
|
-
[:x, :y].each do |name|
|
34
|
-
expect(props[name].source?).to be false
|
35
|
-
expect(props[name].primary?).to be true
|
36
|
-
end
|
37
75
|
|
38
|
-
|
39
|
-
|
76
|
+
describe ".props only_primary: true" do
|
77
|
+
# ========================================================================
|
78
|
+
|
79
|
+
subject { point_class.props only_primary: true }
|
80
|
+
|
81
|
+
it {
|
82
|
+
is_expected.to be_a( Hash ).
|
83
|
+
and have_attributes(
|
84
|
+
keys: eq( [:x, :y] ),
|
85
|
+
values: all(
|
86
|
+
be_a( NRSER::Meta::Props::Prop ).
|
87
|
+
and have_attributes source?: false, primary?: true
|
88
|
+
)
|
89
|
+
)
|
90
|
+
}
|
91
|
+
|
92
|
+
end # .props only_primary: true
|
40
93
|
|
41
|
-
|
94
|
+
# ************************************************************************
|
42
95
|
|
43
|
-
|
96
|
+
describe "Point instance where x=1 and y=2 (default blah)" do
|
97
|
+
# ========================================================================
|
98
|
+
|
99
|
+
subject { point_class.new x: 1, y: 2 }
|
100
|
+
|
101
|
+
it { is_expected.to have_attributes x: 1, y: 2, blah: "blah!" }
|
102
|
+
|
103
|
+
describe "#to_h" do
|
104
|
+
subject { super().to_h }
|
105
|
+
it { is_expected.to eq x: 1, y: 2, blah: 'blah!' }
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#to_h only_primary: true" do
|
109
|
+
subject { super().to_h only_primary: true }
|
110
|
+
it { is_expected.to eq x: 1, y: 2 }
|
111
|
+
end
|
112
|
+
|
113
|
+
# ************************************************************************
|
114
|
+
|
115
|
+
end # Point instance where x=1 and y=2 (default blah)
|
44
116
|
|
45
|
-
|
117
|
+
# ************************************************************************
|
46
118
|
|
47
|
-
expect(p.x).to be 1
|
48
|
-
expect(p.y).to be 2
|
49
119
|
|
50
|
-
|
51
|
-
|
120
|
+
describe "bad constructor args" do
|
121
|
+
# ========================================================================
|
122
|
+
|
123
|
+
it "rejects string `y: 'why?'` value" do
|
124
|
+
expect { point_class.new x: 1, y: 'why?' }.to raise_error TypeError
|
125
|
+
end
|
126
|
+
|
127
|
+
end # bad constructor args
|
52
128
|
|
53
|
-
expect { point.new x: 1, y: 'why?' }.to raise_error TypeError
|
54
|
-
expect { p.x = 3 }.to raise_error NoMethodError
|
55
129
|
|
56
|
-
|
130
|
+
describe ".new" do
|
131
|
+
subject { point_class.method :new }
|
132
|
+
|
133
|
+
it_behaves_like "function",
|
134
|
+
mapping: {
|
135
|
+
[{x: 1, y: 2}] => NRSER::Message.new(
|
136
|
+
:have_attributes, x: 1, y: 2, blah: 'blah!'
|
137
|
+
),
|
138
|
+
},
|
139
|
+
raising: {
|
140
|
+
[{x: 1, y: 'why?'}] => [TypeError, /must be of type `IntType`/],
|
141
|
+
}
|
142
|
+
end # .new
|
57
143
|
|
58
|
-
p2 = point.new p_hash
|
59
144
|
|
60
|
-
|
61
|
-
|
145
|
+
describe "dump / load cycle" do
|
146
|
+
context "Point with x=1, y=2" do
|
147
|
+
let( :point ) { point_class.new x: 1, y: 2 }
|
148
|
+
let( :point_hash ) { point.to_h }
|
149
|
+
|
150
|
+
describe "new Point from old point's #to_h" do
|
151
|
+
subject { point_class.new point_hash }
|
152
|
+
it { is_expected.to have_attributes x: 1, y: 2, blah: 'blah!' }
|
153
|
+
end # new Point from old point's #to_h
|
154
|
+
end
|
155
|
+
end # dump / load cycle
|
62
156
|
|
63
|
-
|
64
|
-
end
|
157
|
+
end # simple Point class
|
65
158
|
|
66
159
|
end # NRSER::Meta::Props
|
67
160
|
|