alf-shell 0.13.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/CHANGELOG.md +6 -0
  2. data/Gemfile +1 -3
  3. data/Gemfile.lock +3 -3
  4. data/doc/commands/show.md +1 -8
  5. data/doc/operators/relational/frame.md +26 -0
  6. data/doc/operators/relational/hierarchize.md +14 -0
  7. data/doc/operators/relational/page.md +31 -0
  8. data/lib/alf/shell.rb +4 -0
  9. data/lib/alf/shell/alfrc.rb +40 -0
  10. data/lib/alf/shell/command/exec.rb +1 -1
  11. data/lib/alf/shell/command/main.rb +58 -38
  12. data/lib/alf/shell/command/show.rb +0 -26
  13. data/lib/alf/shell/doc_manager.rb +5 -4
  14. data/lib/alf/shell/from_argv.rb +6 -0
  15. data/lib/alf/shell/support.rb +5 -4
  16. data/lib/alf/shell/version.rb +2 -2
  17. data/spec/fixtures/example.alfrc +13 -0
  18. data/spec/integration/alf/alf_db.cmd +1 -1
  19. data/spec/integration/alf/alf_help.stdout +6 -2
  20. data/spec/integration/frame/frame_0.cmd +1 -0
  21. data/spec/integration/frame/frame_0.stdout +6 -0
  22. data/spec/integration/help/help_1.stdout +1 -14
  23. data/spec/integration/page/page_0.cmd +1 -0
  24. data/spec/integration/page/page_0.stdout +6 -0
  25. data/spec/integration/show/show_base_sort_1.cmd +1 -1
  26. data/spec/integration/show/show_base_sort_2.cmd +1 -1
  27. data/spec/integration/show/show_ff.cmd +1 -1
  28. data/spec/integration/show/show_rash.cmd +1 -1
  29. data/spec/integration/show/show_rash_pretty.cmd +1 -1
  30. data/spec/integration/show/show_yaml.cmd +1 -1
  31. data/spec/integration/test_shell.rb +6 -3
  32. data/spec/unit/alfrc/test_alfrc.rb +59 -0
  33. data/spec/unit/doc_manager/test_call.rb +9 -11
  34. data/spec/unit/main/test_I_option.rb +36 -0
  35. data/spec/unit/main/test_r_option.rb +36 -0
  36. data/spec/unit/main/test_renderer_option.rb +28 -0
  37. metadata +18 -7
  38. data/spec/integration/show/show_conflictual.cmd +0 -1
  39. data/spec/integration/show/show_conflictual.stdout +0 -5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.14.0 / 2013-10-01
2
+
3
+ * Added a .alfrc abstraction
4
+ * Added documentation for `page` (follows alf-core changes)
5
+ * Added documentation for `frame` (follows alf-core changes)
6
+
1
7
  # 0.13.1 / 2013-07-29
2
8
 
3
9
  * Embed the documentation so as to --help to work.
data/Gemfile CHANGED
@@ -1,9 +1,7 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  group :runtime do
4
- #gem "alf-core", :git => "git://github.com/alf-tool/alf-core.git"
5
- #gem "alf-core", :path => "../alf-core"
6
- gem "alf-core", "~> 0.13.0"
4
+ gem "alf-core", "~> 0.14.0"
7
5
  gem "quickl", "~> 0.4.3"
8
6
  end
9
7
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- alf-core (0.13.0)
4
+ alf-core (0.14.0)
5
5
  domain (~> 1.0)
6
6
  myrrha (~> 3.0)
7
7
  path (~> 1.3)
@@ -11,7 +11,7 @@ GEM
11
11
  highline (1.6.19)
12
12
  myrrha (3.0.0)
13
13
  domain (~> 1.0)
14
- path (1.3.1)
14
+ path (1.3.3)
15
15
  quickl (0.4.3)
16
16
  rake (10.1.0)
17
17
  rspec (2.14.1)
@@ -28,7 +28,7 @@ PLATFORMS
28
28
  ruby
29
29
 
30
30
  DEPENDENCIES
31
- alf-core (~> 0.13.0)
31
+ alf-core (~> 0.14.0)
32
32
  highline (~> 1.6)
33
33
  quickl (~> 0.4.3)
34
34
  rake (~> 10.1)
data/doc/commands/show.md CHANGED
@@ -1,19 +1,12 @@
1
1
 
2
- Output input tuples through a specific renderer (text, yaml, ...)
2
+ Output input tuples through the default renderer in a specific order.
3
3
 
4
4
  SYNOPSIS
5
5
 
6
6
  alf #(command_name) NAME -- [ORDERING]
7
7
 
8
- OPTIONS
9
-
10
- #(summarized_options)
11
-
12
8
  DESCRIPTION
