grizzled-ruby 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/bin/grinc ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # See the man page or http://software.clapper.org/grizzled-ruby/grinc/
4
+ # for documentation.
5
+ #--
6
+ # This software is released under a BSD license, adapted from
7
+ # http://opensource.org/licenses/bsd-license.php
8
+ #
9
+ # Copyright (c) 2011, Brian M. Clapper
10
+ # All rights reserved.
11
+ #
12
+ # Redistribution and use in source and binary forms, with or without
13
+ # modification, are permitted provided that the following conditions are
14
+ # met:
15
+ #
16
+ # * Redistributions of source code must retain the above copyright notice,
17
+ # this list of conditions and the following disclaimer.
18
+ #
19
+ # * Redistributions in binary form must reproduce the above copyright
20
+ # notice, this list of conditions and the following disclaimer in the
21
+ # documentation and/or other materials provided with the distribution.
22
+ #
23
+ # * Neither the names "clapper.org", "Grizzled Ruby Library", nor the
24
+ # names of its contributors may be used to endorse or promote products
25
+ # derived from this software without specific prior written permission.
26
+ #
27
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28
+ # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
31
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
+ #++
39
+
40
+ require 'optparse'
41
+ require 'grizzled/fileutil/includer'
42
+
43
+ include Grizzled::FileUtil
44
+
45
+ # ---------------------------------------------------------------------------
46
+ # Constants
47
+ # ---------------------------------------------------------------------------
48
+
49
+ DEFAULT_MAX_NEST = 100
50
+ PROGRAM_NAME = 'grinc'
51
+
52
+ # ---------------------------------------------------------------------------
53
+ # Classes
54
+ # ---------------------------------------------------------------------------
55
+
56
+ class Parameters
57
+ attr_reader :output, :max_nesting, :input_paths
58
+
59
+ def initialize(options_hash, argv)
60
+ @output = options_hash[:output]
61
+ @max_nesting = options_hash[:max_nesting] || DEFAULT_MAX_NEST
62
+ @input_paths = argv.length == 0 ? nil : argv
63
+ end
64
+
65
+ def to_s
66
+ inspect
67
+ end
68
+ end
69
+
70
+ class UsageError < StandardError; end
71
+
72
+ # ---------------------------------------------------------------------------
73
+ # Parameter parsing
74
+ # ---------------------------------------------------------------------------
75
+
76
+ def parse_params
77
+ options_hash = {}
78
+ error = nil
79
+ option_parser = OptionParser.new do |opts|
80
+ opts.program_name = PROGRAM_NAME
81
+ opts.banner = "Usage: #{opts.program_name} [OPTIONS] inputfile ..."
82
+ opts.separator ''
83
+ opts.separator 'OPTIONS:'
84
+
85
+ opts.on('-o FILE', 'Output file. Default: standard output.') do |f|
86
+ options_hash[:output] = f
87
+ end
88
+
89
+ opts.on('-n', '--nesting n',
90
+ "Max nesting. Default: #{DEFAULT_MAX_NEST}") do |n|
91
+ if n !~ /^[0-9]+$/
92
+ error = "Non-numeric parameter \"#{n}\" to -n option."
93
+ end
94
+ options_hash[:max_nesting] = n.to_i
95
+ end
96
+ end
97
+
98
+ begin
99
+ option_parser.parse!(ARGV)
100
+ rescue OptionParser::InvalidOption => ex
101
+ error = ex.to_s
102
+ end
103
+
104
+ if error
105
+ $stderr.puts(error) unless error.nil?
106
+ option_parser.display
107
+ raise UsageError.new
108
+ end
109
+
110
+ if ARGV.length == 0
111
+ options_hash[:input_files] = nil
112
+ else
113
+ options_hash[:input_files] = ARGV
114
+ end
115
+
116
+ Parameters.new(options_hash, ARGV)
117
+ end
118
+
119
+ def process_include(input_file, output_file, max_nesting = 100)
120
+ Includer.new(input_file, :max_nesting => max_nesting).each do |line|
121
+ output_file.write(line)
122
+ end
123
+ end
124
+
125
+ # ---------------------------------------------------------------------------
126
+ # Main logic
127
+ # ---------------------------------------------------------------------------
128
+
129
+ begin
130
+ params = parse_params
131
+ out = params.output.nil? ? $stderr : File.open(params.output, 'w')
132
+
133
+ if params.input_paths.nil?
134
+ process_include($stdin, out, params.max_nesting)
135
+ else
136
+ params.input_paths.each do |f|
137
+ process_include(File.open(f), out, params.max_nesting)
138
+ end
139
+ end
140
+
141
+ rescue UsageError
142
+ exit 1
143
+
144
+ rescue
145
+ $stderr.puts("#{PROGRAM_NAME}: #{$!}")
146
+ exit 1
147
+
148
+ else
149
+ exit 0
150
+ end
151
+
data/lib/grizzled/dir.rb CHANGED
@@ -43,6 +43,11 @@ class Dir
43
43
  # walked top-down, not depth-first. To terminate the traversal, the block
44
44
  # should return +false+. Anything else (including +nil+) continues the
45
45
  # traversal.
46
+ #
47
+ # Parameters:
48
+ #
49
+ # dirname:: The name (path) of the directory to walk.
50
+ # block:: The block to invoke on each entry.
46
51
  def self.walk(dirname, &block)
