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,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