alf 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +42 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +15 -0
  6. data/README.md +769 -0
  7. data/Rakefile +23 -0
  8. data/TODO.md +26 -0
  9. data/alf.gemspec +191 -0
  10. data/alf.noespec +30 -0
  11. data/bin/alf +31 -0
  12. data/examples/autonum.alf +6 -0
  13. data/examples/cities.rash +4 -0
  14. data/examples/clip.alf +3 -0
  15. data/examples/compact.alf +2 -0
  16. data/examples/database.alf +6 -0
  17. data/examples/defaults.alf +3 -0
  18. data/examples/extend.alf +3 -0
  19. data/examples/group.alf +3 -0
  20. data/examples/intersect.alf +4 -0
  21. data/examples/join.alf +2 -0
  22. data/examples/minus.alf +8 -0
  23. data/examples/nest.alf +2 -0
  24. data/examples/nulls.rash +3 -0
  25. data/examples/parts.rash +6 -0
  26. data/examples/project.alf +2 -0
  27. data/examples/quota.alf +4 -0
  28. data/examples/rename.alf +3 -0
  29. data/examples/restrict.alf +2 -0
  30. data/examples/runall.sh +26 -0
  31. data/examples/schema.yaml +28 -0
  32. data/examples/sort.alf +4 -0
  33. data/examples/summarize.alf +16 -0
  34. data/examples/suppliers.rash +5 -0
  35. data/examples/supplies.rash +12 -0
  36. data/examples/ungroup.alf +4 -0
  37. data/examples/union.alf +3 -0
  38. data/examples/unnest.alf +4 -0
  39. data/examples/with.alf +23 -0
  40. data/lib/alf.rb +2984 -0
  41. data/lib/alf/loader.rb +1 -0
  42. data/lib/alf/renderer/text.rb +153 -0
  43. data/lib/alf/renderer/yaml.rb +22 -0
  44. data/lib/alf/version.rb +14 -0
  45. data/spec/aggregator_spec.rb +62 -0
  46. data/spec/alf_spec.rb +47 -0
  47. data/spec/assumptions_spec.rb +15 -0
  48. data/spec/environment/explicit_spec.rb +15 -0
  49. data/spec/environment/folder_spec.rb +30 -0
  50. data/spec/examples_spec.rb +26 -0
  51. data/spec/lispy_spec.rb +23 -0
  52. data/spec/operator/command_methods_spec.rb +38 -0
  53. data/spec/operator/non_relational/autonum_spec.rb +61 -0
  54. data/spec/operator/non_relational/clip_spec.rb +49 -0
  55. data/spec/operator/non_relational/compact/buffer_based.rb +30 -0
  56. data/spec/operator/non_relational/compact/sort_based_spec.rb +30 -0
  57. data/spec/operator/non_relational/compact_spec.rb +38 -0
  58. data/spec/operator/non_relational/defaults_spec.rb +55 -0
  59. data/spec/operator/non_relational/sort_spec.rb +66 -0
  60. data/spec/operator/relational/extend_spec.rb +34 -0
  61. data/spec/operator/relational/group_spec.rb +54 -0
  62. data/spec/operator/relational/intersect_spec.rb +58 -0
  63. data/spec/operator/relational/join/hash_based_spec.rb +63 -0
  64. data/spec/operator/relational/minus_spec.rb +56 -0
  65. data/spec/operator/relational/nest_spec.rb +32 -0
  66. data/spec/operator/relational/project_spec.rb +65 -0
  67. data/spec/operator/relational/quota_spec.rb +44 -0
  68. data/spec/operator/relational/rename_spec.rb +32 -0
  69. data/spec/operator/relational/restrict_spec.rb +56 -0
  70. data/spec/operator/relational/summarize/sort_based_spec.rb +31 -0
  71. data/spec/operator/relational/summarize_spec.rb +41 -0
  72. data/spec/operator/relational/ungroup_spec.rb +35 -0
  73. data/spec/operator/relational/union_spec.rb +35 -0
  74. data/spec/operator/relational/unnest_spec.rb +32 -0
  75. data/spec/reader/alf_file_spec.rb +15 -0
  76. data/spec/reader/input.rb +2 -0
  77. data/spec/reader/rash_spec.rb +31 -0
  78. data/spec/reader_spec.rb +27 -0
  79. data/spec/renderer/text/cell_spec.rb +34 -0
  80. data/spec/renderer/text/row_spec.rb +30 -0
  81. data/spec/renderer/text/table_spec.rb +39 -0
  82. data/spec/renderer_spec.rb +42 -0
  83. data/spec/spec_helper.rb +26 -0
  84. data/spec/tools/ordering_key_spec.rb +81 -0
  85. data/spec/tools/projection_key_spec.rb +83 -0
  86. data/spec/tools/tools_spec.rb +25 -0
  87. data/spec/tools/tuple_handle_spec.rb +78 -0
  88. data/tasks/debug_mail.rake +78 -0
  89. data/tasks/debug_mail.txt +13 -0
  90. data/tasks/gem.rake +68 -0
  91. data/tasks/spec_test.rake +79 -0
  92. data/tasks/unit_test.rake +77 -0
  93. data/tasks/yard.rake +51 -0
  94. metadata +282 -0
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Autonum do
5
+
6
+ let(:operator_class){ Autonum }
7
+ it_should_behave_like("An operator class")
8
+
9
+ let(:input) {[
10
+ {:a => "a"},
11
+ {:a => "b"},
12
+ {:a => "a"},
13
+ ]}
14
+
15
+ subject{ operator.to_a }
16
+
17
+ describe "without providing an attribute name" do
18
+
19
+ let(:expected){[
20
+ {:a => "a", :autonum => 0},
21
+ {:a => "b", :autonum => 1},
22
+ {:a => "a", :autonum => 2},
23
+ ]}
24
+
25
+ describe "When factored with Lispy" do
26
+ let(:operator){ Lispy.autonum(input) }
27
+ it{ should == expected }
28
+ end
29
+
30
+ describe "When factored from commandline args" do
31
+ let(:operator){ Autonum.run([]) }
32
+ before{ operator.pipe(input) }
33
+ it{ should == expected }
34
+ end
35
+
36
+ end
37
+
38
+ describe "when providing an attribute name" do
39
+
40
+ let(:expected){[
41
+ {:a => "a", :unique => 0},
42
+ {:a => "b", :unique => 1},
43
+ {:a => "a", :unique => 2},
44
+ ]}
45
+
46
+ describe "When factored with Lispy" do
47
+ let(:operator){ Lispy.autonum(input, :unique) }
48
+ it{ should == expected }
49
+ end
50
+
51
+ describe "When factored from commandline args" do
52
+ let(:operator){ Autonum.run(["--", "unique"]) }
53
+ before{ operator.pipe(input) }
54
+ it{ should == expected }
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Clip do
5
+
6
+ let(:operator_class){ Clip }
7
+ it_should_behave_like("An operator class")
8
+
9
+ let(:input) {[
10
+ {:a => "a", :b => "b"},
11
+ ]}
12
+
13
+ subject{ operator.to_a }
14
+
15
+ describe "When used without --allbut" do
16
+ let(:expected){[{:a => "a"}]}
17
+
18
+ describe "when factored from commandline" do
19
+ let(:operator){ Clip.run(%w{-- a}) }
20
+ before{ operator.pipe(input) }
21
+ it { should == expected }
22
+ end
23
+
24
+ describe "when factored with Lispy" do
25
+ let(:operator){ Lispy.clip(input, [:a]) }
26
+ it { should == expected }
27
+ end
28
+
29
+ end
30
+
31
+ describe "When used with --allbut" do
32
+ let(:expected){[{:b => "b"}]}
33
+
34
+ describe "when factored with commandline args" do
35
+ let(:operator){ Clip.run(%w{--allbut -- a}) }
36
+ before{ operator.pipe(input) }
37
+ it { should == expected }
38
+ end
39
+
40
+ describe "when factored with Lispy" do
41
+ let(:operator){ Lispy.clip(input, [:a], true) }
42
+ it { should == expected }
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Compact::BufferBased do
5
+
6
+ let(:input) {[
7
+ {:a => "via_method", :time => 1, :b => "b"},
8
+ {:a => "via_method", :time => 1, :b => "b"},
9
+ {:a => "via_method", :time => 2, :b => "b"},
10
+ {:a => "via_reader", :time => 3, :b => "b"},
11
+ {:a => "via_reader", :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 }
21
+
22
+ describe "when factored with commandline args" do
23
+ let(:operator){ Compact::BufferBased.new }
24
+ before{ operator.pipe(input) }
25
+ it { should == expected }
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Compact::SortBased do
5
+
6
+ let(:input) {[
7
+ {:a => "via_method", :time => 1, :b => "b"},
8
+ {:a => "via_method", :time => 1, :b => "b"},
9
+ {:a => "via_method", :time => 2, :b => "b"},
10
+ {:a => "via_reader", :time => 3, :b => "b"},
11
+ {:a => "via_reader", :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 }
21
+
22
+ describe "when factored with commandline args" do
23
+ let(:operator){ Compact::SortBased.new }
24
+ before{ operator.pipe(input) }
25
+ it { should == expected }
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Compact do
5
+
6
+ let(:operator_class){ Compact }
7
+ it_should_behave_like("An operator class")
8
+
9
+ let(:input) {[
10
+ {:a => "via_method", :time => 1, :b => "b"},
11
+ {:a => "via_reader", :time => 3, :b => "b"},
12
+ {:a => "via_method", :time => 2, :b => "b"},
13
+ {:a => "via_reader", :time => 3, :b => "b"},
14
+ {:a => "via_method", :time => 1, :b => "b"},
15
+ ]}
16
+
17
+ let(:expected) {[
18
+ {:a => "via_method", :time => 1, :b => "b"},
19
+ {:a => "via_reader", :time => 3, :b => "b"},
20
+ {:a => "via_method", :time => 2, :b => "b"},
21
+ ]}
22
+
23
+ subject{ operator.to_a }
24
+
25
+ describe "when factored with commandline args" do
26
+ let(:operator){ Compact.run(%w{}) }
27
+ before{ operator.pipe(input) }
28
+ it { should == expected }
29
+ end
30
+
31
+ describe "when factored with Lispy" do
32
+ let(:operator){ Lispy.compact(input) }
33
+ it { should == expected }
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Defaults do
5
+
6
+ let(:operator_class){ Defaults }
7
+ it_should_behave_like("An operator class")
8
+
9
+ subject{ operator.to_a }
10
+
11
+ describe "when used without --strict" do
12
+
13
+ let(:input) {[
14
+ {:a => nil, :b => "b"},
15
+ ]}
16
+
17
+ let(:expected) {[
18
+ {:a => 1, :b => "b", :c => "blue"},
19
+ ]}
20
+
21
+ describe "When factored with Lispy" do
22
+ let(:operator){ Lispy.defaults(input, :a => 1, :c => "blue") }
23
+ it{ should == expected }
24
+ end
25
+
26
+ describe "When factored from commandline args" do
27
+ let(:operator){ Defaults.run(%w{-- a 1 c 'blue'}) }
28
+ before{ operator.pipe(input) }
29
+ it{ should == expected }
30
+ end
31
+
32
+ end
33
+
34
+ describe "when used with --strict" do
35
+
36
+ let(:input) {[
37
+ {:a => 3, :b => "b", :c => "blue"},
38
+ {:a => nil, :b => "b", :c => "blue"},
39
+ ]}
40
+
41
+ let(:expected) {[
42
+ {:a => 3, :b => "b"},
43
+ {:a => 1, :b => "b"},
44
+ ]}
45
+
46
+ describe "When factored with Lispy" do
47
+ let(:operator){ Lispy.defaults(input, {:a => 1, :b => "b"}, true) }
48
+ it{ should == expected }
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Sort do
5
+
6
+ let(:operator_class){ Sort }
7
+ it_should_behave_like("An operator class")
8
+
9
+ let(:input) {[
10
+ {:first => "a", :second => 20, :third => true},
11
+ {:first => "b", :second => 10, :third => false},
12
+ {:first => "a", :second => 1, :third => true},
13
+ ]}
14
+
15
+ let(:expected){[
16
+ {:first => "a", :second => 1, :third => true},
17
+ {:first => "a", :second => 20, :third => true},
18
+ {:first => "b", :second => 10, :third => false},
19
+ ]}
20
+
21
+ subject{ operator.to_a }
22
+
23
+ describe "When factored with Lispy" do
24
+ let(:operator){ Lispy.sort(input, [[:first, :asc], [:second, :asc]]) }
25
+ it{ should == expected }
26
+ end
27
+
28
+ describe "When factored from commandline args" do
29
+ let(:operator){ Sort.run(["--", "first", "asc", "second", "asc"]) }
30
+ before{ operator.pipe(input) }
31
+ it{ should == expected }
32
+ end
33
+
34
+ describe "When used on two args" do
35
+ let(:operator){ Lispy.sort(input, [[:second, :asc], [:first, :asc]]) }
36
+ let(:expected){[
37
+ {:first => "a", :second => 1, :third => true},
38
+ {:first => "b", :second => 10, :third => false},
39
+ {:first => "a", :second => 20, :third => true},
40
+ ]}
41
+ it{ should == expected }
42
+ end
43
+
44
+ describe "When used on single arg" do
45
+ let(:operator){ Lispy.sort(input, [[:second, :asc]]) }
46
+ let(:expected){[
47
+ {:first => "a", :second => 1, :third => true},
48
+ {:first => "b", :second => 10, :third => false},
49
+ {:first => "a", :second => 20, :third => true},
50
+ ]}
51
+ it{ should == expected }
52
+ end
53
+
54
+ describe "When used with descending order" do
55
+ let(:operator){ Lispy.sort(input, [[:second, :desc]]) }
56
+ let(:expected){[
57
+ {:first => "a", :second => 20, :third => true},
58
+ {:first => "b", :second => 10, :third => false},
59
+ {:first => "a", :second => 1, :third => true},
60
+ ]}
61
+ it{ should == expected }
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::Relational
4
+ describe Extend do
5
+
6
+ let(:operator_class){ Extend }
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", :big => false},
16
+ {:tested => 30, :other => "a", :big => true},
17
+ ]}
18
+
19
+ subject{ operator.to_a }
20
+
21
+ describe "When factored with Lispy" do
22
+ let(:operator){ Lispy.extend(input, :big => lambda{ tested > 10 }) }
23
+ it{ should == expected }
24
+ end
25
+
26
+ describe "When factored from commandline args" do
27
+ let(:operator){ Extend.run(%w{-- big} + ["tested > 10"]) }
28
+ before{ operator.pipe(input) }
29
+ it{ should == expected }
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::Relational
4
+ describe Group do
5
+
6
+ let(:operator_class){ Group }
7
+ it_should_behave_like("An operator class")
8
+
9
+ let(:input) {[
10
+ {:a => "via_method", :time => 1, :b => "b"},
11
+ {:a => "via_method", :time => 2, :b => "b"},
12
+ {:a => "via_reader", :time => 3, :b => "b"},
13
+ ]}
14
+
15
+ let(:expected) {[
16
+ {:a => "via_method", :as => [{:time => 1, :b => "b"}, {:time => 2, :b => "b"}]},
17
+ {:a => "via_reader", :as => [{:time => 3, :b => "b"}]},
18
+ ]}
19
+
20
+ subject{ operator.to_a.sort{|k1,k2| k1[:a] <=> k2[:a]} }
21
+
22
+ describe "without --allbut" do
23
+
24
+ describe "when factored with commandline args" do
25
+ let(:operator){ Group.run(["--", "time", "b", "as"]) }
26
+ before{ operator.pipe(input) }
27
+ it { should == expected }
28
+ end
29
+
30
+ describe "when factored with Lispy" do
31
+ let(:operator){ Lispy.group(input, [:time, :b], :as) }
32
+ it { should == expected }
33
+ end
34
+
35
+ end
36
+
37
+ describe "with --allbut" do
38
+
39
+ describe "when factored with commandline args" do
40
+ let(:operator){ Group.run(["--","a", "as"]) }
41
+ before{ operator.allbut = true; operator.pipe(input) }
42
+ it { should == expected }
43
+ end
44
+
45
+ describe "when factored with Lispy" do
46
+ let(:operator){ Lispy.group(input, [:a], :as, true) }
47
+ it { should == expected }
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::Relational
4
+ describe Intersect do
5
+
6
+ let(:operator_class){ Intersect }
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){ Intersect.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 == left }
31
+ end
32
+
33
+ describe "when applied on operands sharing tuples" do
34
+ before{ operator.datasets = [left, right] }
35
+ let(:expected) {[
36
+ {:sid => 'S1', :city => 'London'},
37
+ {:sid => 'S2', :city => 'Paris'},
38
+ ]}
39
+ it { should == expected }
40
+ end
41
+
42
+ describe "when applied on disjoint operands" do
43
+ before{ operator.datasets = [left, disjoint] }
44
+ it { should be_empty }
45
+ end
46
+
47
+ describe "when factored with Lispy" do
48
+ let(:operator){ Lispy.intersect(left, right) }
49
+ let(:expected) {[
50
+ {:sid => 'S1', :city => 'London'},
51
+ {:sid => 'S2', :city => 'Paris'},
52
+ ]}
53
+ it { should == expected }
54
+ end
55
+
56
+ end
57
+ end
58
+ end