mundo-pepino 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.1.3 2009-10-27
2
+ * path_to method sensitivity: if present, url_mappings are disabled
3
+ * Configuration as Rails teach me: MundoPepino.configure
4
+ * Possibility to map to dynamic values with access to the World
5
+
1
6
  == 0.1.2 2009-10-20
2
7
 
3
8
  * 2 major enhancements
data/Manifest.txt CHANGED
@@ -5,14 +5,17 @@ README.markdown
5
5
  README_es.markdown
6
6
  init.rb
7
7
  lib/mundo_pepino.rb
8
+ lib/mundo_pepino/base.rb
9
+ lib/mundo_pepino/config.rb
8
10
  lib/mundo_pepino/definitions/en_US.rb
9
11
  lib/mundo_pepino/definitions/es_ES.rb
12
+ lib/mundo_pepino/en_US.rb
13
+ lib/mundo_pepino/es_ES.rb
10
14
  lib/mundo_pepino/implementations.rb
15
+ lib/mundo_pepino/implementations_api.rb
11
16
  lib/mundo_pepino/resources_history.rb
12
17
  lib/mundo_pepino/version.rb
13
18
  lib/mundo_pepino/visits_history.rb
14
- lib/mundo_pepino_en_US.rb
15
- lib/mundo_pepino_es_ES.rb
16
19
  rails_generators/caracteristica/USAGE
17
20
  rails_generators/caracteristica/caracteristica_generator.rb
18
21
  rails_generators/caracteristica/templates/caracteristica.erb
data/README.markdown CHANGED
@@ -17,8 +17,14 @@ MundoPepino is a set of reusable step definitions to test Rails apps with Cucumb
17
17
 
18
18
  **DISCLAIMER**:
19
19
 
20
- MundoPepino was originally implemented to write features in Spanish. However its design has been modified to support different languages (and, theoretically, at the same time if needed). Currently only part of the original set of steps (and just a little of the documentation) has been translated to English.
20
+ MundoPepino was originally implemented to write features in Spanish. Its code has been recently modified to support different languages (and, theoretically, at the same time if needed).
21
21
 
