grizzled-ruby 0.1.1 → 0.1.3

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/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