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,14 @@
1
+ module Cauldron
2
+
3
+ class TemplateBase
4
+
5
+ def self.extend_actualized_composite(x, container, examples, point)
6
+ cloned_container = container.clone_solution
7
+ cloned_container.add_statement_at(x, point)
8
+ cloned_container
9
+ Cauldron::ActualizedComposite.new(cloned_container, examples)
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,55 @@
1
+ module Cauldron
2
+
3
+ class Tracer
4
+
5
+ attr_reader :sexp, :results
6
+
7
+ def initialize(sexp)
8
+ @sexp = sexp
9
+ @results = []
10
+ end
11
+
12
+ def process(example)
13
+ object = Tracer.new(sexp)
14
+ object.instance_eval(Sorcerer.source(sexp, indent: true))
15
+ object.function(example.arguments.first)
16
+
17
+ History.new(object.results)
18
+ #rescue => e
19
+ # binding.pry
20
+ # Sorcerer.source(sexp, indent: true)
21
+ # var0 = [5,7]
22
+ end
23
+
24
+ def record(line, depth, total_line, point, entry)
25
+ #h = Hash[*entry.flatten]
26
+ h = Hash[*entry.flatten(1)]
27
+ h.merge!(:line => line)
28
+ h.merge!(:depth => depth)
29
+ h.merge!(:total_line => total_line)
30
+ h.merge!(:point => point)
31
+ h = h.reject {|key,value| key.to_s.match /^placeholder/ }
32
+ @results << h
33
+ #@results << #entry # TODO Only want the trace to have on result so it should probably be in the initilaize call only
34
+ end
35
+
36
+ def self.substitue_tracking
37
+ %q{
38
+ record("line", "depth", "total_lines", "point")
39
+ }
40
+ end
41
+
42
+ def self.tracking(line, depth, total_line, point)
43
+ a = %Q{
44
+ record(#{line}, #{depth}, #{total_line}, #{point}, local_variables.reject { |foo|
45
+ foo == :_
46
+ }.collect { |bar|
47
+ [bar, eval(bar.to_s)]
48
+ })
49
+ }
50
+ Ripper::SexpBuilder.new(a).parse
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -1,3 +1,3 @@
1
1
  module Cauldron
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -0,0 +1,76 @@
1
+ class PryTester
2
+ extend Forwardable
3
+
4
+ attr_reader :pry, :out
5
+
6
+ def_delegators :@pry, :eval_string, :eval_string=
7
+
8
+ def initialize(target = TOPLEVEL_BINDING, options = {})
9
+ @pry = Pry.new(options.merge(:target => target))
10
+ @history = options[:history]
11
+
12
+ @pry.inject_sticky_locals!
13
+ reset_output
14
+ end
15
+
16
+ def eval(*strs)
17
+ reset_output
18
+ result = nil
19
+
20
+ strs.flatten.each do |str|
21
+ # Check for space prefix. See #1369.
22
+ if str !~ /^\s\S/
23
+ str = "#{str.strip}\n"
24
+ end
25
+ @history.push str if @history
26
+
27
+ if @pry.process_command(str)
28
+ result = last_command_result_or_output
29
+ else
30
+ result = @pry.evaluate_ruby(str)
31
+ end
32
+ end
33
+
34
+ result
35
+ end
36
+
37
+ def push(*lines)
38
+ Array(lines).flatten.each do |line|
39
+ @pry.eval(line)
40
+ end
41
+ end
42
+
43
+ def push_binding(context)
44
+ @pry.push_binding context
45
+ end
46
+
47
+ def last_output
48
+ @out.string if @out
49
+ end
50
+
51
+ def process_command(command_str)
52
+ @pry.process_command(command_str) or raise "Not a valid command"
53
+ last_command_result_or_output
54
+ end
55
+
56
+ def last_command_result
57
+ result = Pry.current[:pry_cmd_result]
58
+ result.retval if result
59
+ end
60
+
61
+ protected
62
+
63
+ def last_command_result_or_output
64
+ result = last_command_result
65
+ if result != Pry::Command::VOID_VALUE
66
+ result
67
+ else
68
+ last_output
69
+ end
70
+ end
71
+
72
+ def reset_output
73
+ @out = StringIO.new
74
+ @pry.output = @out
75
+ end
76
+ end
@@ -0,0 +1,74 @@
1
+ require 'ripper'
2
+ require 'sorcerer'
3
+ require 'pp'
4
+
5
+ sexp = Ripper::SexpBuilder.new(%q{
6
+ var0.to_s
7
+ }).parse
8
+ pp sexp
9
+ pp Sorcerer.source(sexp, indent: true)
10
+ puts '===='
11
+
12
+ sexp = Ripper::SexpBuilder.new(%q{
13
+ def test(var0)
14
+ var0.bounce
15
+ var1.kick
16
+ end
17
+ }).parse
18
+ pp sexp
19
+ pp Sorcerer.source(sexp, indent: true)
20
+ puts '===='
21
+
22
+
23
+ sexp = Ripper::SexpBuilder.new(%q{
24
+ var1 = var0.collect do |x|
25
+ x + 2
26
+ end
27
+ var2 = var1.collect do |x|
28
+ x.to_s
29
+ end
30
+ }).parse
31
+ puts sexp.inspect
32
+ pp sexp
33
+ puts '-------'
34
+
35
+ sexp = Ripper::SexpBuilder.new(%q{
36
+ var0.collect do |x|
37
+ record(local_variable)
38
+ end
39
+ }).parse
40
+ puts sexp.inspect
41
+ pp sexp
42
+ Sorcerer.source(sexp, indent: true)
43
+
44
+ puts '================'
45
+ sexp = Ripper::SexpBuilder.new(%q{
46
+ var0.collect do |var1|
47
+ record(0)
48
+ end
49
+ record(1)
50
+ }).parse
51
+ puts sexp.inspect
52
+ pp sexp
53
+ Sorcerer.source(sexp, indent: true)
54
+
55
+ puts '================'
56
+ sexp = Ripper::SexpBuilder.new(%q{
57
+ var0.collect do |var1|
58
+ var1 * 3
59
+ end
60
+ }).parse
61
+ pp sexp
62
+ Sorcerer.source(sexp, indent: true)
63
+
64
+ puts '================'
65
+ sexp = Ripper::SexpBuilder.new(%q{
66
+ def function(var0)
67
+ var0.collect do |var1|
68
+ record(0,1,1,local_variables.reject {|foo| foo == :_}.collect { |bar| [bar, eval(bar.to_s)] })
69
+ end
70
+ record(1,0,1,local_variables.reject {|foo| foo == :_}.collect { |bar| [bar, eval(bar.to_s)] })
71
+ end
72
+ }).parse
73
+ pp sexp
74
+ Sorcerer.source(sexp, indent: true)
data/sandbox.rb CHANGED
@@ -12,6 +12,9 @@ require 'yaml'
12
12
  #
