nrser 0.0.20 → 0.0.21
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 +3 -6
- data/lib/nrser/collection.rb +58 -20
- data/lib/nrser/enumerable.rb +155 -25
- data/lib/nrser/errors.rb +9 -0
- data/lib/nrser/hash.rb +1 -17
- data/lib/nrser/meta/class_attrs.rb +59 -9
- data/lib/nrser/open_struct.rb +60 -0
- data/lib/nrser/refinements/array.rb +4 -5
- data/lib/nrser/refinements/enumerable.rb +41 -0
- data/lib/nrser/refinements/enumerator.rb +7 -0
- data/lib/nrser/refinements/exception.rb +28 -0
- data/lib/nrser/refinements/hash.rb +9 -7
- data/lib/nrser/refinements/open_struct.rb +30 -0
- data/lib/nrser/refinements/set.rb +9 -0
- data/lib/nrser/refinements/string.rb +9 -0
- data/lib/nrser/refinements.rb +3 -0
- data/lib/nrser/types/attrs.rb +62 -35
- data/lib/nrser/types/bounded.rb +21 -4
- data/lib/nrser/types/combinators.rb +8 -4
- data/lib/nrser/types/is.rb +1 -1
- data/lib/nrser/types/responds.rb +110 -0
- data/lib/nrser/types/strings.rb +6 -0
- data/lib/nrser/types/type.rb +11 -6
- data/lib/nrser/types.rb +41 -6
- data/lib/nrser/version.rb +50 -1
- data/lib/nrser.rb +1 -0
- data/spec/nrser/enumerable_spec.rb +97 -0
- data/spec/nrser/hash_spec.rb +46 -2
- data/spec/nrser/open_struct_spec.rb +94 -0
- data/spec/nrser/refinements/array_spec.rb +25 -1
- data/spec/nrser/refinements/hash_spec.rb +30 -0
- data/spec/nrser/refinements/set_spec.rb +41 -0
- data/spec/nrser/types_spec.rb +13 -3
- metadata +58 -3
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
1
3
|
module NRSER
|
2
4
|
refine String do
|
3
5
|
def squish
|
@@ -27,5 +29,12 @@ module NRSER
|
|
27
29
|
|
28
30
|
alias_method :to_const, :constantize
|
29
31
|
|
32
|
+
# @return [Pathname]
|
33
|
+
# Convert self into a {Pathname}
|
34
|
+
#
|
35
|
+
def to_pn
|
36
|
+
Pathname.new self
|
37
|
+
end
|
38
|
+
|
30
39
|
end # refine String
|
31
40
|
end # NRSER
|
data/lib/nrser/refinements.rb
CHANGED
@@ -5,3 +5,6 @@ require_relative './refinements/hash'
|
|
5
5
|
require_relative './refinements/pathname'
|
6
6
|
require_relative './refinements/exception'
|
7
7
|
require_relative './refinements/binding'
|
8
|
+
require_relative './refinements/set'
|
9
|
+
require_relative './refinements/open_struct'
|
10
|
+
require_relative './refinements/enumerator'
|
data/lib/nrser/types/attrs.rb
CHANGED
@@ -8,62 +8,89 @@ module NRSER::Types
|
|
8
8
|
class Attrs < NRSER::Types::Type
|
9
9
|
def initialize attrs, **options
|
10
10
|
super **options
|
11
|
-
@attrs = attrs
|
11
|
+
@attrs = NRSER.map_values(attrs) { |name, type|
|
12
|
+
NRSER::Types.make type
|
13
|
+
}
|
12
14
|
end
|
13
15
|
|
14
16
|
def default_name
|
15
|
-
attrs_str = @attrs.map {|name, type|
|
17
|
+
attrs_str = @attrs.map { |name, type|
|
16
18
|
"#{ name }=#{ type.name }"
|
17
19
|
}.join(', ')
|
18
20
|
|
19
|
-
"#{ self.class.short_name }
|
21
|
+
"#{ self.class.short_name } #{ attrs_str }"
|
20
22
|
end
|
21
23
|
|
22
24
|
def test value
|
23
|
-
@attrs.all? {|name, type|
|
25
|
+
@attrs.all? { |name, type|
|
24
26
|
value.respond_to?(name) && type.test(value.method(name).call)
|
25
27
|
}
|
26
28
|
end
|
27
29
|
end # Attrs
|
28
30
|
|
29
|
-
def self.attrs attrs, options = {}
|
30
|
-
Attrs.new attrs, **options
|
31
|
-
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
32
|
+
# Eigenclass (Singleton Class)
|
33
|
+
# ========================================================================
|
34
|
+
#
|
35
|
+
class << self
|
36
|
+
def attrs attrs, options = {}
|
37
|
+
Attrs.new attrs, **options
|
38
|
+
end
|
39
|
+
|
40
|
+
def length *args
|
41
|
+
bounds = {}
|
42
|
+
options = {}
|
43
|
+
|
44
|
+
case args.length
|
45
|
+
when 1
|
46
|
+
case args[0]
|
47
|
+
when ::Integer
|
48
|
+
bounds[:min] = bounds[:max] = non_neg_int.check(args[0])
|
49
|
+
|
50
|
+
when ::Hash
|
51
|
+
options = NRSER.symbolize_keys args[0]
|
52
|
+
|
53
|
+
bounds[:min] = options.delete :min
|
54
|
+
bounds[:max] = options.delete :max
|
55
|
+
|
56
|
+
if length = options.delete(:length)
|
57
|
+
bounds[:min] = length
|
58
|
+
bounds[:max] = length
|
47
59
|
end
|
48
|
-
|
60
|
+
|
61
|
+
else
|
62
|
+
raise ArgumentError, <<-END.squish
|
63
|
+
arg must be positive integer or option hash, found:
|
64
|
+
#{ args[0].inspect } of type #{ args[0].class }
|
65
|
+
END
|
66
|
+
end
|
49
67
|
|
50
|
-
|
68
|
+
when 2
|
69
|
+
bounds[:min] = bounds[:max] = non_neg_int.check(args[0])
|
70
|
+
options = args[1]
|
71
|
+
|
72
|
+
else
|
51
73
|
raise ArgumentError, <<-END.squish
|
52
|
-
|
53
|
-
#{ args[0].inspect } of type #{ args[0].class }
|
74
|
+
must provided 1 or 2 args.
|
54
75
|
END
|
55
76
|
end
|
56
77
|
|
57
|
-
|
58
|
-
bounds[:min] = bounds[:max] = non_neg_int.check(args[0])
|
59
|
-
options = args[1]
|
78
|
+
bounded_type = bounded bounds
|
60
79
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
80
|
+
length_type = if !bounded_type.min.nil? && bounded_type.min >= 0
|
81
|
+
# We don't need the non-neg check
|
82
|
+
bounded_type
|
83
|
+
else
|
84
|
+
# We do need the non-neg check
|
85
|
+
intersection(non_neg_int, bounded_type)
|
86
|
+
end
|
87
|
+
|
88
|
+
options[:name] ||= "Length<#{ bounded_type.name }>"
|
89
|
+
|
90
|
+
attrs({ length: length_type }, options)
|
91
|
+
end # #length
|
92
|
+
|
66
93
|
|
67
|
-
|
68
|
-
|
94
|
+
end # class << self (Eigenclass)
|
95
|
+
|
69
96
|
end # NRSER::Types
|
data/lib/nrser/types/bounded.rb
CHANGED
@@ -5,9 +5,26 @@ using NRSER
|
|
5
5
|
|
6
6
|
module NRSER::Types
|
7
7
|
class Bounded < NRSER::Types::Type
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
|
9
|
+
# @!attribute [r] min
|
10
|
+
# @return [Number]
|
11
|
+
# Minimum value.
|
12
|
+
attr_reader :min
|
13
|
+
|
14
|
+
|
15
|
+
# @!attribute [r] max
|
16
|
+
# @return [Number]
|
17
|
+
# Minimum value.
|
18
|
+
attr_reader :max
|
19
|
+
|
20
|
+
|
21
|
+
def initialize min: nil,
|
22
|
+
max: nil,
|
23
|
+
**options
|
24
|
+
super **options
|
25
|
+
|
26
|
+
@min = min
|
27
|
+
@max = max
|
11
28
|
end
|
12
29
|
|
13
30
|
def test value
|
@@ -25,7 +42,7 @@ module NRSER::Types
|
|
25
42
|
"#{ name }=#{ value }"
|
26
43
|
}.join(', ')
|
27
44
|
|
28
|
-
"#{ self.class.short_name }
|
45
|
+
"#{ self.class.short_name } #{ attrs_str }"
|
29
46
|
end
|
30
47
|
end # Bounded
|
31
48
|
|
@@ -13,11 +13,11 @@ module NRSER::Types
|
|
13
13
|
@types = types.map {|type| NRSER::Types.make type}
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def default_name
|
17
17
|
@name || (
|
18
|
-
"#{ self.class.short_name }
|
18
|
+
"#{ self.class.short_name }<" +
|
19
19
|
@types.map {|type| type.name }.join(',') +
|
20
|
-
"
|
20
|
+
">"
|
21
21
|
)
|
22
22
|
end
|
23
23
|
|
@@ -42,7 +42,7 @@ module NRSER::Types
|
|
42
42
|
}
|
43
43
|
|
44
44
|
raise TypeError,
|
45
|
-
"none of
|
45
|
+
"none of combinator #{ self.to_s } types could convert #{ s.inspect }"
|
46
46
|
end
|
47
47
|
|
48
48
|
def == other
|
@@ -69,6 +69,10 @@ module NRSER::Types
|
|
69
69
|
def test value
|
70
70
|
@types.all? {|type| type.test value}
|
71
71
|
end
|
72
|
+
|
73
|
+
def default_name
|
74
|
+
"( #{ @types.map { |t| t.name }.join ' | ' } )"
|
75
|
+
end
|
72
76
|
end
|
73
77
|
|
74
78
|
# match all of the types
|
data/lib/nrser/types/is.rb
CHANGED
@@ -0,0 +1,110 @@
|
|
1
|
+
|
2
|
+
# @todo document NRSER::Types module.
|
3
|
+
module NRSER::Types
|
4
|
+
|
5
|
+
# @todo document Responds class.
|
6
|
+
class Responds < NRSER::Types::Type
|
7
|
+
|
8
|
+
# Constants
|
9
|
+
# ======================================================================
|
10
|
+
|
11
|
+
|
12
|
+
# Class Methods
|
13
|
+
# ======================================================================
|
14
|
+
|
15
|
+
|
16
|
+
# Attributes
|
17
|
+
# ======================================================================
|
18
|
+
|
19
|
+
|
20
|
+
# Constructor
|
21
|
+
# ======================================================================
|
22
|
+
|
23
|
+
# Instantiate a new `Responds`.
|
24
|
+
def initialize map,
|
25
|
+
public: true,
|
26
|
+
**options
|
27
|
+
@map = NRSER.map_values(map) { |args, type|
|
28
|
+
NRSER::Types.make type
|
29
|
+
}
|
30
|
+
end # #initialize
|
31
|
+
|
32
|
+
|
33
|
+
# Instance Methods
|
34
|
+
# ======================================================================
|
35
|
+
|
36
|
+
|
37
|
+
def default_name
|
38
|
+
attrs_str = @map.map { |args, type|
|
39
|
+
args_str = args[1..-1].map(&:inspect).join ', '
|
40
|
+
"#{ args[0] }(#{ args_str })=#{ type.name }"
|
41
|
+
}.join(', ')
|
42
|
+
|
43
|
+
"#{ self.class.short_name } #{ attrs_str }"
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# @todo Document test method.
|
48
|
+
#
|
49
|
+
# @param [type] arg_name
|
50
|
+
# @todo Add name param description.
|
51
|
+
#
|
52
|
+
# @return [return_type]
|
53
|
+
# @todo Document return value.
|
54
|
+
#
|
55
|
+
def test value
|
56
|
+
@map.all? { |args, type|
|
57
|
+
response = if @public
|
58
|
+
value.public_send *args
|
59
|
+
else
|
60
|
+
value.send *args
|
61
|
+
end
|
62
|
+
|
63
|
+
type.test response
|
64
|
+
}
|
65
|
+
end # #test
|
66
|
+
|
67
|
+
|
68
|
+
end # class Responds
|
69
|
+
|
70
|
+
|
71
|
+
# Eigenclass (Singleton Class)
|
72
|
+
# ========================================================================
|
73
|
+
#
|
74
|
+
class << self
|
75
|
+
|
76
|
+
|
77
|
+
# @todo Document responds method.
|
78
|
+
#
|
79
|
+
# @param [type] arg_name
|
80
|
+
# @todo Add name param description.
|
81
|
+
#
|
82
|
+
# @return [return_type]
|
83
|
+
# @todo Document return value.
|
84
|
+
#
|
85
|
+
def responds *args
|
86
|
+
Responds.new *args
|
87
|
+
end # #responds
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
# @todo Document respond_to Responds.
|
92
|
+
#
|
93
|
+
# @param [type] arg_name
|
94
|
+
# @todo Add name param description.
|
95
|
+
#
|
96
|
+
# @return [return_type]
|
97
|
+
# @todo Document return value.
|
98
|
+
#
|
99
|
+
def respond_to name, **options
|
100
|
+
responds(
|
101
|
+
{[:respond_to?, name] => NRSER::Types::TRUE},
|
102
|
+
**options
|
103
|
+
)
|
104
|
+
end # #respond_to
|
105
|
+
|
106
|
+
|
107
|
+
end # class << self (Eigenclass)
|
108
|
+
|
109
|
+
|
110
|
+
end # module NRSER::Types
|
data/lib/nrser/types/strings.rb
CHANGED
data/lib/nrser/types/type.rb
CHANGED
@@ -24,14 +24,19 @@ module NRSER::Types
|
|
24
24
|
raise NotImplementedError
|
25
25
|
end
|
26
26
|
|
27
|
-
def check value
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
def check value, &make_fail_message
|
28
|
+
# success case
|
29
|
+
return value if test value
|
30
|
+
|
31
|
+
msg = if make_fail_message
|
32
|
+
make_fail_message.call type: self, value: value
|
33
|
+
else
|
34
|
+
NRSER.squish <<-END
|
35
|
+
value #{ value.inspect } failed check #{ self.to_s }
|
31
36
|
END
|
32
37
|
end
|
33
38
|
|
34
|
-
|
39
|
+
raise TypeError.new msg
|
35
40
|
end
|
36
41
|
|
37
42
|
def respond_to? name, include_all = false
|
@@ -55,7 +60,7 @@ module NRSER::Types
|
|
55
60
|
end
|
56
61
|
|
57
62
|
def to_s
|
58
|
-
"
|
63
|
+
"`Type: #{ name }`"
|
59
64
|
end
|
60
65
|
end # Type
|
61
66
|
end # NRSER::Types
|
data/lib/nrser/types.rb
CHANGED
@@ -8,6 +8,7 @@ require 'nrser/types/where'
|
|
8
8
|
require 'nrser/types/combinators'
|
9
9
|
require 'nrser/types/maybe'
|
10
10
|
require 'nrser/types/attrs'
|
11
|
+
require 'nrser/types/responds'
|
11
12
|
|
12
13
|
using NRSER
|
13
14
|
|
@@ -32,21 +33,55 @@ module NRSER::Types
|
|
32
33
|
make(type).test value
|
33
34
|
end
|
34
35
|
|
35
|
-
def self.match value,
|
36
|
-
|
36
|
+
def self.match value, *clauses
|
37
|
+
if clauses.empty?
|
38
|
+
raise ArgumentError.new NRSER.dedent <<-END
|
39
|
+
Must supply either a single {type => expression} hash argument or a
|
40
|
+
even amount of arguments representing (type, expression) pairs after
|
41
|
+
`value`.
|
42
|
+
|
43
|
+
#{ NRSER::Version.doc_url 'NRSER/Types#match-class_method' }
|
44
|
+
END
|
45
|
+
end
|
46
|
+
|
47
|
+
enum = if clauses.length == 1 && clauses.first.respond_to?(:each_pair)
|
48
|
+
clauses.first.each_pair
|
49
|
+
else
|
50
|
+
unless clauses.length % 2 == 0
|
51
|
+
raise TypeError.new NRSER.dedent <<-END
|
52
|
+
When passing a list of clauses, it must be an even length
|
53
|
+
representing (type, expression) pairs.
|
54
|
+
|
55
|
+
Found an argument list with length #{ clauses.length }:
|
56
|
+
|
57
|
+
#{ clauses }
|
58
|
+
END
|
59
|
+
end
|
60
|
+
|
61
|
+
clauses.each_slice(2)
|
62
|
+
end
|
63
|
+
|
64
|
+
enum.each { |type, expression|
|
37
65
|
if test value, type
|
38
|
-
|
66
|
+
# OK, we matched! Is the corresponding expression callable?
|
67
|
+
if expression.respond_to? :call
|
68
|
+
# It is; invoke and return result.
|
69
|
+
return expression.call value
|
70
|
+
else
|
71
|
+
# It's not; assume it's a value and return it.
|
72
|
+
return expression
|
73
|
+
end
|
39
74
|
end
|
40
75
|
}
|
41
76
|
|
42
77
|
raise TypeError, <<-END.dedent
|
43
|
-
|
78
|
+
Could not match value
|
44
79
|
|
45
|
-
|
80
|
+
#{ value.inspect }
|
46
81
|
|
47
82
|
to any of types
|
48
83
|
|
49
|
-
#{
|
84
|
+
#{ enum.map {|type, expression| "\n #{ type.inspect }"} }
|
50
85
|
|
51
86
|
END
|
52
87
|
end
|
data/lib/nrser/version.rb
CHANGED
@@ -1,3 +1,52 @@
|
|
1
1
|
module NRSER
|
2
|
-
VERSION = "0.0.
|
2
|
+
VERSION = "0.0.21"
|
3
|
+
|
4
|
+
module Version
|
5
|
+
|
6
|
+
# @return [Gem::Version]
|
7
|
+
# Parse of {NRSER::VERSION}.
|
8
|
+
#
|
9
|
+
def self.gem_version
|
10
|
+
Gem::Version.new VERSION
|
11
|
+
end # .gem_version
|
12
|
+
|
13
|
+
|
14
|
+
# The `Gem::Version` "release" for {NRSER::VERSION} - everything before
|
15
|
+
# any `-<alpha-numeric>` prerelease part (like `-dev`).
|
16
|
+
#
|
17
|
+
# @see https://ruby-doc.org/stdlib-2.4.1/libdoc/rubygems/rdoc/Gem/Version.html#method-i-release
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
#
|
21
|
+
# NRSER::VERSION
|
22
|
+
# # => '0.0.21.dev'
|
23
|
+
#
|
24
|
+
# NRSER::Version.release
|
25
|
+
# # => #<Gem::Version "0.0.21">
|
26
|
+
#
|
27
|
+
# @return [Gem::Version]
|
28
|
+
#
|
29
|
+
def self.release
|
30
|
+
gem_version.release
|
31
|
+
end # .release
|
32
|
+
|
33
|
+
|
34
|
+
# Get a URL to a place in the current version's docs on ruby-docs.org.
|
35
|
+
#
|
36
|
+
# @param [String] rel_path
|
37
|
+
# Relative path.
|
38
|
+
#
|
39
|
+
# @return [String]
|
40
|
+
# The RubyDocs URL.
|
41
|
+
#
|
42
|
+
def self.doc_url rel_path
|
43
|
+
File.join(
|
44
|
+
"http://www.rubydoc.info/gems/nrser",
|
45
|
+
NRSER::Version.release.to_s,
|
46
|
+
rel_path
|
47
|
+
)
|
48
|
+
end # .doc_url
|
49
|
+
|
50
|
+
|
51
|
+
end
|
3
52
|
end
|
data/lib/nrser.rb
CHANGED
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "NRSER Enumerable Methods" do
|
4
|
+
|
5
|
+
describe NRSER.method(:find_bounded) do
|
6
|
+
|
7
|
+
context "when just :length bounds arg is provided" do
|
8
|
+
it "returns found elements when length is correct" do
|
9
|
+
expect(
|
10
|
+
subject.([1, 2, 3], length: 1) { |i| i == 2 }
|
11
|
+
).to eq [2]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "raises TypeError when length in incorrect" do
|
15
|
+
expect {
|
16
|
+
subject.([1, 2, 3], length: 2) { |i| i == 2 }
|
17
|
+
}.to raise_error TypeError
|
18
|
+
end
|
19
|
+
end # when just :length bounds arg is provided
|
20
|
+
|
21
|
+
context "when just :min bounds arg is provided" do
|
22
|
+
it "returns found elements when min is correct" do
|
23
|
+
expect(
|
24
|
+
subject.([1, 2, 3], min: 1) { |i| i == 2 }
|
25
|
+
).to eq [2]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "raises TypeError when min in incorrect" do
|
29
|
+
expect {
|
30
|
+
subject.([1, 2, 3], min: 2) { |i| i == 2 }
|
31
|
+
}.to raise_error TypeError
|
32
|
+
end
|
33
|
+
end # when just :min bounds arg is provided
|
34
|
+
|
35
|
+
context "when just :max bounds arg is provided" do
|
36
|
+
it "returns found elements when max is correct" do
|
37
|
+
expect(
|
38
|
+
subject.([1, 2, 3], max: 2) { |i| i >= 2 }
|
39
|
+
).to eq [2, 3]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises TypeError when max in incorrect" do
|
43
|
+
expect {
|
44
|
+
subject.([1, 2, 3], max: 1) { |i| i >= 2 }
|
45
|
+
}.to raise_error TypeError
|
46
|
+
end
|
47
|
+
end # when just :max bounds arg is provided
|
48
|
+
|
49
|
+
|
50
|
+
context "when :min and :max bounds args are both provided" do
|
51
|
+
it "returns found elements when min and max are correct" do
|
52
|
+
expect(
|
53
|
+
subject.([1, 2, 3], min: 1, max: 2) { |i| i >= 2 }
|
54
|
+
).to eq [2, 3]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raises TypeError when min is incorrect" do
|
58
|
+
expect {
|
59
|
+
subject.([1, 2, 3], min: 1, max: 2) { |i| false }
|
60
|
+
}.to raise_error TypeError
|
61
|
+
end
|
62
|
+
|
63
|
+
it "raises TypeError when max is incorrect" do
|
64
|
+
expect {
|
65
|
+
subject.([1, 2, 3], min: 1, max: 2) { |i| true }
|
66
|
+
}.to raise_error TypeError
|
67
|
+
end
|
68
|
+
end # when :min and :max bounds args are both provided
|
69
|
+
|
70
|
+
end # NRSER.method(:find_bounded)
|
71
|
+
|
72
|
+
|
73
|
+
describe NRSER.method(:find_only) do
|
74
|
+
|
75
|
+
it "returns the element when only one is found" do
|
76
|
+
expect(
|
77
|
+
subject.call [1, 2, 3] { |i| i == 2 }
|
78
|
+
).to be 2
|
79
|
+
end
|
80
|
+
|
81
|
+
it "raises TypeError when more than one element is found" do
|
82
|
+
expect {
|
83
|
+
subject.call [1, 2, 3] { |i| i >= 2 }
|
84
|
+
}.to raise_error TypeError
|
85
|
+
end
|
86
|
+
|
87
|
+
it "raises TypeError when no elements are found" do
|
88
|
+
expect {
|
89
|
+
subject.call [1, 2, 3] { |i| false }
|
90
|
+
}.to raise_error TypeError
|
91
|
+
end
|
92
|
+
|
93
|
+
end # NRSER.method(:find_only)
|
94
|
+
|
95
|
+
|
96
|
+
end # NRSER Enumerable Methods
|
97
|
+
|
data/spec/nrser/hash_spec.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'ostruct'
|
3
|
+
|
1
4
|
require 'spec_helper'
|
2
5
|
|
3
6
|
using NRSER
|
4
7
|
|
5
|
-
describe NRSER.method(:
|
8
|
+
describe NRSER.method(:leaves) do
|
6
9
|
it do
|
7
10
|
expect(NRSER.leaves({a: 1, b: 2})).to eq ({[:a] => 1, [:b] => 2})
|
8
11
|
expect(
|
@@ -21,4 +24,45 @@ describe NRSER.method(:truncate) do
|
|
21
24
|
[:b] => 'bee',
|
22
25
|
})
|
23
26
|
end
|
24
|
-
end #
|
27
|
+
end # NRSER.leaves
|
28
|
+
|
29
|
+
describe NRSER.method(:map_values) do
|
30
|
+
|
31
|
+
it "handles hashes" do
|
32
|
+
expect(
|
33
|
+
NRSER.map_values({a: 1, b: 2}) { |k, v| v * 3 }
|
34
|
+
).to eq(
|
35
|
+
{a: 3, b: 6}
|
36
|
+
)
|
37
|
+
end # handles hashes
|
38
|
+
|
39
|
+
|
40
|
+
it "handles arrays" do
|
41
|
+
expect(
|
42
|
+
NRSER.map_values([:a, :b, :c]) { |k, v| "#{ k } is ok!" }
|
43
|
+
).to eq(
|
44
|
+
{a: "a is ok!", b: "b is ok!", c: "c is ok!"}
|
45
|
+
)
|
46
|
+
end # handles arrays
|
47
|
+
|
48
|
+
|
49
|
+
it "handles sets" do
|
50
|
+
expect(
|
51
|
+
NRSER.map_values(Set.new [:a, :b, :c]) { |k, v| "#{ k } is ok!" }
|
52
|
+
).to eq(
|
53
|
+
{a: "a is ok!", b: "b is ok!", c: "c is ok!"}
|
54
|
+
)
|
55
|
+
end # handles sets
|
56
|
+
|
57
|
+
|
58
|
+
it "handles OpenStruct instances" do
|
59
|
+
expect(
|
60
|
+
NRSER.map_values(OpenStruct.new a: 1, b: 2) { |k, v| v * 3 }
|
61
|
+
).to eq(
|
62
|
+
{a: 3, b: 6}
|
63
|
+
)
|
64
|
+
end # handles OpenStruct instances
|
65
|
+
|
66
|
+
|
67
|
+
end # NRSER.map_values
|
68
|
+
|