ducktrap 0.0.1

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.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/.circle.yml +6 -0
  3. data/.gitignore +5 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +16 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.devtools +59 -0
  8. data/Guardfile +18 -0
  9. data/LICENSE +20 -0
  10. data/README.md +47 -0
  11. data/Rakefile +2 -0
  12. data/TODO +4 -0
  13. data/config/devtools.yml +2 -0
  14. data/config/flay.yml +3 -0
  15. data/config/flog.yml +2 -0
  16. data/config/heckle.yml +3 -0
  17. data/config/mutant.yml +2 -0
  18. data/config/reek.yml +98 -0
  19. data/config/yardstick.yml +2 -0
  20. data/ducktrap.gemspec +23 -0
  21. data/lib/ducktrap.rb +73 -0
  22. data/lib/ducktrap/builder.rb +36 -0
  23. data/lib/ducktrap/error.rb +48 -0
  24. data/lib/ducktrap/evaluator.rb +127 -0
  25. data/lib/ducktrap/evaluator/invalid.rb +30 -0
  26. data/lib/ducktrap/evaluator/static.rb +25 -0
  27. data/lib/ducktrap/formatter.rb +138 -0
  28. data/lib/ducktrap/mapper.rb +59 -0
  29. data/lib/ducktrap/nary.rb +148 -0
  30. data/lib/ducktrap/node.rb +94 -0
  31. data/lib/ducktrap/node/anima.rb +40 -0
  32. data/lib/ducktrap/node/anima/dump.rb +39 -0
  33. data/lib/ducktrap/node/anima/load.rb +39 -0
  34. data/lib/ducktrap/node/block.rb +44 -0
  35. data/lib/ducktrap/node/coercion.rb +7 -0
  36. data/lib/ducktrap/node/custom.rb +121 -0
  37. data/lib/ducktrap/node/disjunction.rb +8 -0
  38. data/lib/ducktrap/node/forward.rb +55 -0
  39. data/lib/ducktrap/node/guard_nil.rb +42 -0
  40. data/lib/ducktrap/node/hash.rb +7 -0
  41. data/lib/ducktrap/node/hash/transform.rb +53 -0
  42. data/lib/ducktrap/node/invalid.rb +29 -0
  43. data/lib/ducktrap/node/inverse.rb +46 -0
  44. data/lib/ducktrap/node/key.rb +61 -0
  45. data/lib/ducktrap/node/key/add.rb +42 -0
  46. data/lib/ducktrap/node/key/delete.rb +44 -0
  47. data/lib/ducktrap/node/key/dump.rb +38 -0
  48. data/lib/ducktrap/node/key/fetch.rb +49 -0
  49. data/lib/ducktrap/node/map.rb +42 -0
  50. data/lib/ducktrap/node/noop.rb +30 -0
  51. data/lib/ducktrap/node/primitive.rb +61 -0
  52. data/lib/ducktrap/node/static.rb +33 -0
  53. data/lib/ducktrap/nullary.rb +41 -0
  54. data/lib/ducktrap/pretty_dump.rb +31 -0
  55. data/lib/ducktrap/registry.rb +60 -0
  56. data/lib/ducktrap/singleton.rb +55 -0
  57. data/lib/ducktrap/unary.rb +153 -0
  58. data/spec/rcov.opts +7 -0
  59. data/spec/shared/inverse_behavior.rb +7 -0
  60. data/spec/spec_helper.rb +20 -0
  61. data/spec/support/ice_nine_config.rb +8 -0
  62. data/spec/support/let_mock_helper.rb +13 -0
  63. data/spec/unit/ducktrap/builder/class_methods/new_spec.rb +41 -0
  64. data/spec/unit/ducktrap/builder/new_spec.rb +41 -0
  65. data/spec/unit/ducktrap/class_methods/build_spec.rb +11 -0
  66. data/spec/unit/ducktrap/error/exception/pretty_inspect_spec.rb +22 -0
  67. data/spec/unit/ducktrap/error/pretty_inspect_spec.rb +19 -0
  68. data/spec/unit/ducktrap/evaluator/assert_successful_spec.rb +38 -0
  69. data/spec/unit/ducktrap/evaluator/invalid/output_spec.rb +14 -0
  70. data/spec/unit/ducktrap/evaluator/noop/output_spec.rb +14 -0
  71. data/spec/unit/ducktrap/evaluator/output_spec.rb +52 -0
  72. data/spec/unit/ducktrap/evaluator/pretty_inspect_spec.rb +63 -0
  73. data/spec/unit/ducktrap/evaluator/successful_predicate_spec.rb +36 -0
  74. data/spec/unit/ducktrap/failed_transformation_error/message_spec.rb +10 -0
  75. data/spec/unit/ducktrap/formatter/attribute_spec.rb +24 -0
  76. data/spec/unit/ducktrap/formatter/body_spec.rb +19 -0
  77. data/spec/unit/ducktrap/formatter/class_methods/new_spec.rb +14 -0
  78. data/spec/unit/ducktrap/formatter/initialize_spec.rb +14 -0
  79. data/spec/unit/ducktrap/formatter/name_spec.rb +25 -0
  80. data/spec/unit/ducktrap/formatter/nest_spec.rb +48 -0
  81. data/spec/unit/ducktrap/formatter/puts_spec.rb +36 -0
  82. data/spec/unit/ducktrap/mapper/builder/dumper_spec.rb +20 -0
  83. data/spec/unit/ducktrap/mapper/builder/loader_spec.rb +20 -0
  84. data/spec/unit/ducktrap/mapper/builder/object_spec.rb +90 -0
  85. data/spec/unit/ducktrap/mapper/class_methods/build_spec.rb +20 -0
  86. data/spec/unit/ducktrap/nary/builder/add_spec.rb +16 -0
  87. data/spec/unit/ducktrap/nary/builder/method_missing_spec.rb +44 -0
  88. data/spec/unit/ducktrap/nary/builder/output_spec.rb +16 -0
  89. data/spec/unit/ducktrap/nary/class_methods/build_spec.rb +22 -0
  90. data/spec/unit/ducktrap/nary/class_methods/included_spec.rb +13 -0
  91. data/spec/unit/ducktrap/nary/evaluator/output_spec.rb +79 -0
  92. data/spec/unit/ducktrap/nary/instance_methods/inverse_spec.rb +24 -0
  93. data/spec/unit/ducktrap/nary/instance_methods/pretty_inspect_spec.rb +31 -0
  94. data/spec/unit/ducktrap/node/anima/dump/evaluator/output_spec.rb +18 -0
  95. data/spec/unit/ducktrap/node/anima/dump/inverse_spec.rb +10 -0
  96. data/spec/unit/ducktrap/node/anima/dump/pretty_inspect_spec.rb +15 -0
  97. data/spec/unit/ducktrap/node/anima/evaluator/output_spec.rb +18 -0
  98. data/spec/unit/ducktrap/node/anima/load/evaluator/output_spec.rb +35 -0
  99. data/spec/unit/ducktrap/node/anima/load/inverse_spec.rb +10 -0
  100. data/spec/unit/ducktrap/node/anima/load/pretty_inspect_spec.rb +15 -0
  101. data/spec/unit/ducktrap/node/anima/pretty_inspect_spec.rb +15 -0
  102. data/spec/unit/ducktrap/node/block/evaluator/output_spec.rb +79 -0
  103. data/spec/unit/ducktrap/node/block/inverse_spec.rb +24 -0
  104. data/spec/unit/ducktrap/node/call_spec.rb +21 -0
  105. data/spec/unit/ducktrap/node/class_methods/build_spec.rb +11 -0
  106. data/spec/unit/ducktrap/node/class_methods/register_spec.rb +16 -0
  107. data/spec/unit/ducktrap/node/custom/builder/forward_spec.rb +54 -0
  108. data/spec/unit/ducktrap/node/custom/builder/inverse_spec.rb +54 -0
  109. data/spec/unit/ducktrap/node/custom/builder/object_spec.rb +54 -0
  110. data/spec/unit/ducktrap/node/custom/call_spec.rb +21 -0
  111. data/spec/unit/ducktrap/node/custom/class_methods/build_spec.rb +20 -0
  112. data/spec/unit/ducktrap/node/custom/inverse_spec.rb +12 -0
  113. data/spec/unit/ducktrap/node/custom/pretty_inspect_spec.rb +15 -0
  114. data/spec/unit/ducktrap/node/forward/evaluator/output_spec.rb +13 -0
  115. data/spec/unit/ducktrap/node/forward/inverse_spec.rb +14 -0
  116. data/spec/unit/ducktrap/node/forward/pretty_inspect_spec.rb +19 -0
  117. data/spec/unit/ducktrap/node/guard_nil/call_spec.rb +21 -0
  118. data/spec/unit/ducktrap/node/guard_nil/evaluator/output_spec.rb +27 -0
  119. data/spec/unit/ducktrap/node/guard_nil/inverse_spec.rb +12 -0
  120. data/spec/unit/ducktrap/node/hash/transform/evaluator/output_spec.rb +51 -0
  121. data/spec/unit/ducktrap/node/hash/transform/inverse_spec.rb +27 -0
  122. data/spec/unit/ducktrap/node/invalid/call_spec.rb +13 -0
  123. data/spec/unit/ducktrap/node/invalid/inverse_spec.rb +11 -0
  124. data/spec/unit/ducktrap/node/inverse/call_spec.rb +11 -0
  125. data/spec/unit/ducktrap/node/inverse/inverse_spec.rb +14 -0
  126. data/spec/unit/ducktrap/node/inverse/pretty_inspect_spec.rb +19 -0
  127. data/spec/unit/ducktrap/node/key/add/call_spec.rb +15 -0
  128. data/spec/unit/ducktrap/node/key/add/evaluator/call_spec.rb +15 -0
  129. data/spec/unit/ducktrap/node/key/add/inverse_spec.rb +14 -0
  130. data/spec/unit/ducktrap/node/key/delete/call_spec.rb +13 -0
  131. data/spec/unit/ducktrap/node/key/delete/evaluator/call_spec.rb +13 -0
  132. data/spec/unit/ducktrap/node/key/delete/inverse_spec.rb +13 -0
  133. data/spec/unit/ducktrap/node/key/dump/evaluator/output_spec.rb +37 -0
  134. data/spec/unit/ducktrap/node/key/dump/inverse_spec.rb +14 -0
  135. data/spec/unit/ducktrap/node/key/evaluator/key_spec.rb +26 -0
  136. data/spec/unit/ducktrap/node/key/fetch/evaluator/output_spec.rb +48 -0
  137. data/spec/unit/ducktrap/node/key/fetch/inverse_spec.rb +14 -0
  138. data/spec/unit/ducktrap/node/key/pretty_inspect_spec.rb +20 -0
  139. data/spec/unit/ducktrap/node/map/evaluator/output_spec.rb +22 -0
  140. data/spec/unit/ducktrap/node/map/inverse_spec.rb +15 -0
  141. data/spec/unit/ducktrap/node/noop/call_spec.rb +11 -0
  142. data/spec/unit/ducktrap/node/noop/inverse_spec.rb +9 -0
  143. data/spec/unit/ducktrap/node/pretty_inspect_spec.rb +17 -0
  144. data/spec/unit/ducktrap/node/primitive/call_spec.rb +19 -0
  145. data/spec/unit/ducktrap/node/primitive/inverse_spec.rb +13 -0
  146. data/spec/unit/ducktrap/node/primitive/pretty_inspect_spec.rb +15 -0
  147. data/spec/unit/ducktrap/node/run_spec.rb +46 -0
  148. data/spec/unit/ducktrap/node/static/call_spec.rb +13 -0
  149. data/spec/unit/ducktrap/node/static/inverse_spec.rb +14 -0
  150. data/spec/unit/ducktrap/nullary/class_methods/build_spec.rb +37 -0
  151. data/spec/unit/ducktrap/nullary/class_methods/included_spec.rb +7 -0
  152. data/spec/unit/ducktrap/pretty_dump/pretty_dump_spec.rb +47 -0
  153. data/spec/unit/ducktrap/pretty_dump/pretty_inspect_spec.rb +22 -0
  154. data/spec/unit/ducktrap/registry/lookup_spec.rb +27 -0
  155. data/spec/unit/ducktrap/registry/register_spec.rb +21 -0
  156. data/spec/unit/ducktrap/singleton/class_methods/included_spec.rb +13 -0
  157. data/spec/unit/ducktrap/singleton/class_methods/instance_spec.rb +19 -0
  158. data/spec/unit/ducktrap/singleton/instance_methods/inspect_spec.rb +19 -0
  159. data/spec/unit/ducktrap/singleton/instance_methods/pretty_inspect_spec.rb +17 -0
  160. data/spec/unit/ducktrap/unary/class_methods/build_spec.rb +18 -0
  161. data/spec/unit/ducktrap/unary/class_methods/included_spec.rb +14 -0
  162. data/spec/unit/ducktrap/unary/evaluator/output2_spec.rb +48 -0
  163. data/spec/unit/ducktrap/unary/evaluator/output_spec.rb +37 -0
  164. data/spec/unit/ducktrap/unary/instance_methods/pretty_inspect_spec.rb +15 -0
  165. metadata +399 -0