13
9
 
14
10
  When a name is specified as commandline arg, request the database to
15
11
  provide the corresponding relation variable and prints its value.
16
12
  Otherwise, take what comes on standard input.
17
-
18
- Note that this command is not an operator and should not be piped
19
- anymore.
@@ -0,0 +1,26 @@
1
+
2
+ Relational framing (aka offset/limit, yet sounder)
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This command provides the classical offset/limit over the input relation.
11
+
12
+ This operator skips tuples whose ranking according to `ordering` is between
13
+ `0` and `offset` exclusive (in other words, it skips `offset` tuples). In
14
+ addition, it returns maximum `limit` tuples.
15
+
16
+ To be sound, this operator requires the ordering to include a candidate key
17
+ for the input relation. Alf will automatically extend the ordering you provide
18
+ to guarantee this, provided key inference is possible.
19
+
20
+ EXAMPLE
21
+
22
+ # Take the first two suppliers ordered by name (then by id)
23
+ !(alf frame suppliers -- name -- 0 -- 2)
24
+
25
+ # Take the next two suppliers
26
+ !(alf frame suppliers -- name -- 2 -- 2)
@@ -0,0 +1,14 @@
1
+
2
+ Relational hierarchy (recursive relation-trees)
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ OPTIONS
9
+
10
+ #(summarized_options)
11
+
12
+ DESCRIPTION
13
+
14
+ This operator converts a "flat" relation to a recursively defined one.
@@ -0,0 +1,31 @@
1
+
2
+ Relational pagination (like frame, but easier)
3
+
4
+ SYNOPSIS
5
+
6
+ #(signature)
7
+
8
+ DESCRIPTION
9
+
10
+ This command provides pagination over the input relation.
11
+
12
+ When page_index is positive (resp. striclty negative), this operator returns
13
+ `page_size` tuples whose ranking according to `ordering` (resp. reverse
14
+ ordering) is between `page_size * (page_index - 1)` and `page_size * page_index`
15
+ (excluded).
16
+
17
+ To be sound, this operator requires the ordering to include a candidate key
18
+ for the input relation. Alf will automatically extend the ordering you provide
19
+ to guarantee this, provided key inference is possible.
20
+
21
+ EXAMPLE
22
+
23
+ # Take the first two suppliers ordered by name (then by id)
24
+ !(alf page --page-size=2 suppliers -- name -- 1)
25
+
26
+ # Take the next two suppliers
27
+ !(alf page --page-size=2 suppliers -- name -- 2)
28
+
29
+ # Take the last two suppliers
30
+ !(alf page --page-size=2 suppliers -- name -- -1)
31
+
data/lib/alf/shell.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require_relative 'shell/version'
2
2
  require_relative 'shell/loader'
3
3
  require_relative 'shell/ext/signature'
4
+ require_relative 'shell/alfrc'
4
5
  require_relative 'shell/doc_manager'
5
6
  module Alf
6
7
  module Shell
@@ -8,6 +9,9 @@ module Alf
8
9
  # This is the main documentation extractor
9
10
  DOC_EXTRACTOR = DocManager.new
10
11
 
12
+ # This is the default configuration to be forked from
13
+ DEFAULT_CONFIG = Alfrc.new
14
+
11
15
  # Delegator command factory
12
16
  def self.Delegator()
