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,8 @@
1
+ # config/cucumber.yml
2
+ ##YAML Template
3
+ # https://github.com/cucumber/cucumber/wiki/cucumber.yml
4
+ ---
5
+ default: --profile main
6
+ html_report: --format progress --format html --out=features_report.html
7
+ bvt: --tags @bvt
8
+ main: --tags ~@wip
@@ -0,0 +1,23 @@
1
+ Feature: Using String#chop
2
+
3
+ Scenario: Using chop example
4
+ Given I'm using the chop example
5
+ When I generate a solution
6
+ Then the solution should include:
7
+ """
8
+ def function(var0)
9
+ var1 = var0.collect do |var2|
10
+ var2.chop
11
+ end
12
+ end
13
+ """
14
+
15
+ Scenario: Using simple chop example
16
+ Given I'm using the simple chop example
17
+ When I generate a solution
18
+ Then the solution should include:
19
+ """
20
+ def function(var0)
21
+ var0.chop
22
+ end
23
+ """
@@ -0,0 +1,14 @@
1
+ Feature: Using dynamic method
2
+
3
+ @wip
4
+ Scenario: Using the collect and + 7 example
5
+ Given I'm using the collect and plus 7 example
6
+ When I generate a solution
7
+ Then the solution should include:
8
+ """
9
+ def function(var0)
10
+ var1 = var0.collect do |var2|
11
+ var2 + 7
12
+ end
13
+ end
14
+ """
@@ -0,0 +1,42 @@
1
+ Feature: Cauldron generates single parameter methods
2
+
3
+ Cauldron can generate runtime methods that accepts one parameters
4
+
5
+ @announce @slow_process
6
+ Scenario: Chop the last character off a string
7
+ Given a file named "launch.rb" with:
8
+ """
9
+ $LOAD_PATH.unshift File.expand_path( File.join(['..','..','lib']) )
10
+ require 'cauldron'
11
+ cauldron = Cauldron::Pot.new
12
+ puts cauldron.solve [{arguments: ['Sparky'], response: 'Spark'}, {arguments: ['Kel'], response: 'Ke'}]
13
+ """
14
+ When I run `ruby launch.rb` interactively
15
+ Then the output should contain:
16
+ """
17
+ def function(var0)
18
+ var0.chop
19
+ end
20
+ """
21
+
22
+ @announce @slow_process @wip
23
+ Scenario: Chop the last character off a string
24
+ Given a file named "launch.rb" with:
25
+ """
26
+ $LOAD_PATH.unshift File.expand_path( File.join('lib') )
27
+ require 'cauldron'
28
+ cauldron = Cauldron::Pot.new
29
+ puts cauldron.solve [
30
+ {arguments: [['Sparky', 'Kels']], response: ['Spark', 'Kel']},
31
+ {arguments: [['Pip','Rowe']], response: ['Pi','Row']}
32
+ ]
33
+ """
34
+ When I run `ruby launch.rb` interactively
35
+ Then the output should contain:
36
+ """
37
+ def function(var0)
38
+ var2 = var0.collect do |var1|
39
+ var1.chop
40
+ end
41
+ end
42
+ """
@@ -0,0 +1,20 @@
1
+ Feature: Cauldron generates single parameter methods
2
+
3
+ Cauldron can generate runtime methods that accepts one parameters
4
+
5
+ @announce @slow_process @wip
6
+ Scenario: Using statements that require a constant
7
+ Given a file named "launch.rb" with:
8
+ """
9
+ $LOAD_PATH.unshift File.expand_path( File.join('lib') )
10
+ require 'cauldron'
11
+ cauldron = Cauldron::Pot.new
12
+ puts cauldron.solve [{arguments: [8], response: 4}, {arguments: [12], response: 8}]
13
+ """
14
+ When I run `ruby launch.rb` interactively
15
+ Then the output should contain:
16
+ """
17
+ def function(var0)
18
+ var0 - 4
19
+ end
20
+ """
@@ -28,4 +28,51 @@ Then /^I should receive a runtime method like this "([^"]*)"$/ do |runtime_metho
28
28
  output.messages.should include(runtime_method_statement)
29
29
  end
30
30
 
