rube 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,9 @@
1
+ == 0.1.0 2009-07-18
2
+
3
+ * First public release
4
+ * Testing, extensions
5
+
6
+ == 0.0.1 2009-07-09
7
+
8
+ * 1 major enhancement:
9
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,15 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ VERSION
7
+ lib/rube
8
+ lib/rube.rb
9
+ script/console
10
+ script/destroy
11
+ script/generate
12
+ templates/test1
13
+ templates/test2
14
+ test/test_helper.rb
15
+ test/test_rube.rb
data/PostInstall.txt ADDED
@@ -0,0 +1,2 @@
1
+
2
+ For more information on rube, see http://rube.rubyforge.org
data/README.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ = rube
2
+
3
+ * http://github.com/rleber/rube
4
+
5
+ == DESCRIPTION:
6
+
7
+ Rube -- Slightly smarter erb front-end
8
+
9
+ Rube allows you to apply erb to templates, interspersed with other ruby code, either as inline source or
10
+ as ruby files (e.g. requires). Rube can be invoked from the command line as a command in the form:
11
+
12
+ rube [options] task ...
13
+
14
+ == FEATURES/PROBLEMS:
15
+
16
+ * Can be invoked from command line or via the Ruby API from within a Ruby script
17
+ * Can process inline ruby code, ruby libraries, and erb templates
18
+ * Information is persistent across tasks: e.g. subsequent templates can refer to results of previous tasks
19
+
20
+ == SYNOPSIS:
21
+
22
+ Rube can be invoked from the command line as a command in the form:
23
+
24
+ rube [options] task ...
25
+
26
+ or as part of a ruby script, as in:
27
+
28
+ require 'rube'
29
+ rube = Rube.new
30
+ rube.add_task(:require, 'active_record')
31
+ rube.add_task(:template, 'foo')
32
+ rube.generate
33
+
34
+ In either case, tasks may be erb templates, ruby files, or inline ruby code. Each of the tasks is
35
+ performed in the order specified and variables, constants etc. are preserved across tasks (including
36
+ local variables) so that subsequent tasks can refer to the the results of earlier tasks. This makes it
37
+ simpler to use erb templates against arbitrary data. For instance:
38
+
39
+ rube -r active_support -r yaml -e "document=YAML.load(IO.read('document.yml))" --trim 2 --stdin convert_to_textile.erb
40
+
41
+ would process the template on stdin followed by the template in convert_to_textile.erb, having already
42
+ loaded the active_support and yaml libraries, and having loaded the YAML file document.yml and parsed it
43
+ into a Ruby variable named document, where the information could easily be referred to in the template.
44
+ This all would be done at erb trim level 2.
45
+
46
+ See rdoc or source for more information, or type the command:
47
+
48
+ rube --help
49
+
50
+ == REQUIREMENTS:
51
+
52
+ * None
53
+
54
+ == INSTALL:
55
+
56
+ * sudo gem install rube
57
+
58
+ == LICENSE:
59
+
60
+ (The MIT License)
61
+
62
+ Copyright (c) 2009 Richard LeBer
63
+
64
+ Permission is hereby granted, free of charge, to any person obtaining
65
+ a copy of this software and associated documentation files (the
66
+ 'Software'), to deal in the Software without restriction, including
67
+ without limitation the rights to use, copy, modify, merge, publish,
68
+ distribute, sublicense, and/or sell copies of the Software, and to
69
+ permit persons to whom the Software is furnished to do so, subject to
70
+ the following conditions:
71
+
72
+ The above copyright notice and this permission notice shall be
73
+ included in all copies or substantial portions of the Software.
74
+
75
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
76
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
77
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
78
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
79
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
80
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
81
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
2
+ %w[rake rake/clean fileutils newgem rubigen].each { |f| require f }
3
+ require File.dirname(__FILE__) + '/lib/rube'
4
+
5
+ # Generate all the Rake tasks
6
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
7
+ $hoe = Hoe.new('rube', Rube::VERSION) do |p|
8
+ p.developer('Richard LeBer', 'rleber@mindspring.com')
9
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
11
+ p.rubyforge_name = p.name # TODO this is default value
12
+ # p.extra_deps = [
13
+ # ['activesupport','>= 2.0.2'],
14
+ # ]
15
+ p.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ]
18
+
19
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
+ p.rsync_args = '-av --delete --ignore-errors'
23
+ end
24
+
25
+ require 'newgem/tasks' # load /tasks/*.rake
26
+ Dir['tasks/**/*.rake'].each { |t| load t }
27
+
28
+ # TODO - want other tests/tasks run by default? Add them to the list
29
+ # task :default => [:spec, :features]
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/rube.rb ADDED
@@ -0,0 +1,278 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Rube --
4
+ # Slightly smarter erb front-end
5
+ #
6
+ # Rube allows you to apply erb to templates, interspersed with other ruby code, either as inline source or as
7
+ # ruby files (e.g. requires). Rube can be invoked from the command line as a command in the form:
8
+ #
9
+ # rube [options] task ...
10
+
11
+ # or as part of a ruby script, as in:
12
+ #
13
+ # require 'rube'
14
+ # rube = Rube.new
15
+ # rube.add_task(:require, 'active_record')
16
+ # rube.add_task(:template, 'foo')
17
+ # rube.generate
18
+ #
19
+ # In either case, tasks may be erb templates, ruby files, or inline ruby code. Each of the tasks is performed in
20
+ # the order specified and variables, constants etc. are preserved across tasks (including local variables) so that
21
+ # subsequent tasks can refer to the the results of earlier tasks. This makes it simpler to use erb templates against
22
+ # arbitrary data. For instance:
23
+ #
24
+ # rube -r active_support -r yaml -e "document=YAML.load(IO.read('document.yml))" --trim 2 --stdin convert_to_textile.erb
25
+ #
26
+ # would process the template on stdin followed by the template in convert_to_textile.erb, having already loaded the
27
+ # active_support and yaml libraries, and having loaded the YAML file document.yml and parsed it into a Ruby variable named
28
+ # document, where the information could easily be referred to in the template. This all would be done at erb trim level 2.
29
+ #
30
+ # The equivalent code for the above, when invoked from within a Ruby script, would be:
31
+ #
32
+ # require 'rube'
33
+ # rube = Rube.new
34
+ # rube.trim_level = 2
35
+ # rube.add_task(:require, 'active_support')
36
+ # rube.add_task(:require, 'yaml')
37
+ # rube.add_task(:eval, "document=YAML.load(IO.read('document.yml))" )
38
+ # rube.add_task(:template, 'dev/stdin') # Note, there is no direct equivalent to the --stdin parameter
39
+ # rube.add_task(:template, 'convert_to_textile.erb')
40
+ # rube.generate
41
+ #
42
+ # If invoked from the command line AND if no template file is specified among the tasks, rube assumes it should read a
43
+ # template from stdin, after processing all other tasks. This behavior can be turned off using the --explicit option.
44
+ #
45
+ # In addition to the above, rube allows similar parameters to erb for setting $SAFE, $DEBUG and trim levels. Type
46
+ #
47
+ # rube --help
48
+ #
49
+ # at the command line for more information.
50
+ #
51
+ # For convenience, the Ruby API allows two additional methods which override the default setting for output,
52
+ # which is to $stdout:
53
+ # rube.to_string = true Causes rube.generate to output results to a string
54
+ # rube.to_file "name" Causes rube.generate to output results to the named file
55
+
56
+ require 'optparse'
57
+ require 'erb'
58
+
59
+ class Rube
60
+ VERSION = %x{cat #{File.dirname(__FILE__)+'/../VERSION'}}.chomp
61
+
62
+ # Class and procedure to provide context for evaluation of tasks: ruby inline code, requires, and erb templates
63
+ class EvalContext
64
+ # All tasks are executed in the sandbox
65
+ def sandbox
66
+ return binding
67
+ end
68
+ end
69
+
70
+ class HelpRequested < ArgumentError
71
+ def self.exit_code
72
+ 1
73
+ end
74
+ end
75
+
76
+ class BadArgumentError < ArgumentError
77
+ def self.exit_code
78
+ 2
79
+ end
80
+ end
81
+
82
+ class MissingRequireError < IOError
83
+ def self.exit_code
84
+ 3
85
+ end
86
+ end
87
+
88
+ class MissingTemplateError < IOError
89
+ def self.exit_code
90
+ 4
91
+ end
92
+ end
93
+
94
+ class ScriptError < IOError
95
+ def self.exit_code
96
+ 5
97
+ end
98
+ end
99
+
100
+ attr_accessor :tasks, :safety, :from_command_line, :to_string, :to_file
101
+ attr_reader :trim_level, :trim_mode, :disable_percent
102
+
103
+ def initialize
104
+ @tasks = []
105
+ @trim_level = nil
106
+ self.disable_percent = false
107
+ self.trim_level = nil
108
+ @from_command_line = nil
109
+ @to_string = false
110
+ @to_file = nil
111
+ @safety = nil
112
+ @explicit = false
113
+ end
114
+
115
+ # Process command line options
116
+ def process_options(*args)
117
+ @tasks = []
118
+ template_count = 0
119
+ tr_level = nil
120
+ @op = OptionParser.new
121
+ @op.banner = "Process erb templates along with other ruby tasks"
122
+ @op.separator "Usage: #{File.basename($0)} [options] task ..."
123
+ @op.separator ''
124
+ @op.separator "Each task may be a template, require or eval (see below). These are processed in the order given,"
125
+ @op.separator "so results from prior tasks are available to subsequent ones. All variables and constants, including"
126
+ @op.separator "local variables, are preserved, so their values are available to subsequent tasks."
127
+ @op.separator ''
128
+ @op.separator "Tasks:"
129
+ @op.separator " path/to/template/file Process the specified erb template file"
130
+ @op.on('-i', '--stdin', "Process the template provided in stdin") do |val|
131
+ template_count += 1
132
+ @tasks << [:template, '/dev/stdin']
133
+ end
134
+ @op.on('-r', '--require path/to/ruby/file', "Load a ruby library or source code file") {|val| @tasks << [:require, val] }
135
+ @op.on('-e', '--eval "ruby code"', "Evaluate some inline ruby code"){|src| @tasks << [:eval, src] }
136
+ @op.separator ''
137
+ @op.separator "Options:"
138
+ @op.on('-E', '--[no-]explicit', "All templates must be explicitly provided. Default is false -- rube assumes it should read",
139
+ "a template from stdin if no templates are specified among the tasks") {|val| @explicit = val }
140
+ @op.on('-S', '--safe SAFE_LEVEL', Integer, "Set $SAFE (0..4). Default off") do |val|
141
+ error BadArgumentError, "Invalid --safe level #{val}. Should be 0..4" unless (0..4).include?(val)
142
+ @safety = val
143
+ end
144
+ @op.on('-T', '--trim TRIM_LEVEL', "Set trim level (0..2, or '-'). Default 0") {|trim| tr_level = trim }
145
+ @op.on('-P', '--[no-]disable-percent', "Disable '%' prefix for erb code. Default false") {|val| self.disable_percent = val }
146
+ @op.on_tail('-h', '--help', "Produce this help list") {|val| help }
147
+ @op.on_tail('-v', '--version', "Show version") {|val| puts VERSION; exit 0 }
148
+ begin
149
+ @templates = @op.order!(args) do |template|
150
+ template_count += 1
151
+ @tasks << [:template, template]
152
+ end
153
+ rescue OptionParser::InvalidOption, OptionParser::InvalidArgument => e
154
+ $stderr.puts e.to_s
155
+ help BadArgumentError
156
+ end
157
+ @tasks << [:template, '/dev/stdin'] if !@explicit && template_count == 0
158
+ self.trim_level = tr_level
159
+ end
160
+
161
+ def disable_percent=(disable_percent)
162
+ @disable_percent = disable_percent
163
+ @trim_mode = trim_mode_opt(@trim_level)
164
+ end
165
+
166
+ def trim_level=(trim_level)
167
+ @trim_level = (trim_level || '0').to_s
168
+ @trim_mode = trim_mode_opt(@trim_level)
169
+ end
170
+
171
+ # Convert command line trim_mode to a form erb will understand
172
+ def trim_mode_opt(trim_mode)
173
+ mode = disable_percent ? '' : '%'
174
+ mode += case trim_mode.to_s
175
+ when '0','' then ''
176
+ when '1' then '>'
177
+ when '2' then '<>'
178
+ when '-' then '-'
179
+ else error BadArgumentError, "Invalid trim mode #{trim_mode}. Should be 0, 1, 2, or -"
180
+ end
181
+ end
182
+
183
+ # Display command line help
184
+ def help(exception=HelpRequested)
185
+ error exception, @op.to_s
186
+ end
187
+
188
+ # Add a task
189
+ def add_task(type, task)
190
+ case type
191
+ when :require, :eval, :template then @tasks << [type, task]
192
+ else raise "Invalid task type #{type.inspect}"
193
+ end
194
+ self # Allow chaining
195
+ end
196
+
197
+ # Run all the tasks
198
+ def generate
199
+ @eval_context = EvalContext.new
200
+ @binding = @eval_context.sandbox
201
+ saved_stdout = $stdout
202
+ if @to_string
203
+ $stdout = StringIO.new
204
+ elsif @to_file
205
+ $stdout = File.new @to_file, 'w'
206
+ end
207
+ @tasks.each {|p| execute p }
208
+ res = nil
209
+ if @to_string
210
+ res = $stdout.string
211
+ elsif @to_file
212
+ $stdout.close
213
+ end
214
+ res
215
+ ensure
216
+ $stdout = saved_stdout
217
+ end
218
+
219
+ # Execute a single task
220
+ def execute(p)
221
+ case p.first
222
+ when :require
223
+ protected_require(p.last)
224
+ when :eval
225
+ protected_eval(p.last)
226
+ when :template
227
+ protected_erb(p.last)
228
+ else
229
+ raise "Unexpected task #{p.inspect}"
230
+ end
231
+ end
232
+
233
+ # Load a ruby file or library
234
+ def protected_require(r)
235
+ @eval_context.instance_eval {require r}
236
+ rescue LoadError
237
+ error MissingRequireError, "Can't find require file #{r}"
238
+ end
239
+
240
+ # Evaluate inline ruby code
241
+ def protected_eval(src)
242
+ bind_at = @binding
243
+ @eval_context.instance_eval{eval src, bind_at}
244
+ rescue => e
245
+ error ScriptError, "Error executing source:\n#{src}\n\n#{e.to_s}"
246
+ end
247
+
248
+ # Process an erb template
249
+ def protected_erb(template)
250
+ error MissingTemplateError, "Can't find template file #{template}" unless File.exists?(template)
251
+ source = File.read(template)
252
+ puts ERB.new(source, @safety, @trim_mode).result(@binding)
253
+ end
254
+
255
+ # Issue an error message or exception
256
+ def error(exception, msg)
257
+ raise exception, msg unless @from_command_line || exception.nil?
258
+ $stderr.puts msg
259
+ exit_code = exception.exit_code rescue 0
260
+ exit exit_code if @from_command_line
261
+ end
262
+
263
+ # Convenience method: create a Rube object and use it to execute command line-style arguments
264
+ def self.generate(*args)
265
+ rube = new
266
+ options = {}
267
+ if args.last.is_a?(Hash)
268
+ options = args.pop
269
+ end
270
+ rube.from_command_line = options[:from_command_line]
271
+ rube.process_options(*args)
272
+ rube.generate
273
+ end
274
+ end
275
+
276
+ if $0 == __FILE__
277
+ Rube.generate(*(ARGV << {:from_command_line=>true}))
278
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/rube.rb'}"
9
+ puts "Loading rube gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/templates/test1 ADDED
@@ -0,0 +1,8 @@
1
+ foo
2
+ <%= 'blurg' %>
3
+ <%= 'blurble'
4
+ %>
5
+ <% z = 'barf' %>
6
+ % z = 'farb'
7
+ <%= z %>
8
+
data/templates/test2 ADDED
@@ -0,0 +1,2 @@
1
+ bar
2
+ <%= b %>*2
@@ -0,0 +1,4 @@
1
+ require 'stringio'
2
+ require 'tempfile'
3
+ require 'test/unit'
4
+ require File.dirname(__FILE__) + '/../lib/rube'
data/test/test_rube.rb ADDED
@@ -0,0 +1,545 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestRubeBasic < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @new_rube = Rube.new
7
+ end
8
+
9
+ def test_truth
10
+ assert true
11
+ end
12
+
13
+ def test_creates_rube_object
14
+ assert_instance_of Rube, @new_rube, "Rube.new does not create Rube object"
15
+ end
16
+
17
+ def test_rube_object_has_tasks
18
+ assert_respond_to @new_rube, :tasks
19
+ end
20
+
21
+ def test_rube_object_has_tasks=
22
+ assert_respond_to @new_rube, :tasks=
23
+ end
24
+
25
+ def test_rube_object_tasks_is_an_array
26
+ assert_kind_of Array, @new_rube.tasks
27
+ end
28
+
29
+ def test_rube_object_has_add_task
30
+ assert_respond_to @new_rube, :add_task
31
+ end
32
+
33
+ def test_rube_object_disable_percent
34
+ assert_respond_to @new_rube, :disable_percent
35
+ end
36
+
37
+ def test_rube_object_disable_percent=
38
+ assert_respond_to @new_rube, :disable_percent=
39
+ end
40
+
41
+ def test_rube_object_safety
42
+ assert_respond_to @new_rube, :safety
43
+ end
44
+
45
+ def test_rube_object_safety=
46
+ assert_respond_to @new_rube, :safety=
47
+ end
48
+
49
+ def test_rube_object_from_command_line
50
+ assert_respond_to @new_rube, :from_command_line
51
+ end
52
+
53
+ def test_rube_object_from_command_line=
54
+ assert_respond_to @new_rube, :from_command_line=
55
+ end
56
+
57
+ def test_rube_object_trim_level
58
+ assert_respond_to @new_rube, :trim_level
59
+ end
60
+
61
+ def test_rube_object_trim_level=
62
+ assert_respond_to @new_rube, :trim_level=
63
+ end
64
+
65
+ def test_rube_object_trim_mode
66
+ assert_respond_to @new_rube, :trim_mode
67
+ end
68
+
69
+ def test_rube_object_to_string
70
+ assert_respond_to @new_rube, :to_string
71
+ end
72
+
73
+ def test_rube_object_to_file
74
+ assert_respond_to @new_rube, :to_file
75
+ end
76
+
77
+ def test_rube_object_go
78
+ assert_respond_to @new_rube, :generate
79
+ end
80
+
81
+ def test_rube_class_go
82
+ assert_respond_to Rube, :generate
83
+ end
84
+ end
85
+
86
+ class TestRubeTaskManipulation < Test::Unit::TestCase
87
+
88
+ def setup
89
+ @empty_rube = Rube.new
90
+ end
91
+
92
+ def test_empty_rube_object_has_no_tasks
93
+ assert_equal @empty_rube.tasks.size, 0
94
+ end
95
+
96
+ def test_rube_object_adds_eval_task
97
+ @empty_rube.add_task :eval, 'bar'
98
+ assert_equal @empty_rube.tasks.size, 1, "Rube add_task did not add eval task"
99
+ end
100
+
101
+ def test_rube_object_adds_require_task
102
+ @empty_rube.add_task :require, 'bar'
103
+ assert_equal @empty_rube.tasks.size, 1, "Rube add_task did not add require task"
104
+ end
105
+
106
+ def test_rube_object_adds_template_task
107
+ @empty_rube.add_task :template, 'bar'
108
+ assert_equal @empty_rube.tasks.size, 1, "Rube add_task did not add template task"
109
+ end
110
+
111
+ def test_rube_object_checks_task_type
112
+ assert_raises(RuntimeError) { @empty_rube.add_task :foo, 'bar' }
113
+ end
114
+
115
+ def test_rube_object_adds_eval_task_correctly
116
+ @empty_rube.add_task :eval, 'bar'
117
+ assert_equal @empty_rube.tasks.last, [:eval, 'bar']
118
+ end
119
+
120
+ def test_rube_object_adds_multiple_tasks
121
+ @empty_rube.add_task :require, 'foo'
122
+ @empty_rube.add_task :eval, 'bar'
123
+ assert_equal @empty_rube.tasks.size, 2
124
+ assert_kind_of Array, @empty_rube.tasks.first
125
+ assert_equal @empty_rube.tasks.first.size, 2
126
+ assert_equal @empty_rube.tasks.first.first, :require
127
+ assert_equal @empty_rube.tasks.first.last, 'foo'
128
+ assert_kind_of Array, @empty_rube.tasks.last
129
+ assert_equal @empty_rube.tasks.first.size, 2
130
+ assert_equal @empty_rube.tasks.last.first, :eval
131
+ assert_equal @empty_rube.tasks.last.last, 'bar'
132
+ end
133
+
134
+ def test_rube_object_task_assignment_works
135
+ @empty_rube.tasks= [[:eval, 'foo'],[:require, 'bar'],[:template, 'baz']]
136
+ assert_equal @empty_rube.tasks.size, 3
137
+ assert_equal @empty_rube.tasks.first, [:eval, 'foo']
138
+ assert_equal @empty_rube.tasks[1], [:require, 'bar']
139
+ assert_equal @empty_rube.tasks.last, [:template, 'baz']
140
+ end
141
+ end
142
+
143
+ class TestRubeSettings < Test::Unit::TestCase
144
+
145
+ def setup
146
+ @empty_rube = Rube.new
147
+ end
148
+
149
+ def test_rube_default_disable_percent
150
+ assert_equal false, !!@empty_rube.disable_percent
151
+ end
152
+
153
+ def test_rube_object_preserves_disable_percent
154
+ @empty_rube.disable_percent = true
155
+ assert_equal true, @empty_rube.disable_percent
156
+ end
157
+
158
+ def test_rube_default_safety
159
+ assert_equal nil, @empty_rube.safety
160
+ end
161
+
162
+ def test_rube_object_preserves_safety
163
+ @empty_rube.safety = 'foo'
164
+ assert_equal 'foo', @empty_rube.safety
165
+ end
166
+
167
+ def test_rube_default_from_command_line
168
+ assert_equal false, !!@empty_rube.from_command_line
169
+ end
170
+
171
+ def test_rube_object_preserves_from_command_line
172
+ @empty_rube.from_command_line = 'foo'
173
+ assert_equal 'foo', @empty_rube.from_command_line
174
+ end
175
+
176
+ def test_rube_default_to_string
177
+ assert_equal false, !!@empty_rube.to_string
178
+ end
179
+
180
+ def test_rube_object_preserves_to_string
181
+ @empty_rube.to_string = 'foo'
182
+ assert_equal 'foo', @empty_rube.to_string
183
+ end
184
+
185
+ def test_rube_default_to_file
186
+ assert_equal nil, @empty_rube.to_file
187
+ end
188
+
189
+ def test_rube_object_preserves_to_file
190
+ @empty_rube.to_file = 'foo'
191
+ assert_equal 'foo', @empty_rube.to_file
192
+ end
193
+ end
194
+
195
+ class TestRubeTrimLevel < Test::Unit::TestCase
196
+
197
+ def setup
198
+ @empty_rube = Rube.new
199
+ @disabled_rube = Rube.new
200
+ @disabled_rube.disable_percent = true
201
+ end
202
+
203
+ def test_rube_default_trim_level
204
+ assert_equal '0', @empty_rube.trim_level
205
+ end
206
+
207
+ def test_rube_default_trim_mode
208
+ assert_equal '%', @empty_rube.trim_mode
209
+ end
210
+
211
+ def test_rube_default_trim_mode_with_disabled_percent
212
+ assert_equal '', @disabled_rube.trim_mode
213
+ end
214
+
215
+ def test_rube_object_accepts_trim_level_0
216
+ @empty_rube.trim_level = '0'
217
+ assert_equal '0', @empty_rube.trim_level
218
+ assert_equal '%', @empty_rube.trim_mode
219
+ end
220
+
221
+ def test_rube_object_accepts_trim_level_1
222
+ @empty_rube.trim_level = '1'
223
+ assert_equal '1', @empty_rube.trim_level
224
+ assert_equal '%>', @empty_rube.trim_mode
225
+ end
226
+
227
+ def test_rube_object_accepts_trim_level_2
228
+ @empty_rube.trim_level = '2'
229
+ assert_equal '2', @empty_rube.trim_level
230
+ assert_equal '%<>', @empty_rube.trim_mode
231
+ end
232
+
233
+ def test_rube_object_accepts_trim_level_numeric_1
234
+ @empty_rube.trim_level = 1
235
+ assert_equal '1', @empty_rube.trim_level
236
+ assert_equal '%>', @empty_rube.trim_mode
237
+ end
238
+
239
+ def test_rube_object_rejects_invalid_trim_level
240
+ assert_raises(Rube::BadArgumentError) { @empty_rube.trim_level = 'foo' }
241
+ end
242
+
243
+ def test_rube_object_accepts_trim_level_dash
244
+ @empty_rube.trim_level = '-'
245
+ assert_equal '-', @empty_rube.trim_level
246
+ assert_equal '%-', @empty_rube.trim_mode
247
+ end
248
+
249
+ def test_rube_object_accepts_trim_level_0_with_disabled_percent
250
+ @disabled_rube.trim_level = '0'
251
+ assert_equal '0', @disabled_rube.trim_level
252
+ assert_equal '', @disabled_rube.trim_mode
253
+ end
254
+
255
+ def test_rube_object_accepts_trim_level_1_with_disabled_percent
256
+ @disabled_rube.trim_level = '1'
257
+ assert_equal '1', @disabled_rube.trim_level
258
+ assert_equal '>', @disabled_rube.trim_mode
259
+ end
260
+
261
+ def test_rube_object_accepts_trim_level_2_with_disabled_percent
262
+ @disabled_rube.trim_level = '2'
263
+ assert_equal '2', @disabled_rube.trim_level
264
+ assert_equal '<>', @disabled_rube.trim_mode
265
+ end
266
+
267
+ def test_rube_object_accepts_trim_level_dash_with_disabled_percent
268
+ @disabled_rube.trim_level = '-'
269
+ assert_equal '-', @disabled_rube.trim_level
270
+ assert_equal '-', @disabled_rube.trim_mode
271
+ end
272
+ end
273
+
274
+ class TestRubeProcessing < Test::Unit::TestCase
275
+
276
+ def setup
277
+ @rube = Rube.new
278
+ @save_stdout = $stdout
279
+ end
280
+
281
+ def teardown
282
+ $stdout = @save_stdout
283
+ end
284
+
285
+ def test_simple_eval_to_stdout
286
+ StringIO.open do |out|
287
+ $stdout = out
288
+ @rube.add_task :eval, 'puts "foo"'
289
+ res = @rube.generate
290
+ assert_equal "foo\n", out.string, "Failed to produce expected output on $stdout"
291
+ assert_equal nil, res, "Without redirection, rube.generate should return nil"
292
+ end
293
+ end
294
+
295
+ def test_simple_eval_to_string
296
+ @rube.to_string = true
297
+ @rube.add_task :eval, 'puts "foo"'
298
+ out = @rube.generate
299
+ assert_equal "foo\n", out, "Failed to output to string"
300
+ end
301
+
302
+ def test_simple_eval_to_file
303
+ out = Tempfile.new('testout')
304
+ @rube.to_file = out.path
305
+ @rube.add_task :eval, 'puts "foo"'
306
+ res = @rube.generate
307
+ out.close
308
+ output = File.read(out.path)
309
+ assert_equal "foo\n", output, "Failed to produce expected output on file #{out.path}"
310
+ assert_equal nil, res, "Without redirection, rube.generate should return nil"
311
+ end
312
+
313
+ def test_process_require_task
314
+ StringIO.open do |out|
315
+ $stdout = out
316
+ @rube.add_task :require, 'English'
317
+ @rube.add_task :eval, 'puts $PID'
318
+ @rube.generate
319
+ # If English doesn't load properly, then $PID is nil; if it does, then it's a numeric process id
320
+ assert_match(/^\d+$/, out.string.chomp, "Failed to load require file")
321
+ end
322
+ end
323
+
324
+ def test_process_template_task
325
+ @rube.to_string = true
326
+ @rube.add_task :template, 'templates/test1'
327
+ out = @rube.generate
328
+ assert_equal "foo\nblurg\nblurble\n\nfarb\n\n", out, "Failed to produce expected result from test1 template"
329
+ end
330
+
331
+ def test_process_template_task_with_disabled_percent
332
+ @rube.to_string = true
333
+ @rube.disable_percent = true
334
+ @rube.add_task :template, 'templates/test1'
335
+ out = @rube.generate
336
+ # Note: test1 template produces different results with % lines disabled
337
+ assert_equal "foo\nblurg\nblurble\n\n% z = 'farb'\nbarf\n\n", out, "Failed to produce expected result from test1 template with percentage lines disabled"
338
+ end
339
+
340
+ def test_process_template_task_with_trim_level_1
341
+ @rube.to_string = true
342
+ @rube.trim_level = 1
343
+ @rube.add_task :template, 'templates/test1'
344
+ out = @rube.generate
345
+ assert_equal "foo\nblurgblurblefarb\n", out, "Failed to produce expected result from test1 template"
346
+ end
347
+
348
+ def test_process_template_task_with_trim_level_2
349
+ @rube.to_string = true
350
+ @rube.trim_level = 2
351
+ @rube.add_task :template, 'templates/test1'
352
+ out = @rube.generate
353
+ assert_equal "foo\nblurgblurble\nfarb\n", out, "Failed to produce expected result from test1 template"
354
+ end
355
+
356
+ def test_process_template_with_persistent_variable
357
+ @rube.to_string = true
358
+ @rube.add_task :eval, 'b="foo"'
359
+ @rube.add_task :template, 'templates/test2'
360
+ out = @rube.generate
361
+ assert_equal "bar\nfoo*2\n", out, "Failed to produce expected result from test2 template with passed variable value"
362
+ end
363
+ end
364
+
365
+ class TestRubeErrors < Test::Unit::TestCase
366
+ def setup
367
+ @rube = Rube.new
368
+ end
369
+
370
+ def test_bad_eval
371
+ @rube.to_string = true
372
+ @rube.add_task :eval, 'foo'
373
+ assert_raises(Rube::ScriptError) { @rube.generate }
374
+ end
375
+
376
+ def test_bad_require
377
+ @rube.to_string = true
378
+ @rube.add_task :require, 'foo'
379
+ assert_raises(Rube::MissingRequireError) { @rube.generate }
380
+ end
381
+
382
+ def test_bad_template
383
+ @rube.to_string = true
384
+ @rube.add_task :template, 'foo'
385
+ assert_raises(Rube::MissingTemplateError) { @rube.generate }
386
+ end
387
+ end
388
+
389
+ class TestRubeCommandLineHelp < Test::Unit::TestCase
390
+ HELP_PATTERN = /erb templates.*Usage:/m
391
+ def test_help
392
+ res = `rube --help 2>&1`
393
+ assert_match HELP_PATTERN, res, "Failed to produce help text for --help"
394
+ assert_equal 1, $?.exitstatus, "Expected return code of 1 for help text"
395
+ end
396
+
397
+ BAD_PATTERN = /invalid option.*foo.*erb templates.*Usage:/m
398
+ def test_bad_argument
399
+ res = `rube --foo 2>&1`
400
+ assert_match BAD_PATTERN, res, "Failed to produce error message and help text for --foo"
401
+ assert_equal 2, $?.exitstatus, "Expected return code of 2 for bad argument"
402
+ end
403
+
404
+ REQUIRE_ERROR_PATTERN = /Can't find require file/
405
+ def test_bad_require
406
+ res = `rube -E -r 'foo' 2>&1`
407
+ assert_match REQUIRE_ERROR_PATTERN, res, "Failed to produce error message for bad require file"
408
+ assert_equal 3, $?.exitstatus, "Expected return code of 3 for bad require file"
409
+ end
410
+
411
+ TEMPLATE_ERROR_PATTERN = /Can't find template file/
412
+ def test_bad_template
413
+ res = `rube -E foo 2>&1`
414
+ assert_match TEMPLATE_ERROR_PATTERN, res, "Failed to produce error message for bad template file"
415
+ assert_equal 4, $?.exitstatus, "Expected return code of 4 for bad template file"
416
+ end
417
+
418
+ SOURCE_ERROR_PATTERN = /Error executing source/
419
+ def test_bad_eval
420
+ res = `rube -E -e 'foo' 2>&1`
421
+ assert_match SOURCE_ERROR_PATTERN, res, "Failed to produce error message for bad eval source"
422
+ assert_equal 5, $?.exitstatus, "Expected return code of 5 for bad eval source"
423
+ end
424
+ end
425
+
426
+ class TestRubeCommandLineIndirectly < Test::Unit::TestCase
427
+ #
428
+ # Not really an exhaustive test, but if this works, things should be okay
429
+ #
430
+
431
+ def setup
432
+ @rube = Rube.new
433
+ @save_stdout = $stdout
434
+ end
435
+
436
+ def teardown
437
+ $stdout = @save_stdout
438
+ end
439
+
440
+ def test_eval
441
+ StringIO.open do |out|
442
+ $stdout = out
443
+ @rube.process_options('-E', '-e', 'puts "foo"')
444
+ res = @rube.generate
445
+ assert_equal "foo\n", out.string, "Failed to produce expected output on $stdout"
446
+ end
447
+ end
448
+
449
+ def test_process_require_task
450
+ StringIO.open do |out|
451
+ $stdout = out
452
+ @rube.process_options('-E', '-r', 'English', '-e', 'puts $PID')
453
+ @rube.generate
454
+ # If English doesn't load properly, then $PID is nil; if it does, then it's a numeric process id
455
+ assert_match(/^\d+$/, out.string.chomp, "Failed to load require file")
456
+ end
457
+ end
458
+
459
+ def test_process_require_task_long_form
460
+ StringIO.open do |out|
461
+ $stdout = out
462
+ @rube.process_options('--explicit', '--require', 'English', '--eval', 'puts $PID')
463
+ @rube.generate
464
+ # If English doesn't load properly, then $PID is nil; if it does, then it's a numeric process id
465
+ assert_match(/^\d+$/, out.string.chomp, "Failed to load require file")
466
+ end
467
+ end
468
+
469
+ def test_process_template_task
470
+ StringIO.open do |out|
471
+ $stdout = out
472
+ @rube.process_options('templates/test1')
473
+ @rube.generate
474
+ assert_equal "foo\nblurg\nblurble\n\nfarb\n\n", out.string, "Failed to produce expected result from test1 template"
475
+ end
476
+ end
477
+
478
+ def test_process_template_task_with_disabled_percent
479
+ StringIO.open do |out|
480
+ $stdout = out
481
+ @rube.process_options('-P', 'templates/test1')
482
+ @rube.generate
483
+ # Note: test1 template produces different results with % lines disabled
484
+ assert_equal "foo\nblurg\nblurble\n\n% z = 'farb'\nbarf\n\n", out.string, "Failed to produce expected result from test1 template with percentage lines disabled"
485
+ end
486
+ end
487
+
488
+ def test_process_template_task_with_trim_level_1
489
+ StringIO.open do |out|
490
+ $stdout = out
491
+ @rube.process_options('--trim', '1', 'templates/test1')
492
+ @rube.generate
493
+ assert_equal "foo\nblurgblurblefarb\n", out.string, "Failed to produce expected result from test1 template"
494
+ end
495
+ end
496
+
497
+ def test_process_template_task_with_trim_level_2
498
+ StringIO.open do |out|
499
+ $stdout = out
500
+ @rube.process_options('--trim', '2', 'templates/test1')
501
+ @rube.generate
502
+ assert_equal "foo\nblurgblurble\nfarb\n", out.string, "Failed to produce expected result from test1 template"
503
+ end
504
+ end
505
+
506
+ def test_process_template_with_persistent_variable
507
+ StringIO.open do |out|
508
+ $stdout = out
509
+ @rube.process_options('--eval', 'b="foo"', 'templates/test2')
510
+ @rube.generate
511
+ assert_equal "bar\nfoo*2\n", out.string, "Failed to produce expected result from test2 template with passed variable value"
512
+ end
513
+ end
514
+ end
515
+
516
+ class TestRubeCommandLineDirectly < Test::Unit::TestCase
517
+ #
518
+ # Not really an exhaustive test, but if this works, things should be okay
519
+ #
520
+ def test_eval
521
+ res = `rube -E -e 'puts "foo"'`
522
+ assert_equal "foo\n", res, "Failed to produce expected output on $stdout"
523
+ end
524
+
525
+ def test_process_require_task
526
+ res = `rube --explicit -r English -e 'puts $PID'`
527
+ # If English doesn't load properly, then $PID is nil; if it does, then it's a numeric process id
528
+ assert_match(/^\d+$/, res.chomp, "Failed to load require file")
529
+ end
530
+
531
+ def test_process_template_task
532
+ res = `rube.rb templates/test1` # Not sure why it insists on the '.rb' here, but it does...
533
+ assert_equal "foo\nblurg\nblurble\n\nfarb\n\n", res, "Failed to produce expected result from test1 template"
534
+ end
535
+
536
+ def test_process_implicit_template_task
537
+ res = `rube < templates/test1`
538
+ assert_equal "foo\nblurg\nblurble\n\nfarb\n\n", res, "Failed to produce expected result from implicit test1 template"
539
+ end
540
+
541
+ def test_process_explicit_stdin_template_task
542
+ res = `rube -e 'b="foo"' --stdin templates/test2 < templates/test1`
543
+ assert_equal "foo\nblurg\nblurble\n\nfarb\n\nbar\nfoo*2\n", res, "Failed to produce expected result from explicit stdin template"
544
+ end
545
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rube
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Richard LeBer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-20 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.4.1
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
35
+ description: |-
36
+ Rube -- Slightly smarter erb front-end
37
+
38
+ Rube allows you to apply erb to templates, interspersed with other ruby code, either as inline source or
39
+ as ruby files (e.g. requires). Rube can be invoked from the command line as a command in the form:
40
+
41
+ rube [options] task ...
42
+ email:
43
+ - rleber@mindspring.com
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ extra_rdoc_files:
49
+ - History.txt
50
+ - Manifest.txt
51
+ - PostInstall.txt
52
+ - README.rdoc
53
+ files:
54
+ - History.txt
55
+ - Manifest.txt
56
+ - PostInstall.txt
57
+ - README.rdoc
58
+ - Rakefile
59
+ - VERSION
60
+ - lib/rube.rb
61
+ - script/console
62
+ - script/destroy
63
+ - script/generate
64
+ - templates/test1
65
+ - templates/test2
66
+ - test/test_helper.rb
67
+ - test/test_rube.rb
68
+ has_rdoc: true
69
+ homepage: http://github.com/rleber/rube
70
+ licenses: []
71
+
72
+ post_install_message: PostInstall.txt
73
+ rdoc_options:
74
+ - --main
75
+ - README.rdoc
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ version:
90
+ requirements: []
91
+
92
+ rubyforge_project: rube
93
+ rubygems_version: 1.3.4
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Rube -- Slightly smarter erb front-end Rube allows you to apply erb to templates, interspersed with other ruby code, either as inline source or as ruby files (e.g
97
+ test_files:
98
+ - test/test_helper.rb
99
+ - test/test_rube.rb