47
52
  Grizzled::Directory.walk(dirname, &block)
48
53
  end
@@ -64,6 +69,11 @@ module Grizzled
64
69
  # directory is walked top-down, not depth-first. To terminate the
65
70
  # traversal, the block should return +false+. Anything else (including
66
71
  # +nil+) continues the traversal.
72
+ #
73
+ # Parameters:
74
+ #
75
+ # dirname:: The name (path) of the directory to walk.
76
+ # block:: The block to invoke on each entry.
67
77
  def self.walk(dirname, &block)
68
78
  if block.call(Dir.new(dirname)) != false
69
79
  Dir.entries(dirname).each do |entry|
@@ -88,9 +88,9 @@ module Grizzled
88
88
  #
89
89
  # Parameters:
90
90
  #
91
- # [+directory+] The starting directory, which is created if it does not
92
- # exist.
93
- # [+tree+] The entry tree, as described above
91
+ # directory:: The starting directory, which is created if it does not
92
+ # exist.
93
+ # tree:: The entry tree, as described above
94
94
  #
95
95
  # Returns:
96
96
  #
@@ -123,17 +123,19 @@ module Grizzled
123
123
  #
124
124
  # Parameters:
125
125
  #
126
- # [+source+] A string, representing a file name or URL (http, https or
127
- # ftp), a +File+ object, or an object with an +each_line+
128
- # method that returns individual lines of input.
129
- # [+options+] Various processing options. See below.
126
+ # source:: A string, representing a file name or URL (http, https or
127
+ # ftp), a +File+ object, or an object with an +each_line+
128
+ # method that returns individual lines of input.
129
+ # options:: Various processing options. See below.
130
130
  #
131
131
  # Options:
132
132
  #
133
- # [+:max_nesting+] Maximum include nesting level. Default: 100
134
- # [+:include_pattern+] String regex pattern to match include directives.
135
- # Must have a single regex group for the file name
136
- # or URL. Default: ^%include\s"([^"]+)"
133
+ # **NOTE**: Options are symbols (e.g., +:recursive+).
134
+ #
135
+ # max_nesting:: Maximum include nesting level. Default: 100
136
+ # include_pattern:: String regex pattern to match include directives.
137
+ # Must have a single regex group for the file name
138
+ # or URL. Default: ^%include\s"([^"]+)"
137
139
  def initialize(source, options={})
138
140
  @max_nesting = options.fetch(:max_nesting, 100)
139
141
  inc_pattern = options.fetch(:include_pattern, '^%include\s"([^"]+)"')
@@ -58,10 +58,10 @@ module Grizzled
58
58
  # class mixes in methods that will allow you to zip up files. Related
59
59
  # modules and classes:
60
60
  #
61
- # [Grizzled::FileUtil::Zipper] A class that includes this module
61
+ # Grizzled::FileUtil::Zipper:: A class that includes this module
62
62
  # and can be instantiated by itself.
63
- # [Grizzled::FileUtil::UnzipMixin] A module mixin for unzipping zip files.
64
- # [Grizzled::FileUtil::Unzipper] A class that includes `UnzipMixin'
63
+ # Grizzled::FileUtil::UnzipMixin:: A module mixin for unzipping zip files.
64
+ # Grizzled::FileUtil::Unzipper:: A class that includes `UnzipMixin'
65
65
  # and can be instantiated by itself.
66
66
  module ZipMixin
67
67
 
@@ -69,31 +69,33 @@ module Grizzled
69
69
  #
70
70
  # Parameters:
71
71
  #
72
- # [+zip_file+] The zip file to open. The file is created if it doesn't
73
- # already exists.
74
- # [+directory+] The directory whose contents are to be included in
75
- # the file.
76
- # [+options+] Options hash, as described below.
77
- # [+&select+] If a block (+select+) is given, then +zip+ passes each
78
- # file or directory to the block and only adds the entry
79
- # to the zip file if the block returns +true+. If no
80
- # block is given, then all files and directories are
81
- # added (subject also to the +:recursive+ option, below).
72
+ # zip_file:: The zip file to open. The file is created if it doesn't
73
+ # already exists.
74
+ # directory:: The directory whose contents are to be included in
75
+ # the file.
76
+ # options:: Options hash, as described below.
77
+ # select:: If a block (+select+) is given, then +zip+ passes each
78
+ # file or directory to the block and only adds the entry
79
+ # to the zip file if the block returns +true+. If no
80
+ # block is given, then all files and directories are
81
+ # added (subject also to the +:recursive+ option, below).
82
82
  #
83
83
  # Options:
84
84
  #
85
- # [+:recursive+] If +false+, only zip the files in the directory; if
86
- # +true+ (the default), recursively zip the entire
87
- # directory.
88
- # [+:dir_at_top+] If +false+, don't include zip the directory itself
89
- # (i.e., the top-level files will be at the top level
90
- # of the zip file). If +true+ (the default), the
91
- # the directory itself (the basename) will be the
92
- # top-level element of the zip file.
93
- # [+:recreate] If +true+, remove the zip file if it exists already,
94
- # so it's recreated from scratch. If +false+ (the
95
- # default), don't recreate the zip file if it doesn't
96
- # exist; instead, update the existing file.
85
+ # **NOTE**: Options are symbols (e.g., +:recursive+).
86
+ #
87
+ # recursive:: If +false+, only zip the files in the directory; if
88
+ # +true+ (the default), recursively zip the entire
89
+ # directory.
90
+ # dir_at_top:: If +false+, don't include zip the directory itself
91
+ # (i.e., the top-level files will be at the top level
92
+ # of the zip file). If +true+ (the default), the
93
+ # the directory itself (the basename) will be the
94
+ # top-level element of the zip file.
95
+ # recreate:: If +true+, remove the zip file if it exists already,
96
+ # so it's recreated from scratch. If +false+ (the
97
+ # default), don't recreate the zip file if it doesn't
98
+ # exist; instead, update the existing file.
97
99
  #
