templater 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -57,7 +57,7 @@ module Templater
57
57
 
58
58
  # removes the destination file
59
59
  def revoke!
60
- ::FileUtils.rm(destination)
60
+ ::FileUtils.rm(destination, :force => true)
61
61
  end
62
62
 
63
63
  end
@@ -61,7 +61,7 @@ module Templater
61
61
 
62
62
  # removes the destination file
63
63
  def revoke!
64
- ::FileUtils.rm(destination)
64
+ ::FileUtils.rm(destination, :force => true)
65
65
  end
66
66
 
67
67
  end
@@ -39,7 +39,7 @@ module Templater
39
39
  if option[:options][:as] == :boolean
40
40
  opts.on("--#{name}", option[:options][:desc]) do |s|
41
41
  options[option[:name]] = s
42
- end
42
+ end
43
43
  else
44
44
  opts.on("--#{name} OPTION", option[:options][:desc]) do |s|
45
45
  options[option[:name]] = s.gsub('-', '_').to_sym
@@ -50,7 +50,6 @@ module Templater
50
50
  end
51
51
 
52
52
  self.help if @options[:help]
53
- self.help if arguments.first == 'help'
54
53
  self.version if @options[:version]
55
54
 
56
55
  # Try to instantiate a generator, if the arguments to it were incorrect: show a help message
@@ -97,7 +97,7 @@ module Templater
97
97
  # :desc<Symbol>:: Provide a description for this argument
98
98
  def argument(n, name, options={}, &block)
99
99
  self.arguments[n] = {
100
- :name => name,
100
+ :name => name.to_sym,
101
101
  :options => options,
102
102
  :block => block
103
103
  }
@@ -179,7 +179,7 @@ module Templater
179
179
  # end
180
180
  def invoke(name, options={}, &block)
181
181
  self.invocations << {
182
- :name => name,
182
+ :name => name.to_sym,
183
183
  :options => options,
184
184
  :block => block
185
185
  }
@@ -226,7 +226,7 @@ module Templater
226
226
  source, destination = source + 't', source if args.size == 1
227
227
 
