rube 0.1.0

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