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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nrser.rb +3 -0
  3. data/lib/nrser/char.rb +2 -3
  4. data/lib/nrser/char/alpha_numeric_sub.rb +233 -0
  5. data/lib/nrser/ext.rb +1 -0
  6. data/lib/nrser/ext/binding.rb +36 -0
  7. data/lib/nrser/ext/string.rb +29 -0
  8. data/lib/nrser/functions/binding.rb +40 -15
  9. data/lib/nrser/functions/string.rb +17 -1
  10. data/lib/nrser/functions/string/style.rb +71 -0
  11. data/lib/nrser/mean_streak.rb +33 -8
  12. data/lib/nrser/mean_streak/document.rb +221 -36
  13. data/lib/nrser/refinements/binding.rb +3 -4
  14. data/lib/nrser/rspex.rb +3 -17
  15. data/lib/nrser/rspex/example.rb +49 -0
  16. data/lib/nrser/rspex/example_group.rb +61 -33
  17. data/lib/nrser/rspex/example_group/describe_called_with.rb +42 -0
  18. data/lib/nrser/rspex/example_group/describe_spec_file.rb +2 -0
  19. data/lib/nrser/rspex/format.rb +48 -78
  20. data/lib/nrser/types.rb +71 -14
  21. data/lib/nrser/types/attrs.rb +121 -110
  22. data/lib/nrser/types/bounded.rb +3 -2
  23. data/lib/nrser/types/combinators.rb +39 -8
  24. data/lib/nrser/types/hashes.rb +5 -4
  25. data/lib/nrser/types/is.rb +11 -1
  26. data/lib/nrser/types/is_a.rb +11 -2
  27. data/lib/nrser/types/maybe.rb +4 -5
  28. data/lib/nrser/types/nil.rb +1 -10
  29. data/lib/nrser/types/not.rb +53 -0
  30. data/lib/nrser/types/numbers.rb +20 -17
  31. data/lib/nrser/types/shape.rb +75 -0
  32. data/lib/nrser/types/strings.rb +49 -59
  33. data/lib/nrser/types/symbols.rb +13 -18
  34. data/lib/nrser/types/type.rb +32 -9
  35. data/lib/nrser/types/when.rb +102 -0
  36. data/lib/nrser/version.rb +1 -1
  37. data/spec/{nrser → lib/nrser}/collection/each_spec.rb +0 -0
  38. data/spec/{nrser → lib/nrser}/collection/map_spec.rb +0 -0
  39. data/spec/{nrser → lib/nrser}/env/path/insert_spec.rb +0 -0
  40. data/spec/{nrser → lib/nrser}/env/path_spec.rb +0 -0
  41. data/spec/{nrser → lib/nrser}/errors/abstract_method_error_spec.rb +0 -0
  42. data/spec/{nrser → lib/nrser}/functions/binding/template_spec.rb +0 -0
  43. data/spec/{nrser → lib/nrser}/functions/enumerable/find_all_map_spec.rb +0 -0
  44. data/spec/{nrser → lib/nrser}/functions/enumerable/find_bounded_spec.rb +0 -0
  45. data/spec/{nrser → lib/nrser}/functions/enumerable/find_map_spec.rb +0 -0
  46. data/spec/{nrser → lib/nrser}/functions/enumerable/find_only_spec.rb +0 -0
  47. data/spec/{nrser → lib/nrser}/functions/enumerable/include_slice_spec.rb +0 -0
  48. data/spec/{nrser → lib/nrser}/functions/enumerable/to_h_by_spec.rb +0 -0
  49. data/spec/{nrser → lib/nrser}/functions/exception/format_exception_spec.rb +0 -0
  50. data/spec/{nrser → lib/nrser}/functions/hash/bury_spec.rb +0 -0
  51. data/spec/{nrser → lib/nrser}/functions/hash/guess_label_key_type_spec.rb +0 -0
  52. data/spec/{nrser → lib/nrser}/functions/hash_spec.rb +0 -0
  53. data/spec/{nrser → lib/nrser}/functions/merge_by_spec.rb +0 -0
  54. data/spec/{nrser → lib/nrser}/functions/object/truthy_spec.rb +0 -0
  55. data/spec/{nrser → lib/nrser}/functions/open_struct_spec.rb +0 -0
  56. data/spec/{nrser → lib/nrser}/functions/string/common_prefix_spec.rb +0 -0
  57. data/spec/{nrser → lib/nrser}/functions/string/looks_like_spec.rb +0 -0
  58. data/spec/{nrser → lib/nrser}/functions/string/truncate_spec.rb +0 -0
  59. data/spec/{nrser → lib/nrser}/functions/text/dedent/gotchas_spec.rb +0 -0
  60. data/spec/{nrser → lib/nrser}/functions/text/dedent_spec.rb +0 -0
  61. data/spec/{nrser → lib/nrser}/functions/text/indent_spec.rb +0 -0
  62. data/spec/{nrser → lib/nrser}/functions/text/words_spec.rb +0 -0
  63. data/spec/{nrser → lib/nrser}/functions/tree/each_branch_spec.rb +0 -0
  64. data/spec/{nrser → lib/nrser}/functions/tree/leaves_spec.rb +0 -0
  65. data/spec/{nrser → lib/nrser}/functions/tree/map_branch_spec.rb +0 -0
  66. data/spec/{nrser → lib/nrser}/functions/tree/map_tree_spec.rb +0 -0
  67. data/spec/{nrser → lib/nrser}/functions/tree/transform_spec.rb +0 -0
  68. data/spec/{nrser → lib/nrser}/functions/tree/transformer_spec.rb +0 -0
  69. data/spec/{nrser → lib/nrser}/labs/globlin_spec.rb +0 -0
  70. data/spec/{nrser → lib/nrser}/labs/index_spec.rb +0 -0
  71. data/spec/{nrser → lib/nrser}/logger/dest_spec.rb +0 -0
  72. data/spec/{nrser → lib/nrser}/logger/die_spec.rb +0 -0
  73. data/spec/{nrser → lib/nrser}/logger/install_spec.rb +0 -0
  74. data/spec/{nrser → lib/nrser}/logger/level_int_spec.rb +0 -0
  75. data/spec/{nrser → lib/nrser}/logger/level_name_spec.rb +0 -0
  76. data/spec/{nrser → lib/nrser}/logger/level_sym_spec.rb +0 -0
  77. data/spec/{nrser → lib/nrser}/logger/send_log_spec.rb +0 -0
  78. data/spec/{nrser → lib/nrser}/logger/use_spec.rb +0 -0
  79. data/spec/lib/nrser/mean_streak/design_spec.rb +68 -0
  80. data/spec/lib/nrser/mean_streak/identity_instance_spec.rb +21 -0
  81. data/spec/{nrser → lib/nrser}/meta/class_attrs_spec.rb +0 -0
  82. data/spec/{nrser → lib/nrser}/meta/props/to_and_from_data_spec.rb +17 -11
  83. data/spec/{nrser → lib/nrser}/meta/props_spec.rb +0 -0
  84. data/spec/{nrser → lib/nrser}/op/message_spec.rb +0 -0
  85. data/spec/{nrser → lib/nrser}/refinements/array_spec.rb +0 -0
  86. data/spec/{nrser → lib/nrser}/refinements/erb_spec.rb +0 -0
  87. data/spec/{nrser → lib/nrser}/refinements/format_exception_spec.rb +0 -0
  88. data/spec/{nrser → lib/nrser}/refinements/hash_spec.rb +0 -0
  89. data/spec/{nrser → lib/nrser}/refinements/indent_spec.rb +0 -0
  90. data/spec/{nrser → lib/nrser}/refinements/object_spec.rb +0 -0
  91. data/spec/{nrser → lib/nrser}/refinements/pathname_spec.rb +0 -0
  92. data/spec/{nrser → lib/nrser}/refinements/set_spec.rb +0 -0
  93. data/spec/{nrser → lib/nrser}/refinements/truncate_spec.rb +0 -0
  94. data/spec/{nrser → lib/nrser}/types/array_spec.rb +0 -0
  95. data/spec/{nrser → lib/nrser}/types/attrs_spec.rb +0 -0
  96. data/spec/{nrser → lib/nrser}/types/combinators_spec.rb +0 -0
  97. data/spec/{nrser → lib/nrser}/types/is_spec.rb +0 -0
  98. data/spec/{nrser → lib/nrser}/types/pairs_spec.rb +0 -0
  99. data/spec/{nrser → lib/nrser}/types/paths_spec.rb +0 -0
  100. data/spec/{nrser → lib/nrser}/types/strings_spec.rb +0 -0
  101. data/spec/{nrser → lib/nrser}/types/symbols_spec.rb +1 -1
  102. data/spec/{nrser → lib/nrser}/types/tuples_spec.rb +0 -0
  103. data/spec/{nrser → lib/nrser}/types_spec.rb +0 -0
  104. data/spec/{nrser_spec.rb → lib/nrser_spec.rb} +0 -0
  105. metadata +148 -136
