alf 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. data/CHANGELOG.md +255 -129
  2. data/Gemfile +31 -1
  3. data/Gemfile.lock +17 -20
  4. data/LICENCE.md +1 -1
  5. data/Manifest.txt +2 -0
  6. data/README.md +37 -43
  7. data/TODO.md +1 -1
  8. data/alf.gemspec +10 -7
  9. data/alf.noespec +24 -13
  10. data/bin/alf +2 -2
  11. data/doc/commands/exec.md +16 -0
  12. data/doc/commands/help.md +11 -0
  13. data/doc/commands/main.md +33 -0
  14. data/doc/commands/show.md +19 -0
  15. data/doc/operators/non_relational/autonum.md +23 -0
  16. data/doc/operators/non_relational/clip.md +31 -0
  17. data/doc/operators/non_relational/coerce.md +15 -0
  18. data/doc/operators/non_relational/compact.md +20 -0
  19. data/doc/operators/non_relational/defaults.md +32 -0
  20. data/doc/operators/non_relational/generator.md +20 -0
  21. data/doc/operators/non_relational/sort.md +24 -0
  22. data/doc/operators/relational/extend.md +18 -0
  23. data/doc/operators/relational/group.md +27 -0
  24. data/doc/operators/relational/intersect.md +13 -0
  25. data/doc/operators/relational/join.md +27 -0
  26. data/doc/operators/relational/matching.md +20 -0
  27. data/doc/operators/relational/minus.md +12 -0
  28. data/doc/operators/relational/not-matching.md +20 -0
  29. data/doc/operators/relational/project.md +28 -0
  30. data/doc/operators/relational/quota.md +21 -0
  31. data/doc/operators/relational/rank.md +27 -0
  32. data/doc/operators/relational/rename.md +17 -0
  33. data/doc/operators/relational/restrict.md +25 -0
  34. data/doc/operators/relational/summarize.md +25 -0
  35. data/doc/operators/relational/ungroup.md +20 -0
  36. data/doc/operators/relational/union.md +14 -0
  37. data/doc/operators/relational/unwrap.md +20 -0
  38. data/doc/operators/relational/wrap.md +24 -0
  39. data/examples/csv/suppliers.csv +6 -0
  40. data/examples/logs/access.log +1000 -0
  41. data/examples/logs/combined.alf +2 -0
  42. data/examples/logs/hits.alf +14 -0
  43. data/examples/logs/not_found.alf +7 -0
  44. data/examples/logs/robots-cheating.alf +11 -0
  45. data/examples/logs/robots.alf +8 -0
  46. data/examples/northwind/customers.csv +92 -0
  47. data/examples/northwind/northwind.db +0 -0
  48. data/examples/northwind/orders.csv +831 -0
  49. data/examples/operators/clip.alf +1 -1
  50. data/examples/operators/database.alf +5 -6
  51. data/examples/operators/defaults.alf +1 -1
  52. data/examples/operators/group.alf +1 -1
  53. data/examples/operators/project.alf +2 -1
  54. data/examples/operators/pseudo-with.alf +2 -2
  55. data/examples/operators/quota.alf +2 -2
  56. data/examples/operators/summarize.alf +2 -2
  57. data/lib/alf/aggregator/aggregators.rb +77 -0
  58. data/lib/alf/aggregator/base.rb +95 -0
  59. data/lib/alf/aggregator/class_methods.rb +57 -0
  60. data/lib/alf/buffer/sorted.rb +48 -0
  61. data/lib/alf/command/class_methods.rb +27 -0
  62. data/lib/alf/command/doc_manager.rb +72 -0
  63. data/lib/alf/command/exec.rb +12 -0
  64. data/lib/alf/command/help.rb +31 -0
  65. data/lib/alf/command/main.rb +146 -0
  66. data/lib/alf/command/show.rb +33 -0
  67. data/lib/alf/environment/base.rb +37 -0
  68. data/lib/alf/environment/class_methods.rb +93 -0
  69. data/lib/alf/environment/explicit.rb +38 -0
  70. data/lib/alf/environment/folder.rb +62 -0
  71. data/lib/alf/extra/csv.rb +104 -0
  72. data/lib/alf/extra/logs.rb +100 -0
  73. data/lib/alf/extra/sequel.rb +77 -0
  74. data/lib/alf/{yaml.rb → extra/yaml.rb} +0 -0
  75. data/lib/alf/extra.rb +5 -0
  76. data/lib/alf/iterator/base.rb +38 -0
  77. data/lib/alf/iterator/class_methods.rb +22 -0
  78. data/lib/alf/iterator/proxy.rb +33 -0
  79. data/lib/alf/lispy/instance_methods.rb +157 -0
  80. data/lib/alf/operator/base.rb +74 -0
  81. data/lib/alf/operator/binary.rb +32 -0
  82. data/lib/alf/operator/cesure.rb +45 -0
  83. data/lib/alf/operator/class_methods.rb +132 -0
  84. data/lib/alf/operator/experimental.rb +9 -0
  85. data/lib/alf/operator/non_relational/autonum.rb +24 -0
  86. data/lib/alf/operator/non_relational/clip.rb +20 -0
  87. data/lib/alf/operator/non_relational/coerce.rb +21 -0
  88. data/lib/alf/operator/non_relational/compact.rb +62 -0
  89. data/lib/alf/operator/non_relational/defaults.rb +25 -0
  90. data/lib/alf/operator/non_relational/generator.rb +38 -0
  91. data/lib/alf/operator/non_relational/sort.rb +23 -0
  92. data/lib/alf/operator/nullary.rb +20 -0
  93. data/lib/alf/operator/relational/extend.rb +24 -0
  94. data/lib/alf/operator/relational/group.rb +32 -0
  95. data/lib/alf/operator/relational/intersect.rb +37 -0
  96. data/lib/alf/operator/relational/join.rb +106 -0
  97. data/lib/alf/operator/relational/matching.rb +45 -0
  98. data/lib/alf/operator/relational/minus.rb +37 -0
  99. data/lib/alf/operator/relational/not_matching.rb +45 -0
  100. data/lib/alf/operator/relational/project.rb +22 -0
  101. data/lib/alf/operator/relational/quota.rb +51 -0
  102. data/lib/alf/operator/relational/rank.rb +55 -0
  103. data/lib/alf/operator/relational/rename.rb +19 -0
  104. data/lib/alf/operator/relational/restrict.rb +20 -0
  105. data/lib/alf/operator/relational/summarize.rb +83 -0
  106. data/lib/alf/operator/relational/ungroup.rb +25 -0
  107. data/lib/alf/operator/relational/union.rb +32 -0
  108. data/lib/alf/operator/relational/unwrap.rb +21 -0
  109. data/lib/alf/operator/relational/wrap.rb +22 -0
  110. data/lib/alf/operator/shortcut.rb +53 -0
  111. data/lib/alf/operator/signature.rb +262 -0
  112. data/lib/alf/operator/transform.rb +27 -0
  113. data/lib/alf/operator/unary.rb +38 -0
  114. data/lib/alf/reader/alf_file.rb +24 -0
  115. data/lib/alf/reader/base.rb +119 -0
  116. data/lib/alf/reader/class_methods.rb +82 -0
  117. data/lib/alf/reader/rash.rb +28 -0
  118. data/lib/alf/relation/class_methods.rb +37 -0
  119. data/lib/alf/relation/instance_methods.rb +127 -0
  120. data/lib/alf/renderer/base.rb +72 -0
  121. data/lib/alf/renderer/class_methods.rb +58 -0
  122. data/lib/alf/renderer/rash.rb +19 -0
  123. data/lib/alf/{text.rb → renderer/text.rb} +1 -1
  124. data/lib/alf/tools/coerce.rb +14 -0
  125. data/lib/alf/tools/miscellaneous.rb +77 -0
  126. data/lib/alf/tools/to_lispy.rb +99 -0
  127. data/lib/alf/tools/to_ruby_literal.rb +14 -0
  128. data/lib/alf/tools/tuple_handle.rb +50 -0
  129. data/lib/alf/types/attr_list.rb +56 -0
  130. data/lib/alf/types/attr_name.rb +28 -0
  131. data/lib/alf/types/boolean.rb +12 -0
  132. data/lib/alf/types/heading.rb +96 -0
  133. data/lib/alf/types/ordering.rb +93 -0
  134. data/lib/alf/types/renaming.rb +57 -0
  135. data/lib/alf/types/summarization.rb +76 -0
  136. data/lib/alf/types/tuple_computation.rb +61 -0
  137. data/lib/alf/types/tuple_expression.rb +61 -0
  138. data/lib/alf/types/tuple_predicate.rb +49 -0
  139. data/lib/alf/version.rb +2 -2
  140. data/lib/alf.rb +193 -3714
  141. data/spec/integration/__database__/group.alf +1 -1
  142. data/spec/integration/__database__/suppliers_csv.csv +6 -0
  143. data/spec/integration/command/alf/alf.db +0 -0
  144. data/spec/integration/command/alf/alf_env_sqlite.cmd +1 -0
  145. data/spec/integration/command/alf/alf_env_sqlite.stdout +9 -0
  146. data/spec/integration/command/alf/alf_help.cmd +1 -0
  147. data/spec/integration/command/alf/alf_help.stdout +67 -0
  148. data/spec/integration/command/autonum/autonum_0.cmd +1 -1
  149. data/spec/integration/command/coerce/coerce_1.cmd +1 -0
  150. data/spec/integration/command/coerce/coerce_1.stdout +5 -0
  151. data/spec/integration/command/defaults/defaults_0.cmd +1 -1
  152. data/spec/integration/command/defaults/defaults_0.stdout +9 -9
  153. data/spec/integration/command/defaults/defaults_2.cmd +1 -0
  154. data/spec/integration/command/defaults/defaults_2.stdout +9 -0
  155. data/spec/integration/command/generator/generator_1.cmd +1 -0
  156. data/spec/integration/command/generator/generator_1.stdout +10 -0
  157. data/spec/integration/command/generator/generator_2.cmd +1 -0
  158. data/spec/integration/command/generator/generator_2.stdout +5 -0
  159. data/spec/integration/command/generator/generator_3.cmd +1 -0
  160. data/spec/integration/command/generator/generator_3.stdout +5 -0
  161. data/spec/integration/command/group/group_0.cmd +1 -1
  162. data/spec/integration/command/group/group_1.cmd +1 -1
  163. data/spec/integration/command/help/help_1.cmd +1 -0
  164. data/spec/integration/command/help/help_1.stdout +22 -0
  165. data/spec/integration/command/quota/quota_0.cmd +1 -1
  166. data/spec/integration/command/rank/rank_1.cmd +1 -1
  167. data/spec/integration/command/rank/rank_1.stdout +10 -10
  168. data/spec/integration/command/rank/rank_2.cmd +1 -1
  169. data/spec/integration/command/rank/rank_2.stdout +10 -10
  170. data/spec/integration/command/rank/rank_3.cmd +1 -1
  171. data/spec/integration/command/rank/rank_3.stdout +10 -10
  172. data/spec/integration/command/rank/rank_4.cmd +1 -1
  173. data/spec/integration/command/rank/rank_5.cmd +1 -1
  174. data/spec/integration/command/show/show_csv.cmd +1 -0
  175. data/spec/integration/command/show/show_csv.stdout +6 -0
  176. data/spec/integration/command/show/show_rash_2.cmd +1 -1
  177. data/spec/integration/command/show/show_rash_2.stdout +5 -5
  178. data/spec/integration/command/sort/sort_0.cmd +1 -1
  179. data/spec/integration/command/sort/sort_1.cmd +1 -1
  180. data/spec/integration/command/sort/sort_1.stdout +2 -2
  181. data/spec/integration/command/sort/sort_2.cmd +1 -0
  182. data/spec/integration/command/sort/sort_2.stdout +9 -0
  183. data/spec/integration/command/sort/sort_3.cmd +1 -0
  184. data/spec/integration/command/sort/sort_3.stdout +9 -0
  185. data/spec/integration/command/summarize/summarize_0.cmd +1 -1
  186. data/spec/integration/command/ungroup/ungroup_0.cmd +1 -1
  187. data/spec/integration/command/wrap/wrap_0.cmd +1 -1
  188. data/spec/integration/semantics/test_project.alf +5 -6
  189. data/spec/integration/semantics/test_rank.alf +16 -16
  190. data/spec/integration/test_command.rb +17 -6
  191. data/spec/integration/test_examples.rb +1 -1
  192. data/spec/regression/logs/apache_combined.log +5 -0
  193. data/spec/regression/logs/test_path_attribute.rb +25 -0
  194. data/spec/regression/relation/test_relation_allbut_all.rb +14 -0
  195. data/spec/shared/an_operator_class.rb +10 -5
  196. data/spec/spec_helper.rb +1 -7
  197. data/spec/unit/assumptions/test_set.rb +64 -0
  198. data/spec/unit/command/doc_manager/dynamic.md +1 -0
  199. data/spec/unit/command/doc_manager/example.md +1 -0
  200. data/spec/unit/command/doc_manager/example_1.txt +11 -0
  201. data/spec/unit/command/doc_manager/static.md +1 -0
  202. data/spec/unit/command/doc_manager/test_call.rb +49 -0
  203. data/spec/unit/csv/input.csv +3 -0
  204. data/spec/unit/csv/test_reader.rb +66 -0
  205. data/spec/unit/csv/test_renderer.rb +73 -0
  206. data/spec/unit/lispy/test_relation.rb +37 -0
  207. data/spec/unit/lispy/test_run.rb +40 -0
  208. data/spec/unit/lispy/test_tuple.rb +36 -0
  209. data/spec/unit/logs/apache_combined.log +5 -0
  210. data/spec/unit/logs/postgresql.log +29 -0
  211. data/spec/unit/logs/test_reader.rb +56 -0
  212. data/spec/unit/operator/non_relational/compact/{buffer_based.rb → test_buffer_based.rb} +0 -0
  213. data/spec/unit/operator/non_relational/test_clip.rb +1 -1
  214. data/spec/unit/operator/non_relational/test_coerce.rb +35 -0
  215. data/spec/unit/operator/non_relational/test_defaults.rb +15 -2
  216. data/spec/unit/operator/non_relational/test_generator.rb +78 -0
  217. data/spec/unit/operator/relational/join/test_hash_based.rb +4 -4
  218. data/spec/unit/operator/relational/matching/test_hash_based.rb +6 -6
  219. data/spec/unit/operator/relational/not_matching/test_hash_based.rb +4 -4
  220. data/spec/unit/operator/relational/summarize/test_hash_based.rb +10 -6
  221. data/spec/unit/operator/relational/summarize/test_sort_based.rb +18 -7
  222. data/spec/unit/operator/relational/test_group.rb +8 -8
  223. data/spec/unit/operator/relational/test_intersect.rb +3 -3
  224. data/spec/unit/operator/relational/test_minus.rb +3 -3
  225. data/spec/unit/operator/relational/test_project.rb +12 -2
  226. data/spec/unit/operator/relational/test_quota.rb +5 -6
  227. data/spec/unit/operator/relational/test_summarize.rb +9 -11
  228. data/spec/unit/operator/relational/test_union.rb +1 -1
  229. data/spec/unit/operator/relational/test_wrap.rb +1 -1
  230. data/spec/unit/operator/signature/test_collect_on.rb +45 -0
  231. data/spec/unit/operator/signature/test_initialize.rb +17 -0
  232. data/spec/unit/operator/signature/test_install.rb +56 -0
  233. data/spec/unit/operator/signature/test_option_parser.rb +36 -0
  234. data/spec/unit/operator/signature/test_parse_args.rb +60 -0
  235. data/spec/unit/operator/signature/test_parse_argv.rb +87 -0
  236. data/spec/unit/operator/signature/test_to_lispy.rb +102 -0
  237. data/spec/unit/operator/signature/test_to_shell.rb +103 -0
  238. data/spec/unit/operator/test_non_relational.rb +3 -1
  239. data/spec/unit/relation/test_relops.rb +20 -15
  240. data/spec/unit/sequel/alf.db +0 -0
  241. data/spec/unit/sequel/test_environment.rb +54 -0
  242. data/spec/unit/test_aggregator.rb +32 -22
  243. data/spec/unit/test_environment.rb +5 -0
  244. data/spec/unit/test_lispy.rb +4 -0
  245. data/spec/unit/test_relation.rb +5 -0
  246. data/spec/unit/text/test_cell.rb +6 -6
  247. data/spec/unit/text/test_row.rb +3 -3
  248. data/spec/unit/text/test_table.rb +6 -6
  249. data/spec/unit/tools/test_coalesce.rb +15 -0
  250. data/spec/unit/tools/test_coerce.rb +10 -0
  251. data/spec/unit/tools/test_to_lispy.rb +138 -0
  252. data/spec/unit/tools/test_to_ruby_literal.rb +10 -0
  253. data/spec/unit/tools/test_tuple_handle.rb +1 -59
  254. data/spec/unit/types/test_attr_list.rb +106 -0
  255. data/spec/unit/types/test_attr_name.rb +52 -0
  256. data/spec/unit/{test_heading.rb → types/test_heading.rb} +10 -0
  257. data/spec/unit/types/test_ordering.rb +127 -0
  258. data/spec/unit/types/test_renaming.rb +55 -0
  259. data/spec/unit/types/test_summarization.rb +63 -0
  260. data/spec/unit/types/test_tuple_computation.rb +60 -0
  261. data/spec/unit/types/test_tuple_expression.rb +64 -0
  262. data/spec/unit/types/test_tuple_predicate.rb +79 -0
  263. data/tasks/debug_mail.rake +1 -1
  264. data/tasks/debug_mail.txt +5 -0
  265. data/tasks/gh-pages.rake +63 -0
  266. metadata +325 -52
  267. data/spec/unit/operator/test_command_methods.rb +0 -38
  268. data/spec/unit/tools/test_ordering_key.rb +0 -94
  269. data/spec/unit/tools/test_parse_commandline_args.rb +0 -47
  270. data/spec/unit/tools/test_projection_key.rb +0 -83
