alf 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (187) hide show
  1. data/CHANGELOG.md +89 -0
  2. data/Gemfile.lock +6 -1
  3. data/README.md +35 -21
  4. data/TODO.md +0 -5
  5. data/alf.gemspec +2 -0
  6. data/alf.noespec +6 -4
  7. data/bin/alf +9 -13
  8. data/examples/{autonum.alf → operators/autonum.alf} +0 -0
  9. data/examples/{cities.rash → operators/cities.rash} +0 -0
  10. data/examples/{clip.alf → operators/clip.alf} +0 -0
  11. data/examples/{compact.alf → operators/compact.alf} +0 -0
  12. data/examples/{database.alf → operators/database.alf} +1 -1
  13. data/examples/{defaults.alf → operators/defaults.alf} +0 -0
  14. data/examples/{extend.alf → operators/extend.alf} +0 -0
  15. data/examples/{group.alf → operators/group.alf} +0 -0
  16. data/examples/{intersect.alf → operators/intersect.alf} +0 -0
  17. data/examples/{join.alf → operators/join.alf} +0 -0
  18. data/examples/operators/matching.alf +2 -0
  19. data/examples/{minus.alf → operators/minus.alf} +0 -0
  20. data/examples/operators/not_matching.alf +2 -0
  21. data/examples/{nulls.rash → operators/nulls.rash} +0 -0
  22. data/examples/{parts.rash → operators/parts.rash} +0 -0
  23. data/examples/{project.alf → operators/project.alf} +0 -0
  24. data/examples/{pseudo-with.alf → operators/pseudo-with.alf} +0 -0
  25. data/examples/{quota.alf → operators/quota.alf} +0 -0
  26. data/examples/operators/rank.alf +4 -0
  27. data/examples/{rename.alf → operators/rename.alf} +0 -0
  28. data/examples/{restrict.alf → operators/restrict.alf} +0 -0
  29. data/examples/{schema.yaml → operators/schema.yaml} +0 -0
  30. data/examples/{sort.alf → operators/sort.alf} +0 -0
  31. data/examples/{summarize.alf → operators/summarize.alf} +0 -0
  32. data/examples/{suppliers.rash → operators/suppliers.rash} +0 -0
  33. data/examples/{supplies.rash → operators/supplies.rash} +0 -0
  34. data/examples/{ungroup.alf → operators/ungroup.alf} +0 -0
  35. data/examples/{union.alf → operators/union.alf} +0 -0
  36. data/examples/{unwrap.alf → operators/unwrap.alf} +0 -0
  37. data/examples/{wrap.alf → operators/wrap.alf} +0 -0
  38. data/lib/alf.rb +837 -62
  39. data/lib/alf/loader.rb +2 -1
  40. data/lib/alf/text.rb +160 -0
  41. data/lib/alf/version.rb +1 -1
  42. data/lib/alf/yaml.rb +24 -0
  43. data/spec/integration/__database__/group.alf +3 -0
  44. data/spec/integration/__database__/parts.rash +6 -0
  45. data/spec/integration/__database__/suppliers.rash +5 -0
  46. data/spec/integration/__database__/supplies.rash +12 -0
  47. data/spec/integration/command/alf/alf_e.cmd +1 -0
  48. data/spec/integration/command/alf/alf_e.stdout +4 -0
  49. data/spec/integration/command/alf/alf_env.cmd +1 -0
  50. data/spec/integration/command/alf/alf_env.stdout +5 -0
  51. data/spec/integration/command/alf/alf_implicit.alf +1 -0
  52. data/spec/integration/command/alf/alf_implicit_exec.cmd +1 -0
  53. data/spec/integration/command/alf/alf_implicit_exec.stdout +4 -0
  54. data/spec/integration/command/alf/alf_r.cmd +1 -0
  55. data/spec/integration/command/alf/alf_r.stdout +5 -0
  56. data/spec/integration/command/alf/alf_version.cmd +1 -0
  57. data/spec/integration/command/alf/alf_version.stdout +2 -0
  58. data/spec/integration/command/alf/alf_yaml.cmd +1 -0
  59. data/spec/integration/command/alf/alf_yaml.stdout +22 -0
  60. data/spec/integration/command/alf/rel.rash +1 -0
  61. data/spec/integration/command/autonum/autonum_0.cmd +1 -0
  62. data/spec/integration/command/autonum/autonum_0.stdout +9 -0
  63. data/spec/integration/command/autonum/autonum_1.cmd +1 -0
  64. data/spec/integration/command/autonum/autonum_1.stdout +9 -0
  65. data/spec/integration/command/clip/clip_0.cmd +1 -0
  66. data/spec/integration/command/clip/clip_0.stdout +9 -0
  67. data/spec/integration/command/clip/clip_1.cmd +1 -0
  68. data/spec/integration/command/clip/clip_1.stdout +9 -0
  69. data/spec/integration/command/compact/compact_0.cmd +1 -0
  70. data/spec/integration/command/compact/compact_0.stdout +9 -0
  71. data/spec/integration/command/defaults/defaults_0.cmd +1 -0
  72. data/spec/integration/command/defaults/defaults_0.stdout +9 -0
  73. data/spec/integration/command/defaults/defaults_1.cmd +1 -0
  74. data/spec/integration/command/defaults/defaults_1.stdout +9 -0
  75. data/spec/integration/command/extend/extend_0.cmd +1 -0
  76. data/spec/integration/command/extend/extend_0.stdout +16 -0
  77. data/spec/integration/command/group/group_0.cmd +1 -0
  78. data/spec/integration/command/group/group_0.stdout +32 -0
  79. data/spec/integration/command/group/group_1.cmd +1 -0
  80. data/spec/integration/command/group/group_1.stdout +32 -0
  81. data/spec/integration/command/intersect/intersect_0.cmd +1 -0
  82. data/spec/integration/command/intersect/intersect_0.stdout +9 -0
  83. data/spec/integration/command/join/join_0.cmd +1 -0
  84. data/spec/integration/command/join/join_0.stdout +16 -0
  85. data/spec/integration/command/matching/matching_0.cmd +1 -0
  86. data/spec/integration/command/matching/matching_0.stdout +8 -0
  87. data/spec/integration/command/minus/minus_0.cmd +1 -0
  88. data/spec/integration/command/minus/minus_0.stdout +4 -0
  89. data/spec/integration/command/not-matching/not-matching_0.cmd +1 -0
  90. data/spec/integration/command/not-matching/not-matching_0.stdout +5 -0
  91. data/spec/integration/command/project/project_0.cmd +1 -0
  92. data/spec/integration/command/project/project_0.stdout +9 -0
  93. data/spec/integration/command/project/project_1.cmd +1 -0
  94. data/spec/integration/command/project/project_1.stdout +9 -0
  95. data/spec/integration/command/quota/quota_0.cmd +1 -0
  96. data/spec/integration/command/quota/quota_0.stdout +16 -0
  97. data/spec/integration/command/rank/rank_1.cmd +1 -0
  98. data/spec/integration/command/rank/rank_1.stdout +10 -0
  99. data/spec/integration/command/rank/rank_2.cmd +1 -0
  100. data/spec/integration/command/rank/rank_2.stdout +10 -0
  101. data/spec/integration/command/rank/rank_3.cmd +1 -0
  102. data/spec/integration/command/rank/rank_3.stdout +10 -0
  103. data/spec/integration/command/rank/rank_4.cmd +1 -0
  104. data/spec/integration/command/rank/rank_4.stdout +6 -0
  105. data/spec/integration/command/rank/rank_5.cmd +1 -0
  106. data/spec/integration/command/rank/rank_5.stdout +6 -0
  107. data/spec/integration/command/rename/rename_0.cmd +1 -0
  108. data/spec/integration/command/rename/rename_0.stdout +9 -0
  109. data/spec/integration/command/restrict/restrict_0.cmd +1 -0
  110. data/spec/integration/command/restrict/restrict_0.stdout +6 -0
  111. data/spec/integration/command/restrict/restrict_1.cmd +1 -0
  112. data/spec/integration/command/restrict/restrict_1.stdout +6 -0
  113. data/spec/integration/command/show/show_base.cmd +1 -0
  114. data/spec/integration/command/show/show_base.stdout +9 -0
  115. data/spec/integration/command/show/show_conflictual.cmd +1 -0
  116. data/spec/integration/command/show/show_conflictual.stdout +5 -0
  117. data/spec/integration/command/show/show_rash.cmd +1 -0
  118. data/spec/integration/command/show/show_rash.stdout +5 -0
  119. data/spec/integration/command/show/show_rash_2.cmd +1 -0
  120. data/spec/integration/command/show/show_rash_2.stdout +5 -0
  121. data/spec/integration/command/show/show_yaml.cmd +1 -0
  122. data/spec/integration/command/show/show_yaml.stdout +22 -0
  123. data/spec/integration/command/sort/sort_0.cmd +1 -0
  124. data/spec/integration/command/sort/sort_0.stdout +9 -0
  125. data/spec/integration/command/sort/sort_1.cmd +1 -0
  126. data/spec/integration/command/sort/sort_1.stdout +9 -0
  127. data/spec/integration/command/summarize/summarize_0.cmd +1 -0
  128. data/spec/integration/command/summarize/summarize_0.stdout +8 -0
  129. data/spec/integration/command/ungroup/ungroup_0.cmd +1 -0
  130. data/spec/integration/command/ungroup/ungroup_0.stdout +16 -0
  131. data/spec/integration/command/union/union_0.cmd +1 -0
  132. data/spec/integration/command/union/union_0.stdout +9 -0
  133. data/spec/integration/command/unwrap/unwrap_0.cmd +1 -0
  134. data/spec/integration/command/unwrap/unwrap_0.stdout +9 -0
  135. data/spec/integration/command/wrap/wrap_0.cmd +1 -0
  136. data/spec/integration/command/wrap/wrap_0.stdout +9 -0
  137. data/spec/integration/semantics/test_join.alf +9 -0
  138. data/spec/integration/{src → semantics}/test_minus.alf +0 -0
  139. data/spec/integration/{src → semantics}/test_project.alf +0 -0
  140. data/spec/integration/semantics/test_rank.alf +34 -0
  141. data/spec/integration/test_command.rb +36 -0
  142. data/spec/integration/test_examples.rb +11 -22
  143. data/spec/integration/test_semantics.rb +40 -0
  144. data/spec/regression/alf_file/__FILE__.alf +2 -0
  145. data/spec/regression/alf_file/suppliers.rash +5 -0
  146. data/spec/regression/alf_file/test___FILE__.rb +17 -0
  147. data/spec/regression/heading/test_heading_with_date.rb +12 -0
  148. data/spec/regression/lispy/test_compile.rb +14 -0
  149. data/spec/regression/relation/test_relation_with_date.rb +12 -0
  150. data/spec/regression/restrict/test_restrict_with_keywords.rb +17 -0
  151. data/spec/shared/a_value.rb +12 -0
  152. data/spec/shared/an_operator_class.rb +35 -0
  153. data/spec/spec_helper.rb +12 -34
  154. data/spec/unit/assumptions/test_file.rb +17 -0
  155. data/spec/unit/{test_assumptions.rb → assumptions/test_instance_eval.rb} +1 -1
  156. data/spec/unit/assumptions/test_scoping.rb +29 -0
  157. data/spec/unit/environment/test_folder.rb +6 -1
  158. data/spec/unit/operator/relational/matching/test_hash_based.rb +60 -0
  159. data/spec/unit/operator/relational/not_matching/test_hash_based.rb +37 -0
  160. data/spec/unit/operator/relational/test_rank.rb +50 -0
  161. data/spec/unit/operator/test_relational.rb +3 -0
  162. data/spec/unit/reader/test_alf_file.rb +7 -4
  163. data/spec/unit/reader/test_initialize.rb +60 -0
  164. data/spec/unit/relation/test_relops.rb +4 -0
  165. data/spec/unit/relation/test_to_a.rb +41 -0
  166. data/spec/unit/renderer/test_initialize.rb +60 -0
  167. data/spec/unit/test_environment.rb +38 -0
  168. data/spec/unit/test_heading.rb +38 -0
  169. data/spec/unit/test_reader.rb +5 -0
  170. data/spec/unit/test_relation.rb +31 -1
  171. data/spec/unit/test_renderer.rb +1 -1
  172. data/spec/unit/{renderer/text → text}/test_cell.rb +1 -1
  173. data/spec/unit/{renderer/text → text}/test_row.rb +1 -1
  174. data/spec/unit/{renderer/text → text}/test_table.rb +1 -1
  175. data/spec/unit/tools/test_ordering_key.rb +13 -0
  176. data/spec/unit/tools/test_parse_commandline_args.rb +47 -0
  177. data/spec/unit/tools/test_tuple_handle.rb +34 -2
  178. data/spec/unit/tools/test_varargs.rb +16 -0
  179. data/tasks/{spec_test.rake → integration_test.rake} +4 -32
  180. data/tasks/regression_test.rake +52 -0
  181. data/tasks/unit_test.rake +33 -58
  182. metadata +326 -66
  183. data/examples/runall.sh +0 -26
  184. data/lib/alf/relation.rb +0 -118
  185. data/lib/alf/renderer/text.rb +0 -153
  186. data/lib/alf/renderer/yaml.rb +0 -22
  187. 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
- let(:io){ StringIO.new(expr) }
6
- def dataset(name)
7
- [{:status => 10},{:status => 30}]
5
+ class TestEnv < Alf::Environment
6
+ def dataset(name)
7
+ [{:status => 10},{:status => 30}]
8
+ end
8
9
  end
9
- subject{ Reader::AlfFile.new(io, self).to_a }
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
@@ -12,6 +12,10 @@ module Alf
12
12
  {:sid => 'S5'},
13
13
  {:sid => 'S2'}
14
14
  )}
15
+
16
+ specify "allbut" do
17
+ rel1.allbut([:sid]).should == rel({})
18
+ end
15
19
 
16
20
  specify "extend" do
17
21
  rel1.extend(:x => lambda{ sid.downcase }).should == rel(
@@ -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