@@ -28,6 +28,10 @@ module NRSER::Types
28
28
  keys.test(k) && values.test(v)
29
29
  }
30
30
  end
31
+
32
+ def default_name
33
+ "Hash{#{ @keys.name }=>#{ @values.name }}"
34
+ end
31
35
  end # HashType
32
36
 
33
37
 
@@ -43,7 +47,7 @@ module NRSER::Types
43
47
  # @return [NRSER::Types::Type]
44
48
  # Newly constructed hash type from `args`.
45
49
  #
46
- def self.hash_type *args
50
+ def_factory :hash_type, aliases: [:dict, :hash_] do |*args|
47
51
  if args.empty?
48
52
  HASH
49
53
  else
@@ -51,9 +55,6 @@ module NRSER::Types
51
55
  end
52
56
  end
53
57
 
54
- singleton_class.send :alias_method, :dict, :hash_type
55
- singleton_class.send :alias_method, :hash_, :hash_type
56
-
57
58
  HASH = HashType.new.freeze
58
59
 
59
60
  end
@@ -23,6 +23,16 @@ module NRSER::Types
23
23
  def == other
24
24
  equal?(other) || @value === other.value
25
25
  end
26
+
27
+ # @return [String]
28
+ # a brief string description of the type - just it's {#name} surrounded
29
+ # by some back-ticks to make it easy to see where it starts and stops.
30
+ #
31
+ def to_s
32
+ "{ x ≡ #{ @value.inspect } }"
33
+ end
34
+
35
+ alias_method :inspect, :to_s
26
36
  end # Is