data/spec/spec_helper.rb CHANGED
@@ -4,12 +4,6 @@ require "rspec"
4
4
 
5
5
  Alf::Lispy.extend(Alf::Lispy)
6
6
 
7
- def rel(*args)
8
- Alf::Relation.coerce(args)
9
- end
10
- def tuple(h)
11
- h
12
- end
13
7
  def _(path, file)
14
8
  File.expand_path("../#{path}", file)
15
9
  end
@@ -19,4 +13,4 @@ def wlang(str, binding)
19
13
  end
20
14
 
21
15
  require 'shared/an_operator_class'
22
- require 'shared/a_value'
16
+ require 'shared/a_value'
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'set'
3
+ describe Set do
4
+
5
+ specify "empty sets should be equal" do
6
+ Set.new([]).should eq(Set.new([]))
7
+ Set.new([]).should eql(Set.new([]))
8
+ end
9
+
10
+ describe "on DEE-like sets" do
11
+ let(:dee){ Set.new([{}]) }
12
+
13
+ specify "DEE sets should be equal" do
14
+ Set.new([{}]).should eq(dee)
15
+ Set.new([{}]).should eql(dee)
16
+ end
17
+
18
+ specify "DEE-like sets should be equal (1)" do
19
+ arr = [{}]
20
+ Set.new(arr).should eq(dee)
21
+ Set.new(arr).should eql(dee)
22
+ end
23
+
24
+ specify "DEE-like sets should be equal (2)" do
25
+ arr = [{}]
26
+ Set.new(arr.to_a).should eq(dee)
27
+ Set.new(arr.to_a).should eql(dee)
28
+ end
29
+
30
+ specify "DEE-like sets should be equal (3)" do
31
+ arr = [{}]
32
+ arr.to_set.should eq(dee)
33
+ arr.to_set.should eql(dee)
34
+ end
35
+
36
+ specify "DEE-like sets should be equal (4)" do
37
+ arr = [{}]
38
+ arr.to_set.should eq(dee)
39
+ arr.to_set.should eql(dee)
40
+ end
41
+
42
+ specify "DEE-like sets should be equal (5)" do
43
+ arr = Object.new.extend(Enumerable)
44
+ def arr.each
45
+ yield({})
46
+ end
47
+ arr.to_set.should eq(dee)
48
+ arr.to_set.should eql(dee)
49
+ end
50
+
51
+ specify "DEE-like sets should be equal (5)" do
52
+ arr = Object.new.extend(Enumerable)
53
+ def arr.each
54
+ tuple = {:sid => "1"}
55
+ tuple.delete(:sid)
56
+ yield(tuple)
57
+ end
58
+ arr.to_set.should eq(dee)
59
+ arr.to_set.should eql(dee)
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1 @@
1
+ #(command_name)
@@ -0,0 +1 @@
1
+ !(alf autonum suppliers -- unique_id)
@@ -0,0 +1,11 @@
1
+ $ alf autonum suppliers -- unique_id
2
+
3
+ +------+-------+---------+--------+------------+
4
+ | :sid | :name | :status | :city | :unique_id |
5
+ +------+-------+---------+--------+------------+
6
+ | S1 | Smith | 20 | London | 0 |
7
+ | S2 | Jones | 10 | Paris | 1 |
8
+ | S3 | Blake | 30 | Paris | 2 |
9
+ | S4 | Clark | 20 | London | 3 |
10
+ | S5 | Adams | 30 | Athens | 4 |
11
+ +------+-------+---------+--------+------------+
@@ -0,0 +1 @@
1
+ Hello
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Command
4
+ describe DocManager, ".call" do
5
+
6
+ let(:dm){ @dm ||= DocManager.new }
7
+ let(:cmd){ Alf::Command::Show }
8
+ subject{
9
+ dm.call(cmd, opts)
10
+ }
11
+
12
+ describe "without options" do
13
+ let(:opts){ {} }
14
+
15
+ describe "on a static file" do
16
+ before{
17
+ def dm.find_file(cmd);
18
+ File.expand_path('../static.md', __FILE__)
19
+ end
20
+ }
21
+ it { should eq("Hello\n") }
22
+ end
23
+
24
+ describe "on a dynamic file" do
25
+ before{
26
+ def dm.find_file(cmd);
27
+ File.expand_path('../dynamic.md', __FILE__)
28
+ end
29
+ }
30
+ it { should eq("show\n") }
31
+ end
32
+
33
+ unless RUBY_VERSION < "1.9"
34
+ describe "on an example file" do
35
+ before{
36
+ def dm.find_file(cmd);
37
+ File.expand_path('../example.md', __FILE__)
38
+ end
39
+ }
40
+ it { should eq(File.read(File.expand_path('../example_1.txt', __FILE__))) }
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ size
2
+ 10
3
+ 20
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module CSV
4
+ describe Reader do
5
+
6
+ describe "without options" do
7
+ let(:input){
8
+ StringIO.new << "size\n10\n20\n"
9
+ }
10
+ let(:expected){
11
+ [{:size => "10"}, {:size => "20"}]
12
+ }
13
+ subject{ reader.to_a }
14
+
15
+ describe "when called on a reader directly" do
16
+ let(:reader){
17
+ ::Alf::CSV::Reader.new(input)
18
+ }
19
+ it{ should eq(expected) }
20
+ end
21
+
22
+ describe "when called through registered one" do
23
+ let(:reader){
24
+ ::Alf::Reader.reader(_('input.csv', __FILE__))
25
+ }
26
+ it{ should eq(expected) }
27
+ end
28
+
29
+ describe "when called through factory method" do
30
+ let(:reader){
31
+ ::Alf::Reader.csv(input)
32
+ }
33
+ it{ should eq(expected) }
34
+ end
35
+ end
36
+
37
+ describe "with options" do
38
+ let(:input){
39
+ StringIO.new << "size;name\n10;blambeau\n20;mmathieu\n"
40
+ }
41
+ let(:options){
42
+ {:col_sep => ";"}
43
+ }
44
+ let(:expected){
45
+ [{:size => "10", :name => 'blambeau'}, {:size => "20", :name => 'mmathieu'}]
46
+ }
47
+ subject{ reader.to_a }
48
+
49
+ describe "when called on a reader directly" do
50
+ let(:reader){
51
+ ::Alf::CSV::Reader.new(input, options)
52
+ }
53
+ it{ should eq(expected) }
54
+ end
55
+
56
+ describe "when called through factory method" do
57
+ let(:reader){
58
+ ::Alf::Reader.csv(input, options)
59
+ }
60
+ it{ should eq(expected) }
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module CSV
4
+ describe Renderer do
5
+
6
+ describe "without options" do
7
+ let(:input){
8
+ [{:size => 10}, {:size => 20}]
9
+ }
10
+ let(:expected){
11
+ "size\n10\n20\n"
12
+ }
13
+ subject{ renderer.execute(StringIO.new).string }
14
+
15
+ describe "when called on a renderer directly" do
16
+ let(:renderer){
17
+ ::Alf::CSV::Renderer.new(input)
18
+ }
19
+ it{ should eq(expected) }
20
+ end
21
+
22
+ describe "when called through registererd one" do
23
+ let(:renderer){
24
+ ::Alf::Renderer.renderer(:csv, input)
25
+ }
26
+ it{ should eq(expected) }
27
+ end
28
+
29
+ describe "when called through factory method" do
30
+ let(:renderer){
31
+ ::Alf::Renderer.csv(input)
32
+ }
33
+ it{ should eq(expected) }
34
+ end
35
+ end
36
+
37
+ describe "with options" do
38
+ let(:input){
39
+ [{:size => 10, :name => "blambeau"}, {:size => 20, :name => "mmathieu"}]
40
+ }
41
+ let(:expected){
42
+ "size;name\n10;blambeau\n20;mmathieu\n"
43
+ }
44
+ let(:options){
45
+ {:col_sep => ";"}
46
+ }
47
+ subject{ renderer.execute(StringIO.new).string }
48
+
49
+ describe "when called on a renderer directly" do
50
+ let(:renderer){
51
+ ::Alf::CSV::Renderer.new(input, options)
52
+ }
53
+ it{ should eq(expected) }
54
+ end
55
+
56
+ describe "when called through registererd one" do
57
+ let(:renderer){
58
+ ::Alf::Renderer.renderer(:csv, input, options)
59
+ }
60
+ it{ should eq(expected) }
61
+ end
62
+
63
+ describe "when called through factory method" do
64
+ let(:renderer){
65
+ ::Alf::Renderer.csv(input, options)
66
+ }
67
+ it{ should eq(expected) }
68
+ end
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ describe Lispy, "Relation(...)" do
4
+ let(:lispy){ Alf.lispy }
5
+ subject{ lispy.Relation(*args) }
6
+
7
+ describe 'on a single tuple' do
8
+ let(:args){ [{:name => "Alf"}] }
9
+ it{ should eq(Relation[*args]) }
10
+ end
11
+
12
+ describe 'on two tuples' do
13
+ let(:args){ [{:name => "Alf"}, {:name => "Lispy"}] }
14
+ it{ should eq(Relation[*args]) }
15
+ end
16
+
17
+ describe 'on a Symbol' do
18
+ let(:args){ [:suppliers] }
19
+ specify{
20
+ subject.should eq(lispy.environment.dataset(:suppliers).to_rel)
21
+ }
22
+ end
23
+
24
+ describe "on the documentation example" do
25
+ specify {
26
+ lispy.evaluate{
27
+ Relation(
28
+ Tuple(:pid => 'P1', :name => 'Nut', :color => 'red', :heavy => true ),
29
+ Tuple(:pid => 'P2', :name => 'Bolt', :color => 'green', :heavy => false),
30
+ Tuple(:pid => 'P3', :name => 'Screw', :color => 'blue', :heavy => false)
31
+ )
32
+ }.should be_a(Relation)
33
+ }
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ describe Lispy, ".run" do
4
+
5
+ let(:cities){Relation[
6
+ {:city => "London"},
7
+ {:city => "Paris"},
8
+ {:city => "Athens"}
9
+ ]}
10
+
11
+ let(:lispy){ Alf.lispy(Environment.examples) }
12
+ subject{ lispy.run(args).to_rel }
13
+
14
+ describe "without any pipe, on a String" do
15
+ let(:args){ "project suppliers -- city" }
16
+ it{ should eq(cities) }
17
+ end
18
+
19
+ describe "without any pipe, on an Array" do
20
+ let(:args){ %w{project suppliers -- city} }
21
+ it{ should eq(cities) }
22
+ end
23
+
24
+ describe "with alf explicitely" do
25
+ let(:args){ %w{alf project suppliers -- city} }
26
+ it{ should eq(cities) }
27
+ end
28
+
29
+ describe "with piped commands" do
30
+ let(:args){ %w{alf project suppliers -- city | alf extend -- upcased city.upcase} }
31
+ it{ should eq(cities.extend(:upcased => lambda{ city.upcase })) }
32
+ end
33
+
34
+ describe "with piped commands and a dyadic op" do
35
+ let(:args){ %w{alf project suppliers -- city | alf matching suppliers} }
36
+ it{ should eq(cities) }
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ describe Lispy, "Tuple(...)" do
4
+ let(:lispy){ Alf.lispy }
5
+ subject{ lispy.Tuple(h) }
6
+
7
+ describe 'on an empty tuple' do
8
+ let(:h){ {} }
9
+ it{ should eq({}) }
10
+ end
11
+
12
+ describe 'on an valid tuple' do
13
+ let(:h){ {:name => "Alf"} }
14
+ it{ should eq({:name => "Alf"}) }
15
+ end
16
+
17
+ describe 'on an invalid tuple because of keys' do
18
+ let(:h){ {12 => "Alf"} }
19
+ specify{ lambda{subject}.should raise_error(ArgumentError) }
20
+ end
21
+
22
+ describe 'on an invalid tuple because of values' do
23
+ let(:h){ {:name => nil} }
24
+ specify{ lambda{subject}.should raise_error(ArgumentError) }
25
+ end
26
+
27
+ describe "on the documentation example" do
28
+ specify{
29
+ lispy.evaluate{
30
+ Tuple(:pid => 'P1', :name => 'Nut', :color => 'red', :heavy => true)
31
+ }.should eq(:pid => 'P1', :name => 'Nut', :color => 'red', :heavy => true)
32
+ }
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ 125.76.230.10 - - [02/Sep/2009:03:33:46 +0200] "GET /cart/install.txt HTTP/1.1" 404 214 "-" "Toata dragostea mea pentru diavola"
2
+ 125.76.230.10 - - [02/Sep/2009:03:33:47 +0200] "GET /store/install.txt HTTP/1.1" 404 215 "-" "Toata dragostea mea pentru diavola"
3
+ 10.0.1.1 - - [02/Sep/2009:05:08:33 +0200] "GET / HTTP/1.1" 200 30 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
4
+ 10.0.1.1 - - [02/Sep/2009:06:41:51 +0200] "GET / HTTP/1.1" 200 30 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
5
+ 69.41.0.45 - - [02/Sep/2009:12:02:40 +0200] "GET //phpMyAdmin/ HTTP/1.1" 404 209 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"
@@ -0,0 +1,29 @@
1
+ 2010-10-10 13:50:24 GMT [38626]: [1-1] LOG: 00000: database system was shut down at 2010-10-10 13:49:33 GMT
2
+ 2010-10-10 13:50:24 GMT [38626]: [2-1] LOCATION: StartupXLOG, xlog.c:4816
3
+ 2010-10-10 13:50:24 GMT [38624]: [1-1] LOG: 00000: database system is ready to accept connections
4
+ 2010-10-10 13:50:24 GMT [38624]: [2-1] LOCATION: reaper, postmaster.c:2156
5
+ 2010-10-10 13:50:24 GMT [38629]: [1-1] LOG: 00000: autovacuum launcher started
6
+ 2010-10-10 13:50:24 GMT [38629]: [2-1] LOCATION: AutoVacLauncherMain, autovacuum.c:520
7
+ 2010-10-10 13:52:04 GMT [38747]: [1-1] LOG: 00000: connection received: host=127.0.0.1 port=60020
8
+ 2010-10-10 13:52:04 GMT [38747]: [2-1] LOCATION: BackendInitialize, postmaster.c:3027
9
+ 2010-10-10 13:52:04 GMT [38747]: [3-1] LOG: 00000: connection authorized: user=root database=demonstration
10
+ 2010-10-10 13:52:04 GMT [38747]: [4-1] LOCATION: BackendInitialize, postmaster.c:3097
11
+ 2010-10-10 13:52:04 GMT [38747]: [5-1] LOG: 00000: duration: 0.329 ms statement: SHOW clients
12
+ 2010-10-10 13:52:05 GMT [38747]: [21-1] LOG: 00000: duration: 0.973 ms statement: SELECT tablename
13
+ FROM pg_tables
14
+ WHERE schemaname IN (E'"$user"',E'public')
15
+ 2010-10-10 13:52:07 GMT [38747]: [33-1] LOG: 00000: duration: 0.710 ms statement: SELECT * FROM "delayed_jobs"
16
+ 2010-10-10 13:52:08 GMT [38747]: [33-1] LOG: 00000: duration: 0.710 ms statement: SELECT * FROM "delayed_jobs"
17
+ 2010-10-10 15:00:02 GMT [38747]: [1667-1] LOG: 00000: duration: 0.024 ms statement: BEGIN
18
+ 2010-10-10 15:00:02 GMT [38747]: [1668-1] LOCATION: exec_simple_query, postgres.c:1081
19
+ 2010-10-10 15:00:02 GMT [38747]: [1669-1] LOG: 00000: duration: 0.195 ms statement: INSERT INTO "delayed_jobs" ("failed_at", "locked_by", "created_at", "handler", "updated_at", "priority", "run_at", "attempts", "locked_at", "last_error") VALUES(NULL, NULL, '2010-10-10 15:00:02.159884', E'--- !ruby/object:RuntheChooChootrain {}
20
+
21
+ ', '2010-10-10 15:00:02.159884', 0, '2010-10-10 16:00:00.000000', 0, NULL, NULL) RETURNING "id"
22
+ 2010-10-10 15:00:02 GMT [38747]: [1670-1] LOCATION: exec_simple_query, postgres.c:1081
23
+ 2010-10-10 15:00:02 GMT [38747]: [1671-1] LOG: 00000: duration: 0.065 ms statement: COMMIT
24
+ 2010-10-10 15:00:02 GMT [38747]: [1672-1] LOCATION: exec_simple_query, postgres.c:1081
25
+ 2010-10-10 15:00:02 GMT [38747]: [1673-1] LOG: 00000: duration: 0.020 ms statement: BEGIN
26
+ 2010-10-10 15:00:02 GMT [38747]: [1674-1] LOCATION: exec_simple_query, postgres.c:1081
27
+ 2010-10-10 15:00:02 GMT [38747]: [1675-1] LOG: 00000: duration: 0.157 ms statement: DELETE FROM "delayed_jobs" WHERE "id" = 123456
28
+ 2010-10-10 15:00:02 GMT [38747]: [1676-1] LOCATION: exec_simple_query, postgres.c:1081
29
+ 2010-10-10 15:00:02 GMT [38747]: [1677-1] LOG: 00000: duration: 0.050 ms statement: COMMIT
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ shared_examples_for "A valid Logs::Reader instance" do
4
+
5
+ specify{ reader.should be_a(::Alf::Logs::Reader) }
6
+
7
+ it "should yield a pseudo-relation" do
8
+ reader.all?{|tuple| tuple.is_a?(Hash)}.should be_true
9
+ end
10
+
11
+ end
12
+ describe Logs::Reader do
13
+
14
+ let(:input){ _("apache_combined.log", __FILE__) }
15
+
16
+ describe "when called on a reader directly" do
17
+ let(:reader){
18
+ ::Alf::Logs::Reader.new(input)
19
+ }
20
+ it_should_behave_like "A valid Logs::Reader instance"
21
+ end
22
+
23
+ describe "when called through registered one" do
24
+ let(:reader){
25
+ ::Alf::Reader.reader(input)
26
+ }
27
+ it_should_behave_like "A valid Logs::Reader instance"
28
+ end
29
+
30
+ describe "when called through factory method" do
31
+ let(:reader){
32
+ ::Alf::Reader.logs(input)
33
+ }
34
+ it_should_behave_like "A valid Logs::Reader instance"
35
+ end
36
+
37
+ describe "the auto-detect feature" do
38
+ let(:reader){ ::Alf::Logs::Reader.new(nil,nil,:file_format => nil) }
39
+ let(:relation){ reader.to_rel }
40
+
41
+ describe "on postgresql.log" do
42
+ before{ reader.pipe(_("postgresql.log", __FILE__)) }
43
+ it_should_behave_like "A valid Logs::Reader instance"
44
+ specify{ relation.should_not be_empty }
45
+ end
46
+
47
+ describe "on apache_combined.log" do
48
+ before{ reader.pipe(_("apache_combined.log", __FILE__)) }
49
+ it_should_behave_like "A valid Logs::Reader instance"
50
+ specify{ relation.should_not be_empty }
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -38,7 +38,7 @@ module Alf
38
38
  end
39
39
 
40
40
  describe "when factored with Lispy" do
41
- let(:operator){ Lispy.clip(input, [:a], true) }
41
+ let(:operator){ Lispy.clip(input, [:a], :allbut => true) }
42
42
  it { should == expected }
43
43
  end
44
44
 
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Coerce do
5
+
6
+ let(:operator_class){ Coerce }
7
+ it_should_behave_like("An operator class")
8
+
9
+ let(:input) {Alf::Relation[
10
+ {:a => "12", :b => "14.0"},
11
+ ]}
12
+
13
+ subject{ operator.to_rel }
14
+
15
+ describe "When used without --strict" do
16
+ let(:expected){Alf::Relation[
17
+ {:a => 12, :b => 14.0}
18
+ ]}
19
+
20
+ describe "when factored from commandline" do
21
+ let(:operator){ Coerce.run(%w{-- a Integer b Float}) }
22
+ before{ operator.pipe(input) }
23
+ it { should == expected }
24
+ end
25
+
26
+ describe "when factored with Lispy" do
27
+ let(:operator){ Lispy.coerce(input, :a => Integer, :b => Float) }
28
+ it { should == expected }
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -44,12 +44,25 @@ module Alf
44
44
  ]}
