templater 0.1.5 → 0.1.6

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.
@@ -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