nrser 0.3.11 → 0.3.12
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/nrser/core_ext/array.rb +2 -35
- data/lib/nrser/core_ext/array/to_proc.rb +39 -0
- data/lib/nrser/core_ext/enumerable.rb +13 -1
- data/lib/nrser/core_ext/enumerable/slash_map.rb +37 -0
- data/lib/nrser/errors.rb +1 -0
- data/lib/nrser/errors/conflict_error.rb +13 -2
- data/lib/nrser/errors/unreachable_error.rb +41 -0
- data/lib/nrser/graph/tsorter.rb +13 -6
- data/lib/nrser/rspex.rb +11 -1
- data/lib/nrser/rspex/example_group.rb +1 -0
- data/lib/nrser/rspex/example_group/describe_message.rb +49 -31
- data/lib/nrser/rspex/example_group/describe_subject.rb +53 -0
- data/lib/nrser/types.rb +1 -0
- data/lib/nrser/types/arrays.rb +1 -1
- data/lib/nrser/types/booleans.rb +7 -5
- data/lib/nrser/types/doc/display_table.md +1 -1
- data/lib/nrser/types/enumerables.rb +142 -0
- data/lib/nrser/types/factory.rb +30 -22
- data/lib/nrser/types/numbers.rb +1 -0
- data/lib/nrser/types/paths.rb +9 -0
- data/lib/nrser/types/top.rb +5 -0
- data/lib/nrser/version.rb +1 -1
- data/spec/lib/nrser/types/enumerables_spec.rb +39 -0
- data/spec/lib/nrser/types/paths_spec.rb +19 -2
- data/spec/lib/nrser/types_spec.rb +10 -2
- metadata +15 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0455e10b137f0194452111ef3a4a55960a7b642
|
4
|
+
data.tar.gz: 4966b5b797d0de2da7f79687d05af23656740e2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aed3f495e077fa4c1167afe6113a5fea5d38f66ca9e7ade3961104b0d38c026f174f36d2bed8ae5b59a21b70515f687f1c1840ec1490403ca8ea4e151acf250d
|
7
|
+
data.tar.gz: 30d68b577092b8250349f636535a53de3031e7b44030c55d4bb4a5d0c7ee159ad65693f53a8100296f3f5b1613f02ca79ad0de284971ad5788514bdbe587b31f
|
data/lib/nrser/core_ext/array.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative './array/to_proc'
|
2
|
+
|
1
3
|
class Array
|
2
4
|
include NRSER::Ext::Tree
|
3
5
|
|
@@ -91,41 +93,6 @@ class Array
|
|
91
93
|
def to_chainer publicly: true
|
92
94
|
NRSER.chainer self, publicly: publicly
|
93
95
|
end # #to_chainer
|
94
|
-
|
95
|
-
|
96
|
-
# Returns a lambda that calls accepts a single arg and calls either:
|
97
|
-
#
|
98
|
-
# 1. `#[self.first]` if this array has only one entry.
|
99
|
-
# 2. `#dig( *self )` if this array has more than one entry.
|
100
|
-
#
|
101
|
-
# @example
|
102
|
-
# list = [{id: 1, name: "Neil"}, {id: 2, name: "Mica"}]
|
103
|
-
# list.assoc_by &[:id]
|
104
|
-
# # => {
|
105
|
-
# # 1 => {id: 1, name: "Neil"},
|
106
|
-
# # 2 => {id: 2, name: "Mica"},
|
107
|
-
# # }
|
108
|
-
#
|
109
|
-
# @return [Proc]
|
110
|
-
# Lambda proc that accepts a single argument and calls `#[]` or `#dig with
|
111
|
-
# this array's contents as the arguments.
|
112
|
-
#
|
113
|
-
def to_proc
|
114
|
-
method_name = case count
|
115
|
-
when 0
|
116
|
-
raise NRSER::CountError.new \
|
117
|
-
"Can not create getter proc from empty array",
|
118
|
-
value: self,
|
119
|
-
expected: '> 0',
|
120
|
-
count: count
|
121
|
-
when 1
|
122
|
-
:[]
|
123
|
-
else
|
124
|
-
:dig
|
125
|
-
end
|
126
|
-
|
127
|
-
NRSER::Message.new( method_name, *self ).to_proc
|
128
|
-
end # #to_proc
|
129
96
|
|
130
97
|
|
131
98
|
# Old name for {#to_proc}.
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'nrser/message'
|
2
|
+
|
3
|
+
class Array
|
4
|
+
|
5
|
+
# Returns a lambda that calls accepts a single arg and calls either:
|
6
|
+
#
|
7
|
+
# 1. `#[self.first]` if this array has only one entry.
|
8
|
+
# 2. `#dig( *self )` if this array has more than one entry.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# list = [{id: 1, name: "Neil"}, {id: 2, name: "Mica"}]
|
12
|
+
# list.assoc_by &[:id]
|
13
|
+
# # => {
|
14
|
+
# # 1 => {id: 1, name: "Neil"},
|
15
|
+
# # 2 => {id: 2, name: "Mica"},
|
16
|
+
# # }
|
17
|
+
#
|
18
|
+
# @return [Proc]
|
19
|
+
# Lambda proc that accepts a single argument and calls `#[]` or `#dig with
|
20
|
+
# this array's contents as the arguments.
|
21
|
+
#
|
22
|
+
def to_proc
|
23
|
+
method_name = case count
|
24
|
+
when 0
|
25
|
+
raise NRSER::CountError.new \
|
26
|
+
"Can not create getter proc from empty array",
|
27
|
+
value: self,
|
28
|
+
expected: '> 0',
|
29
|
+
count: count
|
30
|
+
when 1
|
31
|
+
:[]
|
32
|
+
else
|
33
|
+
:dig
|
34
|
+
end
|
35
|
+
|
36
|
+
NRSER::Message.new( method_name, *self ).to_proc
|
37
|
+
end # #to_proc
|
38
|
+
|
39
|
+
end # class Array
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'nrser/functions/enumerable/associate'
|
2
2
|
require_relative './enumerable/find_map'
|
3
|
+
require_relative './enumerable/slash_map'
|
3
4
|
|
4
5
|
|
5
6
|
# Instance methods to extend {Enumerable}.
|
@@ -16,6 +17,18 @@ module Enumerable
|
|
16
17
|
def find_only &block
|
17
18
|
NRSER.find_only self, &block
|
18
19
|
end
|
20
|
+
|
21
|
+
|
22
|
+
# Right now, *exactly* the same as {#find_only}... though I wished I had
|
23
|
+
# called it this and had {#find_only} return `nil` if it failed, as is
|
24
|
+
# kind-of a some-what established practice, because now I get confused.
|
25
|
+
#
|
26
|
+
# Maybe some day I will make that change. For now, this is here so when I
|
27
|
+
# forget and add the `!` it works.
|
28
|
+
#
|
29
|
+
def find_only! &block
|
30
|
+
NRSER.find_only self, &block
|
31
|
+
end
|
19
32
|
|
20
33
|
|
21
34
|
# See {NRSER.assoc_by}
|
@@ -65,5 +78,4 @@ module Enumerable
|
|
65
78
|
NRSER.slice? self, *args, &block
|
66
79
|
end
|
67
80
|
|
68
|
-
|
69
81
|
end # module Enumerable
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Enumerable
|
2
|
+
|
3
|
+
# @note EXPERIMENTAL!
|
4
|
+
#
|
5
|
+
# An idea I'm playing around with for convenient mapping of {Enumerable}.
|
6
|
+
#
|
7
|
+
# @example Extract Attributes
|
8
|
+
# Cat = Struct.new :name, :breed
|
9
|
+
#
|
10
|
+
# cats = [ Cat.new( 'Hudie', 'Chinese-American Shorthair' ),
|
11
|
+
# Cat.new( 'Oscar', 'Bengal' ) ]
|
12
|
+
#
|
13
|
+
# cats/:name #=> [ 'Hudie', 'Oscar' ]
|
14
|
+
# cats/:breed #=> [ 'Chinese-American Shorthair', 'Bengal' ]
|
15
|
+
#
|
16
|
+
# @example Extract Values
|
17
|
+
# # Need the array.to_proc ~> ->( key ) { array.dig *key } for it to really
|
18
|
+
# # *feel* nice... and that's the whole point!
|
19
|
+
# require 'nrser/core_ext/array/to_proc'
|
20
|
+
#
|
21
|
+
# kitties = [ { name: 'Hootie' },
|
22
|
+
# { name: 'Oscie' } ]
|
23
|
+
#
|
24
|
+
# kitties/[:name] #=> [ 'Hooie', 'Oscie' ]
|
25
|
+
#
|
26
|
+
# Not so bad, eh? I'm calling it "slash-map" for the moment, BTW.
|
27
|
+
#
|
28
|
+
# @param [#to_proc] proc_able
|
29
|
+
# Something that can be `#to_proc`'d for the {Enumerable#map}.
|
30
|
+
#
|
31
|
+
# @return [Enumerable]
|
32
|
+
#
|
33
|
+
def / proc_able
|
34
|
+
map &proc_able
|
35
|
+
end
|
36
|
+
|
37
|
+
end # module NRSER
|
data/lib/nrser/errors.rb
CHANGED
@@ -10,6 +10,12 @@
|
|
10
10
|
require_relative './nicer_error'
|
11
11
|
|
12
12
|
|
13
|
+
# Namespace
|
14
|
+
# ========================================================================
|
15
|
+
|
16
|
+
module NRSER
|
17
|
+
|
18
|
+
|
13
19
|
# Definitions
|
14
20
|
# =======================================================================
|
15
21
|
|
@@ -17,7 +23,12 @@ require_relative './nicer_error'
|
|
17
23
|
# it's not the type or an argument, but something about the data or
|
18
24
|
# configuration just isn't ok.
|
19
25
|
#
|
20
|
-
module NRSER
|
21
26
|
class ConflictError < ::StandardError
|
22
27
|
include NRSER::NicerError
|
23
|
-
end
|
28
|
+
end # class ConflictError
|
29
|
+
|
30
|
+
|
31
|
+
# /Namespace
|
32
|
+
# ========================================================================
|
33
|
+
|
34
|
+
end # module NRSER
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Project / Package
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
require_relative './nicer_error'
|
11
|
+
|
12
|
+
|
13
|
+
# Namespace
|
14
|
+
# ========================================================================
|
15
|
+
|
16
|
+
module NRSER
|
17
|
+
|
18
|
+
|
19
|
+
# Definitions
|
20
|
+
# =======================================================================
|
21
|
+
|
22
|
+
# Raised in places where execution should *never* reach.
|
23
|
+
#
|
24
|
+
class UnreachableError < ::RuntimeError
|
25
|
+
include NRSER::NicerError
|
26
|
+
|
27
|
+
# The default message
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
#
|
31
|
+
def default_message
|
32
|
+
"An expression that should be unreachable has been executed"
|
33
|
+
end
|
34
|
+
|
35
|
+
end # class UnreachableError
|
36
|
+
|
37
|
+
|
38
|
+
# /Namespace
|
39
|
+
# ========================================================================
|
40
|
+
|
41
|
+
end # module NRSER
|
data/lib/nrser/graph/tsorter.rb
CHANGED
@@ -11,11 +11,11 @@
|
|
11
11
|
require 'tsort'
|
12
12
|
|
13
13
|
|
14
|
-
#
|
15
|
-
#
|
14
|
+
# Namespace
|
15
|
+
# ========================================================================
|
16
16
|
|
17
|
-
module
|
18
|
-
module
|
17
|
+
module NRSER
|
18
|
+
module Graph
|
19
19
|
|
20
20
|
|
21
21
|
# Definitions
|
@@ -23,7 +23,7 @@ module NRSER::Graph; end
|
|
23
23
|
|
24
24
|
# Topologically sorts an {Enumerable} by a user-provided `child_node` block.
|
25
25
|
#
|
26
|
-
class
|
26
|
+
class TSorter
|
27
27
|
include TSort
|
28
28
|
|
29
29
|
def initialize entries, &each_child
|
@@ -38,4 +38,11 @@ class NRSER::Graph::TSorter
|
|
38
38
|
def tsort_each_child node, &block
|
39
39
|
@each_child.call node, &block
|
40
40
|
end
|
41
|
-
end # class
|
41
|
+
end # class TSorter
|
42
|
+
|
43
|
+
|
44
|
+
# /Namespace
|
45
|
+
# ========================================================================
|
46
|
+
|
47
|
+
end # module Graph
|
48
|
+
end # module NRSER
|
data/lib/nrser/rspex.rb
CHANGED
@@ -103,7 +103,13 @@ class Wrapper
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def wrap description = nil, &block
|
106
|
-
|
106
|
+
if block
|
107
|
+
Wrapper.new description: description, &block
|
108
|
+
else
|
109
|
+
Wrapper.new description: description.to_s do
|
110
|
+
send description
|
111
|
+
end
|
112
|
+
end
|
107
113
|
end
|
108
114
|
|
109
115
|
def unwrap obj, context: nil
|
@@ -114,6 +120,10 @@ def unwrap obj, context: nil
|
|
114
120
|
end
|
115
121
|
end
|
116
122
|
|
123
|
+
def msg *args, &block
|
124
|
+
NRSER::Message.from *args, &block
|
125
|
+
end
|
126
|
+
|
117
127
|
|
118
128
|
def List *args
|
119
129
|
NRSER::RSpex::List.new args
|
@@ -30,5 +30,6 @@ require_relative './example_group/describe_sent_to'
|
|
30
30
|
require_relative './example_group/describe_setup'
|
31
31
|
require_relative './example_group/describe_source_file'
|
32
32
|
require_relative './example_group/describe_spec_file'
|
33
|
+
require_relative './example_group/describe_subject'
|
33
34
|
require_relative './example_group/describe_when'
|
34
35
|
require_relative './example_group/describe_x'
|
@@ -1,35 +1,53 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
4
|
+
# Namespace
|
5
|
+
# ========================================================================
|
6
|
+
|
7
|
+
module NRSER
|
8
|
+
module RSpex
|
9
|
+
module ExampleGroup
|
10
|
+
|
11
|
+
|
12
|
+
# Definitions
|
13
|
+
# ========================================================================
|
14
|
+
|
15
|
+
# Describe a {NRSER::Message}. Useful when you have a message that you want
|
16
|
+
# to send to many receivers (see {#describe_sent_to}).
|
17
|
+
#
|
18
|
+
# @note
|
19
|
+
# Since the block is used for the example group body, if you want to
|
20
|
+
# describe a message with a {NRSER::Message#block} your need to create
|
21
|
+
# the message yourself and pass it as the only argument.
|
22
|
+
#
|
23
|
+
# @see #describe_x
|
24
|
+
#
|
25
|
+
# @param [Array] args
|
26
|
+
# Passed to {NRSER::Message.from} to get or create the message instance.
|
27
|
+
#
|
28
|
+
# @param &body (see #describe_x)
|
29
|
+
#
|
30
|
+
# @return (see #describe_x)
|
31
|
+
#
|
32
|
+
def describe_message *args, &body
|
33
|
+
message = NRSER::Message.from *args
|
34
34
|
|
35
|
-
|
35
|
+
describe_x \
|
36
|
+
message,
|
37
|
+
type: :message,
|
38
|
+
metadata: {
|
39
|
+
message: message,
|
40
|
+
},
|
41
|
+
subject_block: -> { message.send_to super() },
|
42
|
+
&body
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :MESSAGE, :describe_message
|
46
|
+
|
47
|
+
|
48
|
+
# /Namespace
|
49
|
+
# ========================================================================
|
50
|
+
|
51
|
+
end # module ExampleGroup
|
52
|
+
end # module RSpex
|
53
|
+
end # module NRSER
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
|
5
|
+
# Namespace
|
6
|
+
# ========================================================================
|
7
|
+
|
8
|
+
module NRSER
|
9
|
+
module RSpex
|
10
|
+
module ExampleGroup
|
11
|
+
|
12
|
+
|
13
|
+
# Definitions
|
14
|
+
# ========================================================================
|
15
|
+
|
16
|
+
# Define a example group binding a subject.
|
17
|
+
#
|
18
|
+
# @note Experimental - only used in Rash at the moment. I've wanted *something*
|
19
|
+
# like this to make binding subject less noisy, but I'm not sure this is
|
20
|
+
# exactly it yet...
|
21
|
+
#
|
22
|
+
# @see #describe_x
|
23
|
+
#
|
24
|
+
# @param [Object] subject
|
25
|
+
# The value to bind as the subject. May be wrapped.
|
26
|
+
#
|
27
|
+
# @param [Hash<Symbol, Object>] metadata
|
28
|
+
# Optional metadata for the example group.
|
29
|
+
#
|
30
|
+
# @param &body (see #describe_x)
|
31
|
+
#
|
32
|
+
# @return (see #describe_x)
|
33
|
+
#
|
34
|
+
def describe_subject subject, **metadata, &body
|
35
|
+
describe_x \
|
36
|
+
subject,
|
37
|
+
type: :subject,
|
38
|
+
metadata: metadata,
|
39
|
+
subject_block: -> { unwrap subject, context: self },
|
40
|
+
&body
|
41
|
+
end
|
42
|
+
|
43
|
+
# Short name
|
44
|
+
alias_method :SUBJECT, :describe_subject
|
45
|
+
|
46
|
+
|
47
|
+
# /Namespace
|
48
|
+
# ========================================================================
|
49
|
+
|
50
|
+
end # module ExampleGroup
|
51
|
+
end # module RSpex
|
52
|
+
end # module NRSER
|
53
|
+
|
data/lib/nrser/types.rb
CHANGED
data/lib/nrser/types/arrays.rb
CHANGED
data/lib/nrser/types/booleans.rb
CHANGED
@@ -46,7 +46,7 @@ class Boolean < Is
|
|
46
46
|
# ========================================================================
|
47
47
|
|
48
48
|
def custom_from_s string
|
49
|
-
return value if self::STRINGS.include?( string.downcase )
|
49
|
+
return value if self.class::STRINGS.include?( string.downcase )
|
50
50
|
|
51
51
|
raise NRSER::Types::FromStringError.new \
|
52
52
|
type: self,
|
@@ -74,7 +74,7 @@ end # class Boolean
|
|
74
74
|
# Provides a {#custom_from_s} to load from CLI options and ENV var-like
|
75
75
|
# string values.
|
76
76
|
#
|
77
|
-
class
|
77
|
+
class TrueType < Boolean
|
78
78
|
|
79
79
|
STRINGS = NRSER::TRUTHY_STRINGS
|
80
80
|
|
@@ -92,7 +92,7 @@ end # class True
|
|
92
92
|
# Provides a {#custom_from_s} to load from CLI options and ENV var-like
|
93
93
|
# string values.
|
94
94
|
#
|
95
|
-
class
|
95
|
+
class FalseType < Boolean
|
96
96
|
|
97
97
|
STRINGS = NRSER::FALSY_STRINGS
|
98
98
|
|
@@ -116,7 +116,7 @@ end # class FalseType
|
|
116
116
|
#
|
117
117
|
def_type :True,
|
118
118
|
&->( **options ) do
|
119
|
-
|
119
|
+
TrueType.new **options
|
120
120
|
end
|
121
121
|
|
122
122
|
|
@@ -131,7 +131,7 @@ end
|
|
131
131
|
#
|
132
132
|
def_type :False,
|
133
133
|
&->( **options ) do
|
134
|
-
|
134
|
+
FalseType.new **options
|
135
135
|
end # .False
|
136
136
|
|
137
137
|
|
@@ -145,6 +145,8 @@ end # .False
|
|
145
145
|
#
|
146
146
|
def_type :Boolean,
|
147
147
|
aliases: [ :bool ],
|
148
|
+
default_name: ->( *args, &block ) { 'Boolean' },
|
149
|
+
symbolic: '𝔹',
|
148
150
|
&->( **options ) do
|
149
151
|
union self.True, self.False, **options
|
150
152
|
end # .Boolean
|
@@ -53,7 +53,7 @@ to access it via the API.
|
|
53
53
|
| `t.PositiveInteger` | `PositiveInteger` | `ℤ⁺` | `(Integer & Bounded<min=1>)` |
|
54
54
|
| `t.NegativeInteger` | `NegativeInteger` | `ℤ⁻` | `(Integer & Bounded<max=-1>)` |
|
55
55
|
| `t.NonNegativeInteger` | `NonNegativeInteger` | `ℕ⁰` | `(Integer & Bounded<min=0>)` |
|
56
|
-
| `t.Boolean` | `Boolean` |
|
56
|
+
| `t.Boolean` | `Boolean` | `𝔹` | `(Is<true> \| Is<false>)` |
|
57
57
|
| `t.Bounded( min: 1, max: 2 )` | `Bounded<min=1, max=2>` | `(1..2)` | `Bounded<min=1, max=2>` |
|
58
58
|
| `t.Bounded( min: 1 )` | `Bounded<min=1>` | `(1..)` | `Bounded<min=1>` |
|
59
59
|
| `t.Array` | `Array` | `[*]` | `Array` |
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Project / Package
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Need {Module.safe_name}
|
11
|
+
require 'nrser/core_ext/module/names'
|
12
|
+
|
13
|
+
# Need {Types.Top} for the default entry type
|
14
|
+
require_relative './top'
|
15
|
+
|
16
|
+
|
17
|
+
# Namespace
|
18
|
+
# =======================================================================
|
19
|
+
|
20
|
+
module NRSER
|
21
|
+
module Types
|
22
|
+
|
23
|
+
|
24
|
+
# Definitions
|
25
|
+
# =======================================================================
|
26
|
+
|
27
|
+
# Type class that parameterizes {Enumerable} values of a homogeneous type.
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# array_of_int = NRSER::Types::EnumerableType.new Array, Integer
|
31
|
+
# array_of_int.test? [1, 2, 3] #=> true
|
32
|
+
# array_of_int.test? [1, 2, 'three'] #=> false
|
33
|
+
# array_of_int.test? 'blah' #=> false
|
34
|
+
# array_of_int.test? [] #=> true
|
35
|
+
#
|
36
|
+
class EnumerableType < IsA
|
37
|
+
|
38
|
+
# Attributes
|
39
|
+
# ========================================================================
|
40
|
+
|
41
|
+
# Type all entries must satisfy.
|
42
|
+
#
|
43
|
+
# @return [Type]
|
44
|
+
#
|
45
|
+
attr_reader :entry_type
|
46
|
+
|
47
|
+
|
48
|
+
# Construction
|
49
|
+
# ========================================================================
|
50
|
+
|
51
|
+
# Instantiate a new `EnumerableType`.
|
52
|
+
def initialize enumerable_type = ::Enumerable,
|
53
|
+
entry_type = self.Top,
|
54
|
+
**options
|
55
|
+
super enumerable_type, **options
|
56
|
+
@entry_type = Types.make entry_type
|
57
|
+
end # #initialize
|
58
|
+
|
59
|
+
|
60
|
+
# Instance Methods
|
61
|
+
# ========================================================================
|
62
|
+
|
63
|
+
# @!group Display Instance Methods
|
64
|
+
# ------------------------------------------------------------------------
|
65
|
+
|
66
|
+
def explain
|
67
|
+
"#{ enumerable_type.safe_name }<#{ entry_type.explain }>"
|
68
|
+
end
|
69
|
+
|
70
|
+
# @!endgroup Display Instance Methods # ************************************
|
71
|
+
|
72
|
+
|
73
|
+
# Intuitive alias for {IsA#mod}.
|
74
|
+
#
|
75
|
+
# @return [Class]
|
76
|
+
#
|
77
|
+
def enumerable_type; mod; end
|
78
|
+
|
79
|
+
|
80
|
+
def test? value
|
81
|
+
# Test that `value` is of the right container class first
|
82
|
+
return false unless super( value )
|
83
|
+
|
84
|
+
# If that passed test all the entries against the type
|
85
|
+
value.all? &@entry_type.method( :test? )
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
end # class EnumerableType
|
90
|
+
|
91
|
+
|
92
|
+
# @!group Enumerable Type Factories
|
93
|
+
# --------------------------------------------------------------------------
|
94
|
+
|
95
|
+
# @!method self.Enumerable_ enumerable_type = ::Enumerable, entry_type = self.Top, **options
|
96
|
+
#
|
97
|
+
# @todo
|
98
|
+
# YARDdoc method name has an `_` suffix added to hack around an apparent
|
99
|
+
# bug in YARD - it seems the method name `Enumerable` matching the
|
100
|
+
# `Enumerable` class causes failure:
|
101
|
+
#
|
102
|
+
# ```
|
103
|
+
# [error]: Exception occurred while generating 'NRSER/Types/Type.html'
|
104
|
+
# [error]: ArgumentError: Invalid namespace object: #<yardoc method NRSER::Types.Enumerable>:YARD::CodeObjects::MethodObject
|
105
|
+
# [error]: Stack trace:
|
106
|
+
# //.bundle/ruby/2.3.0/gems/yard-0.9.16/lib/yard/code_objects/proxy.rb:67:in `initialize'
|
107
|
+
# //.bundle/ruby/2.3.0/gems/yard-0.9.16/lib/yard/registry_resolver.rb:87:in `new'
|
108
|
+
# //.bundle/ruby/2.3.0/gems/yard-0.9.16/lib/yard/registry_resolver.rb:87:in `lookup_by_path'
|
109
|
+
# //.bundle/ruby/2.3.0/gems/yard-0.9.16/lib/yard/registry.rb:304:in `resolve'
|
110
|
+
# //.bundle/ruby/2.3.0/gems/yard-0.9.16/lib/yard/templates/helpers/html_helper.rb:292:in `link_object'
|
111
|
+
# //.bundle/ruby/2.3.0/gems/yard-link_stdlib-0.1.0/lib/yard/link_stdlib/html_helper.rb:77:in `link_object'
|
112
|
+
# ```
|
113
|
+
#
|
114
|
+
# Types that parameterize {Enumerable} values of a homogeneous type.
|
115
|
+
#
|
116
|
+
# @param [Class] enumerable_type
|
117
|
+
# Required class of the container itself.
|
118
|
+
#
|
119
|
+
# @param [Type | Object] entry_type
|
120
|
+
# Type of the entries. If this is not a {Type}, one will be created from
|
121
|
+
# it via {NRSER::Types.make}.
|
122
|
+
#
|
123
|
+
# @param [Hash] options
|
124
|
+
# Passed to {Type#initialize}.
|
125
|
+
#
|
126
|
+
# @return [Type]
|
127
|
+
#
|
128
|
+
def_type :Enumerable,
|
129
|
+
aliases: [ :Enum, :enum ],
|
130
|
+
parameterize: [ :enumerable_type, :entry_type ],
|
131
|
+
&->( enumerable_type = ::Enumerable, entry_type = self.Top, **options ) do
|
132
|
+
EnumerableType.new enumerable_type, entry_type, **options
|
133
|
+
end # .Enumerable
|
134
|
+
|
135
|
+
|
136
|
+
# @!endgroup Enumerable Type Factories # ***********************************
|
137
|
+
|
138
|
+
# /Namespace
|
139
|
+
# =======================================================================
|
140
|
+
|
141
|
+
end # module Types
|
142
|
+
end # module NRSER
|
data/lib/nrser/types/factory.rb
CHANGED
@@ -113,36 +113,44 @@ module Factory
|
|
113
113
|
#
|
114
114
|
# @param [nil | false | Proc<(*args, &block): String>] default_name
|
115
115
|
#
|
116
|
-
# Controls
|
117
|
-
#
|
116
|
+
# Controls the default value assigned to the `name:` keyword argument (only
|
117
|
+
# relevant when a `name:` value is *not* explicitly passed when building the
|
118
|
+
# type).
|
118
119
|
#
|
119
120
|
# Everything here is done *before* the `options` are passed to the
|
120
|
-
# factory method's `&body`, so the body will see
|
121
|
-
#
|
121
|
+
# factory method's `&body`, so the body will see the default `name:` value
|
122
|
+
# in the factory method body.
|
122
123
|
#
|
123
124
|
# When...
|
124
125
|
#
|
125
|
-
# - `nil`
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
126
|
+
# - `default_name == nil`
|
127
|
+
#
|
128
|
+
# Behavior depends on the value of the `parameterize:` keyword:
|
129
|
+
#
|
130
|
+
# - `parameterize == nil`
|
131
|
+
#
|
132
|
+
# The `name` parameter will be used as the default value.
|
129
133
|
#
|
130
134
|
# This situation covers "static" types that will only differ by
|
131
|
-
# their `options`
|
132
|
-
#
|
133
|
-
#
|
135
|
+
# their `options` (custom {Type#from_s}, {Type#to_data}, etc.).
|
136
|
+
# Really, these are more like aliases since the types' member sets
|
137
|
+
# are identical.
|
134
138
|
#
|
135
|
-
# - `parameterize
|
136
|
-
# as `nil` if none is provided by the factory caller.
|
139
|
+
# - `parameterize != nil`
|
137
140
|
#
|
138
|
-
#
|
139
|
-
#
|
141
|
+
# The default `name:` value will be left as `nil`.
|
142
|
+
#
|
143
|
+
# - `default_name == false`
|
144
|
+
#
|
145
|
+
# The `name:` option will not be touched - it will stay `nil` unless the
|
146
|
+
# factory caller provides a value.
|
140
147
|
#
|
141
|
-
# - `Proc<(*args, &block)->String>`
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
# that
|
148
|
+
# - `default_name is a Proc<(*args, &block)->String>`
|
149
|
+
#
|
150
|
+
# When the factory caller does not provide a `name:` option this
|
151
|
+
# function will be called with the arguments (including `options`) and
|
152
|
+
# block (if any) that the factory method was called with, and is
|
153
|
+
# expected to return a {String} that will be set as the `name:` option.
|
146
154
|
#
|
147
155
|
# @param [nil | Symbol | Array<Symbol>] parameterize
|
148
156
|
# Indicates if the type is parameterized, and, if so, what arguments
|
@@ -200,9 +208,9 @@ module Factory
|
|
200
208
|
unless default_name.nil? ||
|
201
209
|
default_name == false ||
|
202
210
|
default_name.is_a?( Proc )
|
203
|
-
raise NRSER::TypeError
|
211
|
+
raise NRSER::TypeError.new \
|
204
212
|
"`default_name:` keyword argument must be {nil}, {false} or a {Proc},",
|
205
|
-
"found", default_name,
|
213
|
+
"found", default_name.inspect,
|
206
214
|
expected: [ nil, false, Proc ],
|
207
215
|
received: default_name
|
208
216
|
end
|
data/lib/nrser/types/numbers.rb
CHANGED
data/lib/nrser/types/paths.rb
CHANGED
@@ -167,6 +167,15 @@ def_type :HomePath,
|
|
167
167
|
end # .HomePath
|
168
168
|
|
169
169
|
|
170
|
+
def_type :TildePath,
|
171
|
+
&->( **options ) do
|
172
|
+
self.Intersection \
|
173
|
+
self.Path,
|
174
|
+
self.When( TILDE_PATH_RE ),
|
175
|
+
**options
|
176
|
+
end # .TildePath
|
177
|
+
|
178
|
+
|
170
179
|
# @!method self.AbsPath **options
|
171
180
|
# A relative {.Path}, which is just a {.Path} that's not {.AbsPath} or
|
172
181
|
# {.TildePath}.
|
data/lib/nrser/types/top.rb
CHANGED
@@ -30,6 +30,11 @@ class Top < NRSER::Types::Type
|
|
30
30
|
|
31
31
|
def initialize
|
32
32
|
super name: NAME
|
33
|
+
|
34
|
+
# All types maybe *should* be frozen so they can be used as prop defaults,
|
35
|
+
# but this is the first one I ran into in practice, so it's the first one
|
36
|
+
# to freeze.
|
37
|
+
freeze
|
33
38
|
end
|
34
39
|
|
35
40
|
def test? value
|
data/lib/nrser/version.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'nrser/refinements/types'
|
5
|
+
using NRSER::Types
|
6
|
+
|
7
|
+
|
8
|
+
SPEC_FILE(
|
9
|
+
spec_path: __FILE__,
|
10
|
+
module: NRSER::Types,
|
11
|
+
method: :Enumerable,
|
12
|
+
) do
|
13
|
+
|
14
|
+
it_behaves_like 'type maker method'
|
15
|
+
|
16
|
+
include_examples 'make type',
|
17
|
+
args: [ Array, Integer ],
|
18
|
+
|
19
|
+
accepts: [
|
20
|
+
[],
|
21
|
+
[1, 2, 3],
|
22
|
+
],
|
23
|
+
|
24
|
+
rejects: [
|
25
|
+
nil,
|
26
|
+
{},
|
27
|
+
Set[1, 2, 3],
|
28
|
+
],
|
29
|
+
|
30
|
+
and_is_expected: {
|
31
|
+
to: {
|
32
|
+
have_attributes: {
|
33
|
+
class: t::EnumerableType,
|
34
|
+
name: 'Array<Integer>',
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
end # SPEC_FILE
|
@@ -92,8 +92,25 @@ SPEC_FILE(
|
|
92
92
|
end # METHOD .path_seg
|
93
93
|
|
94
94
|
|
95
|
-
METHOD :
|
96
|
-
|
95
|
+
METHOD :TildePath do
|
96
|
+
include_examples 'make type',
|
97
|
+
accepts: [
|
98
|
+
'~',
|
99
|
+
'~/blah',
|
100
|
+
],
|
101
|
+
|
102
|
+
rejects: [
|
103
|
+
'hey/ho',
|
104
|
+
'./blah',
|
105
|
+
],
|
106
|
+
|
107
|
+
and_is_expected: {
|
108
|
+
to: {
|
109
|
+
have_attributes: {
|
110
|
+
name: 'TildePath',
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
97
114
|
end # METHOD .tilde_path Description
|
98
115
|
|
99
116
|
|
@@ -22,14 +22,22 @@ describe NRSER::Types do
|
|
22
22
|
fail: [{}],
|
23
23
|
},
|
24
24
|
|
25
|
-
t.
|
25
|
+
t.True => {
|
26
26
|
pass: [true],
|
27
27
|
fail: [1, 'true'],
|
28
|
+
from_s: {
|
29
|
+
pass: [ 'true', 'True', '1', 'T', 't'],
|
30
|
+
fail: [ 'f', '100' ],
|
31
|
+
}
|
28
32
|
},
|
29
33
|
|
30
|
-
t.
|
34
|
+
t.False => {
|
31
35
|
pass: [false],
|
32
36
|
fail: [true, 0, nil, 'false'],
|
37
|
+
from_s: {
|
38
|
+
pass: [ 'false', 'f', 'F', '0' ],
|
39
|
+
fail: [ 't', '-1' ],
|
40
|
+
}
|
33
41
|
},
|
34
42
|
|
35
43
|
t.bool => {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nrser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nrser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hamster
|
@@ -31,6 +31,9 @@ dependencies:
|
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '4.2'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '4.4'
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -38,6 +41,9 @@ dependencies:
|
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
43
|
version: '4.2'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '4.4'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: awesome_print
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,9 +118,6 @@ dependencies:
|
|
112
118
|
name: bundler
|
113
119
|
requirement: !ruby/object:Gem::Requirement
|
114
120
|
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '1.16'
|
118
121
|
- - ">="
|
119
122
|
- !ruby/object:Gem::Version
|
120
123
|
version: 1.16.1
|
@@ -122,9 +125,6 @@ dependencies:
|
|
122
125
|
prerelease: false
|
123
126
|
version_requirements: !ruby/object:Gem::Requirement
|
124
127
|
requirements:
|
125
|
-
- - "~>"
|
126
|
-
- !ruby/object:Gem::Version
|
127
|
-
version: '1.16'
|
128
128
|
- - ">="
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: 1.16.1
|
@@ -312,9 +312,11 @@ files:
|
|
312
312
|
- lib/nrser/collection.rb
|
313
313
|
- lib/nrser/core_ext.rb
|
314
314
|
- lib/nrser/core_ext/array.rb
|
315
|
+
- lib/nrser/core_ext/array/to_proc.rb
|
315
316
|
- lib/nrser/core_ext/binding.rb
|
316
317
|
- lib/nrser/core_ext/enumerable.rb
|
317
318
|
- lib/nrser/core_ext/enumerable/find_map.rb
|
319
|
+
- lib/nrser/core_ext/enumerable/slash_map.rb
|
318
320
|
- lib/nrser/core_ext/exception.rb
|
319
321
|
- lib/nrser/core_ext/hash.rb
|
320
322
|
- lib/nrser/core_ext/hash/bury.rb
|
@@ -344,6 +346,7 @@ files:
|
|
344
346
|
- lib/nrser/errors/count_error.rb
|
345
347
|
- lib/nrser/errors/nicer_error.rb
|
346
348
|
- lib/nrser/errors/type_error.rb
|
349
|
+
- lib/nrser/errors/unreachable_error.rb
|
347
350
|
- lib/nrser/errors/value_error.rb
|
348
351
|
- lib/nrser/ext/tree.rb
|
349
352
|
- lib/nrser/functions.rb
|
@@ -462,6 +465,7 @@ files:
|
|
462
465
|
- lib/nrser/rspex/example_group/describe_setup.rb
|
463
466
|
- lib/nrser/rspex/example_group/describe_source_file.rb
|
464
467
|
- lib/nrser/rspex/example_group/describe_spec_file.rb
|
468
|
+
- lib/nrser/rspex/example_group/describe_subject.rb
|
465
469
|
- lib/nrser/rspex/example_group/describe_when.rb
|
466
470
|
- lib/nrser/rspex/example_group/describe_x.rb
|
467
471
|
- lib/nrser/rspex/example_group/overrides.rb
|
@@ -480,6 +484,7 @@ files:
|
|
480
484
|
- lib/nrser/types/collections.rb
|
481
485
|
- lib/nrser/types/combinators.rb
|
482
486
|
- lib/nrser/types/doc/display_table.md
|
487
|
+
- lib/nrser/types/enumerables.rb
|
483
488
|
- lib/nrser/types/eqiuvalent.rb
|
484
489
|
- lib/nrser/types/errors/check_error.rb
|
485
490
|
- lib/nrser/types/errors/from_string_error.rb
|
@@ -570,6 +575,7 @@ files:
|
|
570
575
|
- spec/lib/nrser/types/attrs_spec.rb
|
571
576
|
- spec/lib/nrser/types/combinators_spec.rb
|
572
577
|
- spec/lib/nrser/types/display_spec.rb
|
578
|
+
- spec/lib/nrser/types/enumerables_spec.rb
|
573
579
|
- spec/lib/nrser/types/is_spec.rb
|
574
580
|
- spec/lib/nrser/types/pairs_spec.rb
|
575
581
|
- spec/lib/nrser/types/paths_spec.rb
|
@@ -629,6 +635,7 @@ test_files:
|
|
629
635
|
- spec/lib/nrser/types/strings_spec.rb
|
630
636
|
- spec/lib/nrser/types/symbols_spec.rb
|
631
637
|
- spec/lib/nrser/types/tuples_spec.rb
|
638
|
+
- spec/lib/nrser/types/enumerables_spec.rb
|
632
639
|
- spec/lib/nrser/types/attrs_spec.rb
|
633
640
|
- spec/lib/nrser/core_ext/hash/short_transform_keys_spec.rb
|
634
641
|
- spec/lib/nrser/core_ext/hash_spec.rb
|