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,421 @@
1
+ require 'spec_helper'
2
+
3
+ module Cauldron::Solution
4
+
5
+ describe 'Composite' do
6
+
7
+ describe '#clone_solution' do
8
+
9
+ let(:composite) do
10
+ Cauldron::Solution::Composite.new([])
11
+ end
12
+
13
+ it 'creates a new composite' do
14
+ composite.clone_solution.object_id.should_not == composite.object_id
15
+ end
16
+
17
+ context %q{it is:
18
+ def function(var0)
19
+ var0.chop
20
+ end
21
+ } do
22
+
23
+ let(:containing_statement) do
24
+ Cauldron::StatementGenerator.new.default_template('lion',:chop).new([0])
25
+ end
26
+
27
+ let(:composite) do
28
+ Cauldron::Solution::Composite.new(
29
+ [Tree::TreeNode.new("CHILD1", containing_statement )]
30
+ )
31
+ end
32
+
33
+ it 'has different operators' do
34
+ composite.clone_solution.operators.object_id.should_not == composite.operators.object_id
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ describe '#end_points' do
42
+
43
+ context 'with empty composite' do
44
+
45
+ let(:composite) do
46
+ Cauldron::Solution::Composite.new([])
47
+ end
48
+
49
+ it 'returns [[0]]' do
50
+ composite.end_points.should include([0])
51
+ end
52
+
53
+ end
54
+
55
+ context %q{it is:
56
+ def function(var0)
57
+ var0.chop
58
+ end
59
+ } do
60
+
61
+ let(:containing_statement) do
62
+ Cauldron::StatementGenerator.new.default_template('lion',:chop).new([0])
63
+ end
64
+
65
+ let(:composite) do
66
+ Cauldron::Solution::Composite.new(
67
+ [Tree::TreeNode.new("CHILD1", containing_statement )]
68
+ )
69
+ end
70
+
71
+ it 'returns [[1]]' do
72
+ composite.end_points.should include([1])
73
+ end
74
+
75
+ it 'has 1 point' do
76
+ composite.end_points.length.should == 1
77
+ end
78
+
79
+ end
80
+
81
+ context %q{it is:
82
+ def function(var0)
83
+ var2 = var0.collect do |var1|
84
+ end
85
+ end
86
+ } do
87
+
88
+ let(:containing_statement) do
89
+ Cauldron::StatementGenerator.new.default_template(['lion','bear'],:collect).new([0])
90
+ end
91
+
92
+ let(:composite) do
93
+ Cauldron::Solution::Composite.new(
94
+ [Tree::TreeNode.new("CHILD1", containing_statement )]
95
+ )
96
+ end
97
+
98
+ it 'has 2 points' do
99
+ composite.end_points.length.should == 2
100
+ end
101
+
102
+ it 'has point [[1]]' do
103
+ composite.end_points.should include([1])
104
+ end
105
+
106
+ it 'has point [[0,0]]' do
107
+ composite.end_points.should include([0,0])
108
+ end
109
+
110
+ end
111
+
112
+ context %q{it is:
113
+ def function(var0)
114
+ var2 = var0.collect do |var1|
115
+ var1.chop
116
+ end
117
+ end
118
+ } do
119
+
120
+ let(:var1_chop) do
121
+ Cauldron::StatementGenerator.new.default_template('lion',:chop).new([0])
122
+ end
123
+
124
+ let(:containing_statement) do
125
+ Cauldron::StatementGenerator.new.default_template(['lion','bear'],:collect).new([0])
126
+ end
127
+
128
+ let(:composite) do
129
+ statement = Tree::TreeNode.new("CHILD1", containing_statement )
130
+ statement << Tree::TreeNode.new("CHILD1", var1_chop )
131
+ Cauldron::Solution::Composite.new(
132
+ [statement]#[Tree::TreeNode.new("CHILD1", containing_statement )]
133
+ )
134
+ end
135
+
136
+ it 'has 2 points' do
137
+ composite.end_points.length.should == 2
138
+ end
139
+
140
+ it 'has point [[1]]' do
141
+ composite.end_points.should include([1])
142
+ end
143
+
144
+ it 'has point [[0,1]]' do
145
+ composite.end_points.should include([0,1])
146
+ end
147
+
148
+ end
149
+
150
+ end
151
+
152
+ describe '#record' do
153
+
154
+ context %q{there is one example "var0 = ['lion','bear']"} do
155
+
156
+ let(:example) do
157
+ Cauldron::Example.new( {arguments: [['lion','bear']], response: 8} )
158
+ end
159
+
160
+ context 'composite is "var0 = var1.collect { |var2|}' do
161
+
162
+ let(:containing_statement) do
163
+ Cauldron::StatementGenerator.new.default_template(['lion','bear'],:collect).new([0])
164
+ end
165
+
166
+ let(:composite) do
167
+ Cauldron::Solution::Composite.new(
168
+ [Tree::TreeNode.new("CHILD1", containing_statement )]
169
+ )
170
+ end
171
+
172
+ it 'returns a history with 3 log entries' do
173
+ composite.record(example).logs.length.should == 3
174
+ end
175
+
176
+ end
177
+
178
+ end
179
+
180
+ end
181
+
182
+ describe '#solution?' do
183
+
184
+ let(:problems) do
185
+ Cauldron::ExampleSet.new(
186
+ [
187
+ Cauldron::Example.new({ arguments: [["lion", "bear"]], response: ["bear", "lion"]}),
188
+ Cauldron::Example.new({ arguments: [["foo", "bar"]], response: ["bar", "foo"]})
189
+ ]
190
+ )
191
+ end
192
+
193
+ let(:composite) do
194
+ Cauldron::Solution::Composite.new(
195
+ [Tree::TreeNode.new("CHILD1", Cauldron::ArrayCollectTemplate::Default.new([0]))]
196
+ )
197
+ end
198
+
199
+ it 'is false' do
200
+ composite.solution?(problems).should == false
201
+ end
202
+
203
+ context "using valid chop example" do
204
+
205
+ let(:examples) do
206
+ Cauldron::ExampleSet.new(
207
+ [
208
+ Cauldron::Example.new({ arguments: ["Sparky"], response: 'Spark'}),
209
+ Cauldron::Example.new({ arguments: ["Kel"], response: 'Ke'})
210
+ ]
211
+ )
212
+ end
213
+
214
+ let(:dynamic_operator) do
215
+ Cauldron::StatementGenerator.new.default_template('string',:chop).new([0])
216
+ end
217
+
218
+ let(:composite) do
219
+ Cauldron::Solution::Composite.new(
220
+ [Tree::TreeNode.new("CHILD1", dynamic_operator)]
221
+ )
222
+ end
223
+
224
+ it 'is true' do
225
+ composite.solution?(examples).should == true
226
+ end
227
+
228
+ end
229
+
230
+ end
231
+
232
+ describe '#insert_tracking' do
233
+
234
+ context %q{
235
+ given a composite:
236
+ def function(params)
237
+
238
+ end
239
+ } do
240
+
241
+ # code = """
242
+ # """
243
+ let(:params) { ['var0'] }
244
+
245
+ it %q{
246
+ generates a method:
247
+ def function(params)
248
+ record(0,0,1,[0],local_variables.reject {|foo| foo == :_}.collect { |bar| [bar, eval(bar.to_s)] })
249
+ end
250
+ } do
251
+ Composite.new([]).insert_tracking(params).sexp.should match_code_of( %q{
252
+ def function(var0)
253
+ record(0,0,1,[0],local_variables.reject {|foo| foo == :_}.collect { |bar| [bar, eval(bar.to_s)] })
254
+ end
255
+ })
256
+ end
257
+
258
+ end
259
+
260
+ end
261
+
262
+ describe '#to_ruby' do
263
+
264
+ context "hasn't any operators" do
265
+
266
+ let(:variables) { Cauldron::Scope.new(['var0']) }
267
+
268
+ let(:subject) do
269
+ Cauldron::Solution::Composite.new([])
270
+ end
271
+
272
+ it "doesn't raise an error" do
273
+ expect{
274
+ subject.to_ruby( variables )
275
+ }.not_to raise_error
276
+ end
277
+
278
+ end
279
+
280
+ context 'first line' do
281
+
282
+ context 'has operator "Array#collect"' do
283
+
284
+ let(:array_collect) { Cauldron::ArrayCollectTemplate::Default.new([0]) }
285
+
286
+ let(:tree) do
287
+ # Tree::TreeNode.new("ROOT", "Root Content").tap do |root|
288
+ # root << Tree::TreeNode.new("CHILD1", array_collect)
289
+ # root << Tree::TreeNode.new("CHILD2", string_asterisk)
290
+ # end
291
+ root = Tree::TreeNode.new("ROOT", "Root Content")
292
+ child = Tree::TreeNode.new("CHILD1", array_collect)
293
+ grand_child = Tree::TreeNode.new("CHILD2", string_asterisk)
294
+ child << grand_child
295
+ root << child
296
+ root
297
+ end
298
+
299
+ context 'has operator "String#*"' do
300
+
301
+ let(:string_asterisk) { StringAsteriskOperator.new([1]) }
302
+
303
+ let(:scope) { Cauldron::Scope.new(['var0']) }
304
+
305
+ it 'is "var0.collect { |var1| var1 * 2 }"' do
306
+ Cauldron::Solution::Composite.new(
307
+ tree.children
308
+ ).to_ruby( scope ).should == 'var0.collect { |var1| var1 * 2 }'
309
+ end
310
+
311
+ end
312
+
313
+ end
314
+
315
+ end
316
+
317
+ context %q{with the operators} do
318
+
319
+ let(:scope) { Cauldron::Scope.new(['var0']) }
320
+
321
+ let(:tree) do
322
+ root_node = Tree::TreeNode.new("ROOT", "Root Content")
323
+ child_node = Tree::TreeNode.new("CHILD1", Cauldron::VarCollectOperator.new([0]) )
324
+ #child_node << Tree::TreeNode.new("GRANDCHILD1", NumericOperator.new([2], 2) )
325
+ child_node << Tree::TreeNode.new("GRANDCHILD1", NumericOperator.new([2]) )
326
+ root_node << child_node
327
+ # --
328
+ child_node_2 = Tree::TreeNode.new("CHILD2", Cauldron::VarCollectOperator.new([1]) )
329
+ child_node_2 << Tree::TreeNode.new("GRAND-CHILD2", ToSOperator.new([4]) )
330
+ root_node << child_node_2
331
+ root_node
332
+ end
333
+
334
+ it %q{generates the code} do
335
+ pending
336
+ Composite.new(
337
+ tree.children
338
+ #[Cauldron::VarCollectOperator.new([0]), NumericOperator.new([2], 2) ],
339
+ #[Cauldron::VarCollectOperator.new([1]), ToSOperator.new([4])]
340
+ ).to_ruby( scope ).should == %q{
341
+ var1 = var0.collect do |var2|
342
+ var2 + 2
343
+ end;
344
+ var3 = var1.collect do |var4|
345
+ var4.to_s
346
+ end
347
+ }.strip.gsub(/\n/,'')
348
+ end
349
+
350
+ end
351
+
352
+ context 'with VarCollect' do
353
+
354
+ let(:variables) { Cauldron::Scope.new(['var0']) }
355
+
356
+ let(:tree) do
357
+ root_node = Tree::TreeNode.new("ROOT", "Root Content")
358
+ child_node = Tree::TreeNode.new("CHILD1", Cauldron::VarCollectOperator.new([0]) )
359
+ child_node_2 = Tree::TreeNode.new("CHILD2", StringAsteriskOperator.new([2]) )
360
+ child_node << child_node_2
361
+ root_node << child_node
362
+ root_node
363
+ end
364
+
365
+ it %q{
366
+ var1 = var0.collect do |var2|
367
+ var2 * 2
368
+ end
369
+ } do
370
+ Composite.new(
371
+ tree.children
372
+ ).to_ruby( variables ).should == %q{
373
+ var1 = var0.collect do |var2|
374
+ var2 * 2
375
+ end
376
+ }.strip.gsub(/\n/,'')
377
+ end
378
+
379
+ end
380
+
381
+ end
382
+
383
+ describe '#to_sexp' do
384
+
385
+ context 'using initial operator "Array#collect"' do
386
+
387
+ let(:collect_operator) { Cauldron::ArrayCollectTemplate::Default.new([0]) }
388
+
389
+ let(:scope) { Cauldron::Scope.new(['var0']) }
390
+
391
+ context 'using second operator "x * 3"' do
392
+
393
+ let(:string_multiple) { StringAsteriskOperator.new([1]) }
394
+
395
+ let(:tree) do
396
+ root_node = Tree::TreeNode.new("ROOT", "Root Content")
397
+ child_node = Tree::TreeNode.new("CHILD1", collect_operator )
398
+ child_node_2 = Tree::TreeNode.new("CHILD2", string_multiple )
399
+ child_node << child_node_2
400
+ root_node << child_node
401
+ root_node
402
+ end
403
+
404
+ it 'returns "var0.collect {|x| x * 2}"' do
405
+ Composite.new(tree.children).to_sexp(scope).should match_code_of(
406
+ %q{
407
+ var0.collect { |var1|
408
+ var1 * 2
409
+ }
410
+ }
411
+ )
412
+ end
413
+
414
+ end
415
+
416
+ end
417
+
418
+ end
419
+
420
+ end
421
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ module Cauldron::Solution
4
+
5
+ describe 'One' do
6
+
7
+ let(:solution) do
8
+ Cauldron::Solution::One.new
9
+ end
10
+
11
+ describe '#to_ruby' do
12
+
13
+ #it 'returns "var0.concat("bar")"' do
14
+ it %q{returns var0.collect { |x| x * 2 } } do
15
+ solution.to_ruby(['var0']).to_s.should == %q{
16
+ var0.collect { |x| x * 2 }
17
+ }.strip
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,211 @@
1
+ require 'spec_helper'
2
+
3
+ module Cauldron
4
+
5
+ describe StatementGenerator do
6
+
7
+ describe '#method_to_sexp' do
8
+
9
+ let(:subject) { StatementGenerator.new}
10
+
11
+ context 'instance is "3"' do
12
+
13
+ let(:instance) { 3 }
14
+
15
+ context 'dynamic_method is ":+"' do
16
+
17
+ let(:dynamic_method) { :+ }
18
+
19
+ it "doesn't raise an error" do
20
+ expect{
21
+ subject.method_to_sexp(instance, dynamic_method)
22
+ }.not_to raise_error
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ describe '#build_class' do
32
+
33
+ let(:subject) { StatementGenerator.new }
34
+
35
+ context 'with string instance "string"' do
36
+
37
+ context 'with method "chop"' do
38
+
39
+ it "doesn't raise an error" do
40
+ expect{
41
+ subject.build_class('string', 'chop')
42
+ }.not_to raise_error
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ describe '#dynamic_template_name' do
52
+
53
+ context 'with instance 4' do
54
+
55
+ context 'with method "+"' do
56
+
57
+ let(:subject) do
58
+ Object.const_set(
59
+ StatementGenerator.new.dynamic_template_name(4,'+'),
60
+ Class.new
61
+ )
62
+ end
63
+
64
+ it 'generates a valid class name' do
65
+ expect{
66
+ subject.new
67
+ }.not_to raise_error
68
+ end
69
+
70
+ after(:each) do
71
+ Object.send(:remove_const, StatementGenerator.new.dynamic_template_name(4,'+'))
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+
80
+ describe '#build_template' do
81
+
82
+ let(:subject) { StatementGenerator.new}
83
+
84
+ context 'with instance 4' do
85
+
86
+ context 'with method "+"' do
87
+
88
+ it "doesn't raise an error" do
89
+ expect{ subject.build_template(4, '+') }.not_to raise_error
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+
98
+ describe '#build' do
99
+
100
+ let(:subject) { StatementGenerator.new}
101
+
102
+ it 'returns 1 operator' do
103
+ expect(subject.build('string',[:chop]).length).to eql(1)
104
+ end
105
+
106
+ describe 'generating String#chop' do
107
+
108
+ let(:operators) { [] }
109
+ let(:scope) { Cauldron::Scope.new(['var0']) }
110
+
111
+ describe 'unbuilt instance' do
112
+
113
+ it 'returns a instance that raises an error when #to_tracking_sexp' do
114
+ expect{
115
+ subject.build(
116
+ 'string',[:chop]
117
+ ).first.to_tracking_sexp(
118
+ operators, scope, Cauldron::Caret.new
119
+ )
120
+ }.to raise_error(StandardError)
121
+ end
122
+
123
+ end
124
+
125
+ describe '#realizable?' do
126
+
127
+ let(:operator) do
128
+ subject.default_template('string',:chop).new([0])
129
+ end
130
+
131
+ end
132
+
133
+ describe '#to_ruby' do
134
+
135
+ let(:operator) do
136
+ subject.default_template('string',:chop).new([0])
137
+ end
138
+
139
+ it 'returns the "var0.chop"' do
140
+ operator.to_ruby(scope,[]).should == 'var0.chop'
141
+ end
142
+
143
+ end
144
+
145
+ describe '#instances' do
146
+
147
+ describe 'adding String#chop in collect statement' do
148
+
149
+ let(:histories) do
150
+ Cauldron::Histories.new(
151
+ [
152
+ Cauldron::History.new(
153
+ [
154
+ {:var2=>"Sparky", :var0=>["Sparky", "Kels"], :var1=>nil, :line=>0, :depth=>1, :total_line=>3, :point=>[0, 0]},
155
+ {:var2=>"Kels", :var0=>["Sparky", "Kels"], :var1=>nil, :line=>0, :depth=>1, :total_line=>3, :point=>[0, 0]},
156
+ {:var0=>["Sparky", "Kels"], :var1=>["Sparky", "Kels"], :line=>0, :depth=>0, :total_line=>4, :point=>[1]}
157
+ ]
158
+ )
159
+ ]
160
+ )
161
+ end
162
+
163
+ let(:composite) do
164
+ Cauldron::Solution::Composite.new(
165
+ [
166
+ Tree::TreeNode.new(
167
+ "ROOT",
168
+ StatementGenerator.new.default_template(
169
+ ["Sparky", "Kels"],
170
+ :collect
171
+ ).new([0])
172
+ )
173
+ ]
174
+ )
175
+ end
176
+
177
+ let(:examples) do
178
+ Cauldron::ExampleSet.new(
179
+ [
180
+ Cauldron::Example.new({arguments: [["Sparky", "Kels"]], response: ["Spark", "Kel"]}),
181
+ Cauldron::Example.new({arguments: [["Pip", "Rowe"]], response: ["Pi", "Row"]})
182
+ ]
183
+ )
184
+ end
185
+
186
+ let(:insert_points) { [[0, 0], [1]] }
187
+
188
+ let(:operator) do
189
+ subject.default_template('string',:chop)
190
+ end
191
+
192
+ # instances(histories, composite, examples, insert_points)
193
+ it 'returns 1 new composite' do
194
+ expect(
195
+ operator.instances(
196
+ histories, composite, examples, insert_points
197
+ ).length
198
+ ).to eql(1)
199
+ end
200
+
201
+ end
202
+
203
+ end
204
+
205
+ end
206
+
207
+ end
208
+
209
+ end
210
+
211
+ end