98
100
  # Returns:
99
101
  #
@@ -157,35 +159,37 @@ module Grizzled
157
159
  # class mixes in methods that will allow you to unzip zip files.
158
160
  # Related modules and classes:
159
161
  #
160
- # [Grizzled::FileUtil::Zipper] A class that includes this module
162
+ # Grizzled::FileUtil::Zipper:: A class that includes this module
161
163
  # and can be instantiated by itself.
162
- # [Grizzled::FileUtil::ZipMixin] A module mixin for zipping zip files.
163
- # [Grizzled::FileUtil::Unzipper] A class that includes `UnzipMixin'
164
+ # Grizzled::FileUtil::ZipMixin:: A module mixin for zipping zip files.
165
+ # Grizzled::FileUtil::Unzipper:: A class that includes `UnzipMixin'
164
166
  # and can be instantiated by itself.
165
167
  module UnzipMixin
166
168
  # Unzips a zip file into a directory.
167
169
  #
168
170
  # Parameters:
169
171
  #
170
- # [+zip_file+] The zip file to unzip.
171
- # [+directory+] The directory into which to unzip the file. The
172
- # directory is created if it doesn't already exist.
173
- # [+options+] Options hash, as described below.
174
- # [+&select+] If a block (+select+) is given, then +unzip+ passes each
175
- # zip file entry name to the block and only unzips the
176
- # entry if the block returns +true+. If no block is
177
- # given, then everything is unzipped (subject also to
178
- # the +:recursive+ option, below).
172
+ # zip_file:: The zip file to unzip.
173
+ # directory:: The directory into which to unzip the file. The
174
+ # directory is created if it doesn't already exist.
175
+ # options:: Options hash, as described below.
176
+ # select:: If a block (+select+) is given, then +unzip+ passes each
177
+ # zip file entry name to the block and only unzips the
178
+ # entry if the block returns +true+. If no block is
179
+ # given, then everything is unzipped (subject also to
180
+ # the +:recursive+ option, below).
179
181
  #
180
182
  # Options:
181
183
  #
182
- # [+:recursive+] If +false+, only extract the top-level files from
183
- # the zip file. If +true+ (the default),
184
- # recursively extract everything.
185
- # [+:overwrite+] If +false+ (the default), do not overwrite existing
186
- # files in the directory. If +true+, overwrite
187
- # any existing files in the directory with extracted
188
- # zip files whose names match.
184
+ # **NOTE**: Options are symbols (e.g., +:recursive+).
185
+ #
186
+ # recursive:: If +false+, only extract the top-level files from the
187
+ # zip file. If +true+ (the default), recursively
188
+ # extract everything.
189
+ # overwrite:: If +false+ (the default), do not overwrite existing
190
+ # files in the directory. If +true+, overwrite
191
+ # any existing files in the directory with extracted
192
+ # zip files whose names match.
189
193
  #
190
194
  # Example:
191
195
  #
@@ -198,7 +202,6 @@ module Grizzled
198
202
  # unzip zipfile_path, d
199
203
  # # muck with unpacked contents
200
204
  # end
201
-
202
205
  def unzip(zip_file, directory, options = {}, &select)
203
206
  overwrite = options.fetch(:overwrite, false)
204
207
  recurse = options.fetch(:recursive, true)
@@ -228,10 +231,10 @@ module Grizzled
228
231
  #
229
232
  # Parameters:
230
233
  #
231
- # [+zip_file+] The zip file to unzip.
232
- # [+block+] Block to execute on each entry. If omitted, an
233
- # Enumerator is returned. The block receives a string
234
- # representing the path of the item in the file.
234
+ # zip_file:: The zip file to unzip.
235
+ # block:: Block to execute on each entry. If omitted, an
236
+ # Enumerator is returned. The block receives a string
237
+ # representing the path of the item in the file.
235
238
  def zip_file_entries(zip_file, &block)
236
239
  if not block_given?
237
240
  a = []
@@ -70,6 +70,13 @@ module Grizzled
70
70
 
71
71
  # Forward all unimplemented method calls to +obj+, except those
72
72
  # whose symbols are listed in the +exceptions+ array.
73
+ #
74
+ # Parameters:
75
+ #
76
+ # obj:: The object to which to forward unimplemented method calls
77
+ # exception+:: A list of symbols for unimplemented methods that should
78
+ # not be forwarded to +obj+. Note: You do _not_ have to put
79
+ # methods you've implemented in here.
73
80
  def forward_to(obj, exceptions=[])
74
81
  @forward_obj = obj
75
82
 
@@ -53,8 +53,8 @@ module Grizzled
53
53
  #
54
54
  # Parameters:
55
55
  #
