ducktrap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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