cauldron 0.1.5 → 0.1.6

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 (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -1
  3. data/.rspec +1 -0
  4. data/Gemfile +16 -9
  5. data/Gemfile.lock +134 -64
  6. data/README.md +26 -0
  7. data/Rakefile +24 -99
  8. data/build_sandbox.rb +41 -0
  9. data/cucumber.yml +8 -0
  10. data/features/chop.feature +23 -0
  11. data/features/create_dynamic_statements.feature +14 -0
  12. data/features/generate_known_solution.feature +42 -0
  13. data/features/generate_new_statement.feature +20 -0
  14. data/features/step_definitions/cauldron_steps.rb +47 -0
  15. data/features/support/env.rb +1 -1
  16. data/features/use_existing_statements.feature +23 -0
  17. data/lib/cauldron.rb +41 -5
  18. data/lib/cauldron/actualized_composite.rb +35 -0
  19. data/lib/cauldron/array_collect_template/default.rb +95 -0
  20. data/lib/cauldron/array_collect_template/template.rb +57 -0
  21. data/lib/cauldron/builder.rb +60 -0
  22. data/lib/cauldron/caret.rb +50 -0
  23. data/lib/cauldron/dynamic_operator.rb +90 -0
  24. data/lib/cauldron/dynamic_operator_module.rb +140 -0
  25. data/lib/cauldron/example.rb +18 -0
  26. data/lib/cauldron/example_set.rb +36 -0
  27. data/lib/cauldron/histories.rb +53 -0
  28. data/lib/cauldron/history.rb +34 -0
  29. data/lib/cauldron/if_relationship.rb +4 -6
  30. data/lib/cauldron/number_addition_template/add_five.rb +71 -0
  31. data/lib/cauldron/number_addition_template/template.rb +56 -0
  32. data/lib/cauldron/operator.rb +62 -0
  33. data/lib/cauldron/operator/array_reverse_operator.rb +160 -0
  34. data/lib/cauldron/operator/concat_operator.rb +72 -0
  35. data/lib/cauldron/operator/hash_key_value_operator.rb +74 -0
  36. data/lib/cauldron/operator/numeric_operator.rb +115 -0
  37. data/lib/cauldron/operator/string_asterisk_operator.rb +131 -0
  38. data/lib/cauldron/operator/to_s_operator.rb +18 -0
  39. data/lib/cauldron/operator/var_collect_operator.rb +29 -0
  40. data/lib/cauldron/pot.rb +136 -26
  41. data/lib/cauldron/scope.rb +24 -0
  42. data/lib/cauldron/solution/composite.rb +236 -0
  43. data/lib/cauldron/solution/one.rb +49 -0
  44. data/lib/cauldron/statement_generator.rb +298 -0
  45. data/lib/cauldron/template_base.rb +14 -0
  46. data/lib/cauldron/tracer.rb +55 -0
  47. data/lib/cauldron/version.rb +1 -1
  48. data/lib/pry_tester.rb +76 -0
  49. data/ruby_to_sexp.rb +74 -0
  50. data/sandbox.rb +7 -0
  51. data/sexp_to_ruby.rb +150 -0
  52. data/spec/cauldron/actualized_composite_spec.rb +140 -0
  53. data/spec/cauldron/array_collect_template/default_spec.rb +41 -0
  54. data/spec/cauldron/builder_spec.rb +186 -0
  55. data/spec/cauldron/dynamic/add_number_template_spec.rb +30 -0
  56. data/spec/cauldron/dynamic_operator_spec.rb +416 -0
  57. data/spec/cauldron/example_set_spec.rb +49 -0
  58. data/spec/cauldron/example_spec.rb +33 -0
  59. data/spec/cauldron/histories_spec.rb +135 -0
  60. data/spec/cauldron/history_spec.rb +118 -0
  61. data/spec/cauldron/if_relationship_spec.rb +1 -1
  62. data/spec/cauldron/operator/array_reverse_operator_spec.rb +73 -0
  63. data/spec/cauldron/{concat_operator_spec.rb → operator/concat_operator_spec.rb} +30 -12
  64. data/spec/cauldron/operator/hash_key_value_operator_spec.rb +98 -0
  65. data/spec/cauldron/operator/numeric_operator_spec.rb +110 -0
  66. data/spec/cauldron/operator/string_asterisk_operator_spec.rb +196 -0
  67. data/spec/cauldron/operator/var_collect_operator_spec.rb +38 -0
  68. data/spec/cauldron/pot_spec.rb +176 -14
  69. data/spec/cauldron/solution/composite_spec.rb +421 -0
  70. data/spec/cauldron/solution/one_spec.rb +24 -0
  71. data/spec/cauldron/statement_generator_spec.rb +211 -0
  72. data/spec/cauldron/terminal_spec.rb +2 -2
  73. data/spec/spec_helper.rb +5 -1
  74. data/spec/support/code_matcher.rb +55 -0
  75. data/spec/support/include_instance_of_matcher.rb +9 -0
  76. data/spec/support/shared_examples_for_leaf_operators.rb +22 -0
  77. data/spec/support/shared_examples_for_operators.rb +23 -0
  78. data/syntax_spec.txt +2 -0
  79. metadata +104 -41
  80. data/README +0 -1
  81. data/README.rdoc +0 -19
  82. data/VERSION +0 -1
  83. data/features/cauldron_new_approach.feature +0 -46
  84. data/lib/cauldron/array_reverse_operator.rb +0 -39
  85. data/lib/cauldron/concat_operator.rb +0 -34
  86. data/lib/cauldron/numeric_operator.rb +0 -45
  87. data/lib/cauldron/relationship.rb +0 -5
  88. data/spec/cauldron/array_reverse_operator_spec.rb +0 -59
  89. data/spec/cauldron/numeric_operator_spec.rb +0 -70
@@ -0,0 +1,60 @@
1
+ module Cauldron
2
+
3
+ class Builder
4
+
5
+ attr_reader :composite
6
+
7
+ def initialize(composite)
8
+ @composite = composite
9
+ end
10
+
11
+ def tree
12
+ root_node = Tree::TreeNode.new("ROOT", "Root Content")
13
+ line_count = 0
14
+ composite.operators.each do |x|
15
+ child_node = Tree::TreeNode.new('CHILD-'+line_count.to_s)
16
+ root_node << child_node
17
+ line_count += 1
18
+ end
19
+ end
20
+
21
+ # NOTE: returns an array of new actualized composites extending the current composite
22
+ def insertable_operators(examples)
23
+ actualized_composite = ActualizedComposite.new(composite.clone_solution, examples)
24
+ h = actualized_composite.histories
25
+ results = self.class.available_statement_types.inject([]) do |total,x|
26
+ total += x.instances(h, composite, examples, h.insert_points)
27
+ total
28
+ end
29
+ #binding.pry
30
+ results
31
+ end
32
+
33
+ def self.available_statement_types
34
+
35
+ # CURRENT
36
+ # StatementGenerator.new.build(
37
+ # ['A','B', 'AC'],
38
+ # [:collect]
39
+ # )+Cauldron::StatementGenerator.new.build('string',[:chop])
40
+
41
+ # TRYING
42
+ # StatementGenerator.new.build(
43
+ # ['A','B', 'AC'],
44
+ # [:collect]
45
+ # )+Cauldron::StatementGenerator.new.build('string',[:chop])+[Cauldron::ArrayCollectTemplate::Template]
46
+ [StatementGenerator.new.build_template(
47
+ ['A','B', 'AC'],
48
+ :collect
49
+ ).statement_classes.first]+[Cauldron::StatementGenerator.new.build_template('string',:chop).statement_classes.first]+[Cauldron::ArrayCollectTemplate::Template]+[Cauldron::NumberAdditionTemplate::Template]
50
+
51
+ # TODO Not very effient to regenerate the opperators
52
+ # StatementGenerator.new.build(
53
+ # ['A','B', 'AC'],
54
+ # [:collect]
55
+ # )+Cauldron::StatementGenerator.new.build('string',[:chop])+[ArrayReverseOperator]+[StatementGenerator.new.build(3,[:+])]
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,50 @@
1
+ module Cauldron
2
+
3
+ class Caret
4
+
5
+ #attr_reader :line, :depth, :total_line
6
+ attr_reader :total_lines, :current_depth
7
+
8
+ def initialize
9
+ @total_lines, @current_depth = 0, 0 #,@line = 0, 0, 0
10
+ @lines = { 0 => 0}
11
+ end
12
+
13
+ # TODO This approach will need re-worked to support nesting - in and out
14
+ def add_line(depth)
15
+ unless @lines.has_key?(depth)
16
+ @lines[depth] = 0
17
+ end
18
+
19
+ @total_lines += 1
20
+ if @current_depth != depth
21
+ @current_depth = depth
22
+ else
23
+ @lines[depth] += 1
24
+ end
25
+
26
+ end
27
+
28
+ def point
29
+
30
+ end
31
+
32
+ def line
33
+ @lines[@current_depth]
34
+ end
35
+
36
+ def step_in
37
+ @current_depth += 1
38
+ unless @lines.has_key?(@current_depth)
39
+ @lines[@current_depth] = 0
40
+ end
41
+ #@line = 0
42
+ end
43
+
44
+ def return_depth(depth)
45
+ @current_depth = depth
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,90 @@
1
+ module Cauldron
2
+
3
+ class DynamicOperator
4
+
5
+ include Cauldron::Operator
6
+
7
+ attr_reader :indexes
8
+ attr_accessor :failed_uses
9
+
10
+ def initialize(information, sexp_methods)
11
+ @information, @sexp_methods = information, sexp_methods
12
+ @failed_uses = []
13
+ @closed = false
14
+ end
15
+
16
+ def uses_constants?
17
+ @information[:constants]
18
+ end
19
+
20
+ def indexes=(value)
21
+ raise StandardError.new('') if @closed
22
+ @indexes = value
23
+ end
24
+
25
+ def close
26
+ @closed = true
27
+ end
28
+
29
+ def extend_actualized_composite(x, container, examples, point)
30
+ cloned_container = container.clone_solution
31
+ cloned_container.add_statement_at(x, point)
32
+ cloned_container
33
+ Cauldron::ActualizedComposite.new(cloned_container, examples)
34
+ end
35
+
36
+ def context_realizable?(context)
37
+
38
+ vars = context.keys.select {|x| x.match(/var\d/) }
39
+ var_names = vars.collect(&:to_s)
40
+
41
+ a = %Q{
42
+ def function(var0)
43
+ #{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
44
+ end
45
+ }
46
+
47
+ o = Object.new
48
+ o.instance_eval(a)
49
+
50
+ begin
51
+ o.function(vars.collect {|x| context[x] })
52
+ rescue NoMethodError => e
53
+ return false
54
+ rescue StandardError => e
55
+ puts e
56
+ end
57
+ return true
58
+
59
+ end
60
+
61
+ def write_to_file(filename)
62
+ FileUtils.mkdir_p File.join('tmp')
63
+ File.open( File.join('tmp',filename), 'w+') do |file|
64
+ file << "class DynamicOperator"+"\n"
65
+ file << Sorcerer.source(@sexp_methods, indent: true)
66
+ file << "\n"
67
+ file << "end"
68
+ end
69
+ end
70
+
71
+ def rip2
72
+ %Q{
73
+ def function(var0)
74
+ #{Sorcerer.source(to_sexp(Cauldron::Scope.new(['var0'])), indent: true)}
75
+ end
76
+ }
77
+ end
78
+
79
+ def rip(composite,examples)
80
+ Ripper::SexpBuilder.new(
81
+ %Q{
82
+ def function(var0)
83
+ #{composite.to_ruby(examples.scope)}
84
+ end
85
+ }).parse
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,140 @@
1
+ module Cauldron
2
+
3
+ module DynamicOperatorModule
4
+
5
+ def uses_constants?
6
+ @information[:constants]
7
+ end
8
+
9
+ def indexes=(value)
10
+ raise StandardError.new('') if @closed
11
+ @indexes = value
12
+ end
13
+
14
+ def close
15
+ @closed = true
16
+ end
17
+
18
+ def clone_statement
19
+ # TODO Need to clone the sexp methods
20
+ # o = DynamicOperator.new(@information, @sexp_methods)
21
+ # o.instance_eval(Sorcerer.source(@sexp_methods, indent: true))
22
+ # o
23
+ self.class.new(@indexes.clone)
24
+ end
25
+
26
+ # def context_instances(contexts)
27
+ # results = []
28
+ # contexts.each do |context|
29
+ # results << context.keys.collect(&:to_s).select {|x| x.match(/var\d/) }
30
+ # end
31
+ # results = results.flatten.uniq
32
+ # variable_numbers = results.collect { |x| x.match(/var(\d+)/)[1] }
33
+ # variable_numbers.collect { |x| init([x.to_i])}
34
+ # end
35
+
36
+ # def extend_actualized_composite(x, container, examples, point)
37
+ # cloned_container = container.clone_solution
38
+ # cloned_container.add_statement_at(x, point)
39
+ # cloned_container
40
+ # Cauldron::ActualizedComposite.new(cloned_container, examples)
41
+ # end
42
+
43
+ def context_realizable?(context)
44
+
45
+ vars = context.keys.select {|x| x.match(/var\d/) }
46
+ var_names = vars.collect(&:to_s)
47
+
48
+ first_variable = 'var'+@indexes[0].to_s
49
+
50
+ # a = %Q{
51
+ # def function(var0)
52
+ # #{Sorcerer.source(to_sexp(var_names), indent: true)}
53
+ # end
54
+ # }
55
+ # a = %Q{
56
+ # def function(var0)
57
+ # #{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
58
+ # end
59
+ # }
60
+ a = %Q{
61
+ def function(#{first_variable})
62
+ #{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
63
+ end
64
+ }
65
+
66
+ o = Object.new
67
+ o.instance_eval(a)
68
+
69
+ begin
70
+ #o.function(*vars.collect {|x| context[x] })
71
+ o.function context[first_variable.to_sym]
72
+ rescue NoMethodError => e
73
+ return false
74
+ rescue StandardError => e
75
+ puts e
76
+ return false
77
+ end
78
+ return true
79
+
80
+
81
+
82
+ #o.function(*params.values)
83
+
84
+ # a = %Q{
85
+ # def function(var0)
86
+ # #{Sorcerer.source(to_sexp(Cauldron::Scope.new(['var0'])), indent: true)}
87
+ # end
88
+ # }
89
+ end
90
+
91
+ def write_to_file(filename)
92
+ File.open( File.join('tmp',filename), 'w+') do |file|
93
+ file << "class DynamicOperator"+"\n"
94
+ file << Sorcerer.source(@sexp_methods, indent: true)
95
+ file << "\n"
96
+ file << "end"
97
+ end
98
+ end
99
+
100
+ def rip(composite,examples)
101
+ Ripper::SexpBuilder.new(
102
+ %Q{
103
+ def function(var0)
104
+ #{composite.to_ruby(examples.scope)}
105
+ end
106
+ }).parse
107
+ end
108
+
109
+ # def to_tracking_sexp(operators, scope, caret)
110
+ # raise StandardError.new('statement has been instance closed') unless @closed
111
+ # to_sexp(scope)
112
+ # end
113
+
114
+ def realizable?(histories, point)
115
+ parameters = histories.variable_permutations(@indexes.length)
116
+ parameters.each do |params|
117
+ begin
118
+ realize(params)
119
+ rescue => e
120
+ puts e
121
+ failed_uses.push(histories)
122
+ return false
123
+ end
124
+ end
125
+ true
126
+ rescue => e
127
+ puts e
128
+ puts e.backtrace
129
+ # TODO GENERATE RSPEC TEST with arguments
130
+ end
131
+
132
+ def realize(params)
133
+ o = Object.new
134
+ o.instance_eval(rip2)
135
+ o.function(*params.values)
136
+ end
137
+
138
+ end
139
+
140
+ end
@@ -0,0 +1,18 @@
1
+ module Cauldron
2
+
3
+ class Example
4
+
5
+ attr_reader :arguments, :response
6
+
7
+ def initialize(hash)
8
+ @arguments, @response = hash[:arguments], hash[:response]
9
+ @arguments.freeze
10
+ end
11
+
12
+ def params
13
+ (0...@arguments.length).collect {|x| 'var'+x.to_s}
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,36 @@
1
+ module Cauldron
2
+
3
+ class ExampleSet
4
+
5
+ attr_reader :examples
6
+
7
+ def initialize(examples)
8
+ @examples = examples
9
+ end
10
+
11
+ def variables
12
+ args = examples.first.arguments
13
+ (0...args.length).collect {|x| 'var'+x.to_s}
14
+ end
15
+
16
+ def all?(&block)
17
+ examples.all?(&block)
18
+ end
19
+
20
+ def collect(&block)
21
+ examples.collect(&block)
22
+ end
23
+
24
+ # TODO Might drop - limit access
25
+ def each_with_index(&block)
26
+ examples.each_with_index(&block)
27
+ end
28
+
29
+ def scope
30
+ sexp = Ripper::SexpBuilder.new(examples.first.params.to_s).parse
31
+ Cauldron::Scope.new(eval(Sorcerer.source(sexp)))
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,53 @@
1
+ module Cauldron
2
+
3
+ class Histories
4
+
5
+ def initialize(results)
6
+ @results = results
7
+ end
8
+
9
+ def variable_permutations(count)
10
+ variables = @results.first.logs.first.keys.select { |x| x.match /var/ }
11
+ v = Hash[*variables.collect {|x| [x,nil]}.flatten]
12
+
13
+ @results.collect do |history|
14
+ history.logs.collect do |a|
15
+ Hash[*v.keys.collect do |x|
16
+ [x, a[x] ]
17
+ end.flatten(1)]
18
+ end
19
+ end.flatten
20
+ end
21
+
22
+ def each(&block)
23
+ @results.each(&block)
24
+ end
25
+
26
+ def first
27
+ @results.first
28
+ end
29
+
30
+ def length
31
+ @results.length
32
+ end
33
+
34
+ def insert_points
35
+ @results.inject([]) { |total, x| total += x.insert_points; total }.uniq
36
+ end
37
+
38
+ def contexts_at(point)
39
+ a = []
40
+ @results.each do |history|
41
+ a += history.logs.inject([]) do |total,log|
42
+ if log[:point] == point
43
+ total << log
44
+ end
45
+ total
46
+ end
47
+ end
48
+ a
49
+ end
50
+
51
+ end
52
+
53
+ end