56
- # [+pop_empty_nil+] +true+ if popping an empty stack should just return
57
- # +nil+, +false+ if it should thrown an exception.
56
+ # pop_empty_nil:: +true+ if popping an empty stack should just return
57
+ # +nil+, +false+ if it should thrown an exception.
58
58
  def initialize(pop_empty_nil=true)
59
59
  @the_stack = []
60
60
  @pop_empty_nil = pop_empty_nil
@@ -93,6 +93,10 @@ module Grizzled
93
93
  #
94
94
  # stack = Stack.new
95
95
  # [1, 2, 3].each {|i| stack.push i}
96
+ #
97
+ # Parameters:
98
+ #
99
+ # element:: The object to push onto the stack.
96
100
  def push(element)
97
101
  if element.class == Array
98
102
  element.each {|e| @the_stack.push e}
@@ -81,14 +81,14 @@ module Grizzled
81
81
  #
82
82
  # Parameters:
83
83
  #
84
- # [+resolver+] A hash-like object that can take a variable name (via
84
+ # +resolver+:: A hash-like object that can take a variable name (via
85
85
  # the +[]+ function) and resolve its value, returning
86
86
  # the value (which is converted to string) or +nil+.
87
- # [+options+] hash of options. See below.
87
+ # +options+:: hash of options. See below.
88
88
  #
89
89
  # Options:
90
90
  #
91
- # [+:safe+] +true+ for a safe template that substitutes a blank
91
+ # +:safe+:: +true+ for a safe template that substitutes a blank
92
92
  # string for a non-existent variable, instead of
93
93
  # throwing an exception. Defaults to +true+.
94
94
  def initialize(resolver, options={})
@@ -108,7 +108,7 @@ module Grizzled
108
108
  #
109
109
  # Parameters:
110
110
  #
111
- # [+s+] the string in which to replace variable references
111
+ # +s+:: the string in which to replace variable references
112
112
  #
113
113
  # Returns the substituted result.
114
114
  def substitute(s)
@@ -135,7 +135,7 @@ module Grizzled
135
135
  #
136
136
  # Parameters:
137
137
  #
138
- # [+s+] the string
138
+ # +s+:: the string
139
139
  #
140
140
  # Returns a +Variable+ object, or +nil+.
141
141
  def find_variable_ref(s)
@@ -147,8 +147,8 @@ module Grizzled
147
147
  #
148
148
  # Parameters:
149
149
  #
150
- # [+name+] Variable name
151
- # [+default+] Default value, or +nil+
150
+ # +name+:: Variable name
151
+ # +default+:: Default value, or +nil+
152
152
  def get_variable(name, default)
153
153
 
154
154
  def handle_no_value(default, name)
@@ -193,17 +193,17 @@ module Grizzled
193
193
  #
194
194
  # Parameters:
195
195
  #
196
- # [+resolver+] A hash-like object that can take a variable name (via
196
+ # +resolver+:: A hash-like object that can take a variable name (via
197
197
  # the +[]+ function) and resolve its value, returning
198
198
  # the value (which is converted to string) or +nil+.
199
- # [+options+] hash of options. See below.
199
+ # +options+:: hash of options. See below.
200
200
  #
201
201
  # Options:
202
202
  #
203
- # [+:safe+] +true+ for a safe template that substitutes a blank
203
+ # +:safe+:: +true+ for a safe template that substitutes a blank
204
204
  # string for a non-existent variable, instead of
205
205
  # throwing an exception. Defaults to +true+.
206
- # [+:var_pattern+] Regular expression pattern (as a string, not a
206
+ # +:var_pattern+:: Regular expression pattern (as a string, not a
207
207
  # Regexp object) to match a variable name. Defaults
208
208
  # to "[A-Za-z0-9_]+"
209
209
  def initialize(resolver, options={})
@@ -225,7 +225,7 @@ module Grizzled
225
225
  #
226
226
  # Parameters:
227
227
  #
228
- # [+s+] the string in which to replace variable references
228
+ # +s+:: the string in which to replace variable references
229
229
  #
230
230
  # Returns the substituted result.
231
231
  def substitute(s)
@@ -269,7 +269,7 @@ module Grizzled
269
269
  #
270
270
  # Parameters:
271
271
  #
272
- # [+s+] the string
272
+ # +s+:: the string
273
273
  #
274
274
  # Returns a +Variable+ object, or +nil+.
275
275
  def find_variable_ref(s)
@@ -319,17 +319,17 @@ module Grizzled
319
319
  #
320
320
  # Parameters:
321
321
  #
322
- # [+resolver+] A hash-like object that can take a variable name (via
322
+ # +resolver+:: A hash-like object that can take a variable name (via
323
323
  # the +[]+ function) and resolve its value, returning
324
324
  # the value (which is converted to string) or +nil+.
325
- # [+options+] hash of options. See below.
325
+ # +options+:: hash of options. See below.
326
326
  #
327
327
  # Options:
328
328
  #
329
- # [+:safe+] +true+ for a safe template that substitutes a blank
329
+ # +:safe+:: +true+ for a safe template that substitutes a blank
330
330
  # string for a non-existent variable, instead of
331
331
  # throwing an exception. Defaults to +true+.
332
- # [+:var_pattern+] Regular expression pattern (as a string, not a
332
+ # +:var_pattern+:: Regular expression pattern (as a string, not a
333
333
  # Regexp object) to match a variable name. Defaults
334
334
  # to "[A-Za-z0-9_]+"
335
335
  def initialize(resolver, options={})