27
37
 
28
38
  # an exact value (using ===)
@@ -30,4 +40,4 @@ module NRSER::Types
30
40
  Is.new value, **options
31
41
  end
32
42
 
33
- end # NRSER::Types
43
+ end # NRSER::Types
@@ -20,10 +20,12 @@ module NRSER::Types
20
20
  @klass = klass
21
21
  end
22
22
 
23
+
23
24
  def default_name
24
- "#{ self.class.short_name }(#{ @klass.name })"
25
+ @klass.name
25
26
  end
26
27
 
28
+
27
29
  def test value
28
30
  value.is_a? @klass
29
31
  end
@@ -56,6 +58,13 @@ module NRSER::Types
56
58
  @from_data || @klass.respond_to?( :from_data )
57
59
  end
58
60
 
61
+
62
+ def == other
63
+ equal?( other ) ||
64
+ ( self.class == other.class &&
65
+ self.klass == other.klass )
66
+ end
67
+
59
68
  end # IsA
60
69
 
61
70
 
@@ -63,4 +72,4 @@ module NRSER::Types
63
72
  def self.is_a klass, **options
64
73
  IsA.new klass, **options
65
74
  end
66
- end # NRSER::Types
75
+ end # NRSER::Types
@@ -1,11 +1,10 @@
1
- require 'nrser/refinements'
2
1
  require 'nrser/types/combinators'
3
2
 
4
- using NRSER
5
-
6
3
  module NRSER::Types
4
+
7
5
  # nil or the argument type
8
- def self.maybe type
9
- union nil, type, name: "Maybe(#{ type.name })"
6
+ def self.maybe type, **options
7
+ union self.nil, type, name: "#{ type.name }?", **options
10
8
  end
9
+
11
10
  end # NRSER::Types
@@ -1,17 +1,8 @@
1
1
  require 'nrser/types/is'
2
2
 
3
3
  module NRSER::Types
4
-
5
- NIL_TYPE = is(
6
- nil,
7
- name: 'NilType',
8
- # from_s: ->( s ) {
9
- #
10
- # }
11
- ).freeze
12
-
13
4
  # nothing
14
5
  def self.nil
15
- NIL_TYPE
6
+ is nil, name: 'Nil'
16
7
  end
