alf 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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