13
17
  Quickl::Delegator(){|builder|
@@ -0,0 +1,40 @@
1
+ module Alf
2
+ module Shell
3
+ class Alfrc < Support::Config
4
+
5
+ # Path to be put in $LOAD_PATH before executing alf
6
+ option :load_paths, Array, []
7
+
8
+ # Libraries to require before executing alf
9
+ option :requires, Array, []
10
+
11
+ # Default renderer to use for outputting relations
12
+ option :default_renderer, Class, ->{ $stdout.tty? ? Renderer::Text : Renderer::Rash }
13
+
14
+ # Float format to use
15
+ option :float_format, String, "%.3f"
16
+
17
+ # Pretty print in console mode?
18
+ option :pretty, Boolean, ->{ $stdout.tty? }
19
+
20
+ # The adapter to use by default
21
+ option :adapter, Object, ->{ Path.pwd }
22
+
23
+ # The database to use by default
24
+ option :database, Database, ->{ Database.new(adapter) }
25
+
26
+ # The viewpoint to use by default
27
+ option :viewpoint, Module, ->{ Viewpoint::NATIVE }
28
+
29
+ # If `path` is provided, evaluates the content of the file on this
30
+ # instance. Also, if a block is passed, yields it with self. Return
31
+ # self in any case.
32
+ def alfrc(path = nil)
33
+ ::Kernel.eval(Path(path).read, binding, path.to_s) if path
34
+ yield(self) if block_given?
35
+ self
36
+ end
37
+
38
+ end # class Alfrc
39
+ end # module Shell
40
+ end # module Alf
@@ -8,7 +8,7 @@ module Alf
8
8
  else
9
9
  $stdin.read
10
10
  end
11
- database.query(cmd)
11
+ connection.query(cmd)
12
12
  end
13
13
 
14
14
  end # class Exec
@@ -42,45 +42,37 @@ module Alf
42
42
 
43
43
  end # class << self
44
44
 
45
- # Connection instance to use to get base relations
46
- attr_accessor :database
47
-
48
45
  # The reader to use when stdin is used as operand
49
46
  attr_accessor :stdin_operand
50
47
 
51
- # Output renderer
52
- attr_accessor :renderer_class
53
-
54
- # Rendering options
55
- attr_reader :rendering_options
56
-
57
48
  # Creates a command instance
58
- def initialize(db = Alf.connect(Path.pwd))
59
- @database = db
60
- @rendering_options = {}
49
+ def initialize(config = load_config)
50
+ @config = config
61
51
  end
52
+ attr_reader :config
62
53
 
63
54
  # Install options
64
55
  options do |opt|
56
+ @rendering_options = {}
57
+
65
58
  @execute = false
66
59
  opt.on("-e", "--execute", "Execute one line of script (Lispy API)") do
67
60
  @execute = true
68
61
  end
69
62
 
70
- @renderer_class = nil
71
63
  Renderer.each do |name,descr,clazz|
72
64
  opt.on("--#{name}", "Render output #{descr}"){
73
- @renderer_class = clazz
65
+ config.default_renderer = clazz
74
66
  }
75
67
  end
76
68
 
77
69
  opt.on('--examples', "Use the example database for database") do
78
- @database = Alf.examples
70
+ config.adapter = Alf.examples_adapter
79
71
  end
80
72
 
81
73
  opt.on('--db=DB',
82
74
  "Set the database to use") do |value|
83
- @database = Alf.connect(value)
75
+ config.adapter = value
84
76
  end
85
77
 
86
78
  @input_reader = :rash
@@ -93,20 +85,27 @@ module Alf
93
85
 
94
86
  opt.on("-Idirectory",
95
87
  "Specify $LOAD_PATH directory (may be used more than once)") do |val|
96
- $LOAD_PATH.unshift val
88
+ config.load_paths << val
97
89
  end
98
90
 
99
91
  opt.on('-rlibrary',
100
- "Require the library, before executing alf") do |value|
101
- require(value)
92
+ "Require the library, before executing alf") do |val|
93
+ config.requires << val
94
+ end
95
+
96
+ opt.on("--ff=FORMAT",
97
+ "Specify the floating point format") do |val|
98
+ config.float_format = val
102
99
  end
103
100
 
104
101
  opt.on("--[no-]pretty",
105
102
  "Enable/disable pretty print best effort") do |val|
106
- self.pretty = val
103
+ config.pretty = val
107
104
  end
108
105
 
109
106
  opt.on_tail('-h', "--help", "Show help") do
107
+ install_load_path
108
+ install_requires
110
109
  raise Quickl::Help
111
110
  end
112
111
 
@@ -120,42 +119,68 @@ module Alf
120
119
  @stdin_operand || Reader.send(@input_reader, $stdin)
121
120
  end
122
121
 
122
+ def connection
123
+ @connection ||= config.database.connection(viewpoint: config.viewpoint)
124
+ end
125
+
123
126
  def execute(argv)
127
+ install_load_path
128
+ install_requires
129
+
124
130
  # special case where a .alf file is provided
125
- if argv.empty? or (argv.size == 1 && Path(argv.first).exist?)
131
+ if argv.empty? or (argv.size == 1 && Path(argv.first).file?)
126
132
  argv.unshift("exec")
127
133
  end
128
134
 
129
135
  # compile the operator, render and returns it
130
136
  compile(argv){ super }.tap do |op|
131
- render(op.to_cog) if op && requester
137
+ render(connection.compile(op)) if op && requester
138
+ end
139
+ end
140
+
141
+ private
142
+
143
+ def install_load_path
144
+ config.load_paths.each do |path|
145
+ $: << path
132
146
  end
133
147
  end
134
148
 
135
- def pretty=(val)
136
- @rendering_options[:pretty] = val
137
- if val && (hl = highline)
138
- @rendering_options[:trim_at] = hl.output_cols
139
- @rendering_options[:page_at] = hl.output_rows
149
+ def install_requires
150
+ config.requires.each do |who|
151
+ require(who)
140
152
  end
