judit-pickle 0.4.2
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/.gitignore +6 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +98 -0
- data/History.txt +409 -0
- data/License.txt +20 -0
- data/README.rdoc +367 -0
- data/Rakefile +20 -0
- data/Rakefile.d/cucumber.rake +24 -0
- data/Rakefile.d/jeweler.rake +23 -0
- data/Rakefile.d/rcov.rake +18 -0
- data/Rakefile.d/rspec.rake +7 -0
- data/Rakefile.d/yard.rake +5 -0
- data/Todo.txt +3 -0
- data/VERSION +1 -0
- data/features/app/app.rb +122 -0
- data/features/app/blueprints.rb +11 -0
- data/features/app/factories.rb +23 -0
- data/features/app/views/notifier/email.erb +1 -0
- data/features/app/views/notifier/user_email.erb +6 -0
- data/features/email/email.feature +64 -0
- data/features/generator/generators.feature +59 -0
- data/features/path/models_page.feature +44 -0
- data/features/path/named_route_page.feature +10 -0
- data/features/pickle/create_from_active_record.feature +76 -0
- data/features/pickle/create_from_factory_girl.feature +63 -0
- data/features/pickle/create_from_machinist.feature +39 -0
- data/features/step_definitions/email_steps.rb +63 -0
- data/features/step_definitions/extra_email_steps.rb +7 -0
- data/features/step_definitions/fork_steps.rb +4 -0
- data/features/step_definitions/generator_steps.rb +46 -0
- data/features/step_definitions/path_steps.rb +14 -0
- data/features/step_definitions/pickle_steps.rb +100 -0
- data/features/step_definitions/raise_error_steps.rb +3 -0
- data/features/support/email.rb +21 -0
- data/features/support/env.rb +52 -0
- data/features/support/paths.rb +47 -0
- data/features/support/pickle.rb +26 -0
- data/features/support/pickle_app.rb +4 -0
- data/init.rb +0 -0
- data/lib/generators/pickle_generator.rb +69 -0
- data/lib/pickle/adapter.rb +137 -0
- data/lib/pickle/adapters/active_record.rb +57 -0
- data/lib/pickle/adapters/data_mapper.rb +42 -0
- data/lib/pickle/adapters/mongoid.rb +44 -0
- data/lib/pickle/config.rb +49 -0
- data/lib/pickle/email/parser.rb +18 -0
- data/lib/pickle/email/world.rb +13 -0
- data/lib/pickle/email.rb +77 -0
- data/lib/pickle/parser/matchers.rb +87 -0
- data/lib/pickle/parser.rb +65 -0
- data/lib/pickle/path/world.rb +5 -0
- data/lib/pickle/path.rb +45 -0
- data/lib/pickle/session/parser.rb +34 -0
- data/lib/pickle/session.rb +205 -0
- data/lib/pickle/version.rb +9 -0
- data/lib/pickle/world.rb +14 -0
- data/lib/pickle.rb +26 -0
- data/pickle.gemspec +134 -0
- data/rails_generators/pickle/pickle_generator.rb +33 -0
- data/rails_generators/pickle/templates/email.rb +21 -0
- data/rails_generators/pickle/templates/email_steps.rb +63 -0
- data/rails_generators/pickle/templates/paths.rb +47 -0
- data/rails_generators/pickle/templates/pickle.rb +28 -0
- data/rails_generators/pickle/templates/pickle_steps.rb +100 -0
- data/spec/pickle/adapter_spec.rb +186 -0
- data/spec/pickle/config_spec.rb +109 -0
- data/spec/pickle/email/parser_spec.rb +51 -0
- data/spec/pickle/email_spec.rb +166 -0
- data/spec/pickle/parser/matchers_spec.rb +70 -0
- data/spec/pickle/parser_spec.rb +161 -0
- data/spec/pickle/path_spec.rb +101 -0
- data/spec/pickle/session_spec.rb +434 -0
- data/spec/pickle_spec.rb +24 -0
- data/spec/spec_helper.rb +8 -0
- metadata +199 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
module Pickle
|
2
|
+
class Parser
|
3
|
+
module Matchers
|
4
|
+
def match_ordinal
|
5
|
+
'(?:\d+(?:st|nd|rd|th))'
|
6
|
+
end
|
7
|
+
|
8
|
+
def match_index
|
9
|
+
"(?:first|last|#{match_ordinal})"
|
10
|
+
end
|
11
|
+
|
12
|
+
def match_prefix
|
13
|
+
'(?:(?:a|an|another|the|that) )'
|
14
|
+
end
|
15
|
+
|
16
|
+
def match_quoted
|
17
|
+
'(?:[^\\"]|\\.)*'
|
18
|
+
end
|
19
|
+
|
20
|
+
def match_label
|
21
|
+
"(?::? \"#{match_quoted}\")"
|
22
|
+
end
|
23
|
+
|
24
|
+
def match_value
|
25
|
+
"(?:\"#{match_quoted}\"|nil|true|false|[+-]?[0-9_]+(?:\\.\\d+)?)"
|
26
|
+
end
|
27
|
+
|
28
|
+
def match_field
|
29
|
+
"(?:\\w+: #{match_value})"
|
30
|
+
end
|
31
|
+
|
32
|
+
def match_fields
|
33
|
+
"(?:#{match_field}, )*#{match_field}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def match_mapping
|
37
|
+
"(?:#{config.mappings.map(&:search).join('|')})"
|
38
|
+
end
|
39
|
+
|
40
|
+
def match_factory
|
41
|
+
"(?:#{config.factories.keys.map{|n| n.gsub('_','[_ ]')}.join('|')})"
|
42
|
+
end
|
43
|
+
|
44
|
+
def match_plural_factory
|
45
|
+
"(?:#{config.factories.keys.map{|n| n.pluralize.gsub('_','[_ ]')}.join('|')})"
|
46
|
+
end
|
47
|
+
|
48
|
+
def match_indexed_model
|
49
|
+
"(?:(?:#{match_index} )?#{match_factory})"
|
50
|
+
end
|
51
|
+
|
52
|
+
def match_labeled_model
|
53
|
+
"(?:#{match_factory}#{match_label})"
|
54
|
+
end
|
55
|
+
|
56
|
+
def match_model
|
57
|
+
"(?:#{match_mapping}|#{match_prefix}?(?:#{match_indexed_model}|#{match_labeled_model}))"
|
58
|
+
end
|
59
|
+
|
60
|
+
def match_predicate
|
61
|
+
"(?:#{config.predicates.map{|m| m.to_s.sub(/^has_/,'').sub(/\?$/,'').gsub('_','[_ ]')}.join('|')})"
|
62
|
+
end
|
63
|
+
|
64
|
+
# create capture analogues of match methods
|
65
|
+
instance_methods.select{|m| m =~ /^match_/}.each do |method|
|
66
|
+
eval <<-end_eval
|
67
|
+
def #{method.to_s.sub('match_', 'capture_')} # def capture_field
|
68
|
+
"(" + #{method} + ")" # "(" + match_field + ")"
|
69
|
+
end # end
|
70
|
+
end_eval
|
71
|
+
end
|
72
|
+
|
73
|
+
# special capture methods
|
74
|
+
def capture_number_in_ordinal
|
75
|
+
'(?:(\d+)(?:st|nd|rd|th))'
|
76
|
+
end
|
77
|
+
|
78
|
+
def capture_name_in_label
|
79
|
+
"(?::? \"(#{match_quoted})\")"
|
80
|
+
end
|
81
|
+
|
82
|
+
def capture_key_and_value_in_field
|
83
|
+
"(?:(\\w+): #{capture_value})"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'pickle/parser/matchers'
|
2
|
+
|
3
|
+
module Pickle
|
4
|
+
class Parser
|
5
|
+
include Matchers
|
6
|
+
|
7
|
+
attr_reader :config
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@config = options[:config] || raise(ArgumentError, "Parser.new requires a :config")
|
11
|
+
end
|
12
|
+
|
13
|
+
# given a string like 'foo: "bar", bar: "baz"' returns {"foo" => "bar", "bar" => "baz"}
|
14
|
+
def parse_fields(fields)
|
15
|
+
if fields.blank?
|
16
|
+
{}
|
17
|
+
elsif fields =~ /^#{match_fields}$/
|
18
|
+
fields.scan(/(#{match_field})(?:,|$)/).inject({}) do |m, match|
|
19
|
+
m.merge(parse_field(match[0]))
|
20
|
+
end
|
21
|
+
else
|
22
|
+
raise ArgumentError, "The fields string is not in the correct format.\n\n'#{fields}' did not match: #{match_fields}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# given a string like 'foo: expr' returns {key => value}
|
27
|
+
def parse_field(field)
|
28
|
+
if field =~ /^#{capture_key_and_value_in_field}$/
|
29
|
+
{ $1 => eval($2) }
|
30
|
+
else
|
31
|
+
raise ArgumentError, "The field argument is not in the correct format.\n\n'#{field}' did not match: #{match_field}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# returns really underscored name
|
36
|
+
def canonical(str)
|
37
|
+
str.to_s.underscore.gsub(' ','_').gsub('/','_')
|
38
|
+
end
|
39
|
+
|
40
|
+
# return [factory_name, name or integer index]
|
41
|
+
def parse_model(model_name)
|
42
|
+
apply_mappings!(model_name)
|
43
|
+
if /#{capture_index} #{capture_factory}$/ =~ model_name
|
44
|
+
[canonical($2), parse_index($1)]
|
45
|
+
elsif /#{capture_factory}#{capture_name_in_label}?$/ =~ model_name
|
46
|
+
[canonical($1), canonical($2)]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_index(index)
|
51
|
+
case index
|
52
|
+
when nil, '', 'last' then -1
|
53
|
+
when /#{capture_number_in_ordinal}/ then $1.to_i - 1
|
54
|
+
when 'first' then 0
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def apply_mappings!(string)
|
60
|
+
config.mappings.each do |mapping|
|
61
|
+
string.sub! /^#{mapping.search}$/, mapping.replacement
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/pickle/path.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Pickle
|
2
|
+
module Path
|
3
|
+
# given args of pickle model name, and an optional extra action, or segment, will attempt to find
|
4
|
+
# a matching named route
|
5
|
+
#
|
6
|
+
# path_to_pickle 'the user', :action => 'edit' # => /users/3/edit
|
7
|
+
# path_to_pickle 'the user', 'the comment' # => /users/3/comments/1
|
8
|
+
# path_to_pickle 'the user', :segment => 'comments' # => /users/3/comments
|
9
|
+
#
|
10
|
+
# If you don;t know if the 'extra' part of the path is an action or a segment, then just
|
11
|
+
# pass it as 'extra' and this method will run through the possibilities
|
12
|
+
#
|
13
|
+
# path_to_pickle 'the user', :extra => 'new comment' # => /users/3/comments/new
|
14
|
+
def path_to_pickle(*pickle_names)
|
15
|
+
options = pickle_names.extract_options!
|
16
|
+
resources = pickle_names.map{|n| model(n) || n.to_sym}
|
17
|
+
if options[:extra]
|
18
|
+
parts = options[:extra].underscore.gsub(' ','_').split("_")
|
19
|
+
find_pickle_path_using_action_segment_combinations(resources, parts)
|
20
|
+
else
|
21
|
+
pickle_path_for_resources_action_segment(resources, options[:action], options[:segment])
|
22
|
+
end or raise "Could not figure out a path for #{pickle_names.inspect} #{options.inspect}"
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
def find_pickle_path_using_action_segment_combinations(resources, parts)
|
27
|
+
path = nil
|
28
|
+
(0..parts.length).each do |idx|
|
29
|
+
action = parts.slice(0, idx).join('_')
|
30
|
+
segment = parts.slice(idx, parts.length).join('_')
|
31
|
+
path = pickle_path_for_resources_action_segment(resources, action, segment) and break
|
32
|
+
end
|
33
|
+
path
|
34
|
+
end
|
35
|
+
|
36
|
+
def pickle_path_for_resources_action_segment(resources, action, segment)
|
37
|
+
action.blank? or action = action.downcase.gsub(' ','_')
|
38
|
+
segment.blank? or segment = segment.downcase.gsub(' ','_')
|
39
|
+
resource_names = resources.map{|s| s.is_a?(Symbol) ? s.to_s : s.class.name.underscore}.join("_")
|
40
|
+
models = resources.reject{|s| s.is_a?(Symbol)}
|
41
|
+
parts = [action, resource_names, segment].reject(&:blank?)
|
42
|
+
send("#{parts.join('_')}_path", *models) rescue nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Pickle
|
2
|
+
module Session
|
3
|
+
# add ability to parse model names as fields, using a session
|
4
|
+
module Parser
|
5
|
+
def self.included(parser_class)
|
6
|
+
parser_class.alias_method_chain :parse_field, :model
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :session
|
10
|
+
|
11
|
+
def match_field
|
12
|
+
"(?:\\w+: (?:#{match_model}|#{match_value}))"
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_field_with_model(field)
|
16
|
+
if session && field =~ /^(\w+): #{capture_model}$/
|
17
|
+
{$1 => session.model!($2)}
|
18
|
+
else
|
19
|
+
parse_field_without_model(field)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_hash(hash)
|
24
|
+
hash.inject({}) do |parsed, (key, val)|
|
25
|
+
if session && val =~ /^#{capture_model}$/
|
26
|
+
parsed.merge(key => session.model($1))
|
27
|
+
else
|
28
|
+
parsed.merge(key => val)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
module Pickle
|
2
|
+
module Session
|
3
|
+
class ModelNotKnownError < RuntimeError
|
4
|
+
attr_reader :name
|
5
|
+
|
6
|
+
def initialize(name, message = nil)
|
7
|
+
@name = name
|
8
|
+
@message = message || "The model: '#{name}' is not known in this scenario. Use #create_model to create, or #find_model to find, and store a reference in this scenario."
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
@message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def included(world_class)
|
18
|
+
proxy_to_pickle_parser(world_class)
|
19
|
+
end
|
20
|
+
|
21
|
+
def extended(world_object)
|
22
|
+
proxy_to_pickle_parser(class << world_object; self; end) # metaclass is not 2.1 compatible
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
def proxy_to_pickle_parser(world_class)
|
27
|
+
world_class.class_eval do
|
28
|
+
unless methods.include?('method_missing_with_pickle_parser')
|
29
|
+
alias_method_chain :method_missing, :pickle_parser
|
30
|
+
alias_method_chain :respond_to?, :pickle_parser
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_model(pickle_ref, fields = nil)
|
37
|
+
factory, label = *parse_model(pickle_ref)
|
38
|
+
raise ArgumentError, "Can't create with an ordinal (e.g. 1st user)" if label.is_a?(Integer)
|
39
|
+
fields = fields.is_a?(Hash) ? parse_hash(fields) : parse_fields(fields)
|
40
|
+
record = pickle_config.factories[factory].create(fields)
|
41
|
+
store_model(factory, label, record)
|
42
|
+
record
|
43
|
+
end
|
44
|
+
|
45
|
+
# if a column exists in the table which matches the singular factory name, this is used as the pickle ref
|
46
|
+
def create_models_from_table(plural_factory, table)
|
47
|
+
factory = plural_factory.singularize
|
48
|
+
table.hashes.map do |hash|
|
49
|
+
pickle_ref = factory + (hash[factory] ? " \"#{hash.delete(factory)}\"" : "")
|
50
|
+
create_model(pickle_ref, hash)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def find_model(a_model_name, fields = nil)
|
55
|
+
factory, name = *parse_model(a_model_name)
|
56
|
+
|
57
|
+
raise ArgumentError, "Can't find a model with an ordinal (e.g. 1st user)" if name.is_a?(Integer)
|
58
|
+
|
59
|
+
model_class = pickle_config.factories[factory].klass
|
60
|
+
fields = fields.is_a?(Hash) ? parse_hash(fields) : parse_fields(fields)
|
61
|
+
conditions = convert_models_to_attributes(model_class, fields)
|
62
|
+
record = Pickle::Adapter.find_first_model(model_class, conditions)
|
63
|
+
|
64
|
+
store_model(factory, name, record) if record
|
65
|
+
|
66
|
+
record
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_model!(name, fields = nil)
|
70
|
+
find_model(name, fields) or raise ModelNotKnownError, name
|
71
|
+
end
|
72
|
+
|
73
|
+
def find_models(factory, fields = nil)
|
74
|
+
factory = pickle_parser.canonical(factory)
|
75
|
+
|
76
|
+
models_by_index(factory).clear
|
77
|
+
|
78
|
+
model_class = pickle_config.factories[factory].klass
|
79
|
+
conditions = convert_models_to_attributes(model_class, parse_fields(fields))
|
80
|
+
records = Pickle::Adapter.find_all_models(model_class, conditions)
|
81
|
+
|
82
|
+
records.each {|record| store_model(factory, nil, record)}
|
83
|
+
end
|
84
|
+
|
85
|
+
# if a column exists in the table which matches the singular factory name, this is used as the pickle ref
|
86
|
+
def find_models_from_table(plural_factory, table)
|
87
|
+
factory = plural_factory.singularize
|
88
|
+
table.hashes.map do |hash|
|
89
|
+
pickle_ref = factory + (hash[factory] ? " \"#{hash.delete(factory)}\"" : "")
|
90
|
+
find_model(pickle_ref, hash)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# return the original model stored by create_model or find_model
|
95
|
+
def created_model(name)
|
96
|
+
factory, name_or_index = *parse_model(name)
|
97
|
+
|
98
|
+
if name_or_index.blank?
|
99
|
+
models_by_index(factory).last
|
100
|
+
elsif name_or_index.is_a?(Integer)
|
101
|
+
models_by_index(factory)[name_or_index]
|
102
|
+
else
|
103
|
+
models_by_name(factory)[name_or_index] or raise ModelNotKnownError, name
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# predicate version which raises no errors
|
108
|
+
def created_model?(name)
|
109
|
+
(created_model(name) rescue nil) ? true : false
|
110
|
+
end
|
111
|
+
|
112
|
+
# return a newly selected model
|
113
|
+
def model(name)
|
114
|
+
model = created_model(name)
|
115
|
+
return nil unless model
|
116
|
+
Pickle::Adapter.get_model(model.class, model.id)
|
117
|
+
end
|
118
|
+
|
119
|
+
# predicate version which raises no errors
|
120
|
+
def model?(name)
|
121
|
+
(model(name) rescue nil) ? true : false
|
122
|
+
end
|
123
|
+
|
124
|
+
# like model, but raise an error if it can't be found
|
125
|
+
def model!(name)
|
126
|
+
model(name) or raise ModelNotKnownError, name
|
127
|
+
end
|
128
|
+
|
129
|
+
# like created_model, but raise an error if it can't be found
|
130
|
+
def created_model!(name)
|
131
|
+
created_model(name) or raise ModelNotKnownError, name
|
132
|
+
end
|
133
|
+
|
134
|
+
# return all original models of specified type
|
135
|
+
def created_models(factory)
|
136
|
+
models_by_index(factory)
|
137
|
+
end
|
138
|
+
|
139
|
+
# return all models of specified type (freshly selected from the database)
|
140
|
+
def models(factory)
|
141
|
+
created_models(factory).map do |model|
|
142
|
+
Pickle::Adapter.get_model(model.class, model.id)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def respond_to_with_pickle_parser?(method, include_private = false)
|
147
|
+
respond_to_without_pickle_parser?(method, include_private) || pickle_parser.respond_to?(method, include_private)
|
148
|
+
end
|
149
|
+
|
150
|
+
protected
|
151
|
+
def method_missing_with_pickle_parser(method, *args, &block)
|
152
|
+
if pickle_parser.respond_to?(method)
|
153
|
+
pickle_parser.send(method, *args, &block)
|
154
|
+
else
|
155
|
+
method_missing_without_pickle_parser(method, *args, &block)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def pickle_parser=(parser)
|
160
|
+
parser.session = self
|
161
|
+
@pickle_parser = parser
|
162
|
+
end
|
163
|
+
|
164
|
+
def pickle_parser
|
165
|
+
@pickle_parser or self.pickle_parser = Pickle.parser
|
166
|
+
end
|
167
|
+
|
168
|
+
def pickle_config
|
169
|
+
pickle_parser.config
|
170
|
+
end
|
171
|
+
|
172
|
+
def convert_models_to_attributes(ar_class, attrs)
|
173
|
+
attrs.each do |key, val|
|
174
|
+
if ((defined?(ActiveRecord::Base) && val.is_a?(ActiveRecord::Base)) ||
|
175
|
+
(defined?(DataMapper::Model) && val.is_a?(DataMapper::Model))) &&
|
176
|
+
Pickle::Adapter.column_names(ar_class).include?("#{key}_id")
|
177
|
+
attrs["#{key}_id"] = val.id
|
178
|
+
attrs["#{key}_type"] = val.class.base_class.name if ar_class.column_names.include?("#{key}_type")
|
179
|
+
attrs.delete(key)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def models_by_name(factory)
|
185
|
+
@models_by_name ||= {}
|
186
|
+
@models_by_name[pickle_parser.canonical(factory)] ||= {}
|
187
|
+
end
|
188
|
+
|
189
|
+
def models_by_index(factory)
|
190
|
+
@models_by_index ||= {}
|
191
|
+
@models_by_index[pickle_parser.canonical(factory)] ||= []
|
192
|
+
end
|
193
|
+
|
194
|
+
# if the factory name != the model name, store under both names
|
195
|
+
def store_model(factory, name, record)
|
196
|
+
store_record(record.class.name, name, record) unless pickle_parser.canonical(factory) == pickle_parser.canonical(record.class.name)
|
197
|
+
store_record(factory, name, record)
|
198
|
+
end
|
199
|
+
|
200
|
+
def store_record(factory, name, record)
|
201
|
+
models_by_name(factory)[name] = record
|
202
|
+
models_by_index(factory) << record
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
data/lib/pickle/world.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'pickle'
|
2
|
+
|
3
|
+
# auto require for active record, datamapper and mongoid
|
4
|
+
require 'pickle/adapters/active_record' if defined?(ActiveRecord::Base)
|
5
|
+
require 'pickle/adapters/data_mapper' if defined?(DataMapper::Resource)
|
6
|
+
require 'pickle/adapters/mongoid' if defined?(Mongoid::Document)
|
7
|
+
|
8
|
+
# make cucumber world pickle aware
|
9
|
+
World(Pickle::Session)
|
10
|
+
|
11
|
+
# shortcuts to regexps for use in step definition regexps
|
12
|
+
class << self
|
13
|
+
delegate :capture_model, :capture_fields, :capture_factory, :capture_plural_factory, :capture_predicate, :capture_value, :to => 'Pickle.parser'
|
14
|
+
end
|
data/lib/pickle.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'pickle/version'
|
3
|
+
require 'pickle/adapter'
|
4
|
+
require 'pickle/config'
|
5
|
+
require 'pickle/parser'
|
6
|
+
require 'pickle/session'
|
7
|
+
require 'pickle/session/parser'
|
8
|
+
|
9
|
+
# make the parser aware of models in the session (for fields refering to models)
|
10
|
+
Pickle::Parser.send :include, Pickle::Session::Parser
|
11
|
+
|
12
|
+
module Pickle
|
13
|
+
class << self
|
14
|
+
def config
|
15
|
+
@config ||= Config.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def configure(&block)
|
19
|
+
config.configure(&block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def parser(options = {})
|
23
|
+
@parser ||= Parser.new({:config => config}.merge(options))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/pickle.gemspec
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{judit-pickle}
|
8
|
+
s.version = "0.4.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ian White"]
|
12
|
+
s.date = %q{2010-08-23}
|
13
|
+
s.description = %q{Easy model creation and reference in your cucumber features}
|
14
|
+
s.email = %q{ian.w.white@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"History.txt",
|
23
|
+
"License.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"Rakefile.d/cucumber.rake",
|
27
|
+
"Rakefile.d/jeweler.rake",
|
28
|
+
"Rakefile.d/rcov.rake",
|
29
|
+
"Rakefile.d/rspec.rake",
|
30
|
+
"Rakefile.d/yard.rake",
|
31
|
+
"Todo.txt",
|
32
|
+
"VERSION",
|
33
|
+
"features/app/app.rb",
|
34
|
+
"features/app/blueprints.rb",
|
35
|
+
"features/app/factories.rb",
|
36
|
+
"features/app/views/notifier/email.erb",
|
37
|
+
"features/app/views/notifier/user_email.erb",
|
38
|
+
"features/email/email.feature",
|
39
|
+
"features/generator/generators.feature",
|
40
|
+
"features/path/models_page.feature",
|
41
|
+
"features/path/named_route_page.feature",
|
42
|
+
"features/pickle/create_from_active_record.feature",
|
43
|
+
"features/pickle/create_from_factory_girl.feature",
|
44
|
+
"features/pickle/create_from_machinist.feature",
|
45
|
+
"features/step_definitions/email_steps.rb",
|
46
|
+
"features/step_definitions/extra_email_steps.rb",
|
47
|
+
"features/step_definitions/fork_steps.rb",
|
48
|
+
"features/step_definitions/generator_steps.rb",
|
49
|
+
"features/step_definitions/path_steps.rb",
|
50
|
+
"features/step_definitions/pickle_steps.rb",
|
51
|
+
"features/step_definitions/raise_error_steps.rb",
|
52
|
+
"features/support/email.rb",
|
53
|
+
"features/support/env.rb",
|
54
|
+
"features/support/paths.rb",
|
55
|
+
"features/support/pickle.rb",
|
56
|
+
"features/support/pickle_app.rb",
|
57
|
+
"init.rb",
|
58
|
+
"lib/generators/pickle_generator.rb",
|
59
|
+
"lib/pickle.rb",
|
60
|
+
"lib/pickle/adapter.rb",
|
61
|
+
"lib/pickle/adapters/active_record.rb",
|
62
|
+
"lib/pickle/adapters/data_mapper.rb",
|
63
|
+
"lib/pickle/adapters/mongoid.rb",
|
64
|
+
"lib/pickle/config.rb",
|
65
|
+
"lib/pickle/email.rb",
|
66
|
+
"lib/pickle/email/parser.rb",
|
67
|
+
"lib/pickle/email/world.rb",
|
68
|
+
"lib/pickle/parser.rb",
|
69
|
+
"lib/pickle/parser/matchers.rb",
|
70
|
+
"lib/pickle/path.rb",
|
71
|
+
"lib/pickle/path/world.rb",
|
72
|
+
"lib/pickle/session.rb",
|
73
|
+
"lib/pickle/session/parser.rb",
|
74
|
+
"lib/pickle/version.rb",
|
75
|
+
"lib/pickle/world.rb",
|
76
|
+
"pickle.gemspec",
|
77
|
+
"rails_generators/pickle/pickle_generator.rb",
|
78
|
+
"rails_generators/pickle/templates/email.rb",
|
79
|
+
"rails_generators/pickle/templates/email_steps.rb",
|
80
|
+
"rails_generators/pickle/templates/paths.rb",
|
81
|
+
"rails_generators/pickle/templates/pickle.rb",
|
82
|
+
"rails_generators/pickle/templates/pickle_steps.rb",
|
83
|
+
"spec/pickle/adapter_spec.rb",
|
84
|
+
"spec/pickle/config_spec.rb",
|
85
|
+
"spec/pickle/email/parser_spec.rb",
|
86
|
+
"spec/pickle/email_spec.rb",
|
87
|
+
"spec/pickle/parser/matchers_spec.rb",
|
88
|
+
"spec/pickle/parser_spec.rb",
|
89
|
+
"spec/pickle/path_spec.rb",
|
90
|
+
"spec/pickle/session_spec.rb",
|
91
|
+
"spec/pickle_spec.rb",
|
92
|
+
"spec/spec_helper.rb"
|
93
|
+
]
|
94
|
+
s.homepage = %q{http://github.com/ianwhite/pickle/tree}
|
95
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
96
|
+
s.require_paths = ["lib"]
|
97
|
+
s.rubygems_version = %q{1.3.7}
|
98
|
+
s.summary = %q{Easy model creation and reference in your cucumber features}
|
99
|
+
s.test_files = [
|
100
|
+
"spec/pickle/adapter_spec.rb",
|
101
|
+
"spec/pickle/config_spec.rb",
|
102
|
+
"spec/pickle/email/parser_spec.rb",
|
103
|
+
"spec/pickle/email_spec.rb",
|
104
|
+
"spec/pickle/parser/matchers_spec.rb",
|
105
|
+
"spec/pickle/parser_spec.rb",
|
106
|
+
"spec/pickle/path_spec.rb",
|
107
|
+
"spec/pickle/session_spec.rb",
|
108
|
+
"spec/pickle_spec.rb",
|
109
|
+
"spec/spec_helper.rb"
|
110
|
+
]
|
111
|
+
|
112
|
+
if s.respond_to? :specification_version then
|
113
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
114
|
+
s.specification_version = 3
|
115
|
+
|
116
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
117
|
+
s.add_runtime_dependency(%q<rspec>, [">= 1.3"])
|
118
|
+
s.add_runtime_dependency(%q<cucumber>, [">= 0.8"])
|
119
|
+
s.add_runtime_dependency(%q<yard>, [">= 0"])
|
120
|
+
s.add_runtime_dependency(%q<rake>, [">= 0"])
|
121
|
+
else
|
122
|
+
s.add_dependency(%q<rspec>, [">= 1.3"])
|
123
|
+
s.add_dependency(%q<cucumber>, [">= 0.8"])
|
124
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
125
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
126
|
+
end
|
127
|
+
else
|
128
|
+
s.add_dependency(%q<rspec>, [">= 1.3"])
|
129
|
+
s.add_dependency(%q<cucumber>, [">= 0.8"])
|
130
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
131
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class PickleGenerator < Rails::Generator::Base
|
2
|
+
def initialize(args, options)
|
3
|
+
super(args, options)
|
4
|
+
@generate_email_steps = args.include?('email')
|
5
|
+
if @generate_path_steps = args.include?('path') || args.include?('paths')
|
6
|
+
File.exists?('features/support/paths.rb') or raise "features/support/paths.rb not found, is your cucumber up to date?"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def manifest
|
11
|
+
record do |m|
|
12
|
+
m.directory File.join('features/step_definitions')
|
13
|
+
m.directory File.join('features/support')
|
14
|
+
|
15
|
+
current_pickle = File.exists?('features/support/pickle.rb') ? File.read('features/support/pickle.rb') : ''
|
16
|
+
pickle_assigns = {:pickle_path => false, :pickle_email => false}
|
17
|
+
|
18
|
+
if @generate_path_steps
|
19
|
+
pickle_assigns[:pickle_path] = true
|
20
|
+
m.template 'paths.rb', File.join('features/support', 'paths.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
if @generate_email_steps
|
24
|
+
pickle_assigns[:pickle_email] = true
|
25
|
+
m.template 'email_steps.rb', File.join('features/step_definitions', 'email_steps.rb')
|
26
|
+
m.template 'email.rb', File.join('features/support', 'email.rb')
|
27
|
+
end
|
28
|
+
|
29
|
+
m.template 'pickle_steps.rb', File.join('features/step_definitions', 'pickle_steps.rb')
|
30
|
+
m.template 'pickle.rb', File.join('features/support', 'pickle.rb'), :assigns => pickle_assigns
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module EmailHelpers
|
2
|
+
# Maps a name to an email address. Used by email_steps
|
3
|
+
|
4
|
+
def email_for(to)
|
5
|
+
case to
|
6
|
+
|
7
|
+
# add your own name => email address mappings here
|
8
|
+
|
9
|
+
when /^#{capture_model}$/
|
10
|
+
model($1).email
|
11
|
+
|
12
|
+
when /^"(.*)"$/
|
13
|
+
$1
|
14
|
+
|
15
|
+
else
|
16
|
+
to
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
World(EmailHelpers)
|