17
8
  end # NRSER::Types
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+
5
+ # Definitions
6
+ # =======================================================================
7
+
8
+ module NRSER::Types
9
+
10
+ class Not < Type
11
+
12
+ # Constructor
13
+ # ======================================================================
14
+
15
+ # Instantiate a new `NRSER::Types::Not`.
16
+ def initialize type, **options
17
+ super **options
18
+ @type = type
19
+ end # #initialize
20
+
21
+
22
+ # Instance Methods
23
+ # ======================================================================
24
+
25
+ def test value
26
+ ! @type.test( value )
27
+ end
28
+
29
+
30
+ def default_name
31
+ "!#{ @type.name }"
32
+ end
33
+
34
+
35
+ # @return [String]
36
+ # a brief string description of the type - just it's {#name} surrounded
37
+ # by some back-ticks to make it easy to see where it starts and stops.
38
+ #
39
+ def to_s
40
+ "{ x ∉ #{ @type.name } }"
41
+ end
42
+
43
+ alias_method :inspect, :to_s
44
+
45
+
46
+ end # class Not
47
+
48
+
49
+ def self.not type, **options
50
+ Not.new type, **options
51
+ end
52
+
53
+ end # module NRSER::Types
@@ -94,14 +94,12 @@ module NRSER::Types
94
94
  # Integer less than zero.
95
95
  #
96
96
 
97
- NEG_INT = intersection(
98
- INT,
99
- bounded(max: -1),
100
- name: 'NegIntType'
101
- ).freeze
102
-
103
97
  def self.neg_int
104
- NEG_INT
98
+ intersection(
99
+ INT,
100
+ bounded(max: -1),
101
+ name: 'NegIntType'
102
+ ).freeze
105
103
  end
106
104
 
107
105
 
@@ -109,16 +107,23 @@ module NRSER::Types
109
107
  # --------------------
110
108
  #
111
109
  # Positive integers and zero... but it seems more efficient to define these
112
- # as bounded instead of a union.
110
+ # as bounded instead of a union.
113
111
  #
114
112
 
115
- NON_NEG_INT = intersection INT, bounded(min: 0), name: 'NonNegIntType'
113
+ def self.natural **options
114
+ intersection INT, bounded(min: 0), name: 'ℕ', **options
115
+ end
116
116
 
117
- def self.non_neg_int
118
- NON_NEG_INT
117
+ singleton_class.send :alias_method, :non_neg_int, :natural
118
+ singleton_class.send :alias_method, :unsigned, :natural
119
+
120
+
121
+ def self.natural? **options
122
+ maybe non_neg_int, **options
119
123
  end
120
124
 
121
- singleton_class.send :alias_method, :unsigned, :non_neg_int
125
+ singleton_class.send :alias_method, :non_neg_int?, :natural?
126
+ singleton_class.send :alias_method, :unsigned?, :natural?
122
127
 
123
128
 
124
129
  # Non-Positive Integer
@@ -127,10 +132,8 @@ module NRSER::Types
127
132
  # negative integers and zero.
128
133
  #
129
134
 
130
- NON_POS_INT = intersection INT, bounded(max: 0), name: 'NonPosIntType'
131
-
132
- def self.non_pos_int
133
- NON_POS_INT
135
+ def self.non_pos_int **options
136
+ intersection INT, bounded(max: 0), name: 'NonPosIntType', **options
134
137
  end
135
138
 
136
- end # NRSER::Types
139
+ end # NRSER::Types
@@ -0,0 +1,75 @@
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 Shape < Type
30
+
31
+ # Constructor
32
+ # ======================================================================
33
+
34
+ # Instantiate a new `NRSER::Types::Shape`.
35
+ def initialize pairs, **options
36
+ super **options
37
+ @pairs = pairs.map { |k, v|
38
+ [k, NRSER::Types.make( v )]
39
+ }.to_h
40
+ end # #initialize
41
+
42
+
43
+ # Instance Methods
44
+ # ======================================================================
45
+
46
+ def test value
47
+ begin
48
+ @pairs.all? { |k, v|
49
+ v === value[k]
50
+ }
51
+ rescue
52
+ false
53
+ end
54
+ end
55
+
56
+ def default_name
57
+ inner = @pairs.map { |k, v|
58
+ "[#{ k.inspect }]→#{ v.name }"
59
+ }.join( ", " )
60
+
61
+ if @pairs.count == 1
62
+ inner
63
+ else
64
+ '(' + inner + ')'
65
+ end
66
+ end
67
+
68
+ end # class Shape
69
+
70
+
71
+ def self.shape pairs, **options
72
+ Shape.new pairs, **options
73
+ end
74
+
75
+ end # module NRSER::Types
@@ -2,73 +2,63 @@ require 'nrser/refinements'
2
2
  require 'nrser/types/is'
3
3
  require 'nrser/types/is_a'
4
4
  require 'nrser/types/attrs'
5
+ require 'nrser/types/not'
5
6
 
6
7
  using NRSER
7
8
 
8
9
  module NRSER::Types
9
10
 