45
45
 
46
46
  describe "When factored with Lispy" do
47
- let(:operator){ Lispy.defaults(input, {:a => 1, :b => "b"}, true) }
47
+ let(:operator){ Lispy.defaults(input, {:a => 1, :b => "b"}, :strict => true) }
48
48
  it{ should == expected }
49
49
  end
50
50
 
51
51
  end
52
+
53
+ describe "when used with tuple expressions" do
54
+ let(:input) {[
55
+ {:a => nil, :b => "b"},
56
+ ]}
57
+ let(:expected) {[
58
+ {:a => "b", :b => "b"},
59
+ ]}
60
+ let(:operator){
61
+ Lispy.defaults(input, {:a => TupleExpression.coerce("b")})
62
+ }
63
+ it{ should == expected }
64
+ end
52
65
 
53
66
  end
54
67
  end
55
- end
68
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Operator::NonRelational
4
+ describe Generator do
5
+
6
+ let(:operator_class){ Generator }
7
+ it_should_behave_like("An operator class")
8
+
9
+ subject{ operator.to_rel }
10
+
11
+ describe "without providing anything" do
12
+
13
+ let(:expected){Relation[
14
+ {:num => 1},
15
+ {:num => 2},
16
+ {:num => 3},
17
+ {:num => 4},
18
+ {:num => 5},
19
+ {:num => 6},
20
+ {:num => 7},
21
+ {:num => 8},
22
+ {:num => 9},
23
+ {:num => 10},
24
+ ]}
25
+
26
+ describe "When factored with Lispy" do
27
+ let(:operator){ Lispy.generator() }
28
+ it{ should == expected }
29
+ end
30
+
31
+ describe "When factored from commandline args" do
32
+ let(:operator){ Generator.run(%w{}) }
33
+ it{ should == expected }
34
+ end
35
+
36
+ end
37
+
38
+ describe "when providing an size" do
39
+
40
+ let(:expected){Relation[
41
+ {:num => 1},
42
+ {:num => 2},
43
+ ]}
44
+
45
+ describe "When factored with Lispy" do
46
+ let(:operator){ Lispy.generator(2) }
47
+ it{ should == expected }
48
+ end
49
+
50
+ describe "When factored from commandline args" do
51
+ let(:operator){ Generator.run(["--", "2"]) }
52
+ it{ should == expected }
53
+ end
54
+
55
+ end
56
+
57
+ describe "when providing a size and a name" do
58
+
59
+ let(:expected){Relation[
60
+ {:id => 1},
61
+ {:id => 2},
62
+ ]}
63
+
64
+ describe "When factored with Lispy" do
65
+ let(:operator){ Lispy.generator(2, :id) }
66
+ it{ should == expected }
67
+ end
68
+
69
+ describe "When factored from commandline args" do
70
+ let(:operator){ Generator.run(["--", "2", "--", "id"]) }
71
+ it{ should == expected }
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+ end
78
+ end