141
- val
142
153
  end
143
154
 
144
- private
155
+ def load_config
156
+ config = Alf::Shell::DEFAULT_CONFIG.dup
157
+ if alfrc_file = Path.pwd.backfind('.alfrc')
158
+ config.alfrc(alfrc_file)
159
+ end
160
+ config
161
+ end
145
162
 
146
163
  def compile(argv)
147
164
  if @execute
148
- database.query(argv.first)
165
+ connection.query(argv.first)
149
166
  else
150
167
  op = yield
151
- op = op.bind(database) if op
168
+ op = op.bind(connection) if op
152
169
  op
153
170
  end
154
171
  end
155
172
 
173
+ def rendering_options
174
+ options = { float_format: config.float_format }
175
+ if config.pretty? and (hl = highline)
176
+ options[:pretty] = config.pretty?
177
+ options[:trim_at] = hl.output_cols - 1
178
+ end
179
+ options
180
+ end
181
+
156
182
  def render(operator, out = $stdout)
157
- renderer_class = self.renderer_class || default_renderer_class
158
- renderer = renderer_class.new(operator, rendering_options)
183
+ renderer = config.default_renderer.new(operator, rendering_options)
159
184
  renderer.execute(out)
160
185
  end
161
186
 
@@ -163,11 +188,6 @@ module Alf
163
188
  require 'highline'
164
189
  HighLine.new($stdin, $stdout)
165
190
  rescue LoadError => ex
166
- nil
167
- end
168
-
169
- def default_renderer_class
170
- $stdout.tty? ? Renderer::Text : Renderer::Rash
171
191
  end
172
192
 
173
193
  end # class Main
@@ -2,37 +2,11 @@ module Alf
2
2
  module Shell
3
3
  class Show < Shell::Command()
4
4
 
5
- options do |opt|
6
- @renderer_class = nil
7
- Renderer.each do |name,descr,clazz|
8
- opt.on("--#{name}", "Render output #{descr}"){
9
- @renderer_class = clazz
10
- }
11
- end
12
-
13
- @pretty = nil
14
- opt.on("--[no-]pretty",
15
- "Enable/disable pretty print best effort") do |val|
16
- @pretty = val
17
- end
18
-
19
- @ff = nil
20
- opt.on("--ff=FORMAT",
21
- "Specify the floating point format") do |val|
22
- @ff = val
23
- end
24
- end
25
-
26
5
  def run(argv, requester)
27
6
  # set requester and parse options
28
7
  @requester = requester
29
8
  argv = parse_options(argv, :split)
30
9
 
31
- # Set options on the requester
32
- requester.pretty = @pretty unless @pretty.nil?
33
- requester.rendering_options[:float_format] = @ff unless @ff.nil?
34
- requester.renderer_class = (@renderer_class || requester.renderer_class)
35
-
36
10
  compile(argv)
37
11
  end
38
12
 
@@ -9,8 +9,8 @@ module Alf
9
9
  # Called by Quickl when it's time to generate documentation of `cmd`.
10
10
  #
11
11
  def call(cmd, options = {})
12
- if File.exists?(file = find_file(cmd))
13
- text = File.read(file)
12
+ if (file = find_file(cmd)).file?
13
+ text = file.read
14
14
 
15
15
  # Replace occurences of #{signature} to #{signature.to_xxx}
16
16
  # according to options
@@ -54,7 +54,8 @@ module Alf
54
54
  argv = Quickl.split_commandline_args(argv, '|')
55
55
  argv.inject(nil) do |cmd,arr|
56
56
  arr.shift if arr.first == "alf"
57
- main = Alf::Shell::Main.new(Alf.examples)
57
+ main = Alf::Shell::Main.new(Alf::Shell::DEFAULT_CONFIG)
58
+ main.config.adapter = Alf.examples_adapter
58
59
  main.stdin_operand = cmd unless cmd.nil?
59
60
  main.run(arr, requester)
60
61
  end
@@ -75,7 +76,7 @@ module Alf
75
76
  else
76
77
  raise "Unexpected command #{cmd}"
77
78
  end
78
- File.join(DOC_FOLDER, where, "#{cmd.command_name}.md")
79
+ DOC_FOLDER/where/"#{cmd.command_name}.md"
79
80
  end
80
81
 
81
82
  end # class DocManager
@@ -15,6 +15,12 @@ module Alf
15
15
  Size.new(Integer(argv.first || 0))
16
16
  }
17
17
 
18
+ # ARGV -> Integer
19
+ c.coercion(Array, Integer){|argv,_|
20
+ throw :next_rule if argv.size > 1
21
+ Integer(argv.first || 0)
22
+ }
23
+
18
24
  # ARGV -> AttrName