22
+ Currently only part of the original set of steps (and just a little of the documentation) has been translated to English. On the other hand features written in English don't have to manage the complexity added by translations of models and attributes. Cousin projects like [pickle](http://github.com/ianwhite/pickle) or [email-spec](http://github.com/bmabey/email-spec) are much more advanced to write features in English.
23
+
24
+ For other languages, before start your own implementation, it'd be nice if you:
25
+
26
+ * start a new language in MundoPepino (we'll be glad to help you if you try), or
27
+ * look for your language in [similar i18n projects](http://groups.google.com/group/cukes/browse_thread/thread/b9b8ff6301393c19/febf6530a1ed1a37).
22
28
 
23
29
  ## Resources
24
30
 
data/README_es.markdown CHANGED
@@ -65,7 +65,11 @@ Como plugin (ver dependencias más abajo):
65
65
  script/plugin install git://github.com/dchelimsky/rspec.git
66
66
  script/plugin install git://github.com/dchelimsky/rspec-rails.git
67
67
 
68
- Además necesitamos instalar la gema o plugin StringMapper (ver más abajo):
68
+ Además necesitamos instalar la gema o plugin StringMapper:
69
+
70
+ gem install string-mapper
71
+
72
+ o
69
73
 
70
74
  script/plugin install git://github.com/nando/string-mapper.git
71
75
 
@@ -74,12 +78,6 @@ Como plugin (ver dependencias más abajo):
74
78
  * instalar el módulo ruby-locale,
75
79
  * o redefinir la función strftime para lograr dicho comportamiento.
76
80
 
77
- #### [StringMapper](http://github.com/nando/string-mapper)
78
-
79
- StringMapper es una extensión de la clase String para obtener modelos, números, nombres de campo, etc. a partir de sus nombres en castellano.
80
-
81
- script/plugin install git://github.com/nando/string-mapper.git
82
-
83
81
  #### [FixtureReplacement](http://replacefixtures.rubyforge.org/)
84
82
 
85
83
  De fábrica MundoPepino utiliza ActiveRecord para incorporar a la BBDD los datos que soliciten los escenarios.
@@ -157,62 +155,33 @@ Y posteriormente en las vistas llamamos al helper con algo parecido a:
157
155
  <%= pepino.datetime_select :harvested_at, :use_month_names => Meses %>
158
156
 
159
157
  ## Uso
160
-
161
- Para utilizar MundoPepino en una aplicación en la que todavía no estamos utilizando Cucumber lo más cómodo es comenzar utilizando los generadores (de forma similar a como se describe más arriba en *Toma de contacto*). Algo como:
162
-
163
- cd miapp-sin-cucumber
164
- script/plugin install git://github.com/nando/string-mapper.git
165
- script/plugin install git://github.com/nando/mundo-pepino.git
166
- script/generate mundo_pepino
167
- script/generate caracteristica Model Modelo name:string:nombre used:boolean:usado
168
-
169
- Aquí ya deberíamos poder lanzar `rake caracteristicas`, obteniendo eso sí los errores pertinentes relacionados con implementación concreta de nuestro controlador. El fichero `gestion_de_modelo.feature` (que podemos renombrar por algo más chulo) nos servirá de patrón para escribir nuestra /característica/.
170
-
171
- Para utilizar MundoPepino en una aplicación en la que ya estamos utilizando Cucumber, al final de `features/support/env.rb` (o equivalente) incorporamos lo siguiente:
172
-
173
- require 'mundo_pepino'
174
- String.model_mappings = {} # Mapeo castellano-inglés de modelos
175
- String.field_mappings = {} # Mapeo castellano-inglés de campos
176
-
177
- World do
178
- MundoPepino.new
179
- end
180
-
181
- Es recomendable también vaciar el contenido de la BBDD antes de comenzar la evaluación de un nuevo escenario para que los datos que pueda haber de otros escenarios no alteren su resultado. La función *Before* nos puede ayudar para conseguirlo, haciendo algo como:
182
-
183
- Before do
184
- MiModelo.destroy_all
185
- MiOtroModelo.destroy_all # etc.
186
- end
187
-
188
- *Before* se ejecutará antes de cada escenario y que los //Antecetentes// ((Background)[http://wiki.github.com/aslakhellesoy/cucumber/background]) de los mismos si los hubiese.
189
-
190
158
  ### generate mundo\_pepino
191
159
 
192
160
  rails_root$ script/generate mundo_pepino
193
- create caracteristicas/support
194
- create caracteristicas/support/mundo_pepino_env.rb
161
+ exists features/step_definitions
162
+ create features/step_definitions/mundo_pepino_es_ES.rb
195
163
  exists lib/tasks
196
164
  create lib/tasks/mundo_pepino.rake
197
165
 
198
- El principio de `mundo_pepino_env.rb` es el contenido del `env.rb` generado por `generate cucumber`, tras el cual añade lo siguiente:
166
+ En `mundo_pepino_es_ES.rb` tenemos lo siguiente:
199
167
 
200
- require 'mundo_pepino' # Cargamos MundoPepino...
201
- MundoPepino::ModelsToClean = [] # Array con los modelos que serán limpiados
168
+ require 'mundo_pepino/es_ES' # Cargamos las definiciones en castellano
169
+ MundoPepino.configure do |c|
170
+ c.models_to_clean = [] # Array con los modelos que serán limpiados
202
171
  # antes de lanzar cada escenario.
203
- String.model_mappings = {} # Hash con el mapeo de los modelos a partir
172
+ c.model_mappings = {} # Hash con el mapeo de los modelos a partir
204
173
  # de sus equivalencias en castellano.
205
- String.field_mappings = {} # Hash con el mapeo de los campos.
174
+ c.field_mappings = {} # Hash con el mapeo de los campos.
206
175
  class MiMundo < MundoPepino # Ejemplo de uso del MundoPepio con herencia.
207
176
  # include FixtureReplacement # FR listo para entrar en acción. Meter aquí
208
177
  # def mi_funcion; ...; end # las funciones específicas que necesitemos
209
178
  end # desde nuestras definiciones.
210
179
  Before do # La limpieza de modelos propiamente dicha...
211
- MundoPepino::ModelsToClean.each { |model| model.destroy_all }
212
- end # ...se realizará antes de cada escenario.
213
- World do # Finalmente le pedimos a Cucumber que
214
- MiMundo.new # utilice una instancia de nuestro mundo como
215
- end # ámbito local de nuestros escenarios.
180
+ MundoPepino.clean_models
181
+ end # ...se realizará antes de cada escenario.
182
+ # Finalmente le pedimos a Cucumber que
183
+ World(MiMundo) # utilice una instancia de nuestro mundo como
184
+ # ámbito local de nuestros escenarios.
216
185
 
217
186
  Por otro lado `mundo_pepino.rake` añade una tarea llamada **caracteristicas** que lanza con la opción `--language es` todos los ficheros con extensión `.feature` que tengamos dentro del directorio `caracteristicas`.
218
187
 
data/lib/mundo_pepino.rb CHANGED
@@ -1,260 +1,76 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
- require 'cucumber/rails/world'
4
+ require 'mundo_pepino/base'
5
+ require 'mundo_pepino/implementations_api'
5
6
  require 'mundo_pepino/implementations'
6
7
  require 'mundo_pepino/resources_history'
7
8
  require 'mundo_pepino/visits_history'
8
9
  require 'mundo_pepino/version'
10
+ require 'mundo_pepino/config'
9
11
 
10
12
  require 'string-mapper'
11
13
 
12
- String.add_mapper :model
13
- String.add_mapper :relation_model
14
- String.add_mapper(:content_type,
15
- /\.png$/ => 'image/png',
16
- /\.jpe?g$/ => 'image/jpg',
17
- /\.gif$/ => 'image/gif') { |str| 'text/plain' }
18
- String.add_mapper(:underscored) { |string| string.gsub(/ +/, '_') }
19
- String.add_mapper(:unquoted) { |str| str =~ /^['"](.*)['"]$/ ? $1 : str}
20
- String.add_mapper(:translated) { |str|
21
- if str =~ /^[a-z_]+\.[a-z_]+[a-z_\.]+$/
22
- I18n.translate(str, :default => str)
23
- elsif str =~ /^([a-z_]+\.[a-z_]+[a-z_\.]+),(\{.+\})$/
24
- I18n.translate($1, {:default => str}.merge(eval($2)))
25
- else
26
- str
27
- end
28
- }
29
-
30
14
  module MundoPepino
15
+ include Base
16
+ include ImplementationsApi
31
17
  include Implementations
32
18
  include ResourcesHistory
33
19
  include VisitsHistory
34
-
35
- def real_value_for(v)
36
- (v.is_a?(String) ? v.to_real_value : v )
37
- end
38
20
 
39
- def parsed_attributes(raw_attributes)
40
- attributes = {}
41
- raw_attributes.each do |k, v|
42
- if k =~ /^(.+)_id$/
43
- if polymorph = raw_attributes.delete($1 + '_type')
44
- attributes[$1.to_sym] = polymorph.constantize.find(v.to_i)
21
+ class << self
22
+ attr_accessor :world
23
+ def extended(current_world)
24
+ self.world = current_world
25
+ common_mappings
26
+ language_specific_mappings
27
+ user_specific_mappings
28
+ end
29
+
30
+ def common_mappings
31
+ String.add_mapper :model
32
+ String.add_mapper :relation_model
33
+ String.add_mapper(:content_type,
34
+ /\.png$/ => 'image/png',
35
+ /\.jpe?g$/ => 'image/jpg',
36
+ /\.gif$/ => 'image/gif') { |str| 'text/plain' }
37
+ String.add_mapper(:underscored) { |string| string.gsub(/ +/, '_') }
38
+ String.add_mapper(:unquoted) { |str| str =~ /^['"](.*)['"]$/ ? $1 : str}
39
+ String.add_mapper(:translated) do |str|
40
+ if str =~ /^[a-z_]+\.[a-z_]+[a-z_\.]+$/
41
+ I18n.translate(str, :default => str)
42
+ elsif str =~ /^([a-z_]+\.[a-z_]+[a-z_\.]+),(\{.+\})$/
43
+ I18n.translate($1, {:default => str}.merge(eval($2)))
45
44
  else
46
- attributes[$1.to_sym] = ($1.to_relation_model || $1.camelize.constantize).find(v.to_i)
45
+ str
47
46
  end
48
- else
49
- attributes[k] = real_value_for(v)
50
47
  end
51
- end
52
- attributes
53
- end
54
-
55
- def create(model, raw_attributes = {})
56
- through = raw_attributes.delete(:through)
57
- attributes = parsed_attributes(raw_attributes)
58
- obj = if defined?(FixtureReplacement)
59
- self.send "create_#{model.name.underscore}", attributes
60
- elsif defined?(Machinist)
61
- model.make attributes
62
- elsif defined?(Factory)
63
- Factory(model.name.underscore.to_sym, attributes)
64
- else
65
- model.create! attributes
66
- end
67
- if(through)
68
- create through['model'], through['attributes'].merge(model.name.underscore.to_sym => obj)
69
- end
70
- obj
71
- end
72
-
73
- def find_or_create(model_or_modelo, attributes = {}, options = {})
74
- model = if model_or_modelo.is_a?(String)
75
- model_or_modelo.to_model
76
- else
77
- model_or_modelo
78
- end
79
- if attributes.any?
80
- attribs = Hash.new
81
- attributes.each do |key, value|
82
- if child_model = (key.to_s.to_model || key.to_s.to_relation_model)
83
- child = add_resource(child_model, field_for(child_model, 'nombre') => value)
84
- field_name = key.to_s.to_relation_model ? key : child_model.name.underscore
85
- attribs["#{field_name}_id"] = child.id
48
+ String.add_mapper(:url) do |string|
49
+ if world.respond_to? :path_to
50
+ world.path_to string
86
51
  else
87
- attribs[key] = value
88
- end
89
- end
90
- if ((options[:force_creation].nil? || !options[:force_creation]) &&
91
- obj = model.find(:first, :conditions => conditions_from_attributes(attribs)))
92
- if(through = attribs[:through])
93
- create through['model'], through['attributes'].merge(model.name.underscore.to_sym => obj)
52
+ string if string =~ /^\/.*$|^https?:\/\//i
94
53
  end
95
- obj
96
- else
97
- create model, attribs
98
54
  end
99
- else
100
- create model
101
55
  end
102
- end
103
-
104
- def conditions_from_attributes(attributes)
105
- attribs = attributes.reject {|k,v| k == :through}
106
- [attribs.keys.map{|s| "#{s}=?"}.join(' AND ')] + attribs.values
107
- end
108
56
 
109
- def names_for_simple_creation(model, number, name_or_names, options = {})
110
- base_hash = base_hash_for(options)
111
- if name_or_names
112
- field = field_for(model, 'nombre')
113
- names = name_or_names.split(/ ?, | y /)
114
- if names.size == number
115
- names.map { |name| base_hash.dup.merge(field => name) }
116
- else
117
- [base_hash.dup.merge(field => name_or_names)] * number
118
- end
119
- else
120
- [base_hash] * number
57
+ def config
58
+ @config ||= Config.new
121
59
  end
122
- end
123
60
 
124
- def field_for(model, campo = 'nombre')
125
- "#{model && model.name}::#{campo}".to_field || campo.to_field
126
- end
127
- def shouldify(should_or_not)
128
- affirmative = 'debo|debo ver|veo|deber[ií]a|deber[íi]a ver|leo|debo leer|deber[ií]a leer'
129
- should_or_not =~ /^(#{affirmative})$/i ? :should : :should_not
130
- end
131
-
132
- def not_shouldify(should_or_not)
133
- shouldify(should_or_not) == :should ? :should_not : :should
134
- end
135
-
136
- def relative_page(pagina)
137
- if pagina =~ /la siguiente p[aá]gina|la p[aá]gina anterior/i
138
- head, current, tail = if last_visited =~ /(.+page=)(\d+)(.*)/
139
- [$1, $2.to_i, $3]
140
- else
141
- [last_visited + '?page=', 1, '']
142
- end
143
- (pagina =~ /siguiente/ ? current += 1 : current -= 1)
144
- head + current.to_s + tail
145
- else
146
- nil
61
+ def configure(&block)
62
+ config.configure(&block)
147
63
  end
148
- end
149
64
 
150
- # Cucumber::Model::Table's hashes traduciendo nombres de campo
151
- def translated_hashes(step_table, options = {})
152
- base_hash = base_hash_for(options)
153
- header = step_table[0].map do |campo|
154
- field_for(options[:model], campo) || campo
65
+ def clean_models
66
+ config.models_to_clean.each { |model| model.destroy_all }
155
67
  end
156
- step_table[1..-1].map do |row|
157
- h = base_hash.dup
158
- row.each_with_index do |v,n|
159
- key = header[n]
160
- h[key] = v
161
- end
162
- h
163
- end
164
- end
165
68
 
166
- def base_hash_for(options)
167
- if options[:parent]
168
- # polymorphic associations
169
- if options[:polymorphic_as]
170
- { "#{options[:polymorphic_as]}_id" => options[:parent].id,
171
- "#{options[:polymorphic_as]}_type" => options[:parent].class.name }
172
- else
173
- field_prefix = options[:parent].class.name.underscore
174
- if options[:through]
175
- {:through => {"model" => eval(options[:through].to_s.classify),
176
- "attributes" => {"#{field_prefix}_id" => options[:parent].id}}}
177
- else
178
- { "#{field_prefix}_id" => options[:parent].id }
179
- end
180
- end
181
- else
182
- {}
183
- end
184
- end
185
-
186
- def campo_to_field(campo, model = nil)
187
- unless campo.nil?
188
- if field = field_for(model, campo.to_unquoted)
189
- field
190
- else
191
- raise MundoPepino::FieldNotMapped.new(campo)
192
- end
193
- end
194
- end
195
-
196
- def last_mentioned_should_have_value(campo, valor)
197
- res = last_mentioned
198
- if child_model = campo.to_model
199
- child = child_model.find_by_name(valor)
200
- child_field = campo.to_field || child_model.name.underscore
201
- (res.send child_field).should == child
202
- elsif field = field_for(res.class, campo)
203
- (res.send field).to_s.should == valor.to_s
204
- else
205
- raise FieldNotMapped.new(campo)
206
- end
207
- end
208
-
209
- def last_mentioned_should_have_child(child, name)
210
- if child_model = child.to_model
211
- child = child_model.find_by_name(name)
212
- (last_mentioned.send child_model.table_name).detect do |c|
213
- c.id == child.id
214
- end.should_not be_nil
215
- else
216
- raise ModelNotMapped.new(child)
69
+ def user_specific_mappings
70
+ config.model_mappings.each {|k,v| String.model_mappings[k] = v}
71
+ config.relation_model_mappings.each {|k,v| String.relation_model_mappings[k] = v}
72
+ config.field_mappings.each {|k,v| String.field_mappings[k] = v}
73
+ config.url_mappings.each {|k,v| String.url_mappings[k] = v}
217
74
  end
218
75
  end
219
-
220
- def find_field_and_do_with_webrat(action, campo, options = nil)
221
- do_with_webrat action, campo.to_unquoted.to_translated, options # a pelo (localización vía labels)
222
- rescue Webrat::NotFoundError
223
- field = campo_to_field(campo, last_mentioned_model)
224
- begin
225
- do_with_webrat action, field, options # campo traducido tal cual...
226
- rescue Webrat::NotFoundError
227
- if singular = last_mentioned_singular # traducido y con el modelo por delante
228
- do_with_webrat action, singular + '_' + field.to_s, options # p.e.: user_name
229
- else
230
- raise
231
- end
232
- end
233
- end
234
-
235
- def do_with_webrat(action, field, options)
236
- if options
237
- if options[:path] and options[:content_type]
238
- self.send action, field, options[:path], options[:content_type]
239
- else
240
- self.send action, field, options
241
- end
242
- else
243
- self.send action, field
244
- end
245
- end
246
-
247
- def parent_options(parent, child)
248
- options = {:parent => parent}
249
- # polymorphic associations
250
- if reflections = parent.class.reflect_on_association(child.table_name.to_sym)
251
- if reflections.options[:as]
252
- options.merge!({:polymorphic_as => reflections.options[:as]})
253
- elsif reflections.options[:through]
254
- options.merge!({:through => reflections.options[:through]})
255
- end
256
- end
257
- options
258
- end
259
-
260
76
  end
@@ -0,0 +1,73 @@
1
+ module MundoPepino
2
+ module Base
3
+ def parsed_attributes(raw_attributes)
4
+ attributes = {}
5
+ raw_attributes.each do |k, v|
6
+ if k =~ /^(.+)_id$/
7
+ if polymorph = raw_attributes.delete($1 + '_type')
8
+ attributes[$1.to_sym] = polymorph.constantize.find(v.to_i)
9
+ else
10
+ attributes[$1.to_sym] = ($1.to_relation_model || $1.camelize.constantize).find(v.to_i)
11
+ end
12
+ else
13
+ attributes[k] = real_value_for(v)
14
+ end
15
+ end
16
+ attributes
17
+ end
18
+
19
+ def create(model, raw_attributes = {})
20
+ through = raw_attributes.delete(:through)
21
+ attributes = parsed_attributes(raw_attributes)
22
+ obj = if defined?(FixtureReplacement)
23
+ self.send "create_#{model.name.underscore}", attributes
24
+ elsif defined?(Machinist)
25
+ model.make attributes
26
+ elsif defined?(Factory)
27
+ Factory(model.name.underscore.to_sym, attributes)
28
+ else
29
+ model.create! attributes
30
+ end
31
+ if(through)
32
+ create through['model'], through['attributes'].merge(model.name.underscore.to_sym => obj)
33
+ end
34
+ obj
35
+ end
36
+
37
+ def find_or_create(model_or_modelo, attributes = {}, options = {})
38
+ model = if model_or_modelo.is_a?(String)
39
+ model_or_modelo.to_model
40
+ else
41
+ model_or_modelo
42
+ end
43
+ if attributes.any?
44
+ attribs = Hash.new
45
+ attributes.each do |key, value|
46
+ if child_model = (key.to_s.to_model || key.to_s.to_relation_model)
47
+ child = add_resource(child_model, field_for(child_model, 'nombre') => value)
48
+ field_name = key.to_s.to_relation_model ? key : child_model.name.underscore
49
+ attribs["#{field_name}_id"] = child.id
50
+ else
51
+ attribs[key] = value
52
+ end
53
+ end
54
+ if ((options[:force_creation].nil? || !options[:force_creation]) &&
55
+ obj = model.find(:first, :conditions => conditions_from_attributes(attribs)))
56
+ if(through = attribs[:through])
57
+ create through['model'], through['attributes'].merge(model.name.underscore.to_sym => obj)
58
+ end
59
+ obj
60
+ else
61
+ create model, attribs
62
+ end
63
+ else
64
+ create model
65
+ end
66
+ end
67
+
68
+ def conditions_from_attributes(attributes)
69
+ attribs = attributes.reject {|k,v| k == :through}
70
+ [attribs.keys.map{|s| "#{s}=?"}.join(' AND ')] + attribs.values
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,26 @@
1
+ require 'ostruct'
2
+
3
+ module MundoPepino
4
+ class Config
5
+ attr_accessor :models_to_clean,
6
+ :model_mappings,
7
+ :field_mappings,
8
+ :relation_model_mappings,
9
+ :url_mappings
10
+
11
+ def initialize(&block)
12
+ @models_to_clean = []
13
+ @model_mappings, @field_mappings,
14
+ @relation_model_mappings, @url_mappings = {}, {}, {}, {}
15
+ configure(&block) if block_given?
16
+ end
17
+
18
+ def configure(&block)
19
+ yield(self)
20
+ end
21
+
22
+ def models_to_clean
23
+ @models_to_clean ||= []
24
+ end
25
+ end
26
+ end
@@ -1,41 +1,45 @@
1
1
  # MundoPepino's step definitions in en_US
2
-
3
- String.add_mapper(:real_value, {
4
- /^tru(e|th)$/i => true,
5
- /^false$/i => false
6
- }) { |value| value } # "true".to_real_value # => true
7
- String.add_mapper(:field, {:nombre => :name})
8
-
9
- String.add_mapper(:url, /^the home(page)?/i => '/') do |string|
10
- string if string =~ /^\/.*$|^https?:\/\//i
2
+ module MundoPepino
3
+ class << self
4
+ def language_specific_mappings
5
+ String.add_mapper(:real_value, {
6
+ /^tru(e|th)$/i => true,
7
+ /^false$/i => false
8
+ }) { |value| value } # "true".to_real_value # => true
9
+ String.add_mapper(:field, {:nombre => :name})
10
+
11
+ String.add_mapper(:number, {
12
+ /^an?$/i => 1,
13
+ /^one$/i => 1,
14
+ /^first?$/i => 1,
15
+ /^two$/i => 2,
16
+ /^second$/i => 2,
17
+ /^three$/i => 3,
18
+ /^third$/i => 3,
19
+ /^four$/i => 4,
20
+ /^fourth$/i => 4,
21
+ /^five$/i => 5,
22
+ /^fifth$/i => 5}) { |string| string.to_i }
23
+ String.add_mapper(:crud_action,
24
+ /^creation$/i => 'new',
25
+ /^changes?$/i => 'edit',
26
+ /^modifications?$/i => 'edit',
27
+ /^editions?$/i => 'edit') { |action| action }
28
+ String.add_mapper(:month) { |month| month.capitalize }
29
+ unless self.world.respond_to? :path_to
30
+ String.url_mappings[/^the home\s?page/i] = self.world.root_path
31
+ end
32
+ end
33
+ end
11
34
  end
12
35
 
13
- String.add_mapper(:number, {
14
- /^an?$/i => 1,
15
- /^one$/i => 1,
16
- /^first?$/i => 1,
17
- /^two$/i => 2,
18
- /^second$/i => 2,
19
- /^three$/i => 3,
20
- /^third$/i => 3,
21
- /^four$/i => 4,
22
- /^fourth$/i => 4,
23
- /^five$/i => 5,
24
- /^fifth$/i => 5}) { |string| string.to_i }
25
- String.add_mapper(:crud_action,
26
- /^creation$/i => 'new',
27
- /^changes?$/i => 'edit',
28
- /^modifications?$/i => 'edit',
29
- /^editions?$/i => 'edit') { |action| action }
30
- String.add_mapper(:month) { |month| month.capitalize }
31
-
32
- number = 'a|an|one|two|three|four|five|six|seven|eight|nine|ten|\d+'
36
+ match_number = 'a|an|one|two|three|four|five|six|seven|eight|nine|ten|\d+'
33
37
  which = '(?:which|that have as)'
34
38
  # Simple creation w/ optional name/s
35
- Given /^(?:that we have )?(#{number}) (?!.+ #{which})(.+?)(?: (?:called )?['"](.+)["'])?$/i do |number, model, name|
39
+ Given /^(?:that we have )?(#{match_number}) (?!.+ #{which})(.+?)(?: (?:called )?['"](.+)["'])?$/i do |number, model, name|
36
40
  given_we_have_a_number_of_instances_called number, model, name
37
41
  end
38
42
 
39
- Then /^we have (#{number}) ([^ ]+)(?: (?:called )?['"](.+)["'])? in our database$/ do |number, model, names|
43
+ Then /^we have (#{match_number}) ([^ ]+)(?: (?:called )?['"](.+)["'])? in our database$/ do |number, model, names|
40
44
  then_we_have_a_number_of_instances_in_our_database number, model, names
41
45
  end
@@ -1,45 +1,51 @@
1
1
  # MundoPepino's step definitions in es_ES
2
+ module MundoPepino
3
+ class << self
4
+ def language_specific_mappings
5
+ String.add_mapper(:real_value, {
6
+ /^verdader[oa]$/i => true,
7
+ /^fals[ao]$/i => false
8
+ }) { |value| value }
9
+ String.add_mapper(:field) { |str| :name if str =~ /nombres?/ }
10
+
11
+ String.add_mapper(:number, {
12
+ /^un[oa]?$/i => 1,
13
+ /^primer[oa]?$/i => 1,
14
+ :dos => 2,
15
+ /^segund[oa]?$/i => 2,
16
+ :tres => 3,
17
+ /^tercer[ao]/i => 3,
18
+ :cuatro => 4,
19
+ /^cuart[ao]/i => 4,
20
+ :cinco => 5,
21
+ /^quint[ao]/i => 5}) { |string| string.to_i }
22
+ String.add_mapper(:crud_action,
23
+ /^alta$/i => 'new',
24
+ /^creaci[óo]n$/i => 'new',
25
+ /^nuev(?:o|a|o\/a|a\/o)$/i => 'new',
26
+ /^cambio$/i => 'edit',
27
+ /^modificaci[oó]n(?:es)?$/i => 'edit',
28
+ /^edici[oó]n$/i => 'edit')
29
+ String.add_mapper(:month,
30
+ :enero => 'January',
31
+ :febrero => 'February',
32
+ :marzo => 'March',
33
+ :abril => 'April',
34
+ :mayo => 'May',
35
+ :junio => 'June',
36
+ :julio => 'July',
37
+ :agosto => 'August',
38
+ /^sep?tiembre$/i => 'September',
39
+ :octubre => 'October',
40
+ :noviembre => 'November',
41
+ :diciembre => 'December')
42
+ unless self.world.respond_to? :path_to
43
+ String.url_mappings[/^la (?:portada|home\s?(?:page)?)/i] = self.world.root_path
44
+ end
2
45
 
3
- String.add_mapper(:real_value, {
4
- /^verdader[oa]$/i => true,
5
- /^fals[ao]$/i => false
6
- }) { |value| value }
7
- String.add_mapper(:field) { |str| :name if str =~ /nombres?/ }
8
- String.add_mapper(:url, /^la (portada|home)/i => '/') do |string|
9
- string if string =~ /^\/.*$|^https?:\/\//i
10
- end
11
-
12
- String.add_mapper(:number, {
13
- /^un[oa]?$/i => 1,
14
- /^primer[oa]?$/i => 1,
15
- :dos => 2,
16
- /^segund[oa]?$/i => 2,
17
- :tres => 3,
18
- /^tercer[ao]/i => 3,
19
- :cuatro => 4,
20
- /^cuart[ao]/i => 4,
21
- :cinco => 5,
22
- /^quint[ao]/i => 5}) { |string| string.to_i }
23
- String.add_mapper(:crud_action,
24
- /^alta$/i => 'new',
25
- /^creaci[óo]n$/i => 'new',
26
- /^nuev(?:o|a|o\/a|a\/o)$/i => 'new',
27
- /^cambio$/i => 'edit',
28
- /^modificaci[oó]n(?:es)?$/i => 'edit',
29
- /^edici[oó]n$/i => 'edit')
30
- String.add_mapper(:month,
31
- :enero => 'January',
32
- :febrero => 'February',
33
- :marzo => 'March',
34
- :abril => 'April',
35
- :mayo => 'May',
36
- :junio => 'June',
37
- :julio => 'July',
38
- :agosto => 'August',
39
- /^sep?tiembre$/i => 'September',
40
- :octubre => 'October',
41
- :noviembre => 'November',
42
- :diciembre => 'December')
46
+ end
47
+ end
48
+ end
43
49
 
44
50
  nro = 'un|una|dos|tres|cuatro|cinco|seis|siete|ocho|nueve|diez|\d+'
45
51
  cuyo = '(?:cuy[oa]s?|que tienen? como)'
@@ -300,9 +306,7 @@ Entonces /^(#{veo_o_no}) (?:las|los) siguientes (?:etiquetas|selectores):$/i do
300
306
  end
301
307
  end
302
308
 
303
-
304
-
305
- Entonces /^(#{veo_o_no}) un enlace (?:a|para) (.+)?$/i do |should, pagina|
309
+ Entonces /^(#{veo_o_no}) un enlace (?:al?|para) (.+)?$/i do |should, pagina|
306
310
  lambda {
307
311
  href = relative_page(pagina) || pagina.to_unquoted.to_url
308
312
  response.should have_tag('a[href=?]', href)
@@ -0,0 +1,160 @@
1
+ module MundoPepino
2
+ module ImplementationsApi
3
+ def real_value_for(v)
4
+ (v.is_a?(String) ? v.to_real_value : v )
5
+ end
6
+
7
+ def names_for_simple_creation(model, number, name_or_names, options = {})
8
+ base_hash = base_hash_for(options)
9
+ if name_or_names
10
+ field = field_for(model, 'nombre')
11
+ names = name_or_names.split(/ ?, | y /)
12
+ if names.size == number
13
+ names.map { |name| base_hash.dup.merge(field => name) }
14
+ else
15
+ [base_hash.dup.merge(field => name_or_names)] * number
16
+ end
17
+ else
18
+ [base_hash] * number
19
+ end
20
+ end
21
+
22
+ def field_for(model, campo = 'nombre')
23
+ "#{model && model.name}::#{campo}".to_field || campo.to_field
24
+ end
25
+
26
+ def shouldify(should_or_not)
27
+ affirmative = 'debo|debo ver|veo|deber[ií]a|deber[íi]a ver|leo|debo leer|deber[ií]a leer'
28
+ should_or_not =~ /^(#{affirmative})$/i ? :should : :should_not
29
+ end
30
+
31
+ def not_shouldify(should_or_not)
32
+ shouldify(should_or_not) == :should ? :should_not : :should
33
+ end
34
+
35
+ def relative_page(pagina)
36
+ if pagina =~ /la siguiente p[aá]gina|la p[aá]gina anterior/i
37
+ head, current, tail = if last_visited =~ /(.+page=)(\d+)(.*)/
38
+ [$1, $2.to_i, $3]
39
+ else
40
+ [last_visited + '?page=', 1, '']
41
+ end
42
+ (pagina =~ /siguiente/ ? current += 1 : current -= 1)
43
+ head + current.to_s + tail
44
+ else
45
+ nil
46
+ end
47
+ end
48
+
49
+ # Cucumber::Model::Table's hashes traduciendo nombres de campo
50
+ def translated_hashes(step_table, options = {})
51
+ base_hash = base_hash_for(options)
52
+ header = step_table[0].map do |campo|
53
+ field_for(options[:model], campo) || campo
54
+ end
55
+ step_table[1..-1].map do |row|
56
+ h = base_hash.dup
57
+ row.each_with_index do |v,n|
58
+ key = header[n]
59
+ h[key] = v
60
+ end
61
+ h
62
+ end
63
+ end
64
+
65
+ def base_hash_for(options)
66
+ if options[:parent]
67
+ # polymorphic associations
68
+ if options[:polymorphic_as]
69
+ { "#{options[:polymorphic_as]}_id" => options[:parent].id,
70
+ "#{options[:polymorphic_as]}_type" => options[:parent].class.name }
71
+ else
72
+ field_prefix = options[:parent].class.name.underscore
73
+ if options[:through]
74
+ {:through => {"model" => eval(options[:through].to_s.classify),
75
+ "attributes" => {"#{field_prefix}_id" => options[:parent].id}}}
76
+ else
77
+ { "#{field_prefix}_id" => options[:parent].id }
78
+ end
79
+ end
80
+ else
81
+ {}
82
+ end
83
+ end
84
+
85
+ def campo_to_field(campo, model = nil)
86
+ unless campo.nil?
87
+ if field = field_for(model, campo.to_unquoted)
88
+ field
89
+ else
90
+ raise MundoPepino::FieldNotMapped.new(campo)
91
+ end
92
+ end
93
+ end
94
+
95
+ def last_mentioned_should_have_value(campo, valor)
96
+ res = last_mentioned
97
+ if child_model = campo.to_model
98
+ child = child_model.find_by_name(valor)
99
+ child_field = campo.to_field || child_model.name.underscore
100
+ (res.send child_field).should == child
101
+ elsif field = field_for(res.class, campo)
102
+ (res.send field).to_s.should == valor.to_s
103
+ else
104
+ raise FieldNotMapped.new(campo)
105
+ end
106
+ end
107
+
108
+ def last_mentioned_should_have_child(child, name)
109
+ if child_model = child.to_model
110
+ child = child_model.find_by_name(name)
111
+ (last_mentioned.send child_model.table_name).detect do |c|
112
+ c.id == child.id
113
+ end.should_not be_nil
114
+ else
115
+ raise ModelNotMapped.new(child)
116
+ end
117
+ end
118
+
119
+ def find_field_and_do_with_webrat(action, campo, options = nil)
120
+ do_with_webrat action, campo.to_unquoted.to_translated, options # a pelo (localización vía labels)
121
+ rescue Webrat::NotFoundError
122
+ field = campo_to_field(campo, last_mentioned_model)
123
+ begin
124
+ do_with_webrat action, field, options # campo traducido tal cual...
125
+ rescue Webrat::NotFoundError
126
+ if singular = last_mentioned_singular # traducido y con el modelo por delante
127
+ do_with_webrat action, singular + '_' + field.to_s, options # p.e.: user_name
128
+ else
129
+ raise
130
+ end
131
+ end
132
+ end
133
+
134
+ def do_with_webrat(action, field, options)
135
+ if options
136
+ if options[:path] and options[:content_type]
137
+ self.send action, field, options[:path], options[:content_type]
138
+ else
139
+ self.send action, field, options
140
+ end
141
+ else
142
+ self.send action, field
143
+ end
144
+ end
145
+
146
+ def parent_options(parent, child)
147
+ options = {:parent => parent}
148
+ # polymorphic associations
149
+ if reflections = parent.class.reflect_on_association(child.table_name.to_sym)
150
+ if reflections.options[:as]
151
+ options.merge!({:polymorphic_as => reflections.options[:as]})
152
+ elsif reflections.options[:through]
153
+ options.merge!({:through => reflections.options[:through]})
154
+ end
155
+ end
156
+ options
157
+ end
158
+ end
159
+ end
160
+
@@ -2,7 +2,7 @@ module MundoPepino #:nodoc:
2
2
  class VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 2
5
+ TINY = 3
6
6
  PATCH = nil # Set to nil for official release
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
@@ -16,17 +16,17 @@ module Rails::Generator::Commands
16
16
 
17
17
  class Create < Base
18
18
  def mp_model_cleaning(model)
19
- add_to_mundo_pepino_env "MundoPepino::ModelsToClean = [", eval(MODEL_CLEANING)
19
+ add_to_mundo_pepino_env "config.models_to_clean = [", eval(MODEL_CLEANING)
20
20
  logger.model_cleaning "added #{model} (#{model}.destroy_all call before each scenario)"
21
21
  end
22
22
 
23
23
  def mp_model_mapping(model, regexp)
24
- add_to_mundo_pepino_env 'String.model_mappings = {', eval(MODEL_MAPPING)
24
+ add_to_mundo_pepino_env 'config.model_mappings = {', eval(MODEL_MAPPING)
25
25
  logger.model_mapping " added /^#{regexp}$/i => #{model}"
26
26
  end
27
27
 
28
28
  def mp_field_mapping(field, regexp)
29
- add_to_mundo_pepino_env 'String.field_mappings = {', eval(FIELD_MAPPING)
29
+ add_to_mundo_pepino_env 'config.field_mappings = {', eval(FIELD_MAPPING)
30
30
  logger.field_mapping " added /^#{regexp}$/i => :#{field}"
31
31
  end
32
32
 
@@ -43,7 +43,7 @@ module Rails::Generator::Commands
43
43
  class Destroy < RewindBase
44
44
  def mp_model_cleaning(model)
45
45
  remove_from_mundo_pepino_env eval(MODEL_CLEANING)
46
- logger.model_cleaning "removing Before { #{model}.destroy_all }"
46
+ logger.model_cleaning "removing #{model} model cleaning"
47
47
  end
48
48
 
49
49
  def mp_model_mapping(model, regexp)
@@ -1,36 +1,37 @@
1
- require 'mundo_pepino_es_ES'
1
+ require 'mundo_pepino/es_ES'
2
2
 
3
3
  Webrat.configure do |config|
4
4
  config.mode = :rails
5
5
  end
6
6
 
7
- MundoPepino::ModelsToClean = [
8
- # MODELOS PARA LIMPIAR antes de cada escenario,
9
- # por ejemplo:
10
- # Orchard, Terrace, Crop...
11
- ]
12
-
13
- String.model_mappings = {
14
- # TRADUCCIÓN DE MODELOS AQUÍ, por ejemplo:
15
- # /^huert[oa]s?/i => Orchard,
16
- # /^bancal(es)?$/i => Terrace,
17
- # /^cultivos?$/i => Crop...
18
- }
19
-
20
- String.field_mappings = {
21
- # TRADUCCIÓN DE CAMPOS AQUÍ:
22
- # /^[Ááa]reas?$/i => 'area',
23
- # /^color(es)?$/i => 'color',
24
- # /^latitud(es)?$/i => 'latitude',
25
- # /^longitud(es)?/i => 'length'
26
- #
27
- # TRADUCCIÓN ESPECÍFICA PARA UN MODELO
28
- # /^Orchard::longitud(es)?$/ => 'longitude'
29
- }
30
-
7
+ MundoPepino.configure do |config|
8
+ config.models_to_clean = [
9
+ # MODELOS PARA LIMPIAR antes de cada escenario,
10
+ # por ejemplo:
11
+ # Orchard, Terrace, Crop...
12
+ ]
13
+
14
+ config.model_mappings = {
15
+ # TRADUCCIÓN DE MODELOS AQUÍ, por ejemplo:
16
+ # /^huert[oa]s?/i => Orchard,
17
+ # /^bancal(es)?$/i => Terrace,
18
+ # /^cultivos?$/i => Crop...
19
+ }
20
+
21
+ config.field_mappings = {
22
+ # TRADUCCIÓN DE CAMPOS AQUÍ:
23
+ # /^[Ááa]reas?$/i => 'area',
24
+ # /^color(es)?$/i => 'color',
25
+ # /^latitud(es)?$/i => 'latitude',
26
+ # /^longitud(es)?/i => 'length'
27
+ #
28
+ # TRADUCCIÓN ESPECÍFICA PARA UN MODELO
29
+ # /^Orchard::longitud(es)?$/ => 'longitude'
30
+ }
31
+ end
31
32
 
32
33
  Before do
33
- MundoPepino::ModelsToClean.each { |model| model.destroy_all }
34
+ MundoPepino.clean_models
34
35
  end
35
36
 
36
37
  #module MundoPepino
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mundo-pepino
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Fernando Garc\xC3\xADa Samblas"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-20 00:00:00 +02:00
12
+ date: 2009-10-27 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -70,7 +70,7 @@ dependencies:
70
70
  requirements:
71
71
  - - ">="
72
72
  - !ruby/object:Gem::Version
73
- version: 0.1.0
73
+ version: 0.1.1
74
74
  version:
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: hoe
@@ -100,14 +100,17 @@ files:
100
100
  - README_es.markdown
101
101
  - init.rb
102
102
  - lib/mundo_pepino.rb
103
+ - lib/mundo_pepino/base.rb
104
+ - lib/mundo_pepino/config.rb
103
105
  - lib/mundo_pepino/definitions/en_US.rb
104
106
  - lib/mundo_pepino/definitions/es_ES.rb
107
+ - lib/mundo_pepino/en_US.rb
108
+ - lib/mundo_pepino/es_ES.rb
105
109
  - lib/mundo_pepino/implementations.rb
110
+ - lib/mundo_pepino/implementations_api.rb
106
111
  - lib/mundo_pepino/resources_history.rb
107
112
  - lib/mundo_pepino/version.rb
108
113
  - lib/mundo_pepino/visits_history.rb
109
- - lib/mundo_pepino_en_US.rb
110
- - lib/mundo_pepino_es_ES.rb
111
114
  - rails_generators/caracteristica/USAGE
112
115
  - rails_generators/caracteristica/caracteristica_generator.rb
113
116
  - rails_generators/caracteristica/templates/caracteristica.erb