generator-spec 0.4.8 → 0.5.0
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/README.markdown +6 -0
- data/VERSION +1 -1
- data/generator-spec.gemspec +4 -2
- data/lib/generator_spec/extensions/core_ext.rb +30 -0
- data/lib/generator_spec/helpers/migration_helper.rb +15 -10
- data/lib/generator_spec/main.rb +5 -3
- data/lib/generator_spec/matchers/content/content_matcher.rb +8 -4
- data/lib/generator_spec/matchers/content/have_call.rb +4 -4
- data/lib/generator_spec/matchers/content/have_comment.rb +42 -0
- data/lib/generator_spec/matchers/file/generate_file.rb +2 -4
- data/lib/generator_spec/matchers/file/have_file.rb +2 -2
- data/lib/generator_spec/matchers/migration/have_up_down.rb +2 -0
- data/lib/generator_spec/rails_helpers/base_helper.rb +171 -0
- data/lib/generator_spec/rails_helpers/rails_app.rb +9 -2
- data/lib/generator_spec/rails_helpers/rails_controller.rb +33 -25
- data/lib/generator_spec/rails_helpers/rails_helper.rb +27 -25
- data/lib/generator_spec/rails_helpers/rails_mailer.rb +29 -21
- data/lib/generator_spec/rails_helpers/rails_migration.rb +41 -26
- data/lib/generator_spec/rails_helpers/rails_model.rb +29 -19
- data/lib/generator_spec/rails_helpers/rails_observer.rb +27 -23
- data/lib/generator_spec/rails_helpers/rails_orm.rb +33 -18
- data/lib/generator_spec/rails_helpers/rails_view.rb +42 -28
- data/spec/generator_spec/matchers/content/have_call_spec.rb +16 -0
- data/spec/generator_spec/matchers/rails/controller_matcher_spec.rb +3 -2
- data/spec/generator_spec/matchers/rails/helper_matcher_spec.rb +1 -1
- data/spec/generator_spec/matchers/rails/mailer_matcher_spec.rb +1 -1
- data/spec/generator_spec/matchers/rails/model_matcher_spec.rb +4 -4
- data/spec/generator_spec/matchers/rails/observer_matcher_spec.rb +1 -1
- data/spec/generator_spec/matchers/rails/view_matcher_spec.rb +1 -1
- data/spec/generator_spec/rails_helpers/rails_controller_spec.rb +33 -0
- data/spec/generator_spec/rails_helpers/rails_helper_spec.rb +33 -0
- data/spec/generator_spec/rails_helpers/rails_mailer_spec.rb +33 -0
- data/spec/generator_spec/rails_helpers/rails_model_spec.rb +31 -0
- data/spec/generator_spec/rails_helpers/rails_observer_spec.rb +33 -0
- data/spec/generator_spec/rails_helpers/rails_view_spec.rb +31 -0
- data/spec/spec_helper.rb +1 -1
- metadata +6 -4
data/README.markdown
CHANGED
@@ -22,6 +22,12 @@ To install the gem from the code, simply use the jeweler rake task:
|
|
22
22
|
|
23
23
|
<code>rake install</code>
|
24
24
|
|
25
|
+
## TODO
|
26
|
+
|
27
|
+
Check out ways to improve the DSL, fx using Macros:
|
28
|
+
|
29
|
+
http://gist.github.com/511087
|
30
|
+
|
25
31
|
## Usage
|
26
32
|
|
27
33
|
The following demonstrates usage of this library. There are many more options and DSL convenience methods (see wiki, code or specs).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/generator-spec.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{generator-spec}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.5.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kristian Mandrup"]
|
12
|
-
s.date = %q{2010-08-
|
12
|
+
s.date = %q{2010-08-14}
|
13
13
|
s.description = %q{RSpec 2 library to assist in writing generator specs}
|
14
14
|
s.email = %q{kmandrup@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -36,6 +36,7 @@ Gem::Specification.new do |s|
|
|
36
36
|
"lib/generator_spec/matchers/content/have_call.rb",
|
37
37
|
"lib/generator_spec/matchers/content/have_calls.rb",
|
38
38
|
"lib/generator_spec/matchers/content/have_class_self.rb",
|
39
|
+
"lib/generator_spec/matchers/content/have_comment.rb",
|
39
40
|
"lib/generator_spec/matchers/content/have_method.rb",
|
40
41
|
"lib/generator_spec/matchers/content/have_module.rb",
|
41
42
|
"lib/generator_spec/matchers/content/have_region.rb",
|
@@ -54,6 +55,7 @@ Gem::Specification.new do |s|
|
|
54
55
|
"lib/generator_spec/matchers/migration/have_table.rb",
|
55
56
|
"lib/generator_spec/matchers/migration/have_tbl_column.rb",
|
56
57
|
"lib/generator_spec/matchers/migration/have_up_down.rb",
|
58
|
+
"lib/generator_spec/rails_helpers/base_helper.rb",
|
57
59
|
"lib/generator_spec/rails_helpers/rails_app.rb",
|
58
60
|
"lib/generator_spec/rails_helpers/rails_controller.rb",
|
59
61
|
"lib/generator_spec/rails_helpers/rails_helper.rb",
|
@@ -15,3 +15,33 @@ class String
|
|
15
15
|
(self =~ /\w+\s+\w+/) ? self.split : self
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
class Module
|
20
|
+
def multi_alias name, options={}
|
21
|
+
config_options = options[:options]
|
22
|
+
options.each_pair do |original, aliases|
|
23
|
+
next if original == :options
|
24
|
+
alias_methods name, original, [aliases].flatten, config_options
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def alias_methods name, original, aliases, config_options
|
31
|
+
aliases.each do |alias_name|
|
32
|
+
new_alias = make_name(name, alias_name.to_s, config_options)
|
33
|
+
original_name = make_name(name, original.to_s, config_options)
|
34
|
+
alias_method new_alias, original_name if respond_to? original_name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def make_name name, alias_name, config_options
|
39
|
+
return alias_name.gsub(/X/, name.to_s) if alias_name =~ /X/
|
40
|
+
case config_options
|
41
|
+
when :after
|
42
|
+
"#{alias_name}_#{name}"
|
43
|
+
when :before
|
44
|
+
"#{name}_#{alias_name}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -17,7 +17,6 @@ module Rails::Generators
|
|
17
17
|
migration_lookup_at(dirname).grep(/\d+_#{file_name}.rb$/).sort.last
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
20
|
def current_migration_number(dirname) #:nodoc:
|
22
21
|
migration_lookup_at(dirname).collect do |file|
|
23
22
|
File.basename(file).split("_").first.to_i
|
@@ -37,20 +36,26 @@ module Rails::Generators
|
|
37
36
|
base.extend ClassMethods
|
38
37
|
end
|
39
38
|
|
39
|
+
def reverse_migration_name name
|
40
|
+
name.gsub(/^add_/, 'remove_').gsub(/^create_/, 'drop_')
|
41
|
+
end
|
42
|
+
|
40
43
|
def reverse_migration! migration_path
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
reverse_class_names! migration_path
|
45
|
+
reverse_up_down_methods! migration_path
|
46
|
+
end
|
44
47
|
|
45
|
-
|
48
|
+
def reverse_class_names! migration_path
|
46
49
|
# Change class name
|
47
|
-
gsub_file
|
48
|
-
gsub_file
|
50
|
+
gsub_file migration_path, /class Add/, 'class Remove'
|
51
|
+
gsub_file migration_path, /class Create/, 'class Drop'
|
52
|
+
end
|
49
53
|
|
54
|
+
def reverse_up_down_methods! migration_path
|
50
55
|
# swap up and down methods
|
51
|
-
gsub_file
|
52
|
-
gsub_file
|
53
|
-
gsub_file
|
56
|
+
gsub_file migration_path, /up/, 'dwn'
|
57
|
+
gsub_file migration_path, /down/, 'up'
|
58
|
+
gsub_file migration_path, /dwn/, 'down'
|
54
59
|
end
|
55
60
|
|
56
61
|
def latest_migration_file dir, name
|
data/lib/generator_spec/main.rb
CHANGED
@@ -25,8 +25,8 @@ module RSpec
|
|
25
25
|
end
|
26
26
|
|
27
27
|
require_all File.dirname(__FILE__) + '/extensions'
|
28
|
-
require_all File.dirname(__FILE__) + '/rails_helpers'
|
29
28
|
require_all File.dirname(__FILE__) + '/helpers'
|
29
|
+
require_all File.dirname(__FILE__) + '/rails_helpers'
|
30
30
|
require_all File.dirname(__FILE__) + '/rspec_generator'
|
31
31
|
|
32
32
|
|
@@ -52,8 +52,10 @@ class Class
|
|
52
52
|
|
53
53
|
def helpers *types
|
54
54
|
types.each{|type| include_helper type}
|
55
|
-
end
|
56
|
-
|
55
|
+
end
|
56
|
+
alias_method :load_helper, :helpers
|
57
|
+
alias_method :load_helpers, :helpers
|
58
|
+
|
57
59
|
protected
|
58
60
|
|
59
61
|
def include_helper type
|
@@ -15,10 +15,10 @@ module RSpec
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def debug?
|
18
|
-
|
18
|
+
RSpec::Generator.debug?
|
19
19
|
end
|
20
20
|
|
21
|
-
def matches? content, &block
|
21
|
+
def matches? content, &block
|
22
22
|
@content = content
|
23
23
|
match = is_match? content
|
24
24
|
content_to_yield = if indexes
|
@@ -31,7 +31,7 @@ module RSpec
|
|
31
31
|
|
32
32
|
def is_match? content
|
33
33
|
expr = get_expr(content)
|
34
|
-
|
34
|
+
debug "match expression: #{expr}"
|
35
35
|
match = (content =~ expr)
|
36
36
|
@content_matches = [$1, $2, $3]
|
37
37
|
match
|
@@ -100,7 +100,11 @@ module RSpec
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def debug_content
|
103
|
-
|
103
|
+
debug "Content: #{content}"
|
104
104
|
end
|
105
|
+
|
106
|
+
def debug msg
|
107
|
+
puts msg if debug?
|
108
|
+
end
|
105
109
|
end
|
106
110
|
end
|
@@ -9,9 +9,9 @@ module RSpec::RubyContentMatchers
|
|
9
9
|
class HaveCall < RSpec::RubyContentMatcher
|
10
10
|
attr_reader :method, :args, :dot
|
11
11
|
|
12
|
-
def initialize(method,
|
12
|
+
def initialize(method, options = {})
|
13
13
|
@method = method.to_s
|
14
|
-
@args = args
|
14
|
+
@args = options[:args] || options
|
15
15
|
@dot = options[:dot]
|
16
16
|
end
|
17
17
|
|
@@ -49,8 +49,8 @@ module RSpec::RubyContentMatchers
|
|
49
49
|
|
50
50
|
end
|
51
51
|
|
52
|
-
def have_call(method,
|
53
|
-
HaveCall.new(method,
|
52
|
+
def have_call(method, options = {})
|
53
|
+
HaveCall.new(method, options)
|
54
54
|
end
|
55
55
|
|
56
56
|
def have_dot_call(method, options = {})
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# This method tries to see if a specific method is contained in the generated file.
|
2
|
+
# It can operate (should) on either a file name or the raw content
|
3
|
+
#
|
4
|
+
# generated_file_name.should have_method "hello" # 'my/path/say_hello.rb'.should have_method "hello"
|
5
|
+
#
|
6
|
+
# say_hello_file_content.should have_method "hello"
|
7
|
+
#
|
8
|
+
module RSpec::RubyContentMatchers
|
9
|
+
class HaveComment < RSpec::RubyContentMatcher
|
10
|
+
attr_accessor :comment
|
11
|
+
|
12
|
+
def initialize comment
|
13
|
+
@comment = comment
|
14
|
+
end
|
15
|
+
|
16
|
+
def matches?(content)
|
17
|
+
@content = content
|
18
|
+
(content =~ /#{main_expr}/)
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message
|
22
|
+
super
|
23
|
+
"Expected there to be the comment '# #{comment}'"
|
24
|
+
end
|
25
|
+
|
26
|
+
def negative_failure_message
|
27
|
+
super
|
28
|
+
"Did not expect there to be the comment '# #{comment}'"
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def main_expr
|
34
|
+
'\s*#\s*' + "#{comment}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def have_comment comment
|
39
|
+
HaveComment.new comment
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -13,18 +13,16 @@ module RSpec::FileMatchers
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def matches?(generator, &block)
|
16
|
-
puts "relative_path"
|
17
16
|
file = File.expand_path(relative_path, generator.class.destination_root)
|
18
17
|
file_exists = File.exists?(file)
|
19
18
|
if block && file_exists
|
20
19
|
read = File.read(file)
|
21
|
-
puts "file content: #{read}, #{file}"
|
22
20
|
ruby_content = read.extend(RSpec::RubyContent::Helpers)
|
23
21
|
yield ruby_content
|
24
22
|
else
|
25
23
|
file_exists
|
26
|
-
end
|
27
|
-
end
|
24
|
+
end
|
25
|
+
end
|
28
26
|
|
29
27
|
def failure_message
|
30
28
|
"Expected file #{relative_path} to have been generated, but it was not"
|
@@ -48,7 +48,7 @@ module RSpec::FileMatchers
|
|
48
48
|
|
49
49
|
|
50
50
|
def postfix type
|
51
|
-
"_#{type}" if [:
|
51
|
+
"_#{type}" if ![:model].include?(type)
|
52
52
|
end
|
53
53
|
|
54
54
|
def folder type
|
@@ -96,7 +96,7 @@ module RSpec::FileMatchers
|
|
96
96
|
end
|
97
97
|
alias_method :contain_helper, :have_helper
|
98
98
|
|
99
|
-
def have_view(relative, action, ext='html.erb')
|
99
|
+
def have_view(relative, action='show', ext='html.erb')
|
100
100
|
HaveFile.new("#{relative}/#{action}.#{ext}", :view)
|
101
101
|
end
|
102
102
|
alias_method :contain_view, :have_view
|
@@ -2,10 +2,12 @@ module RSpec::RubyContentMatchers
|
|
2
2
|
def have_up &block
|
3
3
|
HaveMethod.new 'up', :class, &block
|
4
4
|
end
|
5
|
+
alias_method :have_up_method, :have_up
|
5
6
|
|
6
7
|
def have_down &block
|
7
8
|
HaveMethod.new 'down', :class, &block
|
8
9
|
end
|
10
|
+
alias_method :have_down_method, :have_down
|
9
11
|
end
|
10
12
|
|
11
13
|
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module RSpec::Rails
|
2
|
+
module BaseHelper
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
base.class_eval do
|
6
|
+
include RSpec::Rails::App
|
7
|
+
include Thor::Actions
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def aliases_for name
|
13
|
+
multi_alias name,
|
14
|
+
:create => :new, :insert_into => [:inject_into, :update], :read => :X_content, :remove => :delete,
|
15
|
+
:options => :after
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def type_postfix type
|
20
|
+
"_#{type}" if ![:model].include?(type)
|
21
|
+
end
|
22
|
+
|
23
|
+
def artifact_path name, type, dir=nil
|
24
|
+
dir ||= send :"#{type}_dir"
|
25
|
+
File.join(dir, "#{name}#{type_postfix type}.rb")
|
26
|
+
end
|
27
|
+
|
28
|
+
# CREATE
|
29
|
+
def create_artifact name, options={}, &block
|
30
|
+
type = get_type options
|
31
|
+
|
32
|
+
file = file_name name, type
|
33
|
+
return if File.exist?(file)
|
34
|
+
|
35
|
+
debug "create #{type}: #{name}"
|
36
|
+
debug "file: #{file}"
|
37
|
+
|
38
|
+
# make dir
|
39
|
+
dir = File.dirname(file)
|
40
|
+
FileUtils.mkdir_p dir if !File.directory?(dir)
|
41
|
+
|
42
|
+
content = options[:content]
|
43
|
+
content ||= yield if block
|
44
|
+
|
45
|
+
content_method = :"new_#{type}_content"
|
46
|
+
debug "inner content: #{content}, to inject using ##{content_method}"
|
47
|
+
|
48
|
+
raise "Content method #{content_method} not found #{orm_notify}" if !respond_to?(content_method)
|
49
|
+
insert_content = send content_method, name, content
|
50
|
+
|
51
|
+
debug "content to insert: #{insert_content}"
|
52
|
+
|
53
|
+
return if insert_content.blank?
|
54
|
+
|
55
|
+
File.open(file, 'w') do |f|
|
56
|
+
f.puts insert_content
|
57
|
+
end
|
58
|
+
debug "file created and content inserted"
|
59
|
+
end
|
60
|
+
|
61
|
+
# READ
|
62
|
+
def read_artifact(name, options, &block)
|
63
|
+
type = get_type options
|
64
|
+
file_name = existing_file_name(name, type)
|
65
|
+
debug "reading from: #{file_name}"
|
66
|
+
content = File.new(file_name).try :read
|
67
|
+
debug "read content: #{content}"
|
68
|
+
yield content if block
|
69
|
+
content
|
70
|
+
end
|
71
|
+
|
72
|
+
# UPDATE
|
73
|
+
def insert_content(name, options={}, &block)
|
74
|
+
type = get_type options
|
75
|
+
file = existing_file_name(name, type)
|
76
|
+
file_insertion file, marker(name, type, options), options, &block
|
77
|
+
end
|
78
|
+
|
79
|
+
# DELETE
|
80
|
+
def remove_artifact name, type
|
81
|
+
debug "remove artifact: #{name}"
|
82
|
+
file = file_name name, type
|
83
|
+
debug "removed" if File.exist?(file) && FileUtils.rm_f(file)
|
84
|
+
end
|
85
|
+
|
86
|
+
def remove_artifacts type,*names
|
87
|
+
names.flatten.each{|name| send :"remove_#{type}", name }
|
88
|
+
end
|
89
|
+
|
90
|
+
def new_artifact_content name, type, content=nil, &block
|
91
|
+
content ||= yield if block
|
92
|
+
%Q{class #{marker(name, type)}
|
93
|
+
#{content}
|
94
|
+
end}
|
95
|
+
end
|
96
|
+
|
97
|
+
protected
|
98
|
+
|
99
|
+
def get_type options = {}
|
100
|
+
raise ArgumentError, "No artifact type specified" if !options[:type]
|
101
|
+
options[:type]
|
102
|
+
end
|
103
|
+
|
104
|
+
def debug?
|
105
|
+
RSpec::Generator.debug?
|
106
|
+
end
|
107
|
+
|
108
|
+
def debug msg
|
109
|
+
puts msg if debug?
|
110
|
+
end
|
111
|
+
|
112
|
+
def set options, type
|
113
|
+
options.merge!(:type => type)
|
114
|
+
options
|
115
|
+
end
|
116
|
+
|
117
|
+
def orm_notify
|
118
|
+
''
|
119
|
+
end
|
120
|
+
|
121
|
+
def marker name, type, options={}
|
122
|
+
send :"#{type}_marker", name, options
|
123
|
+
end
|
124
|
+
|
125
|
+
def file_name name, type, options={}
|
126
|
+
send :"#{type}_file_name", name, options
|
127
|
+
end
|
128
|
+
|
129
|
+
def existing_file_name name, type
|
130
|
+
# first try finder method
|
131
|
+
finder_method = :"find_#{type}"
|
132
|
+
found = send finder_method, name if respond_to? finder_method
|
133
|
+
# default
|
134
|
+
file_name(name, type) if !found
|
135
|
+
end
|
136
|
+
|
137
|
+
def file_insertion(file_name, marker, options={}, &block)
|
138
|
+
debug "file insertion: marker = #{marker}"
|
139
|
+
return if !marker
|
140
|
+
|
141
|
+
file = File.new(file_name)
|
142
|
+
return if !File.exist?(file)
|
143
|
+
|
144
|
+
insert_content = options[:content] || (yield if block)
|
145
|
+
|
146
|
+
# already inserted?
|
147
|
+
return if insert_content.blank? || (file.read =~ /#{insert_content}/)
|
148
|
+
|
149
|
+
place = options[:before] ? :before : :after
|
150
|
+
|
151
|
+
debug "inserted #{place}: '#{marker}'"
|
152
|
+
debug "content: #{insert_content}"
|
153
|
+
|
154
|
+
mutate_file file.path, marker, place do
|
155
|
+
insert_content
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def mutate_file file, marker, place, &block
|
160
|
+
raise ArgumentError, "You must define a replacement marker for a :before or :after key" if !marker
|
161
|
+
replace_in_file file, /(#{Regexp.escape(marker)})/mi do |match|
|
162
|
+
place == :after ? "#{match}#{yield}" : "#{yield}#{match}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def replace_in_file(path, regexp, *args, &block)
|
167
|
+
content = File.read(path).gsub(regexp, *args, &block)
|
168
|
+
File.open(path, 'wb') { |file| file.write(content) }
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|