10
- # Eigenclass (Singleton Class)
11
- # ========================================================================
12
- #
13
- class << self
14
- # @!group Type Factory Functions
15
-
16
- def str length: nil, **options
17
- if length.nil? && options.empty?
18
- # if there are no options can point to the constant for efficiency
19
- STR
20
- else
21
- if length.nil?
22
- IsA.new String, from_s: ->(s) { s }, **options
23
- else
24
- intersection \
25
- IsA.new( String, from_s: ->(s) { s } ),
26
- NRSER::Types.length( length ),
27
- **options
28
- end
29
- end
30
- end # string
31
-
32
- alias_method :string, :str
33
-
34
-
35
- def empty_str
36
- EMPTY_STR
37
- end
38
-
39
-
40
- def non_empty_str **options
41
- return NON_EMPTY_STR if options.empty?
42
-
43
- str( length: {min: 1}, **options )
44
- end # .non_empty_str
45
-
46
-
47
- private
48
- # ========================================================================
49
-
50
-
51
- # @todo Document make_string_type method.
52
- #
53
- # @param [type] arg_name
54
- # @todo Add name param description.
55
- #
56
- # @return [return_type]
57
- # @todo Document return value.
58
- #
59
- def make_string_type length: nil, match: nil
60
- # method body...
61
- end # #make_string_type
11
+ # @!group Type Factory Functions
12
+
13
+ def self.str length: nil, encoding: nil, **options
14
+ if [length, encoding].all?( &:nil? )
15
+ IsA.new String, from_s: ->(s) { s }, **options
62
16
 
17
+ else
18
+ types = [str]
19
+ types << self.length( length ) if length
20
+ types << attrs( encoding: encoding ) if encoding
63
21
 
64
- # end private
65
-
66
- end # class << self (Eigenclass)
22
+ intersection *types, **options
23
+ end
24
+ end # string
25
+
26
+ singleton_class.send :alias_method, :string, :str
67
27
 
68
- STR = str( name: 'StringType' ).freeze
69
28
 
70
- EMPTY_STR = str( name: 'EmptyStringType', length: 0 ).freeze
29
+ # Get a {Type} only satisfied by empty strings.
30
+ #
31
+ # @param [String] name: (default 'EmptyString')
32
+ #
33
+ def_factory :empty_str do |name: 'EmptyString', **options|
34
+ str length: 0, name: name, **options
35
+ end
36
+
37
+
38
+ def_factory :non_empty_str do |**options|
39
+ str length: {min: 1}, **options
40
+ end
41
+
42
+
43
+ def_factory :char do |**options|
44
+ str length: 1, name: "Character", **options
45
+ end
46
+
47
+
48
+ # A type satisfied by UTF-8 encoded strings.
49
+ #
50
+ # @param [String] name: (default 'UTF8String')
51
+ #
52
+ def_factory :uft_8, aliases: [:utf8] do |name: 'UTF8String', **options|
53
+ str encoding: Encoding::UTF_8, name: name, **options
54
+ end
55
+
71
56
 
72
- NON_EMPTY_STR = non_empty_str( name: 'NonEmptyStr' ).freeze
57
+ def_factory(
58
+ :utf_8_char,
59
+ aliases: [:utf8_char]
60
+ ) do |name: 'UTF8Character', **options|
61
+ str length: 1, encoding: Encoding::UTF_8, name: name, **options
62
+ end
73
63
 
74
- end # NRSER::Types
64
+ end # NRSER::Types
@@ -8,32 +8,27 @@ using NRSER
8
8
  module NRSER::Types
9
9
 
10
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
11
+ IsA.new(
12
+ Symbol,
13
+ from_s: :to_sym.to_proc,
14
+ **options
15
+ )
21
16
  end # sym
22
17
 
23
18
  singleton_class.send :alias_method, :symbol, :sym
24
19
 
25
- SYM = sym( name: 'SymType' ).freeze
20
+
21
+ def self.empty_sym **options
22
+ is :'', name: 'EmptySymbol', **options
23
+ end
26
24
 
27
25
 
28
26
  def self.non_empty_sym **options
29
- return NON_EMPTY_SYM if options.empty?
30
-
31
27
  intersection \
32
- SYM,
33
- attrs( {to_s: non_empty_str} ),
28
+ sym,
29
+ self.not( empty_sym ),
30
+ name: 'NonEmptySymbol',
34
31
  **options
35
32
  end
36
33
 
37
- NON_EMPTY_SYM = non_empty_sym( name: 'NonEmptySym' ).freeze
38
-
39
- end # NRSER::Types
34
+ end # NRSER::Types