templater 0.1
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/LICENSE +20 -0
- data/README +199 -0
- data/Rakefile +69 -0
- data/TODO +5 -0
- data/lib/templater.rb +44 -0
- data/lib/templater/capture_helpers.rb +62 -0
- data/lib/templater/cli/generator.rb +162 -0
- data/lib/templater/cli/manifold.rb +57 -0
- data/lib/templater/cli/parser.rb +88 -0
- data/lib/templater/core_ext/string.rb +8 -0
- data/lib/templater/file.rb +58 -0
- data/lib/templater/generator.rb +560 -0
- data/lib/templater/manifold.rb +72 -0
- data/lib/templater/proxy.rb +66 -0
- data/lib/templater/template.rb +67 -0
- data/spec/core_ext/string_spec.rb +39 -0
- data/spec/file_spec.rb +74 -0
- data/spec/generator_spec.rb +1011 -0
- data/spec/manifold_spec.rb +77 -0
- data/spec/results/erb.rbs +1 -0
- data/spec/results/file.rbs +1 -0
- data/spec/results/random.rbs +1 -0
- data/spec/results/simple_erb.rbs +1 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/template_spec.rb +124 -0
- data/spec/templater_spec.rb +7 -0
- data/spec/templates/erb.rbt +1 -0
- data/spec/templates/glob/README +1 -0
- data/spec/templates/glob/arg.js +3 -0
- data/spec/templates/glob/subfolder/jessica_alba.jpg +1 -0
- data/spec/templates/glob/subfolder/monkey.rb +1 -0
- data/spec/templates/glob/test.rb +1 -0
- data/spec/templates/literals_erb.rbt +1 -0
- data/spec/templates/simple.rbt +1 -0
- data/spec/templates/simple_erb.rbt +1 -0
- metadata +123 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
module Templater
|
2
|
+
|
3
|
+
module Manifold
|
4
|
+
|
5
|
+
attr_accessor :generators
|
6
|
+
|
7
|
+
# Add a generator to this manifold
|
8
|
+
#
|
9
|
+
# === Parameters
|
10
|
+
# name<Symbol>:: The name given to this generator in the manifold
|
11
|
+
# generator<Templater::Generator>:: The generator class
|
12
|
+
def add(name, generator)
|
13
|
+
@generators ||={}
|
14
|
+
@generators[name.to_sym] = generator
|
15
|
+
generator.manifold = self
|
16
|
+
(class << self; self; end).module_eval <<-MODULE
|
17
|
+
def #{name}
|
18
|
+
generator(:#{name})
|
19
|
+
end
|
20
|
+
MODULE
|
21
|
+
end
|
22
|
+
|
23
|
+
# Remove the generator with the given name from the manifold
|
24
|
+
#
|
25
|
+
# === Parameters
|
26
|
+
# name<Symbol>:: The name of the generator to be removed.
|
27
|
+
def remove(name)
|
28
|
+
@generators.delete(name.to_sym)
|
29
|
+
(class << self; self; end).module_eval <<-MODULE
|
30
|
+
undef #{name}
|
31
|
+
MODULE
|
32
|
+
end
|
33
|
+
|
34
|
+
# Finds the class of a generator, given its name in the manifold.
|
35
|
+
#
|
36
|
+
# === Parameters
|
37
|
+
# name<Symbol>:: The name of the generator to find
|
38
|
+
#
|
39
|
+
# === Returns
|
40
|
+
# Templater::Generator:: The found generator class
|
41
|
+
def generator(name)
|
42
|
+
@generators ||= {}
|
43
|
+
@generators[name.to_sym]
|
44
|
+
end
|
45
|
+
|
46
|
+
# A Shortcut method for invoking the command line interface provided with Templater.
|
47
|
+
#
|
48
|
+
# === Parameters
|
49
|
+
# destination_root<String>:: Where the generated files should be put, this would usually be Dir.pwd
|
50
|
+
# name<String>:: The name of the executable running this generator (such as 'merb-gen')
|
51
|
+
# version<String>:: The version number of the executable.
|
52
|
+
# args<Array[String]>:: An array of arguments to pass into the generator. This would usually be ARGV
|
53
|
+
def run_cli(destination_root, name, version, args)
|
54
|
+
Templater::CLI::Manifold.run(destination_root, self, name, version, args)
|
55
|
+
end
|
56
|
+
|
57
|
+
# If the argument is omitted, simply returns the description for this manifold, otherwise
|
58
|
+
# sets the description to the passed string.
|
59
|
+
#
|
60
|
+
# === Parameters
|
61
|
+
# text<String>:: A description
|
62
|
+
#
|
63
|
+
# === Returns
|
64
|
+
# String:: The description for this manifold
|
65
|
+
def desc(text = nil)
|
66
|
+
@text = text if text
|
67
|
+
return @text.realign_indentation
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Templater
|
2
|
+
|
3
|
+
class Proxy #:nodoc:
|
4
|
+
|
5
|
+
def initialize(name, source, destination, &block)
|
6
|
+
@block, @source, @destination = block, source, destination
|
7
|
+
@name = name.to_sym
|
8
|
+
end
|
9
|
+
|
10
|
+
def source(source)
|
11
|
+
@source = source
|
12
|
+
end
|
13
|
+
|
14
|
+
def destination(dest)
|
15
|
+
@destination = dest
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(method, *args, &block)
|
19
|
+
if @generator
|
20
|
+
@generator.send(method, *args, &block)
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def get_source
|
29
|
+
::File.expand_path(@source.to_s, @generator.source_root)
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_destination
|
33
|
+
::File.expand_path(convert_encoded_instructions(@destination.to_s), @generator.destination_root)
|
34
|
+
end
|
35
|
+
|
36
|
+
def convert_encoded_instructions(filename)
|
37
|
+
filename.gsub(/%.*?%/) do |string|
|
38
|
+
instruction = string.match(/%(.*?)%/)[1]
|
39
|
+
@generator.respond_to?(instruction) ? @generator.send(instruction) : string
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class TemplateProxy < Proxy #:nodoc:
|
46
|
+
|
47
|
+
def to_template(generator)
|
48
|
+
@generator = generator
|
49
|
+
instance_eval(&@block) if @block
|
50
|
+
Templater::Template.new(generator, @name, get_source, get_destination, true)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
class FileProxy < Proxy #:nodoc:
|
56
|
+
|
57
|
+
def to_file(generator)
|
58
|
+
@generator = generator
|
59
|
+
instance_eval(&@block) if @block
|
60
|
+
@generator = nil
|
61
|
+
Templater::File.new(@name, ::File.join(generator.source_root, @source.to_s), ::File.join(generator.destination_root, @destination.to_s))
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Templater
|
2
|
+
class Template
|
3
|
+
|
4
|
+
attr_accessor :context, :name, :source, :destination, :options
|
5
|
+
|
6
|
+
# Builds a new template, given the context (e.g. binding) in which the template will be rendered
|
7
|
+
# (usually a generator), the name of the template and its source and destination.
|
8
|
+
#
|
9
|
+
# === Parameters
|
10
|
+
# context<Object>:: Context for rendering
|
11
|
+
# name<Symbol>:: The name of this template
|
12
|
+
# source<String>:: Full path to the source of this template
|
13
|
+
# destination<String>:: Full path to the destination of this template
|
14
|
+
# render<Boolean>:: If set to false, will do a copy instead of rendering.
|
15
|
+
def initialize(context, name, source, destination, render = true)
|
16
|
+
@context = context
|
17
|
+
@name = name
|
18
|
+
@source = source
|
19
|
+
@destination = destination
|
20
|
+
@options = { :render => render }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the destination path relative to Dir.pwd. This is useful for prettier output in interfaces
|
24
|
+
# where the destination root is Dir.pwd.
|
25
|
+
#
|
26
|
+
# === Returns
|
27
|
+
# String:: The destination relative to Dir.pwd
|
28
|
+
def relative_destination
|
29
|
+
@destination.sub(::Dir.pwd + '/', '')
|
30
|
+
end
|
31
|
+
|
32
|
+
# Renders the template using ERB and returns the result as a String.
|
33
|
+
#
|
34
|
+
# === Returns
|
35
|
+
# String:: The rendered template.
|
36
|
+
def render
|
37
|
+
ERB.new(::File.read(source), nil, '-').result(context.send(:binding))
|
38
|
+
end
|
39
|
+
|
40
|
+
# Checks if the destination file already exists.
|
41
|
+
#
|
42
|
+
# === Returns
|
43
|
+
# Boolean:: true if the file exists, false otherwise.
|
44
|
+
def exists?
|
45
|
+
::File.exists?(destination)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Checks if the content of the file at the destination is identical to the rendered result.
|
49
|
+
#
|
50
|
+
# === Returns
|
51
|
+
# Boolean:: true if it is identical, false otherwise.
|
52
|
+
def identical?
|
53
|
+
::File.read(destination) == render if ::File.exists?(destination)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Renders the template and copies it to the destination.
|
57
|
+
def invoke!
|
58
|
+
::FileUtils.mkdir_p(::File.dirname(destination))
|
59
|
+
if options[:render]
|
60
|
+
::File.open(destination, 'w') {|f| f.write render }
|
61
|
+
else
|
62
|
+
::FileUtils.copy_file(source, destination)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe String, '#strip_indentation!' do
|
4
|
+
|
5
|
+
it "should remove unneccessary whitespace from the beginning of a line" do
|
6
|
+
|
7
|
+
a_string = <<-STRING
|
8
|
+
here be something
|
9
|
+
STRING
|
10
|
+
|
11
|
+
a_string.realign_indentation.should == <<-STRING
|
12
|
+
here be something
|
13
|
+
STRING
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should remove unneccessary whitespace from the beginning of all lines, but keep indentation" do
|
18
|
+
|
19
|
+
a_string = <<-STRING
|
20
|
+
here be something
|
21
|
+
indented
|
22
|
+
more
|
23
|
+
blah
|
24
|
+
test
|
25
|
+
gurr
|
26
|
+
STRING
|
27
|
+
|
28
|
+
a_string.realign_indentation.should == <<-STRING
|
29
|
+
here be something
|
30
|
+
indented
|
31
|
+
more
|
32
|
+
blah
|
33
|
+
test
|
34
|
+
gurr
|
35
|
+
STRING
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Templater::File, '.new' do
|
4
|
+
it "should set name, source and destination" do
|
5
|
+
file = Templater::File.new(:monkey, '/path/to/source', '/path/to/destination')
|
6
|
+
file.name.should == :monkey
|
7
|
+
file.source.should == '/path/to/source'
|
8
|
+
file.destination.should == '/path/to/destination'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Templater::File, '#relative_destination' do
|
13
|
+
it "should get the destination relative to the pwd" do
|
14
|
+
Dir.stub!(:pwd).and_return('/path/to')
|
15
|
+
file = Templater::File.new(:monkey, '/path/to/source', '/path/to/destination/with/some/more/subdirs')
|
16
|
+
file.relative_destination.should == 'destination/with/some/more/subdirs'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Templater::File, '#render' do
|
21
|
+
it "should output the file" do
|
22
|
+
file = Templater::File.new(:monkey, template_path('simple_erb.rbt'), '/path/to/destination')
|
23
|
+
file.render.should == "test<%= 1+1 %>test"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe Templater::File, '#exists?' do
|
28
|
+
|
29
|
+
it "should exist if the destination file exists" do
|
30
|
+
file = Templater::File.new(:monkey, template_path('simple.rbt'), result_path('erb.rbs'))
|
31
|
+
file.should be_exists
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not exist if the destination file does not exist" do
|
35
|
+
file = Templater::File.new(:monkey, template_path('simple.rbt'), result_path('some_weird_file.rbs'))
|
36
|
+
file.should_not be_exists
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Templater::File, '#identical' do
|
42
|
+
|
43
|
+
it "should not be identical if the destination file doesn't exist" do
|
44
|
+
file = Templater::File.new(:monkey, template_path('simple_erb.rbt'), result_path('some_weird_file.rbs'))
|
45
|
+
file.should_not be_identical
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not be identical if the destination file is not identical to the source file" do
|
49
|
+
file = Templater::File.new(:monkey, template_path('simple_erb.rbt'), result_path('simple_erb.rbs'))
|
50
|
+
file.should be_exists
|
51
|
+
file.should_not be_identical
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be identical if the destination file is identical to the source file" do
|
55
|
+
file= Templater::File.new(:monkey, template_path('simple_erb.rbt'), result_path('file.rbs'))
|
56
|
+
file.should be_exists
|
57
|
+
file.should be_identical
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe Templater::File, '#invoke!' do
|
62
|
+
|
63
|
+
it "should copy the source file to the destination" do
|
64
|
+
file = Templater::File.new(:monkey, template_path('simple_erb.rbt'), result_path('path/to/subdir/test2.rbs'))
|
65
|
+
|
66
|
+
file.invoke!
|
67
|
+
|
68
|
+
File.exists?(result_path('path/to/subdir/test2.rbs')).should be_true
|
69
|
+
FileUtils.identical?(template_path('simple_erb.rbt'), result_path('path/to/subdir/test2.rbs')).should be_true
|
70
|
+
|
71
|
+
# cleanup
|
72
|
+
FileUtils.rm_rf(result_path('path'))
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,1011 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Templater::Generator, '#desc' do
|
4
|
+
|
5
|
+
it "should append text when called with an argument, and return it when called with no argument" do
|
6
|
+
@generator_class = Class.new(Templater::Generator)
|
7
|
+
|
8
|
+
@generator_class.desc "some text"
|
9
|
+
@generator_class.desc.should == "some text"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Templater::Generator, '.argument' do
|
15
|
+
|
16
|
+
before do
|
17
|
+
@generator_class = Class.new(Templater::Generator)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should create accessors" do
|
21
|
+
@generator_class.argument(0, :monkey)
|
22
|
+
|
23
|
+
instance = @generator_class.new('/tmp')
|
24
|
+
instance.monkey = 'a test'
|
25
|
+
instance.monkey.should == 'a test'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should pass an initial value to the argument" do
|
29
|
+
@generator_class.argument(0, :monkey)
|
30
|
+
|
31
|
+
instance = @generator_class.new('/tmp', {}, 'i am a monkey')
|
32
|
+
instance.monkey.should == 'i am a monkey'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should create multiple accessors" do
|
36
|
+
@generator_class.argument(0, :monkey)
|
37
|
+
@generator_class.argument(1, :llama)
|
38
|
+
@generator_class.argument(2, :herd)
|
39
|
+
|
40
|
+
instance = @generator_class.new('/tmp')
|
41
|
+
instance.monkey = 'a monkey'
|
42
|
+
instance.monkey.should == 'a monkey'
|
43
|
+
instance.llama = 'a llama'
|
44
|
+
instance.llama.should == 'a llama'
|
45
|
+
instance.herd = 'a herd'
|
46
|
+
instance.herd.should == 'a herd'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should pass an initial value to multiple accessors" do
|
50
|
+
@generator_class.argument(0, :monkey)
|
51
|
+
@generator_class.argument(1, :llama)
|
52
|
+
@generator_class.argument(2, :herd)
|
53
|
+
|
54
|
+
instance = @generator_class.new('/tmp', {}, 'a monkey', 'a llama', 'a herd')
|
55
|
+
instance.monkey.should == 'a monkey'
|
56
|
+
instance.llama.should == 'a llama'
|
57
|
+
instance.herd.should == 'a herd'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set a default value for an argument" do
|
61
|
+
@generator_class.argument(0, :monkey, :default => 'a revision')
|
62
|
+
|
63
|
+
instance = @generator_class.new('/tmp')
|
64
|
+
instance.monkey.should == 'a revision'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should allow some syntactic sugar declaration" do
|
68
|
+
@generator_class.first_argument(:monkey)
|
69
|
+
@generator_class.second_argument(:llama)
|
70
|
+
@generator_class.third_argument(:herd)
|
71
|
+
@generator_class.fourth_argument(:elephant)
|
72
|
+
|
73
|
+
instance = @generator_class.new('/tmp', {}, 'a monkey', 'a llama', 'a herd', 'an elephant')
|
74
|
+
instance.monkey.should == 'a monkey'
|
75
|
+
instance.llama.should == 'a llama'
|
76
|
+
instance.herd.should == 'a herd'
|
77
|
+
instance.elephant.should == 'an elephant'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should whine when there are too many arguments" do
|
81
|
+
@generator_class.argument(0, :monkey)
|
82
|
+
@generator_class.argument(1, :llama)
|
83
|
+
|
84
|
+
lambda { @generator_class.new('/tmp', {}, 'a monkey', 'a llama', 'a herd') }.should raise_error(Templater::TooManyArgumentsError)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should assign arguments if an argument is required and that requirement is fullfilled" do
|
88
|
+
@generator_class.argument(0, :monkey, :required => true)
|
89
|
+
@generator_class.argument(1, :elephant, :required => true)
|
90
|
+
@generator_class.argument(2, :llama)
|
91
|
+
|
92
|
+
instance = @generator_class.new('/tmp', {}, 'enough', 'arguments')
|
93
|
+
instance.monkey.should == "enough"
|
94
|
+
instance.elephant.should == "arguments"
|
95
|
+
instance.llama.should be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should raise an error when a required argument is not passed" do
|
99
|
+
@generator_class.argument(0, :monkey, :required => true)
|
100
|
+
@generator_class.argument(1, :elephant, :required => true)
|
101
|
+
@generator_class.argument(2, :llama)
|
102
|
+
|
103
|
+
lambda { @generator_class.new('/tmp', {}, 'too few arguments') }.should raise_error(Templater::TooFewArgumentsError)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should raise an error if nil is assigned to a require argument" do
|
107
|
+
@generator_class.argument(0, :monkey, :required => true)
|
108
|
+
|
109
|
+
instance = @generator_class.new('/tmp', {}, 'test')
|
110
|
+
|
111
|
+
lambda { instance.monkey = nil }.should raise_error(Templater::TooFewArgumentsError)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should assign an argument when a block appended to an argument does not throw :invalid" do
|
115
|
+
@generator_class.argument(0, :monkey) do
|
116
|
+
1 + 1
|
117
|
+
end
|
118
|
+
@generator_class.argument(1, :elephant) do
|
119
|
+
false
|
120
|
+
end
|
121
|
+
@generator_class.argument(2, :llama)
|
122
|
+
|
123
|
+
instance = @generator_class.new('/tmp', {}, 'blah', 'urgh')
|
124
|
+
instance.monkey.should == 'blah'
|
125
|
+
instance.elephant.should == 'urgh'
|
126
|
+
|
127
|
+
instance.monkey = :harr
|
128
|
+
instance.monkey.should == :harr
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should raise an error with the throw message, when a block is appended to an argument and throws :invalid" do
|
132
|
+
@generator_class.argument(0, :monkey) do
|
133
|
+
throw :invalid, 'this is not a valid monkey, bad monkey!'
|
134
|
+
end
|
135
|
+
|
136
|
+
lambda { @generator_class.new('/tmp', {}, 'blah') }.should raise_error(Templater::ArgumentError, 'this is not a valid monkey, bad monkey!')
|
137
|
+
|
138
|
+
instance = @generator_class.new('/tmp')
|
139
|
+
|
140
|
+
lambda { instance.monkey = :anything }.should raise_error(Templater::ArgumentError, 'this is not a valid monkey, bad monkey!')
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
describe Templater::Generator, '.argument as hash' do
|
146
|
+
|
147
|
+
before do
|
148
|
+
@generator_class = Class.new(Templater::Generator)
|
149
|
+
@generator_class.argument(0, :monkey)
|
150
|
+
@generator_class.argument(1, :llama, :as => :hash)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should allow assignment of hashes" do
|
154
|
+
instance = @generator_class.new('/tmp', {}, 'a monkey', { :hash => 'blah' })
|
155
|
+
|
156
|
+
instance.monkey.should == 'a monkey'
|
157
|
+
instance.llama[:hash].should == 'blah'
|
158
|
+
|
159
|
+
instance.llama = { :me_s_a => :hash }
|
160
|
+
instance.llama[:me_s_a].should == :hash
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should convert a key/value pair to a hash" do
|
164
|
+
instance = @generator_class.new('/tmp', {}, 'a monkey', 'test:unit')
|
165
|
+
instance.llama['test'].should == 'unit'
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should consume the remaining arguments and convert them to a hash if they are key/value pairs" do
|
169
|
+
instance = @generator_class.new('/tmp', {}, 'a monkey', 'test:unit', 'john:silver', 'river:road')
|
170
|
+
instance.llama['test'].should == 'unit'
|
171
|
+
instance.llama['john'].should == 'silver'
|
172
|
+
instance.llama['river'].should == 'road'
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should raise an error if one of the remaining arguments is not a key/value pair" do
|
176
|
+
lambda { @generator_class.new('/tmp', {}, 'a monkey', 'a:llama', 'duck:llama', 'not_a_pair', 'pair:blah') }.should raise_error(Templater::MalformattedArgumentError)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should raise error if the argument is neither a hash nor a key/value pair" do
|
180
|
+
lambda { @generator_class.new('/tmp', {}, 'a monkey', 23) }.should raise_error(Templater::MalformattedArgumentError)
|
181
|
+
instance = @generator_class.new('/tmp')
|
182
|
+
lambda { instance.llama = :not_a_hash }.should raise_error(Templater::MalformattedArgumentError)
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
describe Templater::Generator, '.argument as array' do
|
188
|
+
|
189
|
+
before do
|
190
|
+
@generator_class = Class.new(Templater::Generator)
|
191
|
+
@generator_class.argument(0, :monkey)
|
192
|
+
@generator_class.argument(1, :llama, :as => :array)
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should allow assignment of arrays" do
|
196
|
+
instance = @generator_class.new('/tmp', {}, 'a monkey', %w(an array))
|
197
|
+
|
198
|
+
instance.monkey.should == 'a monkey'
|
199
|
+
instance.llama[0].should == 'an'
|
200
|
+
instance.llama[1].should == 'array'
|
201
|
+
|
202
|
+
instance.llama = %w(another donkey)
|
203
|
+
instance.llama[0].should == 'another'
|
204
|
+
instance.llama[1].should == 'donkey'
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should convert a single argument to an array" do
|
208
|
+
instance = @generator_class.new('/tmp', {}, 'a monkey', 'test')
|
209
|
+
instance.llama[0].should == 'test'
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should consume the remaining arguments and convert them to an array" do
|
213
|
+
instance = @generator_class.new('/tmp', {}, 'a monkey', 'test', 'silver', 'river')
|
214
|
+
instance.llama[0].should == 'test'
|
215
|
+
instance.llama[1].should == 'silver'
|
216
|
+
instance.llama[2].should == 'river'
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should raise error if the argument is not an array" do
|
220
|
+
instance = @generator_class.new('/tmp')
|
221
|
+
lambda { instance.llama = :not_an_array }.should raise_error(Templater::MalformattedArgumentError)
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
describe Templater::Generator, '.template' do
|
227
|
+
|
228
|
+
before do
|
229
|
+
@generator_class = Class.new(Templater::Generator)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should add a template with source and destination" do
|
233
|
+
@generator_class.template(:my_template, 'path/to/source.rbt', 'path/to/destination.rb')
|
234
|
+
@instance = @generator_class.new('/tmp/destination')
|
235
|
+
|
236
|
+
@instance.stub!(:source_root).and_return('/tmp/source')
|
237
|
+
|
238
|
+
@instance.template(:my_template).source.should == '/tmp/source/path/to/source.rbt'
|
239
|
+
@instance.template(:my_template).destination.should == '/tmp/destination/path/to/destination.rb'
|
240
|
+
@instance.template(:my_template).should be_an_instance_of(Templater::Template)
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should add a template with absolute source and destination" do
|
244
|
+
@generator_class.template(:my_template, '/path/to/source.rbt', '/path/to/destination.rb')
|
245
|
+
@instance = @generator_class.new('/tmp/destination')
|
246
|
+
|
247
|
+
@instance.stub!(:source_root).and_return('/tmp/source')
|
248
|
+
|
249
|
+
@instance.template(:my_template).source.should == '/path/to/source.rbt'
|
250
|
+
@instance.template(:my_template).destination.should == '/path/to/destination.rb'
|
251
|
+
@instance.template(:my_template).should be_an_instance_of(Templater::Template)
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should add a template with destination and infer the source" do
|
255
|
+
@generator_class.template(:my_template, 'path/to/destination.rb')
|
256
|
+
@instance = @generator_class.new('/tmp/destination')
|
257
|
+
|
258
|
+
@instance.stub!(:source_root).and_return('/tmp/source')
|
259
|
+
|
260
|
+
@instance.template(:my_template).source.should == '/tmp/source/path/to/destination.rbt'
|
261
|
+
@instance.template(:my_template).destination.should == '/tmp/destination/path/to/destination.rb'
|
262
|
+
@instance.template(:my_template).should be_an_instance_of(Templater::Template)
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should add a template with a block" do
|
266
|
+
@generator_class.template(:my_template) do
|
267
|
+
source 'blah.rbt'
|
268
|
+
destination "gurr#{Process.pid.to_s}.rb"
|
269
|
+
end
|
270
|
+
@instance = @generator_class.new('/tmp/destination')
|
271
|
+
|
272
|
+
@instance.stub!(:source_root).and_return('/tmp/source')
|
273
|
+
|
274
|
+
@instance.template(:my_template).source.should == '/tmp/source/blah.rbt'
|
275
|
+
@instance.template(:my_template).destination.should == "/tmp/destination/gurr#{Process.pid.to_s}.rb"
|
276
|
+
@instance.template(:my_template).should be_an_instance_of(Templater::Template)
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should add a template and convert an with an instruction encoded in the destination, but not one encoded in the source" do
|
280
|
+
@generator_class.template(:my_template, 'template/%some_method%.rbt', 'template/%another_method%.rb')
|
281
|
+
@instance = @generator_class.new('/tmp/destination')
|
282
|
+
|
283
|
+
@instance.stub!(:source_root).and_return('/tmp/source')
|
284
|
+
@instance.should_not_receive(:some_method)
|
285
|
+
@instance.should_receive(:another_method).at_least(:once).and_return('beast')
|
286
|
+
|
287
|
+
@instance.template(:my_template).source.should == '/tmp/source/template/%some_method%.rbt'
|
288
|
+
@instance.template(:my_template).destination.should == "/tmp/destination/template/beast.rb"
|
289
|
+
@instance.template(:my_template).should be_an_instance_of(Templater::Template)
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should add a template and leave an encoded instruction be if it doesn't exist as a method" do
|
293
|
+
@generator_class.template(:my_template, 'template/blah.rbt', 'template/%some_method%.rb')
|
294
|
+
@instance = @generator_class.new('/tmp/destination')
|
295
|
+
|
296
|
+
@instance.stub!(:source_root).and_return('/tmp/source')
|
297
|
+
|
298
|
+
@instance.template(:my_template).destination.should == "/tmp/destination/template/%some_method%.rb"
|
299
|
+
@instance.template(:my_template).should be_an_instance_of(Templater::Template)
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
describe Templater::Generator, '.file' do
|
305
|
+
|
306
|
+
before do
|
307
|
+
@generator_class = Class.new(Templater::Generator)
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should add a file with source and destination" do
|
311
|
+
@generator_class.file(:my_template, 'path/to/source.rbt', 'path/to/destination.rb')
|
312
|
+
@instance = @generator_class.new('/tmp/destination')
|
313
|
+
|
314
|
+
@instance.stub!(:source_root).and_return('/tmp/source')
|
315
|
+
|
316
|
+
@instance.file(:my_template).source.should == '/tmp/source/path/to/source.rbt'
|
317
|
+
@instance.file(:my_template).destination.should == '/tmp/destination/path/to/destination.rb'
|
318
|
+
@instance.file(:my_template).should be_an_instance_of(Templater::File)
|
319
|
+
end
|
320
|
+
|
321
|
+
it "should add a file with source and infer destination " do
|
322
|
+
@generator_class.file(:my_template, 'path/to/file.rb')
|
323
|
+
@instance = @generator_class.new('/tmp/destination')
|
324
|
+
|
325
|
+
@instance.stub!(:source_root).and_return('/tmp/source')
|
326
|
+
|
327
|
+
@instance.file(:my_template).source.should == '/tmp/source/path/to/file.rb'
|
328
|
+
@instance.file(:my_template).destination.should == '/tmp/destination/path/to/file.rb'
|
329
|
+
@instance.file(:my_template).should be_an_instance_of(Templater::File)
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
describe Templater::Generator, '.invoke' do
|
335
|
+
|
336
|
+
before do
|
337
|
+
@generator_class = Class.new(Templater::Generator)
|
338
|
+
@generator_class.first_argument :test1
|
339
|
+
@generator_class.second_argument :test2
|
340
|
+
|
341
|
+
@invoked_generator = mock('an invoked generator')
|
342
|
+
@invoked_instance = mock('an instance of the invoked generator')
|
343
|
+
@invoked_generator.stub!(:new).and_return(@invoked_instance)
|
344
|
+
|
345
|
+
@manifold = mock('a manifold')
|
346
|
+
@manifold.stub!(:generator).with(:test).and_return(@invoked_generator)
|
347
|
+
end
|
348
|
+
|
349
|
+
it "should add nothing if there is no manifold" do
|
350
|
+
@generator_class.invoke(:test)
|
351
|
+
@instance = @generator_class.new('/tmp', {}, 'test', 'argument')
|
352
|
+
|
353
|
+
@instance.invocations.should be_empty
|
354
|
+
end
|
355
|
+
|
356
|
+
describe "with no block" do
|
357
|
+
|
358
|
+
before(:each) do
|
359
|
+
@generator_class.stub!(:manifold).and_return(@manifold)
|
360
|
+
end
|
361
|
+
|
362
|
+
it "should return the instantiaded template" do
|
363
|
+
@generator_class.invoke(:test)
|
364
|
+
@instance = @generator_class.new('/tmp', {}, 'test', 'argument')
|
365
|
+
|
366
|
+
@instance.invocations.first.should == @invoked_instance
|
367
|
+
end
|
368
|
+
|
369
|
+
it "should ask the manifold for the generator" do
|
370
|
+
@generator_class.should_receive(:manifold).at_least(:once).and_return(@manifold)
|
371
|
+
@manifold.should_receive(:generator).with(:test).and_return(@invoked_generator)
|
372
|
+
@generator_class.invoke(:test)
|
373
|
+
@instance = @generator_class.new('/tmp', {}, 'test', 'argument')
|
374
|
+
|
375
|
+
@instance.invocations.first.should == @invoked_instance
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should instantiate the generator with the correct arguments" do
|
379
|
+
@invoked_generator.should_receive(:new).with('/tmp', {}, 'test', 'argument').and_return(@invoked_instance)
|
380
|
+
@generator_class.invoke(:test)
|
381
|
+
@instance = @generator_class.new('/tmp', {}, 'test', 'argument')
|
382
|
+
|
383
|
+
@instance.invocations.first.should == @invoked_instance
|
384
|
+
end
|
385
|
+
|
386
|
+
end
|
387
|
+
|
388
|
+
describe "with a block" do
|
389
|
+
|
390
|
+
before(:each) do
|
391
|
+
@generator_class.stub!(:manifold).and_return(@manifold)
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should pass the generator class to the block and return the result of it" do
|
395
|
+
@generator_class.invoke(:test) do |generator|
|
396
|
+
generator.new(destination_root, options, 'blah', 'monkey', some_method)
|
397
|
+
end
|
398
|
+
@instance = @generator_class.new('/tmp', {}, 'test', 'argument')
|
399
|
+
|
400
|
+
@instance.should_receive(:some_method).and_return('da')
|
401
|
+
@invoked_generator.should_receive(:new).with('/tmp', {}, 'blah', 'monkey', 'da').and_return(@invoked_instance)
|
402
|
+
|
403
|
+
@instance.invocations.first.should == @invoked_instance
|
404
|
+
end
|
405
|
+
|
406
|
+
it "should ask the manifold for the generator" do
|
407
|
+
@generator_class.should_receive(:manifold).at_least(:once).and_return(@manifold)
|
408
|
+
@manifold.should_receive(:generator).with(:test).and_return(@invoked_generator)
|
409
|
+
|
410
|
+
@generator_class.invoke(:test) do |generator|
|
411
|
+
generator.new(destination_root, options, 'blah', 'monkey')
|
412
|
+
end
|
413
|
+
|
414
|
+
@instance = @generator_class.new('/tmp', {}, 'test', 'argument')
|
415
|
+
@instance.invocations.first.should == @invoked_instance
|
416
|
+
end
|
417
|
+
|
418
|
+
end
|
419
|
+
|
420
|
+
end
|
421
|
+
|
422
|
+
describe Templater::Generator, '.template_list' do
|
423
|
+
|
424
|
+
it "should add a series of templates given a list as heredoc" do
|
425
|
+
@generator_class = Class.new(Templater::Generator)
|
426
|
+
|
427
|
+
@generator_class.should_receive(:template).with(:app_model_rb, 'app/model.rb')
|
428
|
+
@generator_class.should_receive(:template).with(:spec_model_rb, 'spec/model.rb')
|
429
|
+
@generator_class.should_receive(:template).with(:donkey_poo_css, 'donkey/poo.css')
|
430
|
+
@generator_class.should_receive(:template).with(:john_smith_file_rb, 'john/smith/file.rb')
|
431
|
+
|
432
|
+
@generator_class.template_list <<-LIST
|
433
|
+
app/model.rb
|
434
|
+
spec/model.rb
|
435
|
+
donkey/poo.css
|
436
|
+
john/smith/file.rb
|
437
|
+
LIST
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should add a series of templates given a list as array" do
|
441
|
+
@generator_class = Class.new(Templater::Generator)
|
442
|
+
|
443
|
+
@generator_class.should_receive(:template).with(:app_model_rb, 'app/model.rb')
|
444
|
+
@generator_class.should_receive(:template).with(:spec_model_rb, 'spec/model.rb')
|
445
|
+
@generator_class.should_receive(:template).with(:donkey_poo_css, 'donkey/poo.css')
|
446
|
+
@generator_class.should_receive(:template).with(:john_smith_file_rb, 'john/smith/file.rb')
|
447
|
+
|
448
|
+
@generator_class.template_list(%w(app/model.rb spec/model.rb donkey/poo.css john/smith/file.rb))
|
449
|
+
end
|
450
|
+
|
451
|
+
end
|
452
|
+
|
453
|
+
describe Templater::Generator, '.file_list' do
|
454
|
+
|
455
|
+
it "should add a series of files given a list as heredoc" do
|
456
|
+
@generator_class = Class.new(Templater::Generator)
|
457
|
+
|
458
|
+
@generator_class.should_receive(:file).with(:app_model_rb, 'app/model.rb')
|
459
|
+
@generator_class.should_receive(:file).with(:spec_model_rb, 'spec/model.rb')
|
460
|
+
@generator_class.should_receive(:file).with(:donkey_poo_css, 'donkey/poo.css')
|
461
|
+
@generator_class.should_receive(:file).with(:john_smith_file_rb, 'john/smith/file.rb')
|
462
|
+
|
463
|
+
@generator_class.file_list <<-LIST
|
464
|
+
app/model.rb
|
465
|
+
spec/model.rb
|
466
|
+
donkey/poo.css
|
467
|
+
john/smith/file.rb
|
468
|
+
LIST
|
469
|
+
end
|
470
|
+
|
471
|
+
it "should add a series of files given a list as array" do
|
472
|
+
@generator_class = Class.new(Templater::Generator)
|
473
|
+
|
474
|
+
@generator_class.should_receive(:file).with(:app_model_rb, 'app/model.rb')
|
475
|
+
@generator_class.should_receive(:file).with(:spec_model_rb, 'spec/model.rb')
|
476
|
+
@generator_class.should_receive(:file).with(:donkey_poo_css, 'donkey/poo.css')
|
477
|
+
@generator_class.should_receive(:file).with(:john_smith_file_rb, 'john/smith/file.rb')
|
478
|
+
|
479
|
+
@generator_class.file_list(%w(app/model.rb spec/model.rb donkey/poo.css john/smith/file.rb))
|
480
|
+
end
|
481
|
+
|
482
|
+
end
|
483
|
+
|
484
|
+
describe Templater::Generator, '.glob!' do
|
485
|
+
|
486
|
+
before do
|
487
|
+
@generator_class = Class.new(Templater::Generator)
|
488
|
+
@generator_class.stub!(:source_root).and_return(template_path('glob'))
|
489
|
+
end
|
490
|
+
|
491
|
+
it "should add templates and files in the source_root based on if their extensions are in the template_extensions array" do
|
492
|
+
@generator_class.glob!()
|
493
|
+
|
494
|
+
@instance = @generator_class.new('/tmp/destination')
|
495
|
+
|
496
|
+
@instance.template(:arg_js).source.should == template_path('glob/arg.js')
|
497
|
+
@instance.template(:arg_js).destination.should == "/tmp/destination/arg.js"
|
498
|
+
|
499
|
+
@instance.template(:test_rb).source.should == template_path('glob/test.rb')
|
500
|
+
@instance.template(:test_rb).destination.should == "/tmp/destination/test.rb"
|
501
|
+
|
502
|
+
@instance.file(:subfolder_jessica_alba_jpg).source.should == template_path('glob/subfolder/jessica_alba.jpg')
|
503
|
+
@instance.file(:subfolder_jessica_alba_jpg).destination.should == '/tmp/destination/subfolder/jessica_alba.jpg'
|
504
|
+
end
|
505
|
+
|
506
|
+
it "should add templates and files with a different template_extensions array" do
|
507
|
+
@generator_class.glob!(nil, %w(jpg))
|
508
|
+
|
509
|
+
@instance = @generator_class.new('/tmp/destination')
|
510
|
+
|
511
|
+
@instance.file(:arg_js).source.should == template_path('glob/arg.js')
|
512
|
+
@instance.file(:arg_js).destination.should == "/tmp/destination/arg.js"
|
513
|
+
|
514
|
+
@instance.file(:test_rb).source.should == template_path('glob/test.rb')
|
515
|
+
@instance.file(:test_rb).destination.should == "/tmp/destination/test.rb"
|
516
|
+
|
517
|
+
@instance.template(:subfolder_jessica_alba_jpg).source.should == template_path('glob/subfolder/jessica_alba.jpg')
|
518
|
+
@instance.template(:subfolder_jessica_alba_jpg).destination.should == '/tmp/destination/subfolder/jessica_alba.jpg'
|
519
|
+
end
|
520
|
+
|
521
|
+
it "should glob in a subdirectory" do
|
522
|
+
@generator_class.stub!(:source_root).and_return(template_path(""))
|
523
|
+
@generator_class.glob!('glob', %w(jpg))
|
524
|
+
|
525
|
+
@instance = @generator_class.new('/tmp/destination')
|
526
|
+
|
527
|
+
@instance.file(:glob_arg_js).source.should == template_path('glob/arg.js')
|
528
|
+
@instance.file(:glob_arg_js).destination.should == "/tmp/destination/glob/arg.js"
|
529
|
+
|
530
|
+
@instance.file(:glob_test_rb).source.should == template_path('glob/test.rb')
|
531
|
+
@instance.file(:glob_test_rb).destination.should == "/tmp/destination/glob/test.rb"
|
532
|
+
|
533
|
+
@instance.template(:glob_subfolder_jessica_alba_jpg).source.should == template_path('glob/subfolder/jessica_alba.jpg')
|
534
|
+
@instance.template(:glob_subfolder_jessica_alba_jpg).destination.should == '/tmp/destination/glob/subfolder/jessica_alba.jpg'
|
535
|
+
end
|
536
|
+
|
537
|
+
it "should add only the given templates and files" do
|
538
|
+
@generator_class.glob!()
|
539
|
+
|
540
|
+
@instance = @generator_class.new('/tmp/destination')
|
541
|
+
|
542
|
+
@instance.templates.map { |t| t.name }.should == [
|
543
|
+
:arg_js,
|
544
|
+
:subfolder_monkey_rb,
|
545
|
+
:test_rb,
|
546
|
+
]
|
547
|
+
@instance.files.map { |f| f.name }.should == [
|
548
|
+
:readme,
|
549
|
+
:subfolder_jessica_alba_jpg
|
550
|
+
]
|
551
|
+
end
|
552
|
+
|
553
|
+
end
|
554
|
+
|
555
|
+
describe Templater::Generator, '.option' do
|
556
|
+
|
557
|
+
before do
|
558
|
+
@generator_class = Class.new(Templater::Generator)
|
559
|
+
end
|
560
|
+
|
561
|
+
it "should add accessors" do
|
562
|
+
@generator_class.option(:test)
|
563
|
+
|
564
|
+
instance = @generator_class.new('/tmp')
|
565
|
+
|
566
|
+
instance.test = "monkey"
|
567
|
+
instance.test.should == "monkey"
|
568
|
+
|
569
|
+
end
|
570
|
+
|
571
|
+
it "should preset a default value" do
|
572
|
+
@generator_class.option(:test, :default => 'elephant')
|
573
|
+
|
574
|
+
instance = @generator_class.new('/tmp')
|
575
|
+
|
576
|
+
instance.test.should == "elephant"
|
577
|
+
end
|
578
|
+
|
579
|
+
it "should allow overwriting of default values" do
|
580
|
+
@generator_class.option(:test, :default => 'elephant')
|
581
|
+
|
582
|
+
instance = @generator_class.new('/tmp')
|
583
|
+
|
584
|
+
instance.test.should == "elephant"
|
585
|
+
instance.test = "monkey"
|
586
|
+
instance.test.should == "monkey"
|
587
|
+
end
|
588
|
+
|
589
|
+
it "should allow passing in of options on generator creation" do
|
590
|
+
@generator_class.option(:test, :default => 'elephant')
|
591
|
+
|
592
|
+
instance = @generator_class.new('/tmp', { :test => 'freebird' })
|
593
|
+
|
594
|
+
instance.test.should == "freebird"
|
595
|
+
instance.test = "monkey"
|
596
|
+
instance.test.should == "monkey"
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
describe Templater::Generator, '.generators' do
|
601
|
+
|
602
|
+
before do
|
603
|
+
@generator_class = Class.new(Templater::Generator)
|
604
|
+
|
605
|
+
@g1 = Class.new(Templater::Generator)
|
606
|
+
@g2 = Class.new(Templater::Generator)
|
607
|
+
@g3 = Class.new(Templater::Generator)
|
608
|
+
@g4 = Class.new(Templater::Generator)
|
609
|
+
|
610
|
+
@manifold = mock('a manifold')
|
611
|
+
@manifold.stub!(:generator).with(:monkey).and_return(@g1)
|
612
|
+
@manifold.stub!(:generator).with(:blah).and_return(@g2)
|
613
|
+
@manifold.stub!(:generator).with(:duck).and_return(@g3)
|
614
|
+
@manifold.stub!(:generator).with(:llama).and_return(@g4)
|
615
|
+
@manifold.stub!(:generator).with(:i_dont_exist).and_return(nil)
|
616
|
+
|
617
|
+
@generator_class.manifold = @manifold
|
618
|
+
@g1.manifold = @manifold
|
619
|
+
@g2.manifold = @manifold
|
620
|
+
@g3.manifold = @manifold
|
621
|
+
@g4.manifold = @manifold
|
622
|
+
end
|
623
|
+
|
624
|
+
it "should return [self] when no manifold or invocations exist" do
|
625
|
+
@generator_class.manifold = nil
|
626
|
+
@generator_class.generators.should == [@generator_class]
|
627
|
+
end
|
628
|
+
|
629
|
+
it "should return [self] when only invocations exist" do
|
630
|
+
@generator_class.manifold = nil
|
631
|
+
@generator_class.invoke(:monkey)
|
632
|
+
@generator_class.invoke(:blah)
|
633
|
+
@generator_class.generators.should == [@generator_class]
|
634
|
+
end
|
635
|
+
|
636
|
+
it "should return a list of invoked generators" do
|
637
|
+
@generator_class.invoke(:monkey)
|
638
|
+
@generator_class.invoke(:blah)
|
639
|
+
|
640
|
+
@generator_class.generators.should == [@generator_class, @g1, @g2]
|
641
|
+
end
|
642
|
+
|
643
|
+
it "should return a list of invoked generators recursively" do
|
644
|
+
@generator_class.invoke(:monkey)
|
645
|
+
@generator_class.invoke(:blah)
|
646
|
+
@g1.invoke(:duck)
|
647
|
+
@g3.invoke(:llama)
|
648
|
+
|
649
|
+
@generator_class.generators.should == [@generator_class, @g1, @g3, @g4, @g2]
|
650
|
+
end
|
651
|
+
|
652
|
+
it "should ignore invocations that do not exist in the manifold" do
|
653
|
+
@generator_class.invoke(:monkey)
|
654
|
+
@generator_class.invoke(:blah)
|
655
|
+
@g1.invoke(:duck)
|
656
|
+
@g3.invoke(:i_dont_exist)
|
657
|
+
|
658
|
+
@generator_class.generators.should == [@generator_class, @g1, @g3, @g2]
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
describe Templater::Generator, '.source_root' do
|
663
|
+
it "should raise an error, complaining that source_root must be overridden" do
|
664
|
+
@generator_class = Class.new(Templater::Generator)
|
665
|
+
lambda { @generator_class.source_root }.should raise_error(Templater::SourceNotSpecifiedError)
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
describe Templater::Generator, '#template' do
|
670
|
+
|
671
|
+
before do
|
672
|
+
@generator_class = Class.new(Templater::Generator)
|
673
|
+
@generator_class.class_eval do
|
674
|
+
def source_root
|
675
|
+
'/tmp/source'
|
676
|
+
end
|
677
|
+
end
|
678
|
+
end
|
679
|
+
|
680
|
+
it "should find a template by name" do
|
681
|
+
@generator_class.template(:blah1, 'blah.rb')
|
682
|
+
@generator_class.template(:blah2, 'blah2.rb')
|
683
|
+
|
684
|
+
instance = @generator_class.new('/tmp')
|
685
|
+
|
686
|
+
instance.template(:blah1).name.should == :blah1
|
687
|
+
instance.template(:blah1).source.should == '/tmp/source/blah.rbt'
|
688
|
+
instance.template(:blah1).destination.should == '/tmp/blah.rb'
|
689
|
+
end
|
690
|
+
|
691
|
+
it "should not return a template with an option that does not match." do
|
692
|
+
@generator_class.option :framework, :default => :rails
|
693
|
+
|
694
|
+
@generator_class.template(:merb, 'blah.rb', :framework => :merb)
|
695
|
+
@generator_class.template(:rails, 'blah2.rb', :framework => :rails)
|
696
|
+
@generator_class.template(:none, 'blah2.rb')
|
697
|
+
|
698
|
+
instance = @generator_class.new('/tmp')
|
699
|
+
|
700
|
+
instance.template(:rails).name.should == :rails
|
701
|
+
instance.template(:merb).should be_nil
|
702
|
+
instance.template(:none).name.should == :none
|
703
|
+
|
704
|
+
instance.framework = :merb
|
705
|
+
instance.template(:rails).should be_nil
|
706
|
+
instance.template(:merb).name.should == :merb
|
707
|
+
instance.template(:none).name.should == :none
|
708
|
+
|
709
|
+
instance.framework = nil
|
710
|
+
instance.template(:rails).should be_nil
|
711
|
+
instance.template(:merb).should be_nil
|
712
|
+
instance.template(:none).name.should == :none
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
describe Templater::Generator, '#templates' do
|
717
|
+
|
718
|
+
before do
|
719
|
+
@generator_class = Class.new(Templater::Generator)
|
720
|
+
@generator_class.class_eval do
|
721
|
+
def source_root
|
722
|
+
'/tmp/source'
|
723
|
+
end
|
724
|
+
end
|
725
|
+
end
|
726
|
+
|
727
|
+
it "should return all templates" do
|
728
|
+
@generator_class.template(:blah1, 'blah.rb')
|
729
|
+
@generator_class.template(:blah2, 'blah2.rb')
|
730
|
+
|
731
|
+
instance = @generator_class.new('/tmp')
|
732
|
+
|
733
|
+
instance.templates[0].name.should == :blah1
|
734
|
+
instance.templates[1].name.should == :blah2
|
735
|
+
end
|
736
|
+
|
737
|
+
it "should not return templates with an option that does not match." do
|
738
|
+
@generator_class.option :framework, :default => :rails
|
739
|
+
|
740
|
+
@generator_class.template(:merb, 'blah.rb', :framework => :merb)
|
741
|
+
@generator_class.template(:rails, 'blah2.rb', :framework => :rails)
|
742
|
+
@generator_class.template(:none, 'blah2.rb')
|
743
|
+
|
744
|
+
instance = @generator_class.new('/tmp')
|
745
|
+
|
746
|
+
instance.templates[0].name.should == :rails
|
747
|
+
instance.templates[1].name.should == :none
|
748
|
+
|
749
|
+
instance.framework = :merb
|
750
|
+
instance.templates[0].name.should == :merb
|
751
|
+
instance.templates[1].name.should == :none
|
752
|
+
|
753
|
+
instance.framework = :rails
|
754
|
+
instance.templates[0].name.should == :rails
|
755
|
+
instance.templates[1].name.should == :none
|
756
|
+
|
757
|
+
instance.framework = nil
|
758
|
+
instance.templates[0].name.should == :none
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
describe Templater::Generator, '#file' do
|
763
|
+
|
764
|
+
before do
|
765
|
+
@generator_class = Class.new(Templater::Generator)
|
766
|
+
@generator_class.class_eval do
|
767
|
+
def source_root
|
768
|
+
'/tmp/source'
|
769
|
+
end
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
773
|
+
it "should find a file by name" do
|
774
|
+
@generator_class.file(:blah1, 'blah.rb')
|
775
|
+
@generator_class.file(:blah2, 'blah2.rb')
|
776
|
+
|
777
|
+
instance = @generator_class.new('/tmp')
|
778
|
+
|
779
|
+
instance.file(:blah1).name.should == :blah1
|
780
|
+
instance.file(:blah1).source.should == '/tmp/source/blah.rb'
|
781
|
+
instance.file(:blah1).destination.should == '/tmp/blah.rb'
|
782
|
+
end
|
783
|
+
|
784
|
+
it "should not return a file with an option that does not match." do
|
785
|
+
@generator_class.option :framework, :default => :rails
|
786
|
+
|
787
|
+
@generator_class.file(:merb, 'blah.rb', :framework => :merb)
|
788
|
+
@generator_class.file(:rails, 'blah2.rb', :framework => :rails)
|
789
|
+
@generator_class.file(:none, 'blah2.rb')
|
790
|
+
|
791
|
+
instance = @generator_class.new('/tmp')
|
792
|
+
|
793
|
+
instance.file(:rails).name.should == :rails
|
794
|
+
instance.file(:merb).should be_nil
|
795
|
+
instance.file(:none).name.should == :none
|
796
|
+
|
797
|
+
instance.framework = :merb
|
798
|
+
instance.file(:rails).should be_nil
|
799
|
+
instance.file(:merb).name.should == :merb
|
800
|
+
instance.file(:none).name.should == :none
|
801
|
+
|
802
|
+
instance.framework = nil
|
803
|
+
instance.file(:rails).should be_nil
|
804
|
+
instance.file(:merb).should be_nil
|
805
|
+
instance.file(:none).name.should == :none
|
806
|
+
end
|
807
|
+
end
|
808
|
+
|
809
|
+
describe Templater::Generator, '#files' do
|
810
|
+
|
811
|
+
before do
|
812
|
+
@generator_class = Class.new(Templater::Generator)
|
813
|
+
@generator_class.class_eval do
|
814
|
+
def source_root
|
815
|
+
'/tmp/source'
|
816
|
+
end
|
817
|
+
end
|
818
|
+
end
|
819
|
+
|
820
|
+
it "should return all files" do
|
821
|
+
@generator_class.file(:blah1, 'blah.rb')
|
822
|
+
@generator_class.file(:blah2, 'blah2.rb')
|
823
|
+
|
824
|
+
instance = @generator_class.new('/tmp')
|
825
|
+
|
826
|
+
instance.files[0].name.should == :blah1
|
827
|
+
instance.files[1].name.should == :blah2
|
828
|
+
end
|
829
|
+
|
830
|
+
it "should not return files with an option that does not match." do
|
831
|
+
@generator_class.option :framework, :default => :rails
|
832
|
+
|
833
|
+
@generator_class.file(:merb, 'blah.rb', :framework => :merb)
|
834
|
+
@generator_class.file(:rails, 'blah2.rb', :framework => :rails)
|
835
|
+
@generator_class.file(:none, 'blah2.rb')
|
836
|
+
|
837
|
+
instance = @generator_class.new('/tmp')
|
838
|
+
|
839
|
+
instance.files[0].name.should == :rails
|
840
|
+
instance.files[1].name.should == :none
|
841
|
+
|
842
|
+
instance.framework = :merb
|
843
|
+
instance.files[0].name.should == :merb
|
844
|
+
instance.files[1].name.should == :none
|
845
|
+
|
846
|
+
instance.framework = :rails
|
847
|
+
instance.files[0].name.should == :rails
|
848
|
+
instance.files[1].name.should == :none
|
849
|
+
|
850
|
+
instance.framework = nil
|
851
|
+
instance.files[0].name.should == :none
|
852
|
+
end
|
853
|
+
end
|
854
|
+
|
855
|
+
describe Templater::Generator, '#invocations' do
|
856
|
+
|
857
|
+
before do
|
858
|
+
@generator_class = Class.new(Templater::Generator)
|
859
|
+
@generator_class.class_eval do
|
860
|
+
def source_root
|
861
|
+
'/tmp/source'
|
862
|
+
end
|
863
|
+
end
|
864
|
+
|
865
|
+
@generator1 = mock('a generator for merb')
|
866
|
+
@instance1 = mock('an instance of the generator for merb')
|
867
|
+
@generator1.stub!(:new).and_return(@instance1)
|
868
|
+
@generator2 = mock('a generator for rails')
|
869
|
+
@instance2 = mock('an instance of the generator for rails')
|
870
|
+
@generator2.stub!(:new).and_return(@instance2)
|
871
|
+
@generator3 = mock('a generator for both')
|
872
|
+
@instance3 = mock('an instance of the generator for both')
|
873
|
+
@generator3.stub!(:new).and_return(@instance3)
|
874
|
+
|
875
|
+
@manifold = mock('a manifold')
|
876
|
+
@manifold.stub!(:generator).with(:merb).and_return(@generator1)
|
877
|
+
@manifold.stub!(:generator).with(:rails).and_return(@generator2)
|
878
|
+
@manifold.stub!(:generator).with(:both).and_return(@generator3)
|
879
|
+
|
880
|
+
@generator_class.stub!(:manifold).and_return(@manifold)
|
881
|
+
end
|
882
|
+
|
883
|
+
it "should return all invocations" do
|
884
|
+
@generator_class.invoke(:merb)
|
885
|
+
@generator_class.invoke(:rails)
|
886
|
+
|
887
|
+
instance = @generator_class.new('/tmp')
|
888
|
+
|
889
|
+
instance.invocations[0].should == @instance1
|
890
|
+
instance.invocations[1].should == @instance2
|
891
|
+
end
|
892
|
+
|
893
|
+
it "should not return templates with an option that does not match." do
|
894
|
+
@generator_class.option :framework, :default => :rails
|
895
|
+
|
896
|
+
@generator_class.invoke(:merb, :framework => :merb)
|
897
|
+
@generator_class.invoke(:rails, :framework => :rails)
|
898
|
+
@generator_class.invoke(:both)
|
899
|
+
|
900
|
+
instance = @generator_class.new('/tmp')
|
901
|
+
|
902
|
+
instance.invocations[0].should == @instance2
|
903
|
+
instance.invocations[1].should == @instance3
|
904
|
+
|
905
|
+
instance.framework = :merb
|
906
|
+
instance.invocations[0].should == @instance1
|
907
|
+
instance.invocations[1].should == @instance3
|
908
|
+
|
909
|
+
instance.framework = :rails
|
910
|
+
instance.invocations[0].should == @instance2
|
911
|
+
instance.invocations[1].should == @instance3
|
912
|
+
|
913
|
+
instance.framework = nil
|
914
|
+
instance.invocations[0].should == @instance3
|
915
|
+
end
|
916
|
+
end
|
917
|
+
|
918
|
+
describe Templater::Generator, '#actions' do
|
919
|
+
|
920
|
+
before do
|
921
|
+
@generator_class = Class.new(Templater::Generator)
|
922
|
+
@generator_class.class_eval do
|
923
|
+
def source_root
|
924
|
+
'/tmp/source'
|
925
|
+
end
|
926
|
+
end
|
927
|
+
|
928
|
+
@generator1 = mock('a generator')
|
929
|
+
@instance1 = mock('an instance of the generator')
|
930
|
+
@generator1.stub!(:new).and_return(@instance1)
|
931
|
+
@generator2 = mock('another generator')
|
932
|
+
@instance2 = mock('an instance of another generator')
|
933
|
+
@generator2.stub!(:new).and_return(@instance2)
|
934
|
+
|
935
|
+
@manifold = mock('a manifold')
|
936
|
+
@manifold.stub!(:generator).with(:one).and_return(@generator1)
|
937
|
+
@manifold.stub!(:generator).with(:two).and_return(@generator2)
|
938
|
+
@manifold.stub!(:generator).with(:three).and_return(@generator3)
|
939
|
+
|
940
|
+
@generator_class.stub!(:manifold).and_return(@manifold)
|
941
|
+
end
|
942
|
+
|
943
|
+
it "should return all templates and files" do
|
944
|
+
instance = @generator_class.new('/tmp')
|
945
|
+
instance.should_receive(:templates).at_least(:once).and_return(['template1', 'template2'])
|
946
|
+
instance.should_receive(:files).at_least(:once).and_return(['file1', 'file2'])
|
947
|
+
|
948
|
+
instance.actions.should include('template1')
|
949
|
+
instance.actions.should include('template2')
|
950
|
+
instance.actions.should include('file1')
|
951
|
+
instance.actions.should include('file2')
|
952
|
+
end
|
953
|
+
|
954
|
+
it "should return all templates and files recursively for all invocations" do
|
955
|
+
instance = @generator_class.new('/tmp')
|
956
|
+
instance.should_receive(:templates).at_least(:once).and_return(['template1', 'template2'])
|
957
|
+
instance.should_receive(:files).at_least(:once).and_return(['file1', 'file2'])
|
958
|
+
instance.should_receive(:invocations).at_least(:once).and_return([@instance1, @instance2])
|
959
|
+
|
960
|
+
@instance1.should_receive(:actions).at_least(:once).and_return(['subtemplate1', 'subfile1'])
|
961
|
+
@instance2.should_receive(:actions).at_least(:once).and_return(['subtemplate2', 'subfile2'])
|
962
|
+
|
963
|
+
instance.actions.should include('template1')
|
964
|
+
instance.actions.should include('template2')
|
965
|
+
instance.actions.should include('subtemplate1')
|
966
|
+
instance.actions.should include('subtemplate2')
|
967
|
+
instance.actions.should include('file1')
|
968
|
+
instance.actions.should include('file2')
|
969
|
+
instance.actions.should include('subfile1')
|
970
|
+
instance.actions.should include('subfile2')
|
971
|
+
end
|
972
|
+
|
973
|
+
end
|
974
|
+
|
975
|
+
describe Templater::Generator, '#invoke!' do
|
976
|
+
|
977
|
+
before do
|
978
|
+
@generator_class = Class.new(Templater::Generator)
|
979
|
+
end
|
980
|
+
|
981
|
+
it "should invoke all templates" do
|
982
|
+
template1 = mock('a template')
|
983
|
+
template2 = mock('another template')
|
984
|
+
|
985
|
+
instance = @generator_class.new('/tmp')
|
986
|
+
|
987
|
+
instance.should_receive(:templates).and_return([template1, template2])
|
988
|
+
template1.should_receive(:invoke!)
|
989
|
+
template2.should_receive(:invoke!)
|
990
|
+
|
991
|
+
instance.invoke!
|
992
|
+
end
|
993
|
+
end
|
994
|
+
|
995
|
+
describe Templater::Generator, '#destination_root' do
|
996
|
+
it "should be remembered" do
|
997
|
+
@generator_class = Class.new(Templater::Generator)
|
998
|
+
instance = @generator_class.new('/path/to/destination')
|
999
|
+
instance.destination_root.should == '/path/to/destination'
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
describe Templater::Generator, '#source_root' do
|
1004
|
+
it "try to retrieve the source root from the class" do
|
1005
|
+
@generator_class = Class.new(Templater::Generator)
|
1006
|
+
@generator_class.should_receive(:source_root).and_return('/tmp/source')
|
1007
|
+
|
1008
|
+
instance = @generator_class.new('/tmp')
|
1009
|
+
instance.source_root.should == '/tmp/source'
|
1010
|
+
end
|
1011
|
+
end
|