31
+ Given(/^I'm using the chop example$/) do
32
+ #pending # Write code here that turns the phrase above into concrete actions
33
+ @pot = Cauldron::Pot.new
34
+ @examples = [
35
+ {arguments: [['Sparky', 'Kels']], response: ['Spark', 'Kel']},
36
+ {arguments: [['Pip','Rowe']], response: ['Pi','Row']}
37
+ ]
38
+ end
39
+
40
+ Given(/^I'm using the simple chop example$/) do
41
+ @pot = Cauldron::Pot.new
42
+ @examples = [
43
+ {arguments: ['Andy'], response: 'And'},
44
+ {arguments: ['Kels'], response: 'Kel'}
45
+ ]
46
+ end
47
+
48
+ Given(/^I'm using the reverse example$/) do
49
+ @pot = Cauldron::Pot.new
50
+ @examples = [
51
+ {arguments: [['Sparky', 'Kels']], response: ['Kels', 'Sparky']}
52
+ ]
53
+ end
54
+
55
+ Given(/^I'm using the collect and \+ (\d+) example$/) do |arg1|
56
+ @pot = Cauldron::Pot.new
57
+ @examples = [
58
+ {arguments: [[5,7]], response: [10, 12]},
59
+ {arguments: [[9,15]], response: [14, 20]}
60
+ ]
61
+ end
62
+
63
+ Given(/^I'm using the collect and plus (\d+) example$/) do |arg1|
64
+ @pot = Cauldron::Pot.new
65
+ @examples = [
66
+ {arguments: [[5,7]], response: [12, 14]},
67
+ {arguments: [[9,15]], response: [16, 22]}
68
+ ]
69
+ end
70
+
71
+ When(/^I generate a solution$/) do
72
+ @solution = @pot.solve @examples
73
+ end
74
+
75
+ Then(/^the solution should include:$/) do |string|
76
+ @solution.should include(string)
77
+ end
31
78
 
@@ -2,7 +2,7 @@ $LOAD_PATH << File.expand_path('../../../lib',__FILE__)
2
2
 
3
3
  #require 'ruby-debug'
4
4
  require 'cauldron'
5
-
5
+ require 'pry'
6
6
  require 'aruba/cucumber'
7
7
  # See https://github.com/cucumber/aruba/blob/master/lib/aruba/cucumber.rb for the available steps
8
8
 
@@ -0,0 +1,23 @@
1
+ Feature: Using Array#reverse
2
+
3
+ Scenario: Using chop example
4
+ Given I'm using the reverse example
5
+ When I generate a solution
6
+ Then the solution should include:
7
+ """
8
+ def function(var0)
9
+ var0.reverse
10
+ end
11
+ """
12
+
13
+ Scenario: Using the collect and + 5 example
14
+ Given I'm using the collect and + 5 example
15
+ When I generate a solution
16
+ Then the solution should include:
17
+ """
18
+ def function(var0)
19
+ var1 = var0.collect do |var2|
20
+ var2 + 5
21
+ end
22
+ end
23
+ """
@@ -5,14 +5,50 @@ require 'logger'
5
5
  require 'yaml'
6
6
  require 'ruby2ruby'
7
7
  require 'ruby_parser'
8
- #require 'ruby-debug'
8
+ require 'sorcerer'
9
+
10
+ require 'pry_tester'
11
+ require 'pry'
12
+
13
+ # http://stackoverflow.com/questions/18732338/trying-to-require-active-support-in-gem
14
+ require "active_support/all"
15
+
16
+ require 'tree'
9
17
 
10
18
  require 'core/string'
11
19
 
12
20
  require 'cauldron/pot'
21
+ require 'cauldron/caret'
22
+ require 'cauldron/example'
23
+ require 'cauldron/example_set'
13
24
  require 'cauldron/terminal'
14
- require 'cauldron/relationship'
25
+ require 'cauldron/scope'
26
+ require 'cauldron/histories'
27
+ require 'cauldron/history'
28
+ require 'cauldron/tracer'
29
+ require 'cauldron/operator'
30
+ require 'cauldron/statement_generator'
31
+ require 'cauldron/dynamic_operator'
32
+ require 'cauldron/operator/numeric_operator'
33
+ require 'cauldron/operator/concat_operator'
34
+ require 'cauldron/operator/array_reverse_operator'
35
+ require 'cauldron/operator/hash_key_value_operator'
36
+ require 'cauldron/operator/string_asterisk_operator'
37
+ require 'cauldron/operator/to_s_operator'
38
+ require 'cauldron/operator/var_collect_operator'
15
39
  require 'cauldron/if_relationship'
16
- require 'cauldron/numeric_operator'
17
- require 'cauldron/concat_operator'
18
- require 'cauldron/array_reverse_operator'
40
+
41
+ require 'cauldron/template_base'
42
+
43
+ require 'cauldron/array_collect_template/default'
44
+ require 'cauldron/array_collect_template/template'
45
+
46
+ require 'cauldron/number_addition_template/template'
47
+ require 'cauldron/number_addition_template/add_five'
48
+
49
+ require 'cauldron/dynamic_operator_module'
50
+
51
+ require 'cauldron/solution/one'
52
+ require 'cauldron/actualized_composite'
53
+ require 'cauldron/solution/composite'
54
+ require 'cauldron/builder'
@@ -0,0 +1,35 @@
1
+ module Cauldron
2
+
3
+ class ActualizedComposite
4
+
5
+ attr_reader :examples, :composite
6
+
7
+ # Might include the insert point here too
8
+ def initialize(composite,examples)
9
+ @composite, @examples = composite, examples
10
+ end
11
+
12
+ def histories
13
+ results = @examples.collect do |example|
14
+ @composite.record(example)
15
+ end
16
+ Cauldron::Histories.new(results)
17
+ end
18
+
19
+ def extend_solution
20
+ builder = Builder.new(composite)
21
+ builder.insertable_operators(examples)
22
+ end
23
+
24
+ def solution?(problems)
25
+ # TODO Should not need to
26
+ composite.solution?(examples)
27
+ end
28
+
29
+ def to_ruby
30
+ composite.to_ruby(examples.scope)
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,95 @@
1
+ module Cauldron
2
+
3
+ module ArrayCollectTemplate
4
+
5
+ class Default
6
+
7
+ attr_reader :indexes
8
+
9
+ def initialize(indexes)
10
+ @indexes = indexes
11
+ end
12
+
13
+ def context_realizable?(context)
14
+
15
+ vars = context.keys.select {|x| x.match(/var\d/) }
16
+ var_names = vars.collect(&:to_s)
17
+
18
+ first_variable = 'var'+@indexes[0].to_s
19
+
20
+ a = %Q{
21
+ def function(#{first_variable})
22
+ #{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
23
+ end
24
+ }
25
+
26
+ o = Object.new
27
+ o.instance_eval(a)
28
+
29
+ begin
30
+ #o.function(*vars.collect {|x| context[x] })
31
+ o.function context[first_variable.to_sym]
32
+ rescue NoMethodError => e
33
+ return false
34
+ rescue StandardError => e
35
+ puts e
36
+ return false
37
+ end
38
+ return true
39
+
40
+ end
41
+
42
+ def to_sexp(scope, children)
43
+ scope_var = scope.new_variable!
44
+ first_variable = 'var'+@indexes[0].to_s
45
+ [:method_add_block,
46
+ [:call,
47
+ [:vcall,
48
+ # [:@ident, scope[@indexes[0]] ]],
49
+ [:@ident, first_variable ]],
50
+ :".",
51
+ [:@ident, "collect"]
52
+ ],
53
+ unless children.empty?
54
+ [:brace_block,
55
+ [:block_var,
56
+ [:params, [[:@ident, scope_var]]]],
57
+ [
58
+ :stmts_add,
59
+ [:stmts_new],
60
+ # TODO Shouild probably be passing the children through here
61
+ children.first.content.to_sexp(scope, [])
62
+ ]
63
+ ]
64
+ else
65
+ [:brace_block,
66
+ [:block_var,
67
+ [:params, [[:@ident, scope_var]]],
68
+ [:stmts_add, [:stmts_new]]
69
+ ]
70
+ ]
71
+ end
72
+ ]
73
+ end
74
+
75
+ def to_ruby(scope, operators)
76
+ Sorcerer.source to_sexp(scope, operators)
77
+ end
78
+
79
+ def clone_statement
80
+ # TODO Need to clone the sexp methods
81
+ # o = DynamicOperator.new(@information, @sexp_methods)
82
+ # o.instance_eval(Sorcerer.source(@sexp_methods, indent: true))
83
+ # o
84
+ self.class.new(@indexes.clone)
85
+ end
86
+
87
+ def branch?
88
+ true
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
95
+ end
@@ -0,0 +1,57 @@
1
+ module Cauldron
2
+
3
+ module ArrayCollectTemplate
4
+
5
+ class Template < Cauldron::TemplateBase
6
+
7
+ def self.instances(histories, composite, examples, insert_points)
8
+
9
+ # TEMP
10
+ unless examples.class == ExampleSet
11
+ raise StandardError.new('Examples should be an example')
12
+ end
13
+
14
+ # Print out each insertable statements
15
+ scope = examples.scope
16
+
17
+ # self.init([0]).to_ruby(scope)
18
+ # - this will print out "var0.chop"
19
+
20
+ # Get the variables available at each point
21
+ results = []
22
+
23
+ insert_points.each do |point|
24
+
25
+ # Find the variables at a particular point
26
+ # TODO Change to test
27
+ contexts = histories.contexts_at(point)
28
+ composites = context_instances(contexts)
29
+
30
+ composites.each do |x|
31
+ if contexts.all? { |context| x.context_realizable?(context) }
32
+ #binding.pry
33
+ results << extend_actualized_composite(x, composite, examples, point)
34
+ end
35
+ #results << extend_actualized_composite(x, composite, examples, point)
36
+ end
37
+ end
38
+
39
+ results
40
+ end
41
+
42
+ def self.context_instances(contexts)
43
+ temp = []
44
+ contexts.each do |context|
45
+ temp << context.keys.collect(&:to_s).select {|x| x.match(/var\d/) }
46
+ end
47
+ results = temp.flatten.uniq
48
+
49
+ variable_numbers = results.collect { |x| x.match(/var(\d+)/)[1] }
50
+ variable_numbers.collect { |x| Cauldron::ArrayCollectTemplate::Default.new([x.to_i])}
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end