19
25
  c.coercion(Array, AttrName){|argv,_|
20
26
  throw :next_rule if argv.size > 1
@@ -2,21 +2,22 @@ module Alf
2
2
  module Shell
3
3
  module Support
4
4
 
5
- def database
6
- requester && requester.database
5
+ def connection
6
+ requester && requester.connection
7
7
  end
8
8
 
9
9
  def compiler
10
- @compiler ||= (database && database.connection.compiler) || Engine::Compiler.new(nil)
10
+ @compiler ||= (connection && connection.compiler) || Engine::Compiler.new(nil)
11
11
  end
12
12
 
13
13
  def operands(argv, size = nil)
14
14
  operands = [ stdin_operand ] + Array(argv)
15
15
  operands = operands[(operands.size - size)..-1] if size
16
16
  operands = operands.map{|arg|
17
- arg = Algebra.named_operand(arg.to_sym, database) if arg.is_a?(String)
17
+ arg = connection.relvar(arg) if arg.is_a?(String)
18
18
  Algebra::Operand.coerce(arg)
19
19
  }
20
+ operands
20
21
  end
21
22
 
22
23
  def stdin_operand
@@ -3,8 +3,8 @@ module Alf
3
3
  module Version
4
4
 
5
5
  MAJOR = 0
6
- MINOR = 13
7
- TINY = 1
6
+ MINOR = 14
7
+ TINY = 0
8
8
 
9
9
  def self.to_s
10
10
  [ MAJOR, MINOR, TINY ].join('.')
@@ -0,0 +1,13 @@
1
+ alfrc do |c|
2
+
3
+ # Include the lib folder that is a brother of .alfrc
4
+ c.load_paths |= [
5
+ Path.dir/'lib'
6
+ ]
7
+
8
+ # Require the 'alf-sequel'
9
+ c.requires |= [
10
+ 'alf-sequel'
11
+ ]
12
+
13
+ end
@@ -1 +1 @@
1
- alf --db=$(_("alf",__FILE__)) show --text rel
1
+ alf --text --db=$(_("alf",__FILE__)) show rel
@@ -19,9 +19,10 @@ OPTIONS
19
19
  --csv Render output in CSV
20
20
  --examples Use the example database for database
21
21
  --db=DB Set the database to use
22
- --input-reader=READER Specify the kind of reader when reading on $stdin (rash,csv,json)
22
+ --input-reader=READER Specify the kind of reader when reading on $stdin (rash,csv,json,ruby)
23
23
  -Idirectory Specify $LOAD_PATH directory (may be used more than once)
24
24
  -rlibrary Require the library, before executing alf
25
+ --ff=FORMAT Specify the floating point format
25
26
  --[no-]pretty Enable/disable pretty print best effort
26
27
  -h, --help Show help
27
28
  -v, --version Show version
@@ -29,12 +30,14 @@ OPTIONS
29
30
  RELATIONAL OPERATORS
30
31
 
31
32
  extend Relational extension (additional, computed attributes)
33
+ frame Relational framing (aka offset/limit, yet sounder)
32
34
  group Relational grouping (relation-valued attributes)
33
35
  intersect Relational intersection (aka a logical and)
34
36
  join Relational join (and cartesian product)
35
37
  matching Relational matching (join + project back on left)
36
38
  minus Relational minus (aka difference)
37
39
  not-matching Relational not matching (inverse of matching)
40
+ page Relational pagination (like frame, but easier)
38
41
  project Relational projection (clip + compact)
39
42
  rank Relational ranking (explicit tuple positions)
40
43
  rename Relational renaming (rename some attributes)
@@ -47,6 +50,7 @@ RELATIONAL OPERATORS
47
50
 
48
51
  EXPERIMENTAL RELATIONAL OPERATORS
49
52
 
53
+ hierarchize Relational hierarchy (recursive relation-trees)
50
54
  infer-heading Relational heading inference (print the relation type)
51
55
  quota Generalized quota-queries (position, sum progression, etc.)
52
56
 
@@ -65,7 +69,7 @@ OTHER NON-RELATIONAL COMMANDS
65
69
 
66
70
  exec Executes an .alf file on current database
67
71
  help Show help about a specific command
68
- show Output input tuples through a specific renderer (text, yaml, ...)
72
+ show Output input tuples through the default renderer in a specific order.
69
73
 
70
74
  See 'alf help COMMAND' for details about a specific command.
71
75
 
@@ -0,0 +1 @@
1
+ alf --text frame suppliers -- name -- 1 -- 2
@@ -0,0 +1,6 @@
1
+ +------+-------+---------+--------+
2
+ | :sid | :name | :status | :city |
3
+ +------+-------+---------+--------+
4
+ | S3 | Blake | 30 | Paris |
5
+ | S4 | Clark | 20 | London |
6
+ +------+-------+---------+--------+
@@ -1,25 +1,12 @@
1
1
 
2
- Output input tuples through a specific renderer (text, yaml, ...)
2
+ Output input tuples through the default renderer in a specific order.
3
3
 
4
4
  SYNOPSIS
5
5
 
6
6
  alf show NAME -- [ORDERING]
7
7
 
8
- OPTIONS
9
-
10
- --rash Render output as ruby hashes
11
- --text Render output as a text table
12
- --yaml Render output in YAML
13
- --json Render output in JSON
14
- --csv Render output in CSV
15
- --[no-]pretty Enable/disable pretty print best effort
16
- --ff=FORMAT Specify the floating point format
17
-
18
8
  DESCRIPTION
19
9
 
20
10
  When a name is specified as commandline arg, request the database to
21
11
  provide the corresponding relation variable and prints its value.
22
12
  Otherwise, take what comes on standard input.
23
-
24
- Note that this command is not an operator and should not be piped
25
- anymore.
@@ -0,0 +1 @@
1
+ alf --text page --page-size=2 suppliers -- name -- 1
@@ -0,0 +1,6 @@
1
+ +------+-------+---------+--------+
2
+ | :sid | :name | :status | :city |
3
+ +------+-------+---------+--------+
4
+ | S5 | Adams | 30 | Athens |
5
+ | S3 | Blake | 30 | Paris |
6
+ +------+-------+---------+--------+
@@ -1 +1 @@
1
- alf show --text suppliers -- city asc sid asc
1
+ alf --text show suppliers -- city asc sid asc
@@ -1 +1 @@
1
- alf show --text suppliers -- city asc status desc sid asc
1
+ alf --text show suppliers -- city asc status desc sid asc
@@ -1 +1 @@
1
- alf show --text parts --ff=%.6f
1
+ alf --text --ff=%.6f show parts
@@ -1 +1 @@
1
- alf show suppliers --rash
1
+ alf --rash show suppliers
@@ -1 +1 @@
1
- alf show suppliers --rash --pretty
1
+ alf --rash --pretty show suppliers
@@ -1 +1 @@
1
- alf show suppliers --yaml -- sid asc
1
+ alf --yaml show suppliers -- sid asc
@@ -10,8 +10,13 @@ end
10
10
 
11
11
  describe "Alf's alf command / " do
12
12
 
13
- Path.dir.glob('**/*.cmd').each do |input|
13
+ before do
14
+ Path.dir.chdir
15
+ end
16
+
17
+ Path.dir.glob('**/*.cmd').each_with_index do |input,index|
14
18
  cmd = wlang(input.readlines.first, binding)
19
+
15
20
  specify{ cmd.should =~ /^alf / }
16
21
 
17
22
  describe "#{input.basename}: #{cmd}" do
@@ -36,9 +41,7 @@ describe "Alf's alf command / " do
36
41
 
37
42
  specify{
38
43
  begin
39
- dir = Path.relative('__database__')
40
44
  main = Alf::Shell::Main.new
41
- main.database = Alf.connect(dir)
42
45
  main.run(argv, __FILE__)
43
46
  rescue => ex
44
47
  begin
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Shell
4
+ describe Alfrc, 'alfrc' do
5
+
6
+ let(:alfrc){ Alfrc.new{|c| c.load_paths = ["foo"] } }
7
+
8
+ context 'with a block' do
9
+ subject{ alfrc.alfrc{|c| @seen = c } }
10
+
11
+ it 'should return the instance itself' do
12
+ subject.should be(alfrc)
13
+ end
14
+
15
+ it 'should yield the block' do
16
+ subject
17
+ @seen.should be(alfrc)
18
+ end
19
+ end
20
+
21
+ context 'with a path' do
22
+ subject{ alfrc.alfrc(path) }
23
+
24
+ let(:path){ Path.backfind("spec/fixtures/example.alfrc") }
25
+
26
+ it 'should return the instance itself' do
27
+ subject.should be(alfrc)
28
+ end
29
+
30
+ it 'should resolve the load paths correctly' do
31
+ subject.load_paths.should eq([ "foo", path.parent/'lib' ])
32
+ end
33
+
34
+ it 'should set requires correctly' do
35
+ subject.requires.should eq([ 'alf-sequel' ])
36
+ end
37
+ end
38
+
39
+ context 'with a path and a block' do
40
+ subject{ alfrc.alfrc(path){|c| c.requires = ['bar'] } }
41
+
42
+ let(:path){ Path.backfind("spec/fixtures/example.alfrc") }
43
+
44
+ it 'should return the instance itself' do
45
+ subject.should be(alfrc)
46
+ end
47
+
48
+ it 'should resolve the load paths correctly' do
49
+ subject.load_paths.should eq([ "foo", path.parent/'lib' ])
50
+ end
51
+
52
+ it 'should yield the block after the path' do
53
+ subject.requires.should eq([ 'bar' ])
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -12,7 +12,7 @@ module Alf
12
12
  describe "on a static file" do
13
13
  before{
14
14
  def dm.find_file(cmd);
15
- File.expand_path('../static.md', __FILE__)
15
+ Path.dir/'static.md'
16
16
  end
17
17
  }
18
18
  it { should eq("Hello\n") }
@@ -21,21 +21,19 @@ module Alf
21
21
  describe "on a dynamic file" do
22
22
  before{
23
23
  def dm.find_file(cmd);
24
- File.expand_path('../dynamic.md', __FILE__)
24
+ Path.dir/'dynamic.md'
25
25
  end
26
26
  }
27
27
  it { should eq("show\n") }
28
28
  end
29
29
 
30
- unless RUBY_VERSION < "1.9"
31
- describe "on an example file" do
32
- before{
33
- def dm.find_file(cmd);
34
- File.expand_path('../example.md', __FILE__)
35
- end
36
- }
37
- it { should eq(File.read(File.expand_path('../example_1.txt', __FILE__))) }
38
- end
30
+ describe "on an example file" do
31
+ before{
32
+ def dm.find_file(cmd);
33
+ Path.dir/'example.md'
34
+ end
35
+ }
36
+ it { should eq((Path.dir/"example_1.txt").read) }
39
37
  end
40
38
 
41
39
  end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Shell
4
+ describe Main, "-I" do
5
+
6
+ before do
7
+ Path.dir.chdir
8
+ subject
9
+ end
10
+
11
+ let(:cmd){ Main.new }
12
+
13
+ subject{
14
+ cmd.parse_options(argv)
15
+ cmd
16
+ }
17
+
18
+ context 'when no explicitly set' do
19
+ let(:argv){ [] }
20
+
21
+ it 'should have defaults only' do
22
+ cmd.config.load_paths.should eq(["a_load_path"])
23
+ end
24
+ end
25
+
26
+ context 'when specified multiple times' do
27
+ let(:argv){ ["-Ilib", "-Ispec"] }
28
+
29
+ it 'should have defaults only' do
30
+ cmd.config.load_paths.should eq(["a_load_path", "lib", "spec"])
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Shell
4
+ describe Main, "-r" do
5
+
6
+ before do
7
+ Path.dir.chdir
8
+ subject
9
+ end
10
+
11
+ let(:cmd){ Main.new }
12
+
13
+ subject{
14
+ cmd.parse_options(argv)
15
+ cmd
16
+ }
17
+
18
+ context 'when no explicitly set' do
19
+ let(:argv){ [] }
20
+
21
+ it 'should have defaults only' do
22
+ cmd.config.requires.should eq(["a_require"])
23
+ end
24
+ end
25
+
26
+ context 'when specified multiple times' do
27
+ let(:argv){ ["-ralf-sequel", "-rpry"] }
28
+
29
+ it 'should have defaults only' do
30
+ cmd.config.requires.should eq(["a_require", "alf-sequel", "pry"])
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+ module Alf
3
+ module Shell
4
+ describe Main, "--text, --json and the like" do
5
+
6
+ before do
7
+ Path.dir.chdir
8
+ subject
9
+ end
10
+
11
+ let(:cmd){ Main.new }
12
+
13
+ subject{
14
+ cmd.parse_options(argv)
15
+ cmd
16
+ }
17
+
18
+ context 'when set to --json' do
19
+ let(:argv){ ["--json"] }
20
+
21
+ it 'should set the default renderer' do
22
+ cmd.config.default_renderer.should be(Alf::Renderer::JSON)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alf-shell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.14.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-29 00:00:00.000000000 Z
12
+ date: 2013-10-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirements:
67
67
  - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: 0.13.0
69
+ version: 0.14.0
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: 0.13.0
77
+ version: 0.14.0
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: quickl
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -116,13 +116,16 @@ files:
116
116
  - doc/operators/non_relational/sort.md
117
117
  - doc/operators/non_relational/type-safe.md
118
118
  - doc/operators/relational/extend.md
119
+ - doc/operators/relational/frame.md
119
120
  - doc/operators/relational/group.md
121
+ - doc/operators/relational/hierarchize.md
120
122
  - doc/operators/relational/infer-heading.md
121
123
  - doc/operators/relational/intersect.md
122
124
  - doc/operators/relational/join.md
123
125
  - doc/operators/relational/matching.md
124
126
  - doc/operators/relational/minus.md
125
127
  - doc/operators/relational/not-matching.md
128
+ - doc/operators/relational/page.md
126
129
  - doc/operators/relational/project.md
127
130
  - doc/operators/relational/quota.md
128
131
  - doc/operators/relational/rank.md
@@ -133,6 +136,7 @@ files:
133
136
  - doc/operators/relational/union.md
134
137
  - doc/operators/relational/unwrap.md
135
138
  - doc/operators/relational/wrap.md
139
+ - lib/alf/shell/alfrc.rb
136
140
  - lib/alf/shell/command/exec.rb
137
141
  - lib/alf/shell/command/help.rb
138
142
  - lib/alf/shell/command/main.rb
@@ -151,6 +155,7 @@ files:
151
155
  - Manifest.txt
152
156
  - Rakefile
153
157
  - README.md
158
+ - spec/fixtures/example.alfrc
154
159
  - spec/integration/__database__/group.alf
155
160
  - spec/integration/__database__/parts.rash
156
161
  - spec/integration/__database__/suppliers.rash
@@ -192,6 +197,8 @@ files:
192
197
  - spec/integration/defaults/defaults_2.stdout
193
198
  - spec/integration/extend/extend_0.cmd
194
199
  - spec/integration/extend/extend_0.stdout
200
+ - spec/integration/frame/frame_0.cmd
201
+ - spec/integration/frame/frame_0.stdout
195
202
  - spec/integration/generator/generator_1.cmd
196
203
  - spec/integration/generator/generator_1.stdout
197
204
  - spec/integration/generator/generator_2.cmd
@@ -214,6 +221,8 @@ files:
214
221
  - spec/integration/minus/minus_0.stdout
215
222
  - spec/integration/not-matching/not-matching_0.cmd
216
223
  - spec/integration/not-matching/not-matching_0.stdout
224
+ - spec/integration/page/page_0.cmd
225
+ - spec/integration/page/page_0.stdout
217
226
  - spec/integration/project/project_0.cmd
218
227
  - spec/integration/project/project_0.stdout
219
228
  - spec/integration/project/project_1.cmd
@@ -242,8 +251,6 @@ files:
242
251
  - spec/integration/show/show_base_sort_1.stdout
243
252
  - spec/integration/show/show_base_sort_2.cmd
244
253
  - spec/integration/show/show_base_sort_2.stdout
245
- - spec/integration/show/show_conflictual.cmd
246
- - spec/integration/show/show_conflictual.stdout
247
254
  - spec/integration/show/show_ff.cmd
248
255
  - spec/integration/show/show_ff.stdout
249
256
  - spec/integration/show/show_rash.cmd
@@ -271,6 +278,7 @@ files:
271
278
  - spec/integration/wrap/wrap_0.stdout
272
279
  - spec/spec_helper.rb
273
280
  - spec/test_shell.rb
281
+ - spec/unit/alfrc/test_alfrc.rb
274
282
  - spec/unit/doc_manager/dynamic.md
275
283
  - spec/unit/doc_manager/example.md
276
284
  - spec/unit/doc_manager/example_1.txt
@@ -290,6 +298,9 @@ files:
290
298
  - spec/unit/from_argv/test_to_tuple_computation.rb
291
299
  - spec/unit/from_argv/test_to_tuple_expression.rb
292
300
  - spec/unit/main/test_class_methods.rb
301
+ - spec/unit/main/test_I_option.rb
302
+ - spec/unit/main/test_r_option.rb
303
+ - spec/unit/main/test_renderer_option.rb
293
304
  - spec/unit/operator/test_autonum.rb
294
305
  - spec/unit/operator/test_clip.rb
295
306
  - spec/unit/operator/test_coerce.rb
@@ -331,7 +342,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
331
342
  version: '0'
332
343
  segments:
333
344
  - 0
334
- hash: 1359397490184999599
345
+ hash: 1654527447503089080
335
346
  required_rubygems_version: !ruby/object:Gem::Requirement
336
347
  none: false
337
348
  requirements:
@@ -1 +0,0 @@
1
- alf --yaml show suppliers --rash
@@ -1,5 +0,0 @@
1
- {:sid => "S1", :name => "Smith", :status => 20, :city => "London"}
2
- {:sid => "S2", :name => "Jones", :status => 10, :city => "Paris"}
3
- {:sid => "S3", :name => "Blake", :status => 30, :city => "Paris"}
4
- {:sid => "S4", :name => "Clark", :status => 20, :city => "London"}
5
- {:sid => "S5", :name => "Adams", :status => 30, :city => "Athens"}