228
228
  self.templates << {
229
- :name => name,
229
+ :name => name.to_sym,
230
230
  :options => options,
231
231
  :source => source,
232
232
  :destination => destination,
@@ -250,7 +250,7 @@ module Templater
250
250
  source, destination = source, source if args.size == 1
251
251
 
252
252
  self.files << {
253
- :name => name,
253
+ :name => name.to_sym,
254
254
  :options => options,
255
255
  :source => source,
256
256
  :destination => destination,
@@ -259,12 +259,22 @@ module Templater
259
259
  }
260
260
  end
261
261
 
262
- def empty_directory(name, path = nil)
263
- path = name.to_s unless path
262
+ # Adds an empty directory that will be created when the generator is run.
263
+ #
264
+ # === Parameters
265
+ # name<Symbol>:: The name of this empty directory
266
+ # destination<String>:: The destination where the empty directory will be created
267
+ # options<Hash>:: Options for this empty directory
268
+ # &block<Proc>:: A block to execute when the generator is instantiated
269
+ def empty_directory(name, *args, &block)
270
+ options = args.last.is_a?(Hash) ? args.pop : {}
271
+ destination = args.first
264
272
 
265
273
  self.empty_directories << {
266
- :name => name,
267
- :destination => path
274
+ :name => name.to_sym,
275
+ :destination => destination,
276
+ :options => options,
277
+ :block => block
268
278
  }
269
279
  end
270
280
 
@@ -385,12 +395,11 @@ module Templater
385
395
  # === Raises
386
396
  # Templater::ArgumentError:: If the arguments are invalid
387
397
  def initialize(destination_root, options = {}, *args)
388
- # FIXME: options as a second argument is kinda stupid, since it forces silly syntax, but since *args
389
- # might contain hashes, I can't come up with another way of making this unambiguous.
390
398
  @destination_root = destination_root
391
399
  @arguments = []
392
400
  @options = options
393
401
 
402
+ # Initialize options to their default values.
394
403
  self.class.options.each do |option|
395
404
  @options[option[:name]] ||= option[:options][:default]
396
405
  end
@@ -437,11 +446,10 @@ module Templater
437
446
  # === Returns
438
447
  # [Templater::Actions::Template]:: The found templates.
439
448
  def templates
440
- templates = self.class.templates.map do |t|
441
- template = Templater::Proxy.new(self, t[:name], t[:source], t[:destination], &t[:block]).to_template
442
- match_options?(t[:options]) ? template : nil
449
+ self.class.templates.inject([]) do |templates, template|
450
+ templates << Templater::Proxy.new(self, template).to_template if match_options?(template[:options])
451
+ templates
443
452
  end
444
- templates.compact
445
453
  end
446
454
 
447
455
  # Finds and returns all files whose options match the generator options.
@@ -449,11 +457,10 @@ module Templater
449
457
  # === Returns
450
458
  # [Templater::Actions::File]:: The found files.
451
459
  def files
452
- files = self.class.files.map do |t|
453
- file = Templater::Proxy.new(self, t[:name], t[:source], t[:destination], &t[:block]).to_file
454
- match_options?(t[:options]) ? file : nil
460
+ self.class.files.inject([]) do |files, file|
461
+ files << Templater::Proxy.new(self, file).to_file if match_options?(file[:options])
462
+ files
455
463
  end
456
- files.compact
457
464
  end
458
465
 
459
466
  # Finds and returns all empty directories generator creates.
@@ -461,9 +468,10 @@ module Templater
461
468
  # === Returns
462
469
  # [Templater::Actions::File]:: The found files.
463
470
  def empty_directories
464
- self.class.empty_directories.map do |t|
465
- Templater::Proxy.new(self, t[:name], nil, t[:destination], &t[:block]).to_empty_directory
466
- end.compact
471
+ self.class.empty_directories.inject([]) do |empty_directories, action|
472
+ empty_directories << Templater::Proxy.new(self, action).to_empty_directory if match_options?(action[:options])
473
+ empty_directories
474
+ end
467
475
  end
468
476
 
469
477
  # Finds and returns all templates whose options match the generator options.
@@ -471,18 +479,20 @@ module Templater
471
479
  # === Returns
472
480
  # [Templater::Generator]:: The found templates.
473
481
  def invocations
474
- if self.class.manifold
475
- invocations = self.class.invocations.map do |invocation|
476
- generator = self.class.manifold.generator(invocation[:name])
477
- if generator and invocation[:block]
478
- instance_exec(generator, &invocation[:block])
479
- elsif generator and match_options?(invocation[:options])
480
- generator.new(destination_root, options, *@arguments)
482
+ return [] unless self.class.manifold
483
+
484
+ self.class.invocations.inject([]) do |invocations, invocation|
485
+ generator = self.class.manifold.generator(invocation[:name])
486
+
487
+ if generator and match_options?(invocation[:options])
488
+
489
+ if invocation[:block]
490
+ invocations << instance_exec(generator, &invocation[:block])
491
+ else
492
+ invocations << generator.new(destination_root, options, *@arguments)
481
493
  end
482
494
  end
483
- invocations.compact
484
- else
485
- []
495
+ invocations
486
496
  end
487
497
  end
488
498
 
@@ -551,7 +561,7 @@ module Templater
551
561
  end
552
562
 
553
563
  def match_options?(options)
554
- options.all? { |key, value| get_option(key) == value }
564
+ options.all? { |key, value| self.send(key) == value }
555
565
  end
556
566
 
557
567
  def valid_argument?(arg, options, &block)
@@ -2,9 +2,11 @@ module Templater
2
2
 
3
3
  class Proxy #:nodoc:
4
4
 
5
- def initialize(generator, name, source, destination, &block)
6
- @generator, @block, @source, @destination = generator, block, source, destination
7
- @name = name.to_sym
5
+ def initialize(generator, action={})
6
+ @generator = generator
7
+ @block = action[:block]
8
+ @source, @destination = action[:source], action[:destination]
9
+ @name = action[:name]
8
10
  end
9
11
 
10
12
  def source(*source)
@@ -0,0 +1,67 @@
1
+ module Templater
2
+ module Spec
3
+ module Helpers
4
+
5
+ class InvokeMatcher
6
+ def initialize(expected)
7
+ @expected = expected
8
+ end
9
+
10
+ def matches?(actual)
11
+ @actual = actual
12
+ # Satisfy expectation here. Return false or raise an error if it's not met.
13
+ found = nil
14
+ @actual.invocations.each { |i| found = i if i.class == @expected }
15
+
16
+ if @with
17
+ return found && (@with == found.arguments)
18
+ else
19
+ return found
20
+ end
21
+ end
22
+
23
+ def with(*arguments)
24
+ @with = arguments
25
+ return self
26
+ end
27
+
28
+ def failure_message
29
+ "expected #{@actual.inspect} to invoke #{@expected.inspect} with #{@with}, but it didn't"
30
+ end
31
+
32
+ def negative_failure_message
33
+ "expected #{@actual.inspect} not to invoke #{@expected.inspect} with #{@with}, but it did"
34
+ end
35
+ end
36
+
37
+ def invoke(expected)
38
+ InvokeMatcher.new(expected)
39
+ end
40
+
41
+ class CreateMatcher
42
+ def initialize(expected)
43
+ @expected = expected
44
+ end
45
+
46
+ def matches?(actual)
47
+ @actual = actual
48
+ # Satisfy expectation here. Return false or raise an error if it's not met.
49
+ @actual.actions.map{|t| t.destination }.include?(@expected)
50
+ end
51
+
52
+ def failure_message
53
+ "expected #{@actual.inspect} to create #{@expected.inspect}, but it didn't"
54
+ end
55
+
56
+ def negative_failure_message
57
+ "expected #{@actual.inspect} not to create #{@expected.inspect}, but it did"
58
+ end
59
+ end
60
+
61
+ def create(expected)
62
+ CreateMatcher.new(expected)
63
+ end
64
+
65
+ end # Helpers
66
+ end # Spec
67
+ end # Templater
data/lib/templater.rb CHANGED
@@ -40,6 +40,6 @@ module Templater
40
40
  class MalformattedArgumentError < ArgumentError #:nodoc:
41
41
  end
42
42
 
43
- VERSION = '0.1.5'
43
+ VERSION = '0.1.6'
44
44
 
45
45
  end
data/spec/file_spec.rb CHANGED
@@ -88,4 +88,10 @@ describe Templater::Actions::File, '#revoke!' do
88
88
  File.exists?(result_path('path/to/subdir/test2.rbs')).should be_false
89
89
  end
90
90
 
91
+ it "should do nothing when the destination file doesn't exist" do
92
+ file = Templater::Actions::File.new(:monkey, template_path('simple_erb.rbt'), result_path('path/to/subdir/test2.rbs'))
93
+
94
+ lambda { file.revoke! }.should_not raise_error
95
+ end
96
+
91
97
  end
@@ -130,3 +130,84 @@ describe Templater::Generator, '.argument' do
130
130
  end
131
131
 
132
132
  end
133
+
134
+ describe Templater::Generator, '.argument as array' do
135
+
136
+ before do
137
+ @generator_class = Class.new(Templater::Generator)
138
+ @generator_class.argument(0, :monkey)
139
+ @generator_class.argument(1, :llama, :as => :array)
140
+ end
141
+
142
+ it "should allow assignment of arrays" do
143
+ instance = @generator_class.new('/tmp', {}, 'a monkey', %w(an array))
144
+
145
+ instance.monkey.should == 'a monkey'
146
+ instance.llama[0].should == 'an'
147
+ instance.llama[1].should == 'array'
148
+
149
+ instance.llama = %w(another donkey)
150
+ instance.llama[0].should == 'another'
151
+ instance.llama[1].should == 'donkey'
152
+ end
153
+
154
+ it "should convert a single argument to an array" do
155
+ instance = @generator_class.new('/tmp', {}, 'a monkey', 'test')
156
+ instance.llama[0].should == 'test'
157
+ end
158
+
159
+ it "should consume the remaining arguments and convert them to an array" do
160
+ instance = @generator_class.new('/tmp', {}, 'a monkey', 'test', 'silver', 'river')
161
+ instance.llama[0].should == 'test'
162
+ instance.llama[1].should == 'silver'
163
+ instance.llama[2].should == 'river'
164
+ end
165
+
166
+ it "should raise error if the argument is not an array" do
167
+ instance = @generator_class.new('/tmp')
168
+ lambda { instance.llama = :not_an_array }.should raise_error(Templater::MalformattedArgumentError)
169
+ end
170
+
171
+ end
172
+
173
+ describe Templater::Generator, '.argument as hash' do
174
+
175
+ before do
176
+ @generator_class = Class.new(Templater::Generator)
177
+ @generator_class.argument(0, :monkey)
178
+ @generator_class.argument(1, :llama, :as => :hash)
179
+ end
180
+
181
+ it "should allow assignment of hashes" do
182
+ instance = @generator_class.new('/tmp', {}, 'a monkey', { :hash => 'blah' })
183
+
184
+ instance.monkey.should == 'a monkey'
185
+ instance.llama[:hash].should == 'blah'
186
+
187
+ instance.llama = { :me_s_a => :hash }
188
+ instance.llama[:me_s_a].should == :hash
189
+ end
190
+
191
+ it "should convert a key/value pair to a hash" do
192
+ instance = @generator_class.new('/tmp', {}, 'a monkey', 'test:unit')
193
+ instance.llama['test'].should == 'unit'
194
+ end
195
+
196
+ it "should consume the remaining arguments and convert them to a hash if they are key/value pairs" do
197
+ instance = @generator_class.new('/tmp', {}, 'a monkey', 'test:unit', 'john:silver', 'river:road')
198
+ instance.llama['test'].should == 'unit'
199
+ instance.llama['john'].should == 'silver'
200
+ instance.llama['river'].should == 'road'
201
+ end
202
+
203
+ it "should raise an error if one of the remaining arguments is not a key/value pair" do
204
+ lambda { @generator_class.new('/tmp', {}, 'a monkey', 'a:llama', 'duck:llama', 'not_a_pair', 'pair:blah') }.should raise_error(Templater::MalformattedArgumentError)
205
+ end
206
+
207
+ it "should raise error if the argument is neither a hash nor a key/value pair" do
208
+ lambda { @generator_class.new('/tmp', {}, 'a monkey', 23) }.should raise_error(Templater::MalformattedArgumentError)
209
+ instance = @generator_class.new('/tmp')
210
+ lambda { instance.llama = :not_a_hash }.should raise_error(Templater::MalformattedArgumentError)
211
+ end
212
+
213
+ end
@@ -0,0 +1,140 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Templater::Generator, ".empty_directory" do
4
+ before do
5
+ @generator_class = Class.new(Templater::Generator)
6
+ end
7
+
8
+ it "should add an empty_directory" do
9
+ @generator_class.empty_directory(:my_empty_directory, 'path/to/destination.rb')
10
+ @instance = @generator_class.new('/tmp/destination')
11
+
12
+ @instance.stub!(:source_root).and_return('/tmp/source')
13
+
14
+ @instance.empty_directory(:my_empty_directory).destination.should == '/tmp/destination/path/to/destination.rb'
15
+ @instance.empty_directory(:my_empty_directory).should be_an_instance_of(Templater::Actions::EmptyDirectory)
16
+ end
17
+
18
+ it "should add a empty_directory and convert an instruction encoded in the destination" do
19
+ @generator_class.empty_directory(:my_empty_directory, 'template/%another_method%.rb')
20
+ @instance = @generator_class.new('/tmp/destination')
21
+
22
+ @instance.should_receive(:another_method).at_least(:once).and_return('beast')
23
+
24
+ @instance.empty_directory(:my_empty_directory).destination.should == "/tmp/destination/template/beast.rb"
25
+ @instance.empty_directory(:my_empty_directory).should be_an_instance_of(Templater::Actions::EmptyDirectory)
26
+ end
27
+
28
+ it "should add an empty directory with a block" do
29
+ @generator_class.empty_directory(:my_empty_directory) do
30
+ destination "gurr#{Process.pid.to_s}.rb"
31
+ end
32
+ @instance = @generator_class.new('/tmp/destination')
33
+
34
+ @instance.empty_directory(:my_empty_directory).destination.should == "/tmp/destination/gurr#{Process.pid.to_s}.rb"
35
+ @instance.empty_directory(:my_empty_directory).should be_an_instance_of(Templater::Actions::EmptyDirectory)
36
+ end
37
+
38
+ it "should add an empty directory with a complex block" do
39
+ @generator_class.empty_directory(:my_empty_directory) do
40
+ destination 'gurr', "gurr#{something}.rb"
41
+ end
42
+ @instance = @generator_class.new('/tmp/destination')
43
+
44
+ @instance.stub!(:something).and_return('anotherthing')
45
+
46
+ @instance.empty_directory(:my_empty_directory).destination.should == "/tmp/destination/gurr/gurranotherthing.rb"
47
+ @instance.empty_directory(:my_empty_directory).should be_an_instance_of(Templater::Actions::EmptyDirectory)
48
+ end
49
+
50
+ it "should add a empty_directory and leave an encoded instruction be if it doesn't exist as a method" do
51
+ @generator_class.empty_directory(:my_empty_directory, 'template/%some_method%.rb')
52
+ @instance = @generator_class.new('/tmp/destination')
53
+
54
+ @instance.empty_directory(:my_empty_directory).destination.should == "/tmp/destination/template/%some_method%.rb"
55
+ @instance.empty_directory(:my_empty_directory).should be_an_instance_of(Templater::Actions::EmptyDirectory)
56
+ end
57
+ end
58
+
59
+ describe Templater::Generator, '#empty_directories' do
60
+
61
+ before do
62
+ @generator_class = Class.new(Templater::Generator)
63
+ end
64
+
65
+ it "should return all empty directories" do
66
+ @generator_class.empty_directory(:blah1, 'blah.rb')
67
+ @generator_class.empty_directory(:blah2, 'blah2.rb')
68
+
69
+ instance = @generator_class.new('/tmp')
70
+
71
+ instance.empty_directories[0].name.should == :blah1
72
+ instance.empty_directories[1].name.should == :blah2
73
+ end
74
+
75
+ it "should not return empty directories with an option that does not match." do
76
+ @generator_class.option :framework, :default => :rails
77
+
78
+ @generator_class.empty_directory(:merb, 'blah.rb', :framework => :merb)
79
+ @generator_class.empty_directory(:rails, 'blah2.rb', :framework => :rails)
80
+ @generator_class.empty_directory(:none, 'blah2.rb')
81
+
82
+ instance = @generator_class.new('/tmp')
83
+
84
+ instance.empty_directories[0].name.should == :rails
85
+ instance.empty_directories[1].name.should == :none
86
+
87
+ instance.framework = :merb
88
+ instance.empty_directories[0].name.should == :merb
89
+ instance.empty_directories[1].name.should == :none
90
+
91
+ instance.framework = :rails
92
+ instance.empty_directories[0].name.should == :rails
93
+ instance.empty_directories[1].name.should == :none
94
+
95
+ instance.framework = nil
96
+ instance.empty_directories[0].name.should == :none
97
+ end
98
+ end
99
+
100
+ describe Templater::Generator, '#empty_directory' do
101
+
102
+ before do
103
+ @generator_class = Class.new(Templater::Generator)
104
+ end
105
+
106
+ it "should find a empty_directory by name" do
107
+ @generator_class.empty_directory(:blah1, 'blah.rb')
108
+ @generator_class.empty_directory(:blah2, 'blah2.rb')
109
+
110
+ instance = @generator_class.new('/tmp')
111
+
112
+ instance.empty_directory(:blah1).name.should == :blah1
113
+ instance.empty_directory(:blah1).destination.should == '/tmp/blah.rb'
114
+ end
115
+
116
+ it "should not return a empty_directory with an option that does not match." do
117
+ @generator_class.send(:attr_accessor, :framework)
118
+
119
+ @generator_class.empty_directory(:merb, 'blah.rb', :framework => :merb)
120
+ @generator_class.empty_directory(:rails, 'blah2.rb', :framework => :rails)
121
+ @generator_class.empty_directory(:none, 'blah2.rb')
122
+
123
+ instance = @generator_class.new('/tmp')
124
+
125
+ instance.framework = :rails
126
+ instance.empty_directory(:rails).name.should == :rails
127
+ instance.empty_directory(:merb).should be_nil
128
+ instance.empty_directory(:none).name.should == :none
129
+
130
+ instance.framework = :merb
131
+ instance.empty_directory(:rails).should be_nil
132
+ instance.empty_directory(:merb).name.should == :merb
133
+ instance.empty_directory(:none).name.should == :none
134
+
135
+ instance.framework = nil
136
+ instance.empty_directory(:rails).should be_nil
137
+ instance.empty_directory(:merb).should be_nil
138
+ instance.empty_directory(:none).name.should == :none
139
+ end
140
+ end