@@ -350,7 +350,7 @@ module Grizzled
350
350
  #
351
351
  # Parameters:
352
352
  #
353
- # [+s+] the string in which to replace variable references
353
+ # +s+:: the string in which to replace variable references
354
354
  #
355
355
  # Returns the substituted result.
356
356
  def substitute(s)
@@ -392,7 +392,7 @@ module Grizzled
392
392
  #
393
393
  # Parameters:
394
394
  #
395
- # [+s+] the string
395
+ # +s+:: the string
396
396
  #
397
397
  # Returns a +Variable+ object, or +nil+.
398
398
  def find_variable_ref(s)
data/lib/grizzled/unix.rb CHANGED
@@ -55,8 +55,10 @@ module Grizzled
55
55
 
56
56
  # Run a block of code as this user.
57
57
  #
58
- # [+block+] the block to execute as that user. It will receive this
59
- # +User+ object as a parameter.
58
+ # Parameters:
59
+ #
60
+ # block:: the block to execute as that user. It will receive this
61
+ # +User+ object as a parameter.
60
62
  #
61
63
  # This function will only run as 'root'.
62
64
  #
@@ -0,0 +1,114 @@
1
+ require '../test_helper'
2
+ require 'test/unit'
3
+ require 'tempfile'
4
+ require 'grizzled/fileutil/includer'
5
+
6
+ include Grizzled::FileUtil
7
+
8
+ class IncluderTestDriver < Test::Unit::TestCase
9
+ include GrizzledTestHelper
10
+
11
+ def test_successful_file_include
12
+ make_include_file do |test_file|
13
+ inc = Includer.new(test_file.main_file)
14
+ lines = inc.readlines.map {|line| line.chomp}
15
+ assert_equal(['one-1', 'one-2', 'two-2', 'two-1'], lines)
16
+ inc.close
17
+ end
18
+ end
19
+
20
+ def test_recursive_include
21
+ temp = Tempfile.new('inctest')
22
+ temp.write <<EOF
23
+ %include "#{temp.path}"
24
+ EOF
25
+ temp.close
26
+ assert_raise(IncludeException) do
27
+ inc = Includer.new(temp.path)
28
+ inc.readlines
29
+ inc.close
30
+ end
31
+ end
32
+
33
+ def test_uri_include
34
+ make_include_file do |test_file|
35
+ inc = Includer.new(test_file.main_file)
36
+ lines = inc.readlines.map {|line| line.chomp}
37
+ assert_equal(['one-1', 'one-2', 'two-2', 'two-1'], lines)
38
+ inc.close
39
+ end
40
+ end
41
+
42
+ def test_path
43
+ make_include_file do |test_file|
44
+ path = test_file.main_file
45
+ inc = Includer.new(test_file.main_file)
46
+ assert_equal(test_file.main_file, inc.path)
47
+ inc.close
48
+ end
49
+ end
50
+
51
+ def test_each_byte
52
+ make_include_file do |test_file|
53
+ inc = Includer.new(test_file.main_file)
54
+ contents = inc.read.split(//)
55
+ inc.close
56
+
57
+ inc = Includer.new(test_file.main_file)
58
+ bytes = []
59
+ inc.each_byte do |b|
60
+ bytes << b.chr
61
+ end
62
+ inc.close
63
+
64
+ assert_equal(contents, bytes)
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def make_include_file
71
+ temp1 = Tempfile.new('inctest')
72
+ temp2 = Tempfile.new('inctest')
73
+
74
+ temp2.write <<EOF2
75
+ one-2
76
+ two-2
77
+ EOF2
78
+
79
+ temp1.write <<EOF1
80
+ one-1
81
+ %include "#{temp2.path}"
82
+ two-1
83
+ EOF1
84
+ temp1.close
85
+ temp2.close
86
+ t = TestIncludeFile.new([temp1, temp2].map {|t| t.path})
87
+ if block_given?
88
+ begin
89
+ yield t
90
+ ensure
91
+ t.unlink
92
+ end
93
+ else
94
+ t
95
+ end
96
+ end
97
+ end
98
+
99
+ class TestIncludeFile
100
+ attr_reader :main_file
101
+
102
+ def initialize(files)
103
+ @main_file = files[0]
104
+ @files = files
105
+ end
106
+
107
+ def unlink
108
+ @files.each do |f|
109
+ if File.exists? f
110
+ File.unlink f
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,55 @@
1
+ require '../test_helper'
2
+ require 'test/unit'
3
+ require 'tempfile'
4
+ require 'tmpdir'
5
+ require 'fileutils'
6
+ require 'grizzled/fileutil'
7
+
8
+ include Grizzled::FileUtil
9
+
10
+ class MakeDirTreeTester < Test::Unit::TestCase
11
+ include GrizzledTestHelper
12
+
13
+ def test_make_directory_tree
14
+ tree = {"bmc" => {"moe" => {"a" => "aaaaaaaaaa",
15
+ "b" => "bbbbbbbbb"},
16
+ "larry" => "larry",
17
+ "curley" => "curley"}}
18
+ Dir.mktmpdir('ziptest') do |tmpdir|
19
+ make_directory_tree(tmpdir, tree)
20
+
21
+ # Now, reload the directory tree, and ensure that the tree
22
+ # matches what we created.
23
+ new_tree = {}
24
+ FileUtils.cd tmpdir do
25
+ new_tree = dir_to_hash "bmc"
26
+ end
27
+
28
+ assert_equal tree, new_tree
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def dir_to_hash(dir)
35
+
36
+ def load_dir_hash(dir)
37
+ h = {}
38
+ Dir.new(dir).entries.each do |dirent|
39
+ if dirent[0..0] != '.'
40
+ path = File.join(dir, dirent)
41
+ if File.directory? path
42
+ FileUtils.cd dir do
43
+ h[dirent] = load_dir_hash(dirent)
44
+ end
45
+ else
46
+ h[dirent] = File.open(path).read
47
+ end
48
+ end
49
+ end
50
+ h
51
+ end
52
+
53
+ {dir => load_dir_hash(dir)}
54
+ end
55
+ end
@@ -0,0 +1,139 @@
1
+ require '../test_helper'
2
+ require 'test/unit'
3
+ require 'tempfile'
4
+ require 'tmpdir'
5
+ require 'grizzled/fileutil/ziputil'
6
+
7
+ include Grizzled::FileUtil::ZipUtil
8
+
9
+ class ZipMixinTestDriver < Test::Unit::TestCase
10
+ include GrizzledTestHelper
11
+ include ZipMixin, UnzipMixin
12
+
13
+ def test_zip_unzip_with_dir
14
+ with_tempfile('ziptest', '.zip') do |t|
15
+
16
+ # Create a zip file of the current directory
17
+ zip t.path, '.'
18
+ assert_equal(true, File.exists?(t.path))
19
+
20
+ # Now, unzip it and compare this file with its zipped-and-unzipped
21
+ # counterpart.
22
+ this_file_size = File.size(__FILE__)
23
+ this_file_contents = File.open(__FILE__).readlines.join('')
24
+ Dir.mktmpdir('ziptest') do |tmpdir|
25
+ unzip t.path, tmpdir
26
+
27
+ # File was unzipped under this directory name.
28
+ entry_dir = File.basename(File.dirname(File.expand_path(__FILE__)))
29
+ unzipped_this_file = File.join(tmpdir, entry_dir,
30
+ File.basename(__FILE__))
31
+ FileUtils.cd(tmpdir) do
32
+ assert_equal true, File.exists?(unzipped_this_file)
33
+ assert_equal this_file_size, File.size(unzipped_this_file)
34
+ contents = File.open(unzipped_this_file).readlines.join('')
35
+ assert_equal this_file_contents, contents
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ def test_zip_unzip_without_dir
42
+ with_tempfile('ziptest', '.zip') do |t|
43
+
44
+ # Create a zip file of the current directory
45
+ zip t.path, '.', :dir_at_top => false
46
+ assert_equal(true, File.exists?(t.path))
47
+
48
+ # Now, unzip it and compare this file with its zipped-and-unzipped
49
+ # counterpart.
50
+ this_file_size = File.size(__FILE__)
51
+ this_file_contents = File.open(__FILE__).readlines.join('')
52
+ Dir.mktmpdir('ziptest') do |tmpdir|
53
+ unzip t.path, tmpdir
54
+
55
+ # File was unzipped in top level.
56
+ unzipped_this_file = File.join(tmpdir, File.basename(__FILE__))
57
+ FileUtils.cd(tmpdir) do
58
+ assert_equal true, File.exists?(unzipped_this_file)
59
+ assert_equal this_file_size, File.size(unzipped_this_file)
60
+ contents = File.open(unzipped_this_file).readlines.join('')
61
+ assert_equal this_file_contents, contents
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def test_non_recursive
68
+ expected_files = ['foo.txt', 'bar.txt']
69
+ Dir.mktmpdir 'ziptest' do |tmpdir|
70
+ FileUtils.cd tmpdir do
71
+
72
+ expected_files.each { |f| create_file(f, (f * 5) + "\n") }
73
+
74
+ # Now create a subdirectory.
75
+ Dir.mkdir 'subdir' do |subdir|
76
+ FileUtils.cd subdir do
77
+ # Create a couple more files which should NOT be zipped.
78
+ ['moe', 'larry', 'curley'].each { |f| create_file(f, f) }
79
+ end
80
+ end
81
+ end
82
+
83
+ # Now, zip up the temporary directory.
84
+
85
+ with_tempfile('ziptest', '.zip') do |t|
86
+ zip t.path, tmpdir, :dir_at_top => false, :recursive => false
87
+
88
+ assert_equal expected_files, zip_file_entries(t.path).to_a
89
+ end
90
+ end
91
+ end
92
+
93
+ def test_zip_with_block
94
+ create_files = ['foo.txt', 'bar.txt']
95
+ expected_files = ['foo.txt']
96
+
97
+ Dir.mktmpdir 'ziptest' do |tmpdir|
98
+ FileUtils.cd tmpdir do
99
+ create_files.each { |f| create_file(f, (f * 5) + "\n") }
100
+ end
101
+
102
+ with_tempfile('ziptest', '.zip') do |t|
103
+ zip t.path, tmpdir, :dir_at_top => false, :recursive => false do |path|
104
+ expected_files.include? path
105
+ end
106
+
107
+ assert_equal expected_files, zip_file_entries(t.path).to_a
108
+ end
109
+ end
110
+ end
111
+
112
+ def test_zip_file_entries
113
+ with_tempfile('ziptest', '.zip') do |t|
114
+
115
+ # Create a zip file of the current directory
116
+ zip t.path, '.', :dir_at_top => false, :recursive => false
117
+ assert_equal(true, File.exists?(t.path))
118
+
119
+ files_here = Dir.entries('.').select {|e| File.file? e}
120
+ entries = Hash[* files_here.map {|e| [e, 0]}.flatten]
121
+
122
+ zip_file_entries t.path do |e|
123
+ assert entries.has_key? e
124
+ entries[e] = 1
125
+ end
126
+
127
+ assert_equal 0, (entries.values.select {|v| v == 0}).length
128
+ end
129
+ end
130
+
131
+ private
132
+
133
+ def create_file(path, contents)
134
+ f = File.open(path, 'w')
135
+ f.write(contents)
136
+ f.close
137
+ end
138
+
139
+ end
@@ -0,0 +1,68 @@
1
+ require '../test_helper'
2
+ require 'test/unit'
3
+ require 'grizzled/string/template'
4
+
5
+ include Grizzled::String::Template
6
+
7
+ module TemplateTestDriver
8
+
9
+ def do_safe_expansion(template_class, resolver, test_data)
10
+ u = template_class.new(resolver, :safe => true)
11
+ test_data.each do |string, expected, has_missing|
12
+ assert_equal(expected, u.substitute(string))
13
+ end
14
+ end
15
+
16
+ def do_unsafe_expansion(template_class, resolver, test_data)
17
+ u = template_class.new(resolver, :safe => false)
18
+ test_data.each do |string, expected, has_missing|
19
+ if has_missing
20
+ assert_raise(VariableNotFoundException) do
21
+ u.substitute(string)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ class TestUnixShellStringTemplate < Test::Unit::TestCase
29
+
30
+ include TemplateTestDriver
31
+
32
+ RESOLVER = {"a" => "alpha", "foo" => "FOOBAR"}
33
+ TEST_DATA =
34
+ [
35
+ ['${a} $foo ${b?bdef} $b ${foo}\$x', 'alpha FOOBAR bdef FOOBAR$x', true],
36
+ ['\$a $foo $b', '$a FOOBAR ', true],
37
+ ['$a', 'alpha', false]
38
+ ]
39
+
40
+ def test_safe_expansion
41
+ do_safe_expansion(UnixShellStringTemplate, RESOLVER, TEST_DATA)
42
+ end
43
+
44
+ def test_unsafe_expansion
45
+ do_unsafe_expansion(UnixShellStringTemplate, RESOLVER, TEST_DATA)
46
+ end
47
+ end
48
+
49
+ class TestWindowsCmdStringTemplate < Test::Unit::TestCase
50
+
51
+ include TemplateTestDriver
52
+
53
+ RESOLVER = {"a" => "alpha", "foo" => "FOOBAR"}
54
+ TEST_DATA =
55
+ [
56
+ ['%a% %foo% %b% %foo%\%x', 'alpha FOOBAR FOOBAR%x', true],
57
+ ['\%a% %foo% %b%', '%a% FOOBAR ', true],
58
+ ['%a%', 'alpha', false]
59
+ ]
60
+
61
+ def test_safe_expansion
62
+ do_safe_expansion(WindowsCmdStringTemplate, RESOLVER, TEST_DATA)
63
+ end
64
+
65
+ def test_unsafe_expansion
66
+ do_unsafe_expansion(WindowsCmdStringTemplate, RESOLVER, TEST_DATA)
67
+ end
68
+ end
@@ -0,0 +1,89 @@
1
+ require 'test_helper'
2
+ require 'test/unit'
3
+ require 'tempfile'
4
+ require 'grizzled/forwarder'
5
+
6
+ class ForwarderTestDriver < Test::Unit::TestCase
7
+
8
+ class ForwardToFile
9
+ include Grizzled::Forwarder
10
+
11
+ def initialize(file, exceptions=[])
12
+ forward_to file, exceptions
13
+ end
14
+ end
15
+
16
+ def test_forward_all
17
+ path = create_file
18
+ begin
19
+ contents = File.open(path).read
20
+
21
+ fwd = ForwardToFile.new(File.open(path))
22
+ contents2 = fwd.read
23
+ assert_equal(contents, contents2)
24
+
25
+ lines = []
26
+ fwd = ForwardToFile.new(File.open(path))
27
+ fwd.each_line do |line|
28
+ lines << line
29
+ end
30
+ contents2 = lines.join('')
31
+ assert_equal(contents, contents2)
32
+ ensure
33
+ File.unlink path
34
+ end
35
+ end
36
+
37
+ def test_forward_all_but_each
38
+ path = create_file
39
+ begin
40
+ contents = File.open(path).read
41
+
42
+ fwd = ForwardToFile.new(File.open(path), [:each])
43
+ contents2 = fwd.read
44
+ assert_equal(contents, contents2)
45
+
46
+ assert_raise(NoMethodError) do
47
+ fwd.each
48
+ end
49
+ ensure
50
+ File.unlink path
51
+ end
52
+ end
53
+
54
+ def test_forward_all_but_each_and_each_line
55
+ path = create_file
56
+ begin
57
+ contents = File.open(path).read
58
+
59
+ fwd = ForwardToFile.new(File.open(path), [:each, :each_line])
60
+ contents2 = fwd.read
61
+ assert_equal(contents, contents2)
62
+
63
+ assert_raise(NoMethodError) do
64
+ fwd.each do |c|
65
+ puts(c) # should not get here
66
+ end
67
+ end
68
+
69
+ assert_raise(NoMethodError) do
70
+ fwd.each_line do |line|
71
+ puts(line) # should not get here
72
+ end
73
+ end
74
+ ensure
75
+ File.unlink path
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def create_file
82
+ temp = Tempfile.new('fwdtest')
83
+ temp.write((1..80).to_a.join(', '))
84
+ temp.write((1..10).to_a.join(', '))
85
+ temp.close
86
+ temp.path
87
+ end
88
+
89
+ end
data/test/tc_stack.rb ADDED
@@ -0,0 +1,83 @@
1
+ require 'test_helper'
2
+ require 'test/unit'
3
+ require 'grizzled/stack'
4
+
5
+ include Grizzled
6
+
7
+ class StackTestDriver < Test::Unit::TestCase
8
+
9
+ def test_correct_class
10
+ assert_equal(Grizzled::Stack, Stack.new.class)
11
+ end
12
+
13
+ def test_underflow_no_exception
14
+ stack = Stack.new
15
+ assert_equal(nil, stack.pop)
16
+ end
17
+
18
+ def test_underflow_exception
19
+ stack = Stack.new(false)
20
+ assert_raise(StackUnderflowException) {stack.pop}
21
+ end
22
+
23
+ def test_push
24
+ stack = Stack.new.push(5)
25
+ assert_equal([5], stack.to_a)
26
+ stack.push(10)
27
+ assert_equal([10, 5], stack.to_a)
28
+ stack.push(10)
29
+ assert_equal([10, 10, 5], stack.to_a)
30
+ stack.push([1, 2, 3])
31
+ assert_equal([3, 2, 1, 10, 10, 5], stack.to_a)
32
+ end
33
+
34
+ def test_length
35
+ stack = Stack.new.push(5)
36
+ assert_equal(1, stack.length)
37
+
38
+ stack.push(5)
39
+ assert_equal(2, stack.length)
40
+
41
+ stack.push((1..10).to_a)
42
+ assert_equal(12, stack.length)
43
+
44
+ stack.pop
45
+ assert_equal(11, stack.length)
46
+
47
+ stack.pop until stack.is_empty?
48
+ assert_equal(0, stack.length)
49
+ end
50
+
51
+ def test_clear
52
+ stack = Stack.new.push((1..10).to_a)
53
+ assert_equal(10, stack.length)
54
+ stack.clear
55
+ assert_equal(0, stack.length)
56
+ end
57
+
58
+ def test_pop_all
59
+ a = (1..10).to_a
60
+ stack = Stack.new.push(a)
61
+ assert_equal(10, stack.length)
62
+ a2 = stack.pop_all
63
+ assert_equal(0, stack.length)
64
+ assert_equal(a2, a.reverse)
65
+ end
66
+
67
+ def test_immutable
68
+ # Ensure that the to_a method doesn't return a stack that's
69
+ stack = Stack.new.push(5).push(10)
70
+ a = stack.to_a
71
+ assert_equal([10, 5], a)
72
+ a.pop
73
+ assert_equal([10, 5], stack.to_a)
74
+ end
75
+
76
+ def test_enumerable
77
+ stack = Stack.new.push([1, 2, 3])
78
+ assert_equal([3, 2, 1], stack.to_a)
79
+ a = []
80
+ stack.each {|element| a << element}
81
+ assert_equal(stack.to_a, a)
82
+ end
83
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grizzled-ruby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brian M. Clapper
@@ -15,16 +15,16 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-18 00:00:00 -04:00
18
+ date: 2011-03-24 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
22
22
  description: |
23
- Grizzled Ruby is a general purpose library of Ruby modules and classes
23
+ Grizzled Ruby is a general purpose library of Ruby modules and classes.
24
24
 
25
25
  email: bmc@clapper.org
26
- executables: []
27
-
26
+ executables:
27
+ - grinc
28
28
  extensions: []
29
29
 
30
30
  extra_rdoc_files: []
@@ -39,10 +39,17 @@ files:
39
39
  - lib/grizzled/string/template.rb
40
40
  - lib/grizzled/unix.rb
41
41
  - lib/grizzled.rb
42
+ - test/tc_stack.rb
43
+ - test/tc_forwarder.rb
44
+ - test/fileutil/tc_zip.rb
45
+ - test/fileutil/tc_includer.rb
46
+ - test/fileutil/tc_make_dir_tree.rb
47
+ - test/string/tc_template.rb
48
+ - bin/grinc
42
49
  has_rdoc: true
43
50
  homepage: http://software.clapper.org/grizzled-ruby
44
- licenses: []
45
-
51
+ licenses:
52
+ - BSD
46
53
  post_install_message:
47
54
  rdoc_options: []
48
55
 
@@ -73,5 +80,10 @@ rubygems_version: 1.6.2
73
80
  signing_key:
74
81
  specification_version: 3
75
82
  summary: Miscellaneous, general-purpose Ruby modules and classes
76
- test_files: []
77
-
83
+ test_files:
84
+ - test/tc_stack.rb
85
+ - test/tc_forwarder.rb
86
+ - test/fileutil/tc_zip.rb
87
+ - test/fileutil/tc_includer.rb
88
+ - test/fileutil/tc_make_dir_tree.rb
89
+ - test/string/tc_template.rb