nrser 0.1.4 → 0.2.0.pre.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/nrser.rb +3 -0
- data/lib/nrser/char.rb +2 -3
- data/lib/nrser/char/alpha_numeric_sub.rb +233 -0
- data/lib/nrser/ext.rb +1 -0
- data/lib/nrser/ext/binding.rb +36 -0
- data/lib/nrser/ext/string.rb +29 -0
- data/lib/nrser/functions/binding.rb +40 -15
- data/lib/nrser/functions/string.rb +17 -1
- data/lib/nrser/functions/string/style.rb +71 -0
- data/lib/nrser/mean_streak.rb +33 -8
- data/lib/nrser/mean_streak/document.rb +221 -36
- data/lib/nrser/refinements/binding.rb +3 -4
- data/lib/nrser/rspex.rb +3 -17
- data/lib/nrser/rspex/example.rb +49 -0
- data/lib/nrser/rspex/example_group.rb +61 -33
- data/lib/nrser/rspex/example_group/describe_called_with.rb +42 -0
- data/lib/nrser/rspex/example_group/describe_spec_file.rb +2 -0
- data/lib/nrser/rspex/format.rb +48 -78
- data/lib/nrser/types.rb +71 -14
- data/lib/nrser/types/attrs.rb +121 -110
- data/lib/nrser/types/bounded.rb +3 -2
- data/lib/nrser/types/combinators.rb +39 -8
- data/lib/nrser/types/hashes.rb +5 -4
- data/lib/nrser/types/is.rb +11 -1
- data/lib/nrser/types/is_a.rb +11 -2
- data/lib/nrser/types/maybe.rb +4 -5
- data/lib/nrser/types/nil.rb +1 -10
- data/lib/nrser/types/not.rb +53 -0
- data/lib/nrser/types/numbers.rb +20 -17
- data/lib/nrser/types/shape.rb +75 -0
- data/lib/nrser/types/strings.rb +49 -59
- data/lib/nrser/types/symbols.rb +13 -18
- data/lib/nrser/types/type.rb +32 -9
- data/lib/nrser/types/when.rb +102 -0
- data/lib/nrser/version.rb +1 -1
- data/spec/{nrser → lib/nrser}/collection/each_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/collection/map_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/env/path/insert_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/env/path_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/errors/abstract_method_error_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/binding/template_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/enumerable/find_all_map_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/enumerable/find_bounded_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/enumerable/find_map_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/enumerable/find_only_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/enumerable/include_slice_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/enumerable/to_h_by_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/exception/format_exception_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/hash/bury_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/hash/guess_label_key_type_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/hash_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/merge_by_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/object/truthy_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/open_struct_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/string/common_prefix_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/string/looks_like_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/string/truncate_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/text/dedent/gotchas_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/text/dedent_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/text/indent_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/text/words_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/tree/each_branch_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/tree/leaves_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/tree/map_branch_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/tree/map_tree_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/tree/transform_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/functions/tree/transformer_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/labs/globlin_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/labs/index_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/logger/dest_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/logger/die_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/logger/install_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/logger/level_int_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/logger/level_name_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/logger/level_sym_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/logger/send_log_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/logger/use_spec.rb +0 -0
- data/spec/lib/nrser/mean_streak/design_spec.rb +68 -0
- data/spec/lib/nrser/mean_streak/identity_instance_spec.rb +21 -0
- data/spec/{nrser → lib/nrser}/meta/class_attrs_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/meta/props/to_and_from_data_spec.rb +17 -11
- data/spec/{nrser → lib/nrser}/meta/props_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/op/message_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/array_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/erb_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/format_exception_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/hash_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/indent_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/object_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/pathname_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/set_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/refinements/truncate_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types/array_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types/attrs_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types/combinators_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types/is_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types/pairs_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types/paths_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types/strings_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types/symbols_spec.rb +1 -1
- data/spec/{nrser → lib/nrser}/types/tuples_spec.rb +0 -0
- data/spec/{nrser → lib/nrser}/types_spec.rb +0 -0
- data/spec/{nrser_spec.rb → lib/nrser_spec.rb} +0 -0
- metadata +148 -136
data/lib/nrser/types/type.rb
CHANGED
@@ -25,15 +25,16 @@ module NRSER::Types
|
|
25
25
|
# default generated name.
|
26
26
|
#
|
27
27
|
# @param [nil | #call] from_s:
|
28
|
-
# Callable that will be passed a {String} and should return an object
|
28
|
+
# Callable that will be passed a {String} and should return an object
|
29
29
|
# that satisfies the type if it possible to create one.
|
30
30
|
#
|
31
|
-
# The returned value *will* be checked against the type, so returning a
|
31
|
+
# The returned value *will* be checked against the type, so returning a
|
32
32
|
# value that doesn't satisfy will result in a {TypeError} being raised
|
33
33
|
# by {#from_s}.
|
34
34
|
#
|
35
35
|
# @param [nil | #call | #to_proc] to_data:
|
36
|
-
#
|
36
|
+
# Optional callable (or object that responds to `#to_proc` so we can
|
37
|
+
# get a callable) to call to turn type members into "data".
|
37
38
|
#
|
38
39
|
def initialize name: nil, from_s: nil, to_data: nil, from_data: nil
|
39
40
|
@name = name
|
@@ -89,6 +90,15 @@ module NRSER::Types
|
|
89
90
|
self.class.short_name
|
90
91
|
end
|
91
92
|
|
93
|
+
|
94
|
+
# See if a value satisfies the type.
|
95
|
+
#
|
96
|
+
# @param [Object] value
|
97
|
+
# Value to test for type satisfaction.
|
98
|
+
#
|
99
|
+
# @return [Boolean]
|
100
|
+
# `true` if the `value` satisfies the type.
|
101
|
+
#
|
92
102
|
def test value
|
93
103
|
raise NotImplementedError
|
94
104
|
end
|
@@ -110,7 +120,7 @@ module NRSER::Types
|
|
110
120
|
end
|
111
121
|
|
112
122
|
|
113
|
-
# Overridden to customize behavior for the {#from_s} and {#to_data}
|
123
|
+
# Overridden to customize behavior for the {#from_s} and {#to_data}
|
114
124
|
# methods - those methods are always defined, but we have {#respond_to?}
|
115
125
|
# return `false` if they lack the underlying instance variables needed
|
116
126
|
# to execute.
|
@@ -158,13 +168,13 @@ module NRSER::Types
|
|
158
168
|
# @raise [NoMethodError]
|
159
169
|
# If this type doesn't know how to load values from strings.
|
160
170
|
#
|
161
|
-
# In basic types this happens when {NRSER::Types::Type#initialize} was
|
171
|
+
# In basic types this happens when {NRSER::Types::Type#initialize} was
|
162
172
|
# not provided a `from_s:` {Proc} argument.
|
163
173
|
#
|
164
174
|
# {NRSER::Types::Type} subclasses may override {#from_s} entirely,
|
165
175
|
# divorcing it from the `from_s:` constructor argument and internal
|
166
176
|
# {@from_s} instance variable (which is why {@from_s} is not publicly
|
167
|
-
# exposed - it should not be assumed to dictate {#from_s} behavior
|
177
|
+
# exposed - it should not be assumed to dictate {#from_s} behavior
|
168
178
|
# in general).
|
169
179
|
#
|
170
180
|
# @raise [TypeError]
|
@@ -200,7 +210,7 @@ module NRSER::Types
|
|
200
210
|
|
201
211
|
|
202
212
|
# Test if the type has custom information about how to convert it's values
|
203
|
-
# into "data" - structures and values suitable for transportation and
|
213
|
+
# into "data" - structures and values suitable for transportation and
|
204
214
|
# storage (JSON, etc.).
|
205
215
|
#
|
206
216
|
# If this method returns `true` then {#to_data} should succeed.
|
@@ -244,7 +254,7 @@ module NRSER::Types
|
|
244
254
|
# by some back-ticks to make it easy to see where it starts and stops.
|
245
255
|
#
|
246
256
|
def to_s
|
247
|
-
"
|
257
|
+
"{ x ∈ #{ name } }"
|
248
258
|
end
|
249
259
|
|
250
260
|
|
@@ -266,5 +276,18 @@ module NRSER::Types
|
|
266
276
|
alias_method :builtin_inspect, :inspect
|
267
277
|
alias_method :inspect, :to_s
|
268
278
|
|
279
|
+
|
280
|
+
# Hook into Ruby's *case subsumption* operator to allow usage in `case`
|
281
|
+
# statements!
|
282
|
+
#
|
283
|
+
# TODO Want to switch {NRSER::Types.match} over to use `===`!
|
284
|
+
#
|
285
|
+
# @param value (see #test)
|
286
|
+
# @return (see #test)
|
287
|
+
#
|
288
|
+
def === value
|
289
|
+
test value
|
290
|
+
end
|
291
|
+
|
269
292
|
end # Type
|
270
|
-
end # NRSER::Types
|
293
|
+
end # NRSER::Types
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Requirements
|
4
|
+
# =======================================================================
|
5
|
+
|
6
|
+
# Stdlib
|
7
|
+
# -----------------------------------------------------------------------
|
8
|
+
|
9
|
+
# Deps
|
10
|
+
# -----------------------------------------------------------------------
|
11
|
+
|
12
|
+
# Project / Package
|
13
|
+
# -----------------------------------------------------------------------
|
14
|
+
|
15
|
+
|
16
|
+
# Refinements
|
17
|
+
# =======================================================================
|
18
|
+
|
19
|
+
|
20
|
+
# Declarations
|
21
|
+
# =======================================================================
|
22
|
+
|
23
|
+
|
24
|
+
# Definitions
|
25
|
+
# =======================================================================
|
26
|
+
|
27
|
+
module NRSER::Types
|
28
|
+
|
29
|
+
class When < Type
|
30
|
+
|
31
|
+
|
32
|
+
# The wrapped {Object} whose `#===` will be used to test membership.
|
33
|
+
#
|
34
|
+
# @return [Object]
|
35
|
+
#
|
36
|
+
attr_reader :object
|
37
|
+
|
38
|
+
|
39
|
+
# Constructor
|
40
|
+
# ======================================================================
|
41
|
+
|
42
|
+
# Instantiate a new `NRSER::Types::When`.
|
43
|
+
def initialize object, **options
|
44
|
+
super **options
|
45
|
+
@object = object
|
46
|
+
end # #initialize
|
47
|
+
|
48
|
+
|
49
|
+
# Instance Methods
|
50
|
+
# ======================================================================
|
51
|
+
|
52
|
+
def test value
|
53
|
+
@object === value
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def default_name
|
58
|
+
@object.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
# If {#object} responds to `#from_data`, call that and check results.
|
62
|
+
#
|
63
|
+
# Otherwise, forward up to {NRSER::Types::Type#from_data}.
|
64
|
+
#
|
65
|
+
# @param [Object] data
|
66
|
+
# Data to create the value from that will satisfy the type.
|
67
|
+
#
|
68
|
+
# @return [Object]
|
69
|
+
# Instance of {#object}.
|
70
|
+
#
|
71
|
+
def from_data data
|
72
|
+
if @from_data.nil?
|
73
|
+
if @object.respond_to? :from_data
|
74
|
+
check @object.from_data( data )
|
75
|
+
else
|
76
|
+
super data
|
77
|
+
end
|
78
|
+
else
|
79
|
+
@from_data.call data
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def has_from_data?
|
85
|
+
@from_data || @object.respond_to?( :from_data )
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
def == other
|
90
|
+
equal?( other ) ||
|
91
|
+
( self.class == other.class &&
|
92
|
+
self.object == other.object )
|
93
|
+
end
|
94
|
+
|
95
|
+
end # class When
|
96
|
+
|
97
|
+
|
98
|
+
def self.when value, **options
|
99
|
+
When.new value, **options
|
100
|
+
end
|
101
|
+
|
102
|
+
end # module NRSER::Types
|
data/lib/nrser/version.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
describe_spec_file(
|
5
|
+
spec_path: __FILE__,
|
6
|
+
class: NRSER::MeanStreak,
|
7
|
+
) do
|
8
|
+
|
9
|
+
describe "Test instance (`*...*` => `<I>...</I>`, etc. replacements)" do
|
10
|
+
subject {
|
11
|
+
described_class.new do |ms|
|
12
|
+
ms.render_type :emph do |doc, node|
|
13
|
+
"<I>#{ doc.render_children( node ) }</I>"
|
14
|
+
end
|
15
|
+
|
16
|
+
ms.render_type :strong do |doc, node|
|
17
|
+
"<B>#{ doc.render_children( node ) }</B>"
|
18
|
+
end
|
19
|
+
|
20
|
+
ms.render_type :code do |doc, node|
|
21
|
+
"<C>#{ node.string_content }</C>"
|
22
|
+
end
|
23
|
+
|
24
|
+
# ms.render_type :code do |doc, prev_node, source_before, node, source_after, next_node|
|
25
|
+
# [
|
26
|
+
# source_before.chomp( '`' ),
|
27
|
+
# "C#{ node.string_content }/C",
|
28
|
+
# source_after.lchomp( '`' ),
|
29
|
+
# ]
|
30
|
+
# end
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
describe_method :render do
|
35
|
+
it_behaves_like "function",
|
36
|
+
mapping: {
|
37
|
+
# No handled nodes
|
38
|
+
"Here I am" => "Here I am",
|
39
|
+
|
40
|
+
# Simple `:emph`, `:strong` with just a text child
|
41
|
+
"Here *I* am" => "Here <I>I</I> am",
|
42
|
+
"**Here** *I* am" => "<B>Here</B> <I>I</I> am",
|
43
|
+
|
44
|
+
# Nested `:emph` / `:strong`
|
45
|
+
"*Here **I** am*" => "<I>Here <B>I</B> am</I>",
|
46
|
+
|
47
|
+
# `:code`
|
48
|
+
"Here `I` am" => "Here <C>I</C> am",
|
49
|
+
# At the start
|
50
|
+
"`Here I` am" => "<C>Here I</C> am",
|
51
|
+
# At the end
|
52
|
+
"Here `I am`" => "Here <C>I am</C>",
|
53
|
+
|
54
|
+
# Some big ol' bytes
|
55
|
+
"北京东城东直门" => "北京东城东直门",
|
56
|
+
"北京*东城*东直门" => "北京<I>东城</I>东直门",
|
57
|
+
|
58
|
+
# Nesty-messtys with `:code` blocks...
|
59
|
+
#
|
60
|
+
# It turns out the way to include ` in inline code is to quote
|
61
|
+
# with more than the longest backtick run inside
|
62
|
+
#
|
63
|
+
%{A string: ``"with `backticks` in it"``} =>
|
64
|
+
%{A string: <C>"with `backticks` in it"</C>}
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
describe_spec_file(
|
5
|
+
description: %{
|
6
|
+
{NRSER::MeanStreak} constructed with no `#render_type` handlers
|
7
|
+
|
8
|
+
Should serves as an identity function, rendering the same markdown source
|
9
|
+
that it received.
|
10
|
+
},
|
11
|
+
spec_path: __FILE__,
|
12
|
+
class: NRSER::MeanStreak,
|
13
|
+
) do
|
14
|
+
describe_instance do
|
15
|
+
describe_method :render do
|
16
|
+
describe_called_with "hey" do
|
17
|
+
it { is_expected.to eq "hey" }
|
18
|
+
end # called with "hey"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end # describe_spec_file
|
File without changes
|
@@ -12,11 +12,14 @@ describe NRSER::Meta::Props do
|
|
12
12
|
describe_section "to and from data" do
|
13
13
|
# ========================================================================
|
14
14
|
|
15
|
+
non_empty_str = t.non_empty_str
|
16
|
+
unsigned = t.unsigned
|
17
|
+
|
15
18
|
before( :all ) {
|
16
|
-
@cat_class = Class.new( NRSER::Meta::Props::Base ) do
|
17
|
-
prop :name, type:
|
18
|
-
prop :breed, type:
|
19
|
-
prop :age, type:
|
19
|
+
Cat = @cat_class = Class.new( NRSER::Meta::Props::Base ) do
|
20
|
+
prop :name, type: non_empty_str
|
21
|
+
prop :breed, type: non_empty_str
|
22
|
+
prop :age, type: unsigned
|
20
23
|
|
21
24
|
def self.name; 'Cat'; end
|
22
25
|
end
|
@@ -31,14 +34,17 @@ describe NRSER::Meta::Props do
|
|
31
34
|
cat_class = @cat_class
|
32
35
|
|
33
36
|
@owner_class = Class.new( NRSER::Meta::Props::Base ) do
|
34
|
-
prop :name, type:
|
37
|
+
prop :name, type: non_empty_str
|
35
38
|
|
36
39
|
prop :cat, type: cat_class
|
37
40
|
|
38
41
|
def self.name; 'Owner'; end
|
39
42
|
end
|
40
43
|
|
41
|
-
@cat = @cat_class.new
|
44
|
+
@cat = @cat_class.new \
|
45
|
+
name: "Hooty",
|
46
|
+
breed: "American Shorthair",
|
47
|
+
age: 2
|
42
48
|
|
43
49
|
@owner = @owner_class.new name: "Neil", cat: @cat
|
44
50
|
}
|
@@ -47,20 +53,20 @@ describe NRSER::Meta::Props do
|
|
47
53
|
expect( @cat_class ).to be_a Class
|
48
54
|
expect( @cat_class.is_a? ::Class ).to be true
|
49
55
|
expect( @cat_class.name ).to eq "Cat"
|
50
|
-
expect( t.make @cat_class ).to be_a NRSER::Types::
|
56
|
+
expect( t.make @cat_class ).to be_a NRSER::Types::When
|
51
57
|
|
52
58
|
name_prop = @owner_class.props[:name]
|
53
|
-
expect( name_prop.type ).to be
|
59
|
+
expect( name_prop.type ).to be non_empty_str
|
54
60
|
|
55
61
|
cat_prop = @owner_class.props[:cat]
|
56
|
-
expect( cat_prop.type ).to be_a NRSER::Types::
|
57
|
-
expect( cat_prop.type.
|
62
|
+
expect( cat_prop.type ).to be_a NRSER::Types::When
|
63
|
+
expect( cat_prop.type.object ).to be @cat_class
|
58
64
|
expect( @cat_class.respond_to? :from_data ).to be true
|
59
65
|
expect( cat_prop.type.has_from_data? ).to be true
|
60
66
|
end
|
61
67
|
|
62
68
|
it "dumps to and loads from data" do
|
63
|
-
data = @owner.to_data
|
69
|
+
data = @owner.to_data
|
64
70
|
restored = @owner_class.from_data data
|
65
71
|
expect( restored.to_data ).to eq data
|
66
72
|
end
|