alf 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +42 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +15 -0
- data/README.md +769 -0
- data/Rakefile +23 -0
- data/TODO.md +26 -0
- data/alf.gemspec +191 -0
- data/alf.noespec +30 -0
- data/bin/alf +31 -0
- data/examples/autonum.alf +6 -0
- data/examples/cities.rash +4 -0
- data/examples/clip.alf +3 -0
- data/examples/compact.alf +2 -0
- data/examples/database.alf +6 -0
- data/examples/defaults.alf +3 -0
- data/examples/extend.alf +3 -0
- data/examples/group.alf +3 -0
- data/examples/intersect.alf +4 -0
- data/examples/join.alf +2 -0
- data/examples/minus.alf +8 -0
- data/examples/nest.alf +2 -0
- data/examples/nulls.rash +3 -0
- data/examples/parts.rash +6 -0
- data/examples/project.alf +2 -0
- data/examples/quota.alf +4 -0
- data/examples/rename.alf +3 -0
- data/examples/restrict.alf +2 -0
- data/examples/runall.sh +26 -0
- data/examples/schema.yaml +28 -0
- data/examples/sort.alf +4 -0
- data/examples/summarize.alf +16 -0
- data/examples/suppliers.rash +5 -0
- data/examples/supplies.rash +12 -0
- data/examples/ungroup.alf +4 -0
- data/examples/union.alf +3 -0
- data/examples/unnest.alf +4 -0
- data/examples/with.alf +23 -0
- data/lib/alf.rb +2984 -0
- data/lib/alf/loader.rb +1 -0
- data/lib/alf/renderer/text.rb +153 -0
- data/lib/alf/renderer/yaml.rb +22 -0
- data/lib/alf/version.rb +14 -0
- data/spec/aggregator_spec.rb +62 -0
- data/spec/alf_spec.rb +47 -0
- data/spec/assumptions_spec.rb +15 -0
- data/spec/environment/explicit_spec.rb +15 -0
- data/spec/environment/folder_spec.rb +30 -0
- data/spec/examples_spec.rb +26 -0
- data/spec/lispy_spec.rb +23 -0
- data/spec/operator/command_methods_spec.rb +38 -0
- data/spec/operator/non_relational/autonum_spec.rb +61 -0
- data/spec/operator/non_relational/clip_spec.rb +49 -0
- data/spec/operator/non_relational/compact/buffer_based.rb +30 -0
- data/spec/operator/non_relational/compact/sort_based_spec.rb +30 -0
- data/spec/operator/non_relational/compact_spec.rb +38 -0
- data/spec/operator/non_relational/defaults_spec.rb +55 -0
- data/spec/operator/non_relational/sort_spec.rb +66 -0
- data/spec/operator/relational/extend_spec.rb +34 -0
- data/spec/operator/relational/group_spec.rb +54 -0
- data/spec/operator/relational/intersect_spec.rb +58 -0
- data/spec/operator/relational/join/hash_based_spec.rb +63 -0
- data/spec/operator/relational/minus_spec.rb +56 -0
- data/spec/operator/relational/nest_spec.rb +32 -0
- data/spec/operator/relational/project_spec.rb +65 -0
- data/spec/operator/relational/quota_spec.rb +44 -0
- data/spec/operator/relational/rename_spec.rb +32 -0
- data/spec/operator/relational/restrict_spec.rb +56 -0
- data/spec/operator/relational/summarize/sort_based_spec.rb +31 -0
- data/spec/operator/relational/summarize_spec.rb +41 -0
- data/spec/operator/relational/ungroup_spec.rb +35 -0
- data/spec/operator/relational/union_spec.rb +35 -0
- data/spec/operator/relational/unnest_spec.rb +32 -0
- data/spec/reader/alf_file_spec.rb +15 -0
- data/spec/reader/input.rb +2 -0
- data/spec/reader/rash_spec.rb +31 -0
- data/spec/reader_spec.rb +27 -0
- data/spec/renderer/text/cell_spec.rb +34 -0
- data/spec/renderer/text/row_spec.rb +30 -0
- data/spec/renderer/text/table_spec.rb +39 -0
- data/spec/renderer_spec.rb +42 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/tools/ordering_key_spec.rb +81 -0
- data/spec/tools/projection_key_spec.rb +83 -0
- data/spec/tools/tools_spec.rb +25 -0
- data/spec/tools/tuple_handle_spec.rb +78 -0
- data/tasks/debug_mail.rake +78 -0
- data/tasks/debug_mail.txt +13 -0
- data/tasks/gem.rake +68 -0
- data/tasks/spec_test.rake +79 -0
- data/tasks/unit_test.rake +77 -0
- data/tasks/yard.rake +51 -0
- metadata +282 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Join::HashBased do
|
5
|
+
|
6
|
+
let(:suppliers) {[
|
7
|
+
{:sid => 'S1', :city => 'London'},
|
8
|
+
{:sid => 'S2', :city => 'Paris'},
|
9
|
+
{:sid => 'S3', :city => 'Paris'}
|
10
|
+
]}
|
11
|
+
|
12
|
+
let(:statuses) {[
|
13
|
+
{:sid => 'S1', :status => 20},
|
14
|
+
{:sid => 'S2', :status => 10},
|
15
|
+
{:sid => 'S3', :status => 30}
|
16
|
+
]}
|
17
|
+
|
18
|
+
let(:countries) {[
|
19
|
+
{:city => 'London', :country => 'England'},
|
20
|
+
{:city => 'Paris', :country => 'France'},
|
21
|
+
{:city => 'Bruxelles', :country => 'Belgium (until ?)'}
|
22
|
+
]}
|
23
|
+
|
24
|
+
let(:operator){ Join::HashBased.new }
|
25
|
+
subject{ operator.to_a }
|
26
|
+
|
27
|
+
describe "when applied on both candidate keys" do
|
28
|
+
before{ operator.datasets = [suppliers, statuses] }
|
29
|
+
let(:expected){[
|
30
|
+
{:sid => 'S1', :city => 'London', :status => 20},
|
31
|
+
{:sid => 'S2', :city => 'Paris', :status => 10},
|
32
|
+
{:sid => 'S3', :city => 'Paris', :status => 30}
|
33
|
+
]}
|
34
|
+
it { should == expected }
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "when applied on a typical foreign key" do
|
38
|
+
let(:expected){[
|
39
|
+
{:sid => 'S1', :city => 'London', :country => 'England'},
|
40
|
+
{:sid => 'S2', :city => 'Paris', :country => 'France'},
|
41
|
+
{:sid => 'S3', :city => 'Paris', :country => 'France'}
|
42
|
+
]}
|
43
|
+
describe "on one way" do
|
44
|
+
before{ operator.datasets = [suppliers, countries] }
|
45
|
+
it { should == expected }
|
46
|
+
end
|
47
|
+
describe "on the other way around" do
|
48
|
+
before{ operator.datasets = [countries, suppliers] }
|
49
|
+
it { should == expected }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "when no attributes are in common" do
|
54
|
+
before{ operator.datasets = [statuses, countries] }
|
55
|
+
let(:expected){
|
56
|
+
statuses.collect{|s| countries.collect{|c| c.merge(s)}}.flatten
|
57
|
+
}
|
58
|
+
it { should == expected }
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Minus do
|
5
|
+
|
6
|
+
let(:operator_class){ Minus }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:left) {[
|
10
|
+
{:sid => 'S1', :city => 'London'},
|
11
|
+
{:sid => 'S2', :city => 'Paris'},
|
12
|
+
{:sid => 'S3', :city => 'Paris'}
|
13
|
+
]}
|
14
|
+
|
15
|
+
let(:right) {[
|
16
|
+
{:sid => 'S2', :city => 'Paris'},
|
17
|
+
{:sid => 'S1', :city => 'London'},
|
18
|
+
]}
|
19
|
+
|
20
|
+
let(:disjoint) {[
|
21
|
+
{:sid => 'S4', :city => 'Oslo'},
|
22
|
+
{:sid => 'S5', :city => 'Bruxelles'},
|
23
|
+
]}
|
24
|
+
|
25
|
+
let(:operator){ Minus.run([]) }
|
26
|
+
subject{ operator.to_a }
|
27
|
+
|
28
|
+
describe "when applied on the same operand twice" do
|
29
|
+
before{ operator.datasets = [left, left] }
|
30
|
+
it { should be_empty }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "when applied on operands sharing tuples" do
|
34
|
+
before{ operator.datasets = [left, right] }
|
35
|
+
let(:expected) {[
|
36
|
+
{:sid => 'S3', :city => 'Paris'}
|
37
|
+
]}
|
38
|
+
it { should == expected }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "when applied on disjoint operands" do
|
42
|
+
before{ operator.datasets = [left, disjoint] }
|
43
|
+
it { should == left }
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "when factored with Lispy" do
|
47
|
+
let(:operator){ Lispy.minus(left, right) }
|
48
|
+
let(:expected) {[
|
49
|
+
{:sid => 'S3', :city => 'Paris'}
|
50
|
+
]}
|
51
|
+
it { should == expected }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Nest do
|
5
|
+
|
6
|
+
let(:operator_class){ Nest }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:input) {[
|
10
|
+
{:a => "a", :b => "b", :c => "c"},
|
11
|
+
]}
|
12
|
+
|
13
|
+
let(:expected) {[
|
14
|
+
{:nested => {:a => "a", :b => "b"}, :c => "c"}
|
15
|
+
]}
|
16
|
+
|
17
|
+
subject{ operator.to_a }
|
18
|
+
|
19
|
+
describe "when factored with commandline args" do
|
20
|
+
let(:operator){ Nest.run(["--", "a", "b", "nested"]) }
|
21
|
+
before{ operator.pipe(input) }
|
22
|
+
it { should == expected }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "when factored with Lispy" do
|
26
|
+
let(:operator){ Lispy.nest(input, [:a, :b], :nested) }
|
27
|
+
it { should == expected }
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Project do
|
5
|
+
|
6
|
+
let(:operator_class){ Project }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:input) {[
|
10
|
+
{:a => "a", :b => "b"},
|
11
|
+
{:a => "a", :b => "b"},
|
12
|
+
]}
|
13
|
+
|
14
|
+
subject{ operator.to_a }
|
15
|
+
|
16
|
+
describe "when used without --allbut" do
|
17
|
+
let(:expected){[{:a => "a"}]}
|
18
|
+
|
19
|
+
describe "and factored with commandline args" do
|
20
|
+
let(:operator){ Project.run(["--", 'a']) }
|
21
|
+
before{ operator.pipe(input) }
|
22
|
+
it { should == expected }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "and factored with Lispy" do
|
26
|
+
let(:operator){ Lispy.project(input, [:a]) }
|
27
|
+
it { should == expected }
|
28
|
+
end
|
29
|
+
|
30
|
+
end # --no-allbut
|
31
|
+
|
32
|
+
describe "when used with --allbut" do
|
33
|
+
let(:expected){[{:b => "b"}]}
|
34
|
+
|
35
|
+
describe "and factored with commandline args" do
|
36
|
+
let(:operator){ Project.run(['--allbut', '--', 'a']) }
|
37
|
+
before{ operator.pipe(input) }
|
38
|
+
it { should == expected }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "and factored with Lispy" do
|
42
|
+
let(:operator){ Lispy.allbut(input, [:a]) }
|
43
|
+
it { should == expected }
|
44
|
+
end
|
45
|
+
|
46
|
+
end # --allbut
|
47
|
+
|
48
|
+
describe "when all is projected" do
|
49
|
+
let(:expected){[{}]}
|
50
|
+
|
51
|
+
describe "when input is not empty" do
|
52
|
+
let(:operator){ Lispy.project(input, []) }
|
53
|
+
it { should == expected }
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "when input is empty" do
|
57
|
+
let(:operator){ Lispy.project([], []) }
|
58
|
+
it { should == [] }
|
59
|
+
end
|
60
|
+
|
61
|
+
end # all attributes projected
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Quota do
|
5
|
+
|
6
|
+
let(:operator_class){ Quota }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:input) {[
|
10
|
+
{:a => "via_method", :time => 1},
|
11
|
+
{:a => "via_method", :time => 2},
|
12
|
+
{:a => "via_method", :time => 3},
|
13
|
+
{:a => "via_reader", :time => 4},
|
14
|
+
{:a => "via_reader", :time => 2},
|
15
|
+
]}
|
16
|
+
|
17
|
+
let(:expected) {[
|
18
|
+
{:a => "via_method", :time => 1, :time_sum => 1, :time_max => 1},
|
19
|
+
{:a => "via_method", :time => 2, :time_sum => 3, :time_max => 2},
|
20
|
+
{:a => "via_method", :time => 3, :time_sum => 6, :time_max => 3},
|
21
|
+
{:a => "via_reader", :time => 2, :time_sum => 2, :time_max => 2},
|
22
|
+
{:a => "via_reader", :time => 4, :time_sum => 6, :time_max => 4},
|
23
|
+
]}
|
24
|
+
|
25
|
+
subject{ operator.to_a }
|
26
|
+
|
27
|
+
describe "When factored with commandline args" do
|
28
|
+
let(:opts){ ['--by=a', "--order=time"] }
|
29
|
+
let(:aggs){ ["time_sum", "sum(:time)", "time_max", "max(:time)"] }
|
30
|
+
let(:operator){ Quota.run(opts + ["--"] + aggs) }
|
31
|
+
before{ operator.pipe(input) }
|
32
|
+
it { should == expected }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "When factored with Lispy" do
|
36
|
+
let(:aggs){{:time_sum => Aggregator.sum(:time),
|
37
|
+
:time_max => Aggregator.max(:time)}}
|
38
|
+
let(:operator){ Lispy.quota(input, [:a], [:time], aggs) }
|
39
|
+
it { should == expected }
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Rename do
|
5
|
+
|
6
|
+
let(:operator_class){ Rename }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:input) {[
|
10
|
+
{:a => "a", :b => "b"},
|
11
|
+
]}
|
12
|
+
|
13
|
+
let(:expected){[
|
14
|
+
{:z => "a", :b => "b"},
|
15
|
+
]}
|
16
|
+
|
17
|
+
subject{ operator.to_a }
|
18
|
+
|
19
|
+
describe "When factored with Lispy" do
|
20
|
+
let(:operator){ Lispy.rename(input, {:a => :z}) }
|
21
|
+
it{ should == expected }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "When factored from commandline args" do
|
25
|
+
let(:operator){ Rename.run(['--', 'a', 'z']) }
|
26
|
+
before{ operator.pipe(input) }
|
27
|
+
it{ should == expected }
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Restrict do
|
5
|
+
|
6
|
+
let(:operator_class){ Restrict }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:input) {[
|
10
|
+
{:tested => 1, :other => "b"},
|
11
|
+
{:tested => 30, :other => "a"},
|
12
|
+
]}
|
13
|
+
|
14
|
+
let(:expected){[
|
15
|
+
{:tested => 1, :other => "b"}
|
16
|
+
]}
|
17
|
+
|
18
|
+
subject{ operator.to_a }
|
19
|
+
|
20
|
+
describe "when used with no argument" do
|
21
|
+
let(:operator){ Restrict.run(%w{}) }
|
22
|
+
before{ operator.pipe(input) }
|
23
|
+
it { should == input }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "when used with a string" do
|
27
|
+
describe "when factored with commandline args" do
|
28
|
+
let(:operator){ Restrict.run(["--", "tested < 10"]) }
|
29
|
+
before{ operator.pipe(input) }
|
30
|
+
it { should == expected }
|
31
|
+
end
|
32
|
+
describe "when factored with Lispy" do
|
33
|
+
let(:operator){ Lispy.restrict(input, "tested < 10") }
|
34
|
+
it { should == expected }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "when used with arguments" do
|
39
|
+
describe "when factored with commandline args" do
|
40
|
+
let(:operator){ Restrict.run(["--", "tested", "1"]) }
|
41
|
+
before{ operator.pipe(input) }
|
42
|
+
it { should == expected }
|
43
|
+
end
|
44
|
+
describe "when factored with Lispy and Proc" do
|
45
|
+
let(:operator){ Lispy.restrict(input, lambda{ tested < 10 }) }
|
46
|
+
it { should == expected }
|
47
|
+
end
|
48
|
+
describe "when factored with Lispy and array" do
|
49
|
+
let(:operator){ Lispy.restrict(input, [:tested, 1]) }
|
50
|
+
it { should == expected }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Summarize::SortBased do
|
5
|
+
|
6
|
+
let(:input) {[
|
7
|
+
{:a => "via_method", :time => 1},
|
8
|
+
{:a => "via_method", :time => 1},
|
9
|
+
{:a => "via_method", :time => 2},
|
10
|
+
{:a => "via_reader", :time => 4},
|
11
|
+
{:a => "via_reader", :time => 2},
|
12
|
+
]}
|
13
|
+
|
14
|
+
let(:expected) {[
|
15
|
+
{:a => "via_method", :time_sum => 4, :time_max => 2},
|
16
|
+
{:a => "via_reader", :time_sum => 6, :time_max => 4},
|
17
|
+
]}
|
18
|
+
|
19
|
+
let(:by_key){ Tools::ProjectionKey.new([:a],false) }
|
20
|
+
let(:aggs){{:time_sum => Aggregator.sum(:time),
|
21
|
+
:time_max => Aggregator.max(:time)}}
|
22
|
+
let(:operator){ Summarize::SortBased.new(by_key, aggs) }
|
23
|
+
|
24
|
+
before{ operator.pipe(input) }
|
25
|
+
subject{ operator.to_a }
|
26
|
+
|
27
|
+
it { should == expected }
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Summarize do
|
5
|
+
|
6
|
+
let(:operator_class){ Summarize }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:input) {[
|
10
|
+
{:a => "via_reader", :time => 2},
|
11
|
+
{:a => "via_method", :time => 1},
|
12
|
+
{:a => "via_method", :time => 2},
|
13
|
+
{:a => "via_reader", :time => 4},
|
14
|
+
{:a => "via_method", :time => 1},
|
15
|
+
]}
|
16
|
+
|
17
|
+
let(:expected) {[
|
18
|
+
{:a => "via_method", :time_sum => 4, :time_max => 2},
|
19
|
+
{:a => "via_reader", :time_sum => 6, :time_max => 4},
|
20
|
+
]}
|
21
|
+
|
22
|
+
subject{ operator.to_a }
|
23
|
+
|
24
|
+
describe "When factored with commandline args" do
|
25
|
+
let(:opts){ ["--by=a"] }
|
26
|
+
let(:aggs){ ["time_sum", "sum(:time)", "time_max", "max(:time)"] }
|
27
|
+
let(:operator){ Summarize.run(opts + ["--"] +aggs) }
|
28
|
+
before{ operator.pipe(input) }
|
29
|
+
it { should == expected }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "When factored with Lispy" do
|
33
|
+
let(:aggs){{:time_sum => Aggregator.sum(:time),
|
34
|
+
:time_max => Aggregator.max(:time)}}
|
35
|
+
let(:operator){ Lispy.summarize(input, [:a], aggs) }
|
36
|
+
it { should == expected }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Ungroup do
|
5
|
+
|
6
|
+
let(:operator_class){ Ungroup }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:input) {[
|
10
|
+
{:a => "via_method", :as => [{:time => 1, :b => "b"}, {:time => 2, :b => "b"}]},
|
11
|
+
{:a => "via_reader", :as => [{:time => 3, :b => "b"}]},
|
12
|
+
]}
|
13
|
+
|
14
|
+
let(:expected) {[
|
15
|
+
{:a => "via_method", :time => 1, :b => "b"},
|
16
|
+
{:a => "via_method", :time => 2, :b => "b"},
|
17
|
+
{:a => "via_reader", :time => 3, :b => "b"},
|
18
|
+
]}
|
19
|
+
|
20
|
+
subject{ operator.to_a.sort{|k1,k2| k1[:time] <=> k2[:time]} }
|
21
|
+
|
22
|
+
describe "when factored with commandline args" do
|
23
|
+
let(:operator) { Ungroup.run(%w{-- as}) }
|
24
|
+
before{ operator.pipe(input) }
|
25
|
+
it { should == expected }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "when factored with Lispy" do
|
29
|
+
let(:operator) { Lispy.ungroup(input, :as) }
|
30
|
+
it { should == expected }
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|