alf 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +89 -0
- data/Gemfile.lock +6 -1
- data/README.md +35 -21
- data/TODO.md +0 -5
- data/alf.gemspec +2 -0
- data/alf.noespec +6 -4
- data/bin/alf +9 -13
- data/examples/{autonum.alf → operators/autonum.alf} +0 -0
- data/examples/{cities.rash → operators/cities.rash} +0 -0
- data/examples/{clip.alf → operators/clip.alf} +0 -0
- data/examples/{compact.alf → operators/compact.alf} +0 -0
- data/examples/{database.alf → operators/database.alf} +1 -1
- data/examples/{defaults.alf → operators/defaults.alf} +0 -0
- data/examples/{extend.alf → operators/extend.alf} +0 -0
- data/examples/{group.alf → operators/group.alf} +0 -0
- data/examples/{intersect.alf → operators/intersect.alf} +0 -0
- data/examples/{join.alf → operators/join.alf} +0 -0
- data/examples/operators/matching.alf +2 -0
- data/examples/{minus.alf → operators/minus.alf} +0 -0
- data/examples/operators/not_matching.alf +2 -0
- data/examples/{nulls.rash → operators/nulls.rash} +0 -0
- data/examples/{parts.rash → operators/parts.rash} +0 -0
- data/examples/{project.alf → operators/project.alf} +0 -0
- data/examples/{pseudo-with.alf → operators/pseudo-with.alf} +0 -0
- data/examples/{quota.alf → operators/quota.alf} +0 -0
- data/examples/operators/rank.alf +4 -0
- data/examples/{rename.alf → operators/rename.alf} +0 -0
- data/examples/{restrict.alf → operators/restrict.alf} +0 -0
- data/examples/{schema.yaml → operators/schema.yaml} +0 -0
- data/examples/{sort.alf → operators/sort.alf} +0 -0
- data/examples/{summarize.alf → operators/summarize.alf} +0 -0
- data/examples/{suppliers.rash → operators/suppliers.rash} +0 -0
- data/examples/{supplies.rash → operators/supplies.rash} +0 -0
- data/examples/{ungroup.alf → operators/ungroup.alf} +0 -0
- data/examples/{union.alf → operators/union.alf} +0 -0
- data/examples/{unwrap.alf → operators/unwrap.alf} +0 -0
- data/examples/{wrap.alf → operators/wrap.alf} +0 -0
- data/lib/alf.rb +837 -62
- data/lib/alf/loader.rb +2 -1
- data/lib/alf/text.rb +160 -0
- data/lib/alf/version.rb +1 -1
- data/lib/alf/yaml.rb +24 -0
- data/spec/integration/__database__/group.alf +3 -0
- data/spec/integration/__database__/parts.rash +6 -0
- data/spec/integration/__database__/suppliers.rash +5 -0
- data/spec/integration/__database__/supplies.rash +12 -0
- data/spec/integration/command/alf/alf_e.cmd +1 -0
- data/spec/integration/command/alf/alf_e.stdout +4 -0
- data/spec/integration/command/alf/alf_env.cmd +1 -0
- data/spec/integration/command/alf/alf_env.stdout +5 -0
- data/spec/integration/command/alf/alf_implicit.alf +1 -0
- data/spec/integration/command/alf/alf_implicit_exec.cmd +1 -0
- data/spec/integration/command/alf/alf_implicit_exec.stdout +4 -0
- data/spec/integration/command/alf/alf_r.cmd +1 -0
- data/spec/integration/command/alf/alf_r.stdout +5 -0
- data/spec/integration/command/alf/alf_version.cmd +1 -0
- data/spec/integration/command/alf/alf_version.stdout +2 -0
- data/spec/integration/command/alf/alf_yaml.cmd +1 -0
- data/spec/integration/command/alf/alf_yaml.stdout +22 -0
- data/spec/integration/command/alf/rel.rash +1 -0
- data/spec/integration/command/autonum/autonum_0.cmd +1 -0
- data/spec/integration/command/autonum/autonum_0.stdout +9 -0
- data/spec/integration/command/autonum/autonum_1.cmd +1 -0
- data/spec/integration/command/autonum/autonum_1.stdout +9 -0
- data/spec/integration/command/clip/clip_0.cmd +1 -0
- data/spec/integration/command/clip/clip_0.stdout +9 -0
- data/spec/integration/command/clip/clip_1.cmd +1 -0
- data/spec/integration/command/clip/clip_1.stdout +9 -0
- data/spec/integration/command/compact/compact_0.cmd +1 -0
- data/spec/integration/command/compact/compact_0.stdout +9 -0
- data/spec/integration/command/defaults/defaults_0.cmd +1 -0
- data/spec/integration/command/defaults/defaults_0.stdout +9 -0
- data/spec/integration/command/defaults/defaults_1.cmd +1 -0
- data/spec/integration/command/defaults/defaults_1.stdout +9 -0
- data/spec/integration/command/extend/extend_0.cmd +1 -0
- data/spec/integration/command/extend/extend_0.stdout +16 -0
- data/spec/integration/command/group/group_0.cmd +1 -0
- data/spec/integration/command/group/group_0.stdout +32 -0
- data/spec/integration/command/group/group_1.cmd +1 -0
- data/spec/integration/command/group/group_1.stdout +32 -0
- data/spec/integration/command/intersect/intersect_0.cmd +1 -0
- data/spec/integration/command/intersect/intersect_0.stdout +9 -0
- data/spec/integration/command/join/join_0.cmd +1 -0
- data/spec/integration/command/join/join_0.stdout +16 -0
- data/spec/integration/command/matching/matching_0.cmd +1 -0
- data/spec/integration/command/matching/matching_0.stdout +8 -0
- data/spec/integration/command/minus/minus_0.cmd +1 -0
- data/spec/integration/command/minus/minus_0.stdout +4 -0
- data/spec/integration/command/not-matching/not-matching_0.cmd +1 -0
- data/spec/integration/command/not-matching/not-matching_0.stdout +5 -0
- data/spec/integration/command/project/project_0.cmd +1 -0
- data/spec/integration/command/project/project_0.stdout +9 -0
- data/spec/integration/command/project/project_1.cmd +1 -0
- data/spec/integration/command/project/project_1.stdout +9 -0
- data/spec/integration/command/quota/quota_0.cmd +1 -0
- data/spec/integration/command/quota/quota_0.stdout +16 -0
- data/spec/integration/command/rank/rank_1.cmd +1 -0
- data/spec/integration/command/rank/rank_1.stdout +10 -0
- data/spec/integration/command/rank/rank_2.cmd +1 -0
- data/spec/integration/command/rank/rank_2.stdout +10 -0
- data/spec/integration/command/rank/rank_3.cmd +1 -0
- data/spec/integration/command/rank/rank_3.stdout +10 -0
- data/spec/integration/command/rank/rank_4.cmd +1 -0
- data/spec/integration/command/rank/rank_4.stdout +6 -0
- data/spec/integration/command/rank/rank_5.cmd +1 -0
- data/spec/integration/command/rank/rank_5.stdout +6 -0
- data/spec/integration/command/rename/rename_0.cmd +1 -0
- data/spec/integration/command/rename/rename_0.stdout +9 -0
- data/spec/integration/command/restrict/restrict_0.cmd +1 -0
- data/spec/integration/command/restrict/restrict_0.stdout +6 -0
- data/spec/integration/command/restrict/restrict_1.cmd +1 -0
- data/spec/integration/command/restrict/restrict_1.stdout +6 -0
- data/spec/integration/command/show/show_base.cmd +1 -0
- data/spec/integration/command/show/show_base.stdout +9 -0
- data/spec/integration/command/show/show_conflictual.cmd +1 -0
- data/spec/integration/command/show/show_conflictual.stdout +5 -0
- data/spec/integration/command/show/show_rash.cmd +1 -0
- data/spec/integration/command/show/show_rash.stdout +5 -0
- data/spec/integration/command/show/show_rash_2.cmd +1 -0
- data/spec/integration/command/show/show_rash_2.stdout +5 -0
- data/spec/integration/command/show/show_yaml.cmd +1 -0
- data/spec/integration/command/show/show_yaml.stdout +22 -0
- data/spec/integration/command/sort/sort_0.cmd +1 -0
- data/spec/integration/command/sort/sort_0.stdout +9 -0
- data/spec/integration/command/sort/sort_1.cmd +1 -0
- data/spec/integration/command/sort/sort_1.stdout +9 -0
- data/spec/integration/command/summarize/summarize_0.cmd +1 -0
- data/spec/integration/command/summarize/summarize_0.stdout +8 -0
- data/spec/integration/command/ungroup/ungroup_0.cmd +1 -0
- data/spec/integration/command/ungroup/ungroup_0.stdout +16 -0
- data/spec/integration/command/union/union_0.cmd +1 -0
- data/spec/integration/command/union/union_0.stdout +9 -0
- data/spec/integration/command/unwrap/unwrap_0.cmd +1 -0
- data/spec/integration/command/unwrap/unwrap_0.stdout +9 -0
- data/spec/integration/command/wrap/wrap_0.cmd +1 -0
- data/spec/integration/command/wrap/wrap_0.stdout +9 -0
- data/spec/integration/semantics/test_join.alf +9 -0
- data/spec/integration/{src → semantics}/test_minus.alf +0 -0
- data/spec/integration/{src → semantics}/test_project.alf +0 -0
- data/spec/integration/semantics/test_rank.alf +34 -0
- data/spec/integration/test_command.rb +36 -0
- data/spec/integration/test_examples.rb +11 -22
- data/spec/integration/test_semantics.rb +40 -0
- data/spec/regression/alf_file/__FILE__.alf +2 -0
- data/spec/regression/alf_file/suppliers.rash +5 -0
- data/spec/regression/alf_file/test___FILE__.rb +17 -0
- data/spec/regression/heading/test_heading_with_date.rb +12 -0
- data/spec/regression/lispy/test_compile.rb +14 -0
- data/spec/regression/relation/test_relation_with_date.rb +12 -0
- data/spec/regression/restrict/test_restrict_with_keywords.rb +17 -0
- data/spec/shared/a_value.rb +12 -0
- data/spec/shared/an_operator_class.rb +35 -0
- data/spec/spec_helper.rb +12 -34
- data/spec/unit/assumptions/test_file.rb +17 -0
- data/spec/unit/{test_assumptions.rb → assumptions/test_instance_eval.rb} +1 -1
- data/spec/unit/assumptions/test_scoping.rb +29 -0
- data/spec/unit/environment/test_folder.rb +6 -1
- data/spec/unit/operator/relational/matching/test_hash_based.rb +60 -0
- data/spec/unit/operator/relational/not_matching/test_hash_based.rb +37 -0
- data/spec/unit/operator/relational/test_rank.rb +50 -0
- data/spec/unit/operator/test_relational.rb +3 -0
- data/spec/unit/reader/test_alf_file.rb +7 -4
- data/spec/unit/reader/test_initialize.rb +60 -0
- data/spec/unit/relation/test_relops.rb +4 -0
- data/spec/unit/relation/test_to_a.rb +41 -0
- data/spec/unit/renderer/test_initialize.rb +60 -0
- data/spec/unit/test_environment.rb +38 -0
- data/spec/unit/test_heading.rb +38 -0
- data/spec/unit/test_reader.rb +5 -0
- data/spec/unit/test_relation.rb +31 -1
- data/spec/unit/test_renderer.rb +1 -1
- data/spec/unit/{renderer/text → text}/test_cell.rb +1 -1
- data/spec/unit/{renderer/text → text}/test_row.rb +1 -1
- data/spec/unit/{renderer/text → text}/test_table.rb +1 -1
- data/spec/unit/tools/test_ordering_key.rb +13 -0
- data/spec/unit/tools/test_parse_commandline_args.rb +47 -0
- data/spec/unit/tools/test_tuple_handle.rb +34 -2
- data/spec/unit/tools/test_varargs.rb +16 -0
- data/tasks/{spec_test.rake → integration_test.rake} +4 -32
- data/tasks/regression_test.rake +52 -0
- data/tasks/unit_test.rake +33 -58
- metadata +326 -66
- data/examples/runall.sh +0 -26
- data/lib/alf/relation.rb +0 -118
- data/lib/alf/renderer/text.rb +0 -153
- data/lib/alf/renderer/yaml.rb +0 -22
- data/spec/integration/test_alf_specs.rb +0 -37
@@ -4,7 +4,12 @@ module Alf
|
|
4
4
|
|
5
5
|
let(:path){ File.expand_path('../examples', __FILE__) }
|
6
6
|
let(:env){ Environment::Folder.new(path) }
|
7
|
-
|
7
|
+
|
8
|
+
specify ".recognizes?" do
|
9
|
+
Environment::Folder.recognizes?([path]).should be_true
|
10
|
+
Environment::Folder.recognizes?(["not/an/existing/one"]).should be_false
|
11
|
+
end
|
12
|
+
|
8
13
|
describe "dataset" do
|
9
14
|
|
10
15
|
subject{ env.dataset(name) }
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Matching::HashBased do
|
5
|
+
|
6
|
+
let(:suppliers) {Alf::Relation[
|
7
|
+
{:sid => 'S1', :city => 'London'},
|
8
|
+
{:sid => 'S2', :city => 'Paris'},
|
9
|
+
{:sid => 'S3', :city => 'Paris'}
|
10
|
+
]}
|
11
|
+
|
12
|
+
let(:statuses) {Alf::Relation[
|
13
|
+
{:sid => 'S1', :status => 20},
|
14
|
+
{:sid => 'S2', :status => 10},
|
15
|
+
{:sid => 'S3', :status => 30}
|
16
|
+
]}
|
17
|
+
|
18
|
+
let(:countries) {Alf::Relation[
|
19
|
+
{:city => 'London', :country => 'England'},
|
20
|
+
{:city => 'Paris', :country => 'France'},
|
21
|
+
{:city => 'Bruxelles', :country => 'Belgium (until ?)'}
|
22
|
+
]}
|
23
|
+
|
24
|
+
let(:operator){ Matching::HashBased.new }
|
25
|
+
subject{ operator.to_rel }
|
26
|
+
|
27
|
+
describe "when applied on both candidate keys" do
|
28
|
+
before{ operator.datasets = [suppliers, statuses] }
|
29
|
+
it { should eq(suppliers) }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "when applied on a typical foreign key" do
|
33
|
+
describe "on one way" do
|
34
|
+
before{ operator.datasets = [suppliers, countries] }
|
35
|
+
it { should eq(suppliers) }
|
36
|
+
end
|
37
|
+
describe "on the other way around" do
|
38
|
+
before{ operator.datasets = [countries, suppliers] }
|
39
|
+
it { should eq(countries.restrict(lambda{ city != 'Bruxelles' })) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "when no attributes are in common" do
|
44
|
+
before{ operator.datasets = [statuses, countries] }
|
45
|
+
it { should eq(statuses) }
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "against DEE" do
|
49
|
+
before{ operator.datasets = [suppliers, Relation::DEE] }
|
50
|
+
it { should eq(suppliers) }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "against DUM" do
|
54
|
+
before{ operator.datasets = [suppliers, Relation::DUM] }
|
55
|
+
it { should eq(Relation::DUM) }
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe NotMatching::HashBased do
|
5
|
+
|
6
|
+
let(:suppliers) {Alf::Relation[
|
7
|
+
{:sid => 'S1', :city => 'London'},
|
8
|
+
{:sid => 'S2', :city => 'Paris'},
|
9
|
+
{:sid => 'S3', :city => 'Paris'}
|
10
|
+
]}
|
11
|
+
|
12
|
+
let(:operator){ NotMatching::HashBased.new }
|
13
|
+
subject{ operator.to_rel }
|
14
|
+
|
15
|
+
describe "when applied on itself" do
|
16
|
+
before{ operator.datasets = [suppliers, suppliers] }
|
17
|
+
it { should eq(suppliers.minus(suppliers)) }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "when applied against a subset" do
|
21
|
+
before{ operator.datasets = [suppliers, Alf::Relation[{:sid => 'S1'}]] }
|
22
|
+
it { should eq(suppliers.restrict(lambda{ sid != 'S1' })) }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "against DEE" do
|
26
|
+
before{ operator.datasets = [suppliers, Relation::DEE] }
|
27
|
+
it { should eq(Relation::DUM) }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "against DUM" do
|
31
|
+
before{ operator.datasets = [suppliers, Relation::DUM] }
|
32
|
+
it { should eq(suppliers) }
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Operator::Relational
|
4
|
+
describe Rank do
|
5
|
+
|
6
|
+
let(:operator_class){ Rank }
|
7
|
+
it_should_behave_like("An operator class")
|
8
|
+
|
9
|
+
let(:input) {Alf::Relation[
|
10
|
+
{:pid => 'P1', :weight => 12.0},
|
11
|
+
{:pid => 'P2', :weight => 17.0},
|
12
|
+
{:pid => 'P3', :weight => 17.0},
|
13
|
+
{:pid => 'P4', :weight => 14.0},
|
14
|
+
{:pid => 'P5', :weight => 12.0},
|
15
|
+
{:pid => 'P6', :weight => 19.0}
|
16
|
+
]}
|
17
|
+
|
18
|
+
subject{ operator.to_rel }
|
19
|
+
|
20
|
+
describe "when a partial ordering is used" do
|
21
|
+
let(:expected) {Alf::Relation[
|
22
|
+
{:pid => 'P1', :weight => 12.0, :rank => 0},
|
23
|
+
{:pid => 'P5', :weight => 12.0, :rank => 0},
|
24
|
+
{:pid => 'P4', :weight => 14.0, :rank => 2},
|
25
|
+
{:pid => 'P2', :weight => 17.0, :rank => 3},
|
26
|
+
{:pid => 'P3', :weight => 17.0, :rank => 3},
|
27
|
+
{:pid => 'P6', :weight => 19.0, :rank => 5}
|
28
|
+
]}
|
29
|
+
let(:operator){ Rank.new([:weight]) }
|
30
|
+
before{ operator.pipe(input) }
|
31
|
+
it{ should eq(expected) }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "when a total ordering is used" do
|
35
|
+
let(:expected) {Alf::Relation[
|
36
|
+
{:pid => 'P1', :weight => 12.0, :rank => 0},
|
37
|
+
{:pid => 'P5', :weight => 12.0, :rank => 1},
|
38
|
+
{:pid => 'P4', :weight => 14.0, :rank => 2},
|
39
|
+
{:pid => 'P2', :weight => 17.0, :rank => 3},
|
40
|
+
{:pid => 'P3', :weight => 17.0, :rank => 4},
|
41
|
+
{:pid => 'P6', :weight => 19.0, :rank => 5}
|
42
|
+
]}
|
43
|
+
let(:operator){ Rank.new([:weight, :pid]) }
|
44
|
+
before{ operator.pipe(input) }
|
45
|
+
it{ should eq(expected) }
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -10,9 +10,12 @@ module Alf
|
|
10
10
|
Alf::Operator::Relational::Group,
|
11
11
|
Alf::Operator::Relational::Intersect,
|
12
12
|
Alf::Operator::Relational::Join,
|
13
|
+
Alf::Operator::Relational::Matching,
|
13
14
|
Alf::Operator::Relational::Minus,
|
15
|
+
Alf::Operator::Relational::NotMatching,
|
14
16
|
Alf::Operator::Relational::Project,
|
15
17
|
Alf::Operator::Relational::Quota,
|
18
|
+
Alf::Operator::Relational::Rank,
|
16
19
|
Alf::Operator::Relational::Rename,
|
17
20
|
Alf::Operator::Relational::Restrict,
|
18
21
|
Alf::Operator::Relational::Summarize,
|
@@ -2,11 +2,14 @@ require 'spec_helper'
|
|
2
2
|
module Alf
|
3
3
|
describe Reader::AlfFile do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
class TestEnv < Alf::Environment
|
6
|
+
def dataset(name)
|
7
|
+
[{:status => 10},{:status => 30}]
|
8
|
+
end
|
8
9
|
end
|
9
|
-
|
10
|
+
|
11
|
+
let(:io){ StringIO.new(expr) }
|
12
|
+
subject{ Reader::AlfFile.new(io, TestEnv.new).to_a }
|
10
13
|
|
11
14
|
describe "on pure functional expressions" do
|
12
15
|
let(:expr){ "(restrict :suppliers, lambda{status > 20})" }
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
describe "Reader#initialize" do
|
4
|
+
|
5
|
+
subject{ Reader.new(*args) }
|
6
|
+
|
7
|
+
describe "with full args" do
|
8
|
+
let(:args){[
|
9
|
+
"suppliers", Environment.examples, {:opts => true}
|
10
|
+
]}
|
11
|
+
specify {
|
12
|
+
subject.input.should eq("suppliers")
|
13
|
+
subject.environment.should be_a(Environment)
|
14
|
+
subject.options.should eq(:opts => true)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "with only options" do
|
19
|
+
let(:args){[
|
20
|
+
{:opts => true}
|
21
|
+
]}
|
22
|
+
specify {
|
23
|
+
subject.input.should be_nil
|
24
|
+
subject.environment.should be_nil
|
25
|
+
subject.options.should eq(:opts => true)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "on a subclass" do
|
30
|
+
class FooReader < Reader
|
31
|
+
DEFAULT_OPTIONS = {:from => :subclass}
|
32
|
+
end
|
33
|
+
subject{ FooReader.new(*args) }
|
34
|
+
|
35
|
+
describe "without option overriding" do
|
36
|
+
let(:args){[
|
37
|
+
{:opts => true}
|
38
|
+
]}
|
39
|
+
specify {
|
40
|
+
subject.input.should be_nil
|
41
|
+
subject.environment.should be_nil
|
42
|
+
subject.options.should eq(:opts => true, :from => :subclass)
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "with option overriding" do
|
47
|
+
let(:args){[
|
48
|
+
{:opts => true, :from => :overrided}
|
49
|
+
]}
|
50
|
+
specify {
|
51
|
+
subject.input.should be_nil
|
52
|
+
subject.environment.should be_nil
|
53
|
+
subject.options.should eq(:opts => true, :from => :overrided)
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
describe "Relation#to_a" do
|
4
|
+
|
5
|
+
let(:rel){Alf::Relation[
|
6
|
+
{:sid => 'S2'},
|
7
|
+
{:sid => 'S1'},
|
8
|
+
{:sid => 'S3'}
|
9
|
+
]}
|
10
|
+
|
11
|
+
specify "without an ordering key" do
|
12
|
+
rel.to_a.sort{|k1,k2| k1[:sid] <=> k2[:sid]}.should eq([
|
13
|
+
{:sid => 'S1'},
|
14
|
+
{:sid => 'S2'},
|
15
|
+
{:sid => 'S3'}
|
16
|
+
])
|
17
|
+
end
|
18
|
+
|
19
|
+
specify "with an ordering key" do
|
20
|
+
rel.to_a([:sid]).should eq([
|
21
|
+
{:sid => 'S1'},
|
22
|
+
{:sid => 'S2'},
|
23
|
+
{:sid => 'S3'}
|
24
|
+
])
|
25
|
+
rel.to_a([[:sid, :desc]]).should eq([
|
26
|
+
{:sid => 'S3'},
|
27
|
+
{:sid => 'S2'},
|
28
|
+
{:sid => 'S1'}
|
29
|
+
])
|
30
|
+
end
|
31
|
+
|
32
|
+
specify "ON DUM" do
|
33
|
+
Relation::DUM.to_a.should eq([])
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "ON DEE" do
|
37
|
+
Relation::DEE.to_a.should eq([{}])
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
describe "Renderer#initialize" do
|
4
|
+
|
5
|
+
subject{ Renderer.new(*args) }
|
6
|
+
|
7
|
+
describe "with full args" do
|
8
|
+
let(:args){[
|
9
|
+
[], Environment.examples, {:opts => true}
|
10
|
+
]}
|
11
|
+
specify {
|
12
|
+
subject.input.should eq([])
|
13
|
+
subject.environment.should be_a(Environment)
|
14
|
+
subject.options.should eq(:opts => true)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "with only options" do
|
19
|
+
let(:args){[
|
20
|
+
{:opts => true}
|
21
|
+
]}
|
22
|
+
specify {
|
23
|
+
subject.input.should be_nil
|
24
|
+
subject.environment.should be_nil
|
25
|
+
subject.options.should eq(:opts => true)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "on a subclass" do
|
30
|
+
class FooRenderer < Renderer
|
31
|
+
DEFAULT_OPTIONS = {:from => :subclass}
|
32
|
+
end
|
33
|
+
subject{ FooRenderer.new(*args) }
|
34
|
+
|
35
|
+
describe "without option overriding" do
|
36
|
+
let(:args){[
|
37
|
+
{:opts => true}
|
38
|
+
]}
|
39
|
+
specify {
|
40
|
+
subject.input.should be_nil
|
41
|
+
subject.environment.should be_nil
|
42
|
+
subject.options.should eq(:opts => true, :from => :subclass)
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "with option overriding" do
|
47
|
+
let(:args){[
|
48
|
+
{:opts => true, :from => :overrided}
|
49
|
+
]}
|
50
|
+
specify {
|
51
|
+
subject.input.should be_nil
|
52
|
+
subject.environment.should be_nil
|
53
|
+
subject.options.should eq(:opts => true, :from => :overrided)
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
describe Environment do
|
4
|
+
|
5
|
+
subject{ Environment }
|
6
|
+
it { should respond_to(:folder) }
|
7
|
+
|
8
|
+
describe "folder" do
|
9
|
+
subject{ Environment.folder(File.dirname(__FILE__)) }
|
10
|
+
it{ should be_a(Environment::Folder) }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "autodetect" do
|
14
|
+
|
15
|
+
it "should support an Environment instance" do
|
16
|
+
env = Environment.examples
|
17
|
+
Environment.autodetect(env).should eq(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should recognize an existing folder" do
|
21
|
+
env = Environment.autodetect(File.dirname(__FILE__))
|
22
|
+
env.should be_a(Environment::Folder)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should raise an Argument when no match" do
|
26
|
+
lambda{ Environment.autodetect(12) }.should raise_error(ArgumentError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be aliased as coerce" do
|
30
|
+
env = Environment.examples
|
31
|
+
Environment.coerce(env).should eq(env)
|
32
|
+
Environment.coerce(File.dirname(__FILE__)).should be_a(Environment::Folder)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
describe Heading do
|
4
|
+
|
5
|
+
let(:h0){ Heading.new({}) }
|
6
|
+
let(:h1){ Heading.new(:name => String) }
|
7
|
+
let(:h2){ Heading.new(:name => String, :price => Float) }
|
8
|
+
|
9
|
+
specify "cardinality" do
|
10
|
+
h0.cardinality.should eq(0)
|
11
|
+
h1.cardinality.should eq(1)
|
12
|
+
h2.cardinality.should eq(2)
|
13
|
+
end
|
14
|
+
|
15
|
+
specify "to_hash" do
|
16
|
+
h0.to_hash.should eq({})
|
17
|
+
h1.to_hash.should eq(:name => String)
|
18
|
+
h2.to_hash.should eq(:name => String, :price => Float)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "EMPTY" do
|
22
|
+
subject{ Heading::EMPTY }
|
23
|
+
it_should_behave_like "A value"
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "h0" do
|
27
|
+
subject{ h0 }
|
28
|
+
it { should == Heading::EMPTY }
|
29
|
+
it_should_behave_like "A value"
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "h1" do
|
33
|
+
subject{ h1 }
|
34
|
+
it_should_behave_like "A value"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|