cauldron 0.1.5 → 0.1.6

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