@@ -0,0 +1,42 @@
1
+ module Ducktrap
2
+ class Node
3
+ # Transformation node to guard nil inputs as nil outputs
4
+ class GuardNil < self
5
+ include Unary, Equalizer.new(:operand)
6
+
7
+ register :guard_nil
8
+
9
+ # Return inverse transformation
10
+ #
11
+ # @return [Node]
12
+ #
13
+ # @api private
14
+ #
15
+ def inverse
16
+ self.class.new(operand.inverse)
17
+ end
18
+
19
+ # Evaluator for guard nil node
20
+ class Evaluator < Unary::Evaluator
21
+
22
+ private
23
+
24
+ # Return output
25
+ #
26
+ # @return [Object]
27
+ # if successful
28
+ #
29
+ # @return [Error]
30
+ # otherwise
31
+ #
32
+ # @api private
33
+ #
34
+ def process
35
+ return if input.nil?
36
+ operand_output
37
+ end
38
+
39
+ end # Evaluator
40
+ end # GuardNil
41
+ end # Node
42
+ end # Ducktrap
@@ -0,0 +1,7 @@
1
+ module Ducktrap
2
+ class Node
3
+ # Base namespace class for hash operations
4
+ class Hash < self
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,53 @@
1
+ module Ducktrap
2
+ class Node
3
+ class Hash
4
+ # Ducktrap that expects outputs to be hashes and merges them together
5
+ #
6
+ # TODO: Find better primitive!
7
+ #
8
+ class Transform < self
9
+ include Nary
10
+
11
+ register :hash_transform
12
+
13
+ # Return inverse transformation
14
+ #
15
+ # @return [Node]
16
+ #
17
+ # @api privateo
18
+ #
19
+ def inverse
20
+ self.class.new(body.map(&:inverse))
21
+ end
22
+
23
+ # Evaluator of chained ducktraps
24
+ class Evaluator < Nary::Evaluator
25
+
26
+ private
27
+
28
+ # Calculate evaluator
29
+ #
30
+ # @return [Object]
31
+ # if successful
32
+ #
33
+ # @return [Error]
34
+ # otherwise
35
+ #
36
+ # @api private
37
+ #
38
+ def process
39
+ body.each_with_object({}) do |ducktrap, hash|
40
+ evaluator = ducktrap.call(input)
41
+
42
+ unless evaluator.successful?
43
+ return nested_error(evaluator)
44
+ end
45
+
46
+ hash.merge!(evaluator.output)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,29 @@
1
+ module Ducktrap
2
+ class Node
3
+ # Noope node, returns input as output
4
+ class Invalid < self
5
+ include Singleton
6
+
7
+ # Run ducktrap
8
+ #
9
+ # @param [Object] input
10
+ #
11
+ # @return [Evaluator]
12
+ #
13
+ # @api private
14
+ #
15
+ def call(input)
16
+ Evaluator::Invalid.new(self, input)
17
+ end
18
+
19
+ # Return inverse ducktrap
20
+ #
21
+ # @return [Ducktrap]
22
+ #
23
+ # @api private
24
+ #
25
+ def inverse; self; end
26
+
27
+ end # Invalid
28
+ end # Node
29
+ end # Ducktrap
@@ -0,0 +1,46 @@
1
+ module Ducktrap
2
+ class Node
3
+ # Noop ducktrap with fixed inverse
4
+ class Inverse < self
5
+ include Concord::Public.new(:operand)
6
+
7
+ register :inverse
8
+
9
+ # Return inverse node
10
+ #
11
+ # @return [Forward]
12
+ #
13
+ # @api private
14
+ #
15
+ def inverse
16
+ Forward.new(operand)
17
+ end
18
+
19
+ # Return evaluator
20
+ #
21
+ # @param [Object] input
22
+ #
23
+ # @return [Evaluator]
24
+ #
25
+ # @api private
26
+ #
27
+ def call(input)
28
+ Evaluator::Noop.new(self, input)
29
+ end
30
+
31
+ private
32
+
33
+ # Perform pretty dump
34
+ #
35
+ # @return [undefined]
36
+ #
37
+ # @api private
38
+ #
39
+ def dump(output)
40
+ output.name(self)
41
+ output.nest(:operand, operand)
42
+ end
43
+
44
+ end # Inverse
45
+ end # Node
46
+ end # Ducktrap
@@ -0,0 +1,61 @@
1
+ module Ducktrap
2
+ class Node
3
+ # Base class for ducktraps that manipulate keys
4
+ class Key < self
5
+ include Unary, Equalizer.new(:operand, :key)
6
+
7
+ # Return key
8
+ #
9
+ # @return [Object]
10
+ #
11
+ # @api private
12
+ #
13
+ attr_reader :key
14
+
15
+ # Initiaize object
16
+ #
17
+ # @param [Ducktrap] operand
18
+ # @param [Object] key
19
+ #
20
+ # @return [undefined]
21
+ #
22
+ # @api private
23
+ #
24
+ def initialize(operand, key)
25
+ @key = key
26
+ super(operand)
27
+ end
28
+
29
+ private
30
+
31
+ # Dump object
32
+ #
33
+ # @return [undefined]
34
+ #
35
+ # @api private
36
+ #
37
+ def dump(output)
38
+ output.name(self)
39
+ output.attribute(:key, key)
40
+ output.nest(:operand, operand)
41
+ end
42
+
43
+ # Base class for key evaluators
44
+ class Evaluator < Unary::Evaluator
45
+
46
+ private
47
+
48
+ # Return key to operate on
49
+ #
50
+ # @return [Object]
51
+ #
52
+ # @api private
53
+ #
54
+ def key
55
+ context.key
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,42 @@
1
+ module Ducktrap
2
+ class Node
3
+ class Key
4
+ # Ducktrap to dump value to a specific key
5
+ class Add < self
6
+
7
+ register :add_key
8
+
9
+ # Return inverse ducktrap
10
+ #
11
+ # @return [Ducktrap]
12
+ #
13
+ # @api private
14
+ #
15
+ def inverse
16
+ Delete.new(operand, key)
17
+ end
18
+
19
+ # Evaluator for add key node
20
+ class Evaluator < Key::Evaluator
21
+
22
+ private
23
+
24
+ # Process input
25
+ #
26
+ # @return [Object]
27
+ # if successful
28
+ #
29
+ # @return [Error]
30
+ # otherwise
31
+ #
32
+ # @api private
33
+ #
34
+ def process_operand_output
35
+ input.merge(key => operand_output)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,44 @@
1
+ module Ducktrap
2
+ class Node
3
+ class Key
4
+ # Ducktrap to dump value to a specific key
5
+ class Delete < self
6
+
7
+ register :delete_key
8
+
9
+ # Return inverse ducktrap
10
+ #
11
+ # @return [Ducktrap]
12
+ #
13
+ # @api private
14
+ #
15
+ def inverse
16
+ Add.new(operand, key)
17
+ end
18
+
19
+ # Evaluator for delete key node
20
+ class Evaluator < Key::Evaluator
21
+
22
+ private
23
+
24
+ # Process input
25
+ #
26
+ # @return [Object]
27
+ # if successful
28
+ #
29
+ # @return [Error]
30
+ # otherwise
31
+ #
32
+ # @api private
33
+ #
34
+ def process
35
+ dup = input.dup
36
+ dup.delete(key)
37
+ dup
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,38 @@
1
+ module Ducktrap
2
+ class Node
3
+ class Key
4
+ # Ducktrap to dump value to a specific key
5
+ class Dump < self
6
+
7
+ register :dump_key
8
+
9
+ # Return inverse ducktrap
10
+ #
11
+ # @return [Ducktrap]
12
+ #
13
+ # @api private
14
+ #
15
+ def inverse
16
+ Fetch.new(operand.inverse, key)
17
+ end
18
+
19
+ # Evaluator for dump key node
20
+ class Evaluator < Key::Evaluator
21
+
22
+ private
23
+
24
+ # Process successful operand output
25
+ #
26
+ # @return [Object]
27
+ #
28
+ # @api private
29
+ #
30
+ def process_operand_output
31
+ { key => operand_output }
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,49 @@
1
+ module Ducktrap
2
+ class Node
3
+ class Key
4
+ # Ducktrap to fetch and transform a specific key
5
+ class Fetch < self
6
+
7
+ register :fetch_key
8
+
9
+ # Return inverse ducktrap
10
+ #
11
+ # @return [Ducktrap]
12
+ #
13
+ # @api private
14
+ #
15
+ def inverse
16
+ Dump.new(operand.inverse, key)
17
+ end
18
+
19
+ # Evaluator for fetch key ducktrap
20
+ class Evaluator < Key::Evaluator
21
+
22
+ private
23
+
24
+ # Process input
25
+ #
26
+ # @return [Object]
27
+ # if successful
28
+ #
29
+ # @return [Error]
30
+ # otherwise
31
+ #
32
+ # @api private
33
+ #
34
+ def process
35
+ value = input.fetch(context.key) do
36
+ return error
37
+ end
38
+ evaluator = process_operand(value)
39
+ unless evaluator.successful?
40
+ return nested_error(evaluator)
41
+ end
42
+ evaluator.output
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,42 @@
1
+ module Ducktrap
2
+ class Node
3
+ # Ducktrap that performs map operation
4
+ class Map < self
5
+ include Unary
6
+
7
+ register :map
8
+
9
+ # Return inverse transformator
10
+ #
11
+ # @return [Ducktrap]
12
+ #
13
+ # @api private
14
+ #
15
+ def inverse
16
+ self.class.new(operand.inverse)
17
+ end
18
+
19
+ # Evaluator for collection ducktrap
20
+ class Evaluator < Unary::Evaluator
21
+
22
+ private
23
+
24
+ # Calculate evaluator
25
+ #
26
+ # @return [Object]
27
+ #
28
+ # @api private
29
+ #
30
+ def process
31
+ input.map do |element|
32
+ evaluator = operand.call(element)
33
+ unless evaluator.successful?
34
+ return nested_error(evaluator)
35
+ end
36
+ evaluator.output
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end