13
13
  # puts 'Working'
14
14
 
15
+ # === Pry ===
16
+ # Pry::Code.new(@str).length
17
+
15
18
 
16
19
  # unified_chain = Cauldron::Util::Saver.load(298)
17
20
  # runtime_method = Cauldron::Util::Saver.load(31)
@@ -19,6 +22,10 @@ require 'yaml'
19
22
  #
20
23
  # puts unified_chain.describe
21
24
 
25
+ # gem install ruby_parser
26
+ # RubyParser.new.parse "1+1"
27
+
28
+ # gem 'sexp_processor', '~> 4.4.3'
22
29
 
23
30
  #unified_chain.valid_mapping_permutations(runtime_method,test_cases)
24
31
 
@@ -0,0 +1,150 @@
1
+ require 'ripper'
2
+ require 'sorcerer'
3
+ require 'pp'
4
+
5
+ # 1. ball.collect
6
+ sexp = [:program,
7
+ [:stmts_add,
8
+ [:stmts_new],
9
+ [:call,
10
+ [:vcall, [:@ident, 'ball']],
11
+ :".",
12
+ [:@ident, 'bounce' ]
13
+ ]
14
+ ]
15
+ ]
16
+
17
+ # 2.
18
+ # ball.bounce
19
+ # ball.kick
20
+ sexp = [:program,
21
+ [:stmts_add,
22
+ [:stmts_add,
23
+ [:stmts_new],
24
+ [:call,
25
+ [:vcall, [:@ident, 'ball']],
26
+ :".",
27
+ [:@ident, 'bounce' ]
28
+ ]
29
+ ],
30
+ [:call,
31
+ [:vcall, [:@ident, 'ball']],
32
+ :".",
33
+ [:@ident, 'kick' ]
34
+ ],
35
+ ]
36
+ ]
37
+ # e.g.
38
+ # [:program, [:stmts_add, [:stmts_add, [:stmts_new], 'ball.bound'], 'ball.kick' ]
39
+
40
+ bounce_call = [:call,
41
+ [:vcall, [:@ident, 'ball']],
42
+ :".",
43
+ [:@ident, 'bounce' ]
44
+ ]
45
+ kick_call = [:call,
46
+ [:vcall, [:@ident, 'ball']],
47
+ :".",
48
+ [:@ident, 'kick' ]
49
+ ]
50
+ throw_call = [:call,
51
+ [:vcall, [:@ident, 'ball']],
52
+ :".",
53
+ [:@ident, 'throw' ]
54
+ ]
55
+
56
+ # 3.
57
+ # ball.bounce
58
+ # ball.kick
59
+ # ball.throw
60
+ sexp = [:program,
61
+ [:stmts_add,
62
+ [:stmts_add,
63
+ [:stmts_add,
64
+ [:stmts_new],
65
+ bounce_call
66
+ ],
67
+ kick_call
68
+ ],
69
+ throw_call
70
+ ]
71
+ ]
72
+
73
+ # 4.
74
+ method_ident = [:@ident, "test"]
75
+ params = [:paren, [:params, [[:@ident, "var0"]] ]]
76
+ # def test(var0)
77
+ # var0.bounce
78
+ # var1.kick
79
+ # end
80
+ sexp = [:program,
81
+ [:stmts_add,
82
+ [:stmts_new],
83
+ [:def,
84
+ method_ident,
85
+ params,
86
+ [:bodystmt,
87
+ [:stmts_add,
88
+ [:stmts_add,
89
+ [:stmts_add,
90
+ [:stmts_new],
91
+ bounce_call
92
+ ],
93
+ kick_call
94
+ ],
95
+ throw_call
96
+ ]
97
+ ]
98
+ ]
99
+ ]
100
+ ]
101
+
102
+ # 5.
103
+ # var0.collect do |x|
104
+ # record(local_variable)
105
+ # end
106
+
107
+ var_collect = [:call,
108
+ [:vcall, [:@ident, "var0"]],
109
+ :".",
110
+ [:@ident, "collect"]
111
+ ]
112
+ var0_block_var = [:block_var,
113
+ [:params, [[:@ident, "x"]] ],
114
+ false
115
+ ]
116
+ method_add_arg = [:method_add_arg,
117
+ [:fcall, [:@ident, "record"]],
118
+ [:arg_paren,
119
+ [:args_add_block,
120
+ [:args_add,
121
+ [:args_new],
122
+ [:vcall, [:@ident, "local_variable"]]
123
+ ]
124
+ ]
125
+ ]
126
+ ]
127
+
128
+ sexp = [:program,
129
+ [:stmts_add,
130
+ [:stmts_new],
131
+ [:method_add_block,
132
+ var_collect,
133
+ [:do_block,
134
+ var0_block_var,
135
+ [:stmts_add,
136
+ [:stmts_new],
137
+ method_add_arg
138
+ ]
139
+ ]
140
+ ]
141
+ ]
142
+ ]
143
+
144
+
145
+ pp Sorcerer.source(sexp, indent: true)
146
+ puts Sorcerer.source(sexp, indent: true)
147
+
148
+
149
+ sexp = [:call, [:vcall, [:@ident, 'var0']], :".", [:@ident, "chop"]]
150
+ pp Sorcerer.source(sexp, indent: true)
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+
3
+ module Cauldron
4
+
5
+ describe ActualizedComposite do
6
+
7
+ let(:empty_composite) do
8
+ Cauldron::Solution::Composite.new([])
9
+ end
10
+
11
+ describe '#to_ruby' do
12
+
13
+ let(:nested_statement) do
14
+ Tree::TreeNode.new( 'x', StatementGenerator.new.default_template(['lion','bear'],:collect).new([0]) )
15
+ end
16
+
17
+ let(:composite) do
18
+ chop = StatementGenerator.new.default_template('lion',:chop).new([2])
19
+ nested_statement << Tree::TreeNode.new('x', chop)
20
+ Cauldron::Solution::Composite.new([nested_statement])
21
+ end
22
+
23
+ let(:examples) do
24
+ Cauldron::ExampleSet.new(
25
+ [ Cauldron::Example.new(
26
+ { arguments: [["lion", "bear"]], response: ["bea", "lio"]}
27
+ )
28
+ ]
29
+ )
30
+ end
31
+
32
+ let(:subject) do
33
+ Cauldron::ActualizedComposite.new(
34
+ composite, examples
35
+ )
36
+ end
37
+
38
+ it 'prints the correct statement' do
39
+ subject.to_ruby.should == %q{var1 = var0.collect do |var2| var2.chop end}
40
+ end
41
+
42
+ end
43
+
44
+ describe '#histories' do
45
+
46
+ context %q{there is one example "var0 = ['lion','bear']"} do
47
+
48
+ let(:examples) do
49
+ Cauldron::ExampleSet.new(
50
+ [Cauldron::Example.new( {arguments: [['lion','bear']], response: 8} )]
51
+ )
52
+ end
53
+
54
+ context 'composite is empty' do
55
+
56
+ let(:subject) { Cauldron::ActualizedComposite.new(empty_composite, examples)}
57
+
58
+ it 'returns 1 history' do
59
+ subject.histories.length.should == 1
60
+ end
61
+
62
+ it 'history contains single log' do
63
+ subject.histories.first.logs.length.should == 1
64
+ end
65
+
66
+ end
67
+
68
+ context 'composite is "var0 = var1.collect { |var2|}' do
69
+
70
+ let(:containing_statement) do
71
+ StatementGenerator.new.default_template(['lion','bear'],:collect).new([0])
72
+ end
73
+
74
+ let(:composite) do
75
+ Cauldron::Solution::Composite.new(
76
+ [Tree::TreeNode.new("CHILD1", containing_statement )]
77
+ )
78
+ end
79
+
80
+ let(:subject) { Cauldron::ActualizedComposite.new(composite, examples)}
81
+
82
+ # TODO total_line is going to be wrong
83
+ log_history = %q{
84
+ | {line: 0, depth: 1, total_line: 3, point: [0,0], var0: ['lion', 'bear'], var2: 'lion', var1: nil} |
85
+ | {line: 0, depth: 1, total_line: 3, point: [0,0], var0: ['lion', 'bear'], var2: 'bear', var1: nil} |
86
+ | {line: 0, depth: 0, total_line: 4, point: [1], var0: ['lion', 'bear'], var1: ['lion', 'bear'] } |
87
+ }
88
+
89
+ it 'contains a history with 3 entries' do
90
+ subject.histories.first.logs.length.should == 3
91
+ end
92
+
93
+ it %Q{retuns the following history: #{log_history} } do
94
+ pending
95
+ # logs = [
96
+ # {line: 0, depth: 1, var0: ['lion', 'bear'], var2: 'lion', var1: nil},
97
+ # {line: 0, depth: 1, var0: ['lion', 'bear'], var2: 'bear', var1: nil},
98
+ # {line: 1, depth: 0, var0: ['lion', 'bear'], var1: ['lion', 'bear'] }
99
+ # ]
100
+ subject.histories.first.logs.should match_history(log_history)
101
+ #logs.should match_history(log_history)
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+
110
+ describe '#extend_solution' do
111
+
112
+ let(:examples) do
113
+ Cauldron::ExampleSet.new(
114
+ [
115
+ Cauldron::Example.new( {arguments: [7], response: 8} ),
116
+ Cauldron::Example.new( {arguments: [10], response: 11} )
117
+ ]
118
+ )
119
+ end
120
+
121
+ let(:subject) { Cauldron::ActualizedComposite.new(empty_composite, examples)}
122
+
123
+ context 'there is only the numeric operator available' do
124
+
125
+ before(:each) do
126
+ Builder.stub(:available_statement_types).and_return [NumericOperator]
127
+ end
128
+
129
+ it 'returns 1 actualized composite' do
130
+ pending
131
+ subject.extend_solution.should have(1).composite
132
+ end
133
+
134
+ end
135
+
136
+ end
137
+
138
+ end
139
+
140
+ end