glue 0.41.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/Manifest.txt +6 -0
- data/README.txt +130 -0
- data/Rakefile +16 -0
- data/lib/glue.rb +49 -72
- data/test/test_glue.rb +218 -0
- metadata +84 -100
- data/doc/AUTHORS +0 -13
- data/doc/CHANGELOG.1 +0 -354
- data/doc/LICENSE +0 -32
- data/doc/RELEASES +0 -207
- data/lib/glue/attribute.rb +0 -113
- data/lib/glue/attributeutils.rb +0 -117
- data/lib/glue/autoreload.rb +0 -60
- data/lib/glue/builder.rb +0 -57
- data/lib/glue/builder/xml.rb +0 -103
- data/lib/glue/cache.rb +0 -22
- data/lib/glue/cache/drb.rb +0 -51
- data/lib/glue/cache/file.rb +0 -78
- data/lib/glue/cache/memcached.rb +0 -68
- data/lib/glue/cache/memory.rb +0 -79
- data/lib/glue/cache/og.rb +0 -61
- data/lib/glue/configuration.rb +0 -305
- data/lib/glue/fixture.rb +0 -154
- data/lib/glue/html.rb +0 -12
- data/lib/glue/localization.rb +0 -129
- data/lib/glue/logger.rb +0 -208
- data/lib/glue/mail.rb +0 -160
- data/lib/glue/mailer.rb +0 -55
- data/lib/glue/mailer/incoming.rb +0 -41
- data/lib/glue/mailer/outgoing.rb +0 -119
- data/lib/glue/settings.rb +0 -3
- data/lib/glue/uri.rb +0 -190
- data/lib/glue/validation.rb +0 -447
- data/lib/html/document.rb +0 -63
- data/lib/html/node.rb +0 -480
- data/lib/html/tokenizer.rb +0 -103
- data/lib/html/version.rb +0 -11
- data/test/fixture/article.csv +0 -3
- data/test/fixture/article.yml +0 -13
- data/test/fixture/user.yml +0 -12
- data/test/glue/builder/tc_xml.rb +0 -57
- data/test/glue/tc_aspects.rb +0 -99
- data/test/glue/tc_attribute.rb +0 -112
- data/test/glue/tc_attribute_mixins.rb +0 -86
- data/test/glue/tc_builder.rb +0 -30
- data/test/glue/tc_configuration.rb +0 -135
- data/test/glue/tc_fixture.rb +0 -98
- data/test/glue/tc_localization.rb +0 -49
- data/test/glue/tc_logger.rb +0 -43
- data/test/glue/tc_mail.rb +0 -99
- data/test/glue/tc_stores.rb +0 -16
- data/test/glue/tc_uri.rb +0 -97
- data/test/glue/tc_validation.rb +0 -217
- data/test/public/dummy_mailer/registration.xhtml +0 -5
data/lib/glue/cache/memory.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'facet/synchash'
|
2
|
-
|
3
|
-
require 'glue/cache'
|
4
|
-
|
5
|
-
module Glue
|
6
|
-
|
7
|
-
# A cache backed in memory.
|
8
|
-
#--
|
9
|
-
# This implementation is also the base for the Drb Cache.
|
10
|
-
#++
|
11
|
-
|
12
|
-
class MemoryCache < Cache
|
13
|
-
attr :hash
|
14
|
-
|
15
|
-
def initialize(options = {})
|
16
|
-
if options[:sync]
|
17
|
-
@hash = SyncHash
|
18
|
-
else
|
19
|
-
@hash = {}
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# Get an object from the cache.
|
24
|
-
|
25
|
-
def get(key, options = nil)
|
26
|
-
@hash[key]
|
27
|
-
end
|
28
|
-
alias_method :read, :get
|
29
|
-
alias_method :[], :get
|
30
|
-
|
31
|
-
# Put an object in the cache.
|
32
|
-
|
33
|
-
def set(key, value = nil, options = nil)
|
34
|
-
@hash[key] = value
|
35
|
-
end
|
36
|
-
alias_method :put, :set
|
37
|
-
alias_method :write, :set
|
38
|
-
alias_method :[]=, :set
|
39
|
-
|
40
|
-
# Delete an object from the cache.
|
41
|
-
|
42
|
-
def delete(key, options = nil)
|
43
|
-
@hash.delete(key)
|
44
|
-
end
|
45
|
-
alias_method :remove, :delete
|
46
|
-
|
47
|
-
def delete_if(&block)
|
48
|
-
@hash.delete_if(&block)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Perform session garbage collection. Typically this method
|
52
|
-
# is called from a cron like mechanism.
|
53
|
-
|
54
|
-
def gc!
|
55
|
-
delete_if { |key, s| s.expired? }
|
56
|
-
end
|
57
|
-
|
58
|
-
# Return the mapping.
|
59
|
-
|
60
|
-
def mapping
|
61
|
-
@hash
|
62
|
-
end
|
63
|
-
|
64
|
-
# Return all keys in the cache.
|
65
|
-
|
66
|
-
def keys
|
67
|
-
@hash.keys
|
68
|
-
end
|
69
|
-
|
70
|
-
# Return all objects in the cache.
|
71
|
-
|
72
|
-
def all
|
73
|
-
@hash.values
|
74
|
-
end
|
75
|
-
alias_method :values, :all
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
data/lib/glue/cache/og.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'og'
|
2
|
-
require 'base64'
|
3
|
-
|
4
|
-
module Glue
|
5
|
-
|
6
|
-
class OgCached
|
7
|
-
include Og::EntityMixin
|
8
|
-
|
9
|
-
property :unique_id, String, :sql => 'PRIMARY KEY'
|
10
|
-
property :expires, Time
|
11
|
-
property :cache_name, String
|
12
|
-
property :content, String
|
13
|
-
|
14
|
-
set_primary_key :unique_id, String
|
15
|
-
end
|
16
|
-
|
17
|
-
class OgCache
|
18
|
-
|
19
|
-
def initialize(cache_name, keepalive = nil)
|
20
|
-
@cache_name = cache_name
|
21
|
-
@keepalive = keepalive
|
22
|
-
end
|
23
|
-
|
24
|
-
def []=(k,v)
|
25
|
-
unless s = OgCached.find_by_unique_id_and_cache_name(k.to_s, @cache_name)
|
26
|
-
s = OgCached.new
|
27
|
-
s.cache_name = @cache_name
|
28
|
-
s.expires = Time.now + @keepalive if @keepalive
|
29
|
-
s.unique_id = k.to_s
|
30
|
-
end
|
31
|
-
#s.content = v.to_yaml
|
32
|
-
s.content = encode(v)
|
33
|
-
s.insert
|
34
|
-
end
|
35
|
-
|
36
|
-
def [](k)
|
37
|
-
s = OgCached.find_by_unique_id_and_cache_name(k.to_s, @cache_name)
|
38
|
-
decode(s.content) if s
|
39
|
-
end
|
40
|
-
|
41
|
-
def gc!
|
42
|
-
OgCached.find(:condition => ["expires < ? AND cache_name = ?", Time.now, @cache_name]).each {|s| s.delete }
|
43
|
-
end
|
44
|
-
|
45
|
-
def all
|
46
|
-
OgCached.find_by_cache_name(@cache_name)
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def encode(c)
|
52
|
-
Base64.encode64(Marshal.dump(c))
|
53
|
-
end
|
54
|
-
|
55
|
-
def decode(c)
|
56
|
-
Marshal::load(Base64.decode64(c))
|
57
|
-
#s.content = YAML::load(s.content)
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
data/lib/glue/configuration.rb
DELETED
@@ -1,305 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
require 'facets/core/kernel/constant'
|
4
|
-
require 'facets/more/synchash'
|
5
|
-
require 'facets/more/dictionary'
|
6
|
-
require 'facets/core/string/capitalized'
|
7
|
-
require 'facets/core/class/cattr'
|
8
|
-
|
9
|
-
module Glue
|
10
|
-
|
11
|
-
# A Configuration holds a group of Settings organized by
|
12
|
-
# Owners. An owner is a class that represents the system to be
|
13
|
-
# configured. An alias for this class is Settings.
|
14
|
-
#
|
15
|
-
# You can pass strings, constants or symbols as keys for the
|
16
|
-
# classes to be configured. Passing symbols you can configure
|
17
|
-
# classes even before they are defined.
|
18
|
-
#--
|
19
|
-
# TODO: implement with annotations.
|
20
|
-
#++
|
21
|
-
|
22
|
-
class Configuration
|
23
|
-
|
24
|
-
# A hash of setting owners. Use double @'s to allow for
|
25
|
-
# the Settings alias.
|
26
|
-
#--
|
27
|
-
# TODO: find a better name.
|
28
|
-
#++
|
29
|
-
|
30
|
-
@@owners = SyncHash.new
|
31
|
-
|
32
|
-
# A datastructure to store Settings metadata.
|
33
|
-
#
|
34
|
-
# Please note the difference between :default and :value,
|
35
|
-
# :default does NOT override :value.
|
36
|
-
|
37
|
-
class Setting
|
38
|
-
attr_accessor :owner, :name, :type, :value, :options
|
39
|
-
|
40
|
-
def initialize(owner, name, options)
|
41
|
-
if options.key? :value
|
42
|
-
@value = options[:value]
|
43
|
-
elsif options.key? :default
|
44
|
-
@value = options[:default]
|
45
|
-
else
|
46
|
-
raise ArgumentError.new('A value is required')
|
47
|
-
end
|
48
|
-
|
49
|
-
@owner, @name = owner, name
|
50
|
-
@options = options
|
51
|
-
@type = options[:type] = options[:type] || @value.class
|
52
|
-
end
|
53
|
-
|
54
|
-
# Update the setting from an options hash. The update does
|
55
|
-
# NOT take default values into account!
|
56
|
-
|
57
|
-
def update(hash)
|
58
|
-
if hash.key? :value
|
59
|
-
@value = hash[:value]
|
60
|
-
@type = @value.class
|
61
|
-
end
|
62
|
-
|
63
|
-
if hash.key? :type
|
64
|
-
@type = hash[:type]
|
65
|
-
end
|
66
|
-
|
67
|
-
@options.update(hash)
|
68
|
-
end
|
69
|
-
|
70
|
-
# Text representation of this setting.
|
71
|
-
|
72
|
-
def to_s
|
73
|
-
@value.to_s
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
# A collection of Settings. This helper enables intuitive
|
79
|
-
# settings initialization like this:
|
80
|
-
#
|
81
|
-
# Configuration.Compiler.template_root = 'public'
|
82
|
-
# instead of
|
83
|
-
# Configuration.setting :compiler, :template_root, :value => 'public'
|
84
|
-
|
85
|
-
class SettingCollection < Hash
|
86
|
-
attr_accessor :owner
|
87
|
-
|
88
|
-
# Handles setting readers and writers.
|
89
|
-
|
90
|
-
def method_missing(sym, *args)
|
91
|
-
if sym.to_s =~ /=$/
|
92
|
-
# Remove trailing
|
93
|
-
sym = sym.to_s.gsub(/=/, '').to_sym
|
94
|
-
Configuration.setting @owner, sym, :value => args.first
|
95
|
-
else
|
96
|
-
self[sym]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
class << self
|
102
|
-
|
103
|
-
# The configuration mode, typical modes include :debug,
|
104
|
-
# :stage, :live.
|
105
|
-
#
|
106
|
-
# [:debug]
|
107
|
-
# useful when debugging, extra debug information
|
108
|
-
# is emmited, actions, templates and shaders are
|
109
|
-
# reloaded, etc. The execution speed of the application
|
110
|
-
# is impaired.
|
111
|
-
#
|
112
|
-
# [:stage]
|
113
|
-
# test the application with live parameters
|
114
|
-
# (typically on a staging server).
|
115
|
-
#
|
116
|
-
# [:live]
|
117
|
-
# use the parameters for the live (production)
|
118
|
-
# server. Optimized for speed.
|
119
|
-
#
|
120
|
-
# Tries to set the default value from the NITRO_MODE
|
121
|
-
# environment variable.
|
122
|
-
|
123
|
-
attr_accessor :mode
|
124
|
-
|
125
|
-
def mode
|
126
|
-
mode = nil
|
127
|
-
if mode = ENV['CONFIGURATION_MODE']
|
128
|
-
$stderr.puts "CONFIGURATION_MODE is deprecated, use NITRO_MODE"
|
129
|
-
end
|
130
|
-
@mode || mode || ENV.fetch('NITRO_MODE', :debug).to_sym
|
131
|
-
end
|
132
|
-
|
133
|
-
# The log output destination.
|
134
|
-
#
|
135
|
-
# ['STDOUT' 'STDERR']
|
136
|
-
# Sets the log to stdout or stderr.
|
137
|
-
#
|
138
|
-
# [str]
|
139
|
-
# Any other string is regarded as path
|
140
|
-
|
141
|
-
attr_accessor :log
|
142
|
-
|
143
|
-
def log
|
144
|
-
return @log if @log
|
145
|
-
|
146
|
-
log = ENV.fetch('NITRO_LOG', Logger.new('log/app.log'))
|
147
|
-
|
148
|
-
if log.kind_of?(String)
|
149
|
-
if log =~ /(STD(?:OUT|ERR))/i
|
150
|
-
log = Object.const_get($1.upcase)
|
151
|
-
elsif File.directory?(File.dirname(log))
|
152
|
-
log = Logger.new(log)
|
153
|
-
else
|
154
|
-
log = 'log/app.log'
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
@log = log
|
159
|
-
end
|
160
|
-
|
161
|
-
alias kernel_load load
|
162
|
-
|
163
|
-
# Attempt to load external configuration in Ruby or
|
164
|
-
# YAML format. The files:
|
165
|
-
#
|
166
|
-
# * conf/mode.rb
|
167
|
-
# * conf/mode.yaml
|
168
|
-
#
|
169
|
-
# are considered.
|
170
|
-
|
171
|
-
def load(m = mode)
|
172
|
-
ruby_conf = "conf/#{m}.rb"
|
173
|
-
kernel_load(ruby_conf) if File.exist?(ruby_conf)
|
174
|
-
|
175
|
-
# Try to configure from a yaml file.
|
176
|
-
yml_conf = "conf/#{m}.yml"
|
177
|
-
Configuration.load_yaml(yml_conf) if File.exist?(yml_conf)
|
178
|
-
end
|
179
|
-
|
180
|
-
# Inject the configuration parameters provided as a hash
|
181
|
-
# (dictionary, ordered) to classes to be configured.
|
182
|
-
#
|
183
|
-
# === Warning: Pass an ordered hash (dictionary)
|
184
|
-
|
185
|
-
def setup(options)
|
186
|
-
options.each do |owner, ss|
|
187
|
-
next unless ss
|
188
|
-
ss.each do |name, s|
|
189
|
-
add_setting(owner, name.to_sym, :value => s)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
# Parse configuration parameters in yaml format.
|
195
|
-
|
196
|
-
def parse_yaml(options)
|
197
|
-
temp = YAML::load(options)
|
198
|
-
options = Dictionary.new
|
199
|
-
temp.each do |k, v|
|
200
|
-
options[k.gsub(/\./, '::').to_sym] = v
|
201
|
-
end
|
202
|
-
|
203
|
-
setup(options)
|
204
|
-
end
|
205
|
-
|
206
|
-
# Load an external ruby configuration file. Constant missing
|
207
|
-
# errors are not reported for extra flexibility.
|
208
|
-
|
209
|
-
def load_ruby(filename)
|
210
|
-
end
|
211
|
-
|
212
|
-
# Load and parse an external yaml configuration file.
|
213
|
-
|
214
|
-
def load_yaml(filename)
|
215
|
-
parse_yaml(File.read(filename))
|
216
|
-
end
|
217
|
-
|
218
|
-
# Manually add a configuration setting. The class key can
|
219
|
-
# be the actual class name constant or a symbol. If the
|
220
|
-
# setting is already defined it updates it.
|
221
|
-
#
|
222
|
-
# === Examples
|
223
|
-
#
|
224
|
-
# Configuration.add_setting Compiler, :verification, :value => 12, :doc => '...'
|
225
|
-
# Configuration.setting :IdPart, :verify_registration_email, :value => false
|
226
|
-
# s = Configuration.Compiler.verification.value
|
227
|
-
|
228
|
-
def add_setting(owner, name, options)
|
229
|
-
owner = owner.to_s.to_sym
|
230
|
-
@@owners[owner] ||= {}
|
231
|
-
if s = @@owners[owner][name]
|
232
|
-
# The setting already exists, update it.
|
233
|
-
s.update(options)
|
234
|
-
else
|
235
|
-
# The setting does not exist, create it.
|
236
|
-
@@owners[owner][name] = Setting.new(owner, name, options)
|
237
|
-
end
|
238
|
-
end
|
239
|
-
alias_method :setting, :add_setting
|
240
|
-
|
241
|
-
# Return the settings for the given owner. The owner is
|
242
|
-
# typically the Class that represents the system to be
|
243
|
-
# configured. If no class is provided, it returns all the
|
244
|
-
# registered settings.
|
245
|
-
|
246
|
-
def settings(owner = nil)
|
247
|
-
if owner
|
248
|
-
owner = owner.to_s.to_sym
|
249
|
-
@@owners[owner]
|
250
|
-
else
|
251
|
-
@@owners.values.inject([]) { |memo, obj| memo.concat(obj.values) }
|
252
|
-
end
|
253
|
-
end
|
254
|
-
alias_method :all, :settings
|
255
|
-
alias_method :[], :settings
|
256
|
-
|
257
|
-
#--
|
258
|
-
# FIXME: this does not work as expected.
|
259
|
-
#++
|
260
|
-
|
261
|
-
def method_missing(sym)
|
262
|
-
if sym.to_s.capitalized?
|
263
|
-
bdl = SettingCollection.new
|
264
|
-
bdl.owner = sym
|
265
|
-
if hash = self[sym]
|
266
|
-
bdl.update(hash)
|
267
|
-
end
|
268
|
-
return bdl
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
end
|
274
|
-
|
275
|
-
# Alias for the Configuration class (shorter).
|
276
|
-
|
277
|
-
Settings = Configuration
|
278
|
-
|
279
|
-
end
|
280
|
-
|
281
|
-
class Module
|
282
|
-
|
283
|
-
# Defines a configuration setting for the enclosing class.
|
284
|
-
#
|
285
|
-
# === Example
|
286
|
-
#
|
287
|
-
# class Compiler
|
288
|
-
# setting :template_root, :default => 'src/template', :doc => 'The template root dir'
|
289
|
-
# end
|
290
|
-
|
291
|
-
def setting(sym, options = {})
|
292
|
-
Glue::Configuration.add_setting(self, sym, options)
|
293
|
-
|
294
|
-
module_eval %{
|
295
|
-
def self.#{sym}
|
296
|
-
Glue::Configuration[#{self}][:#{sym}].value
|
297
|
-
end
|
298
|
-
|
299
|
-
def self.#{sym}=(obj)
|
300
|
-
Glue::Configuration.setting #{self}, :#{sym}, :value => obj
|
301
|
-
end
|
302
|
-
}
|
303
|
-
end
|
304
|
-
|
305
|
-
end
|
data/lib/glue/fixture.rb
DELETED
@@ -1,154 +0,0 @@
|
|
1
|
-
require 'facet/kernel/constant'
|
2
|
-
|
3
|
-
require 'facet/ormsupport'
|
4
|
-
|
5
|
-
require 'glue/configuration'
|
6
|
-
require 'nitro/template'
|
7
|
-
|
8
|
-
module Glue
|
9
|
-
|
10
|
-
# A collection of helper methods.
|
11
|
-
|
12
|
-
class Fixtures
|
13
|
-
|
14
|
-
# The directory where the fixtures are located.
|
15
|
-
|
16
|
-
setting :root_dir, :default => 'test/fixture', :doc => 'The directory where the fixtures are located'
|
17
|
-
|
18
|
-
@fixtures = {}
|
19
|
-
|
20
|
-
class << self
|
21
|
-
|
22
|
-
def load(*classes)
|
23
|
-
for klass in classes
|
24
|
-
f = Fixture.new(klass).load
|
25
|
-
@fixtures[f.name] = f
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def [](klass)
|
30
|
-
@fixtures[klass]
|
31
|
-
end
|
32
|
-
|
33
|
-
def []=(klass, fixture)
|
34
|
-
@fixtures[klass] = fixture
|
35
|
-
end
|
36
|
-
|
37
|
-
def method_missing(sym)
|
38
|
-
if f = @fixtures[sym.to_s]
|
39
|
-
return f
|
40
|
-
end
|
41
|
-
super
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Fixtures is a fancy word for ‘sample data’. Fixtures allow you
|
47
|
-
# to populate your database with predefined data. Fixtures are
|
48
|
-
# typically used during testing or when providing initial data
|
49
|
-
# (bootstrap data) for a live application.
|
50
|
-
#
|
51
|
-
# A Fixture is a collection (Hash) of objects.
|
52
|
-
|
53
|
-
class Fixture < Hash
|
54
|
-
|
55
|
-
# The name of this Fixture.
|
56
|
-
|
57
|
-
attr_accessor :name
|
58
|
-
|
59
|
-
# The class that the Fixtures refer to.
|
60
|
-
|
61
|
-
attr_accessor :klass
|
62
|
-
|
63
|
-
# Used to keep the order.
|
64
|
-
|
65
|
-
attr_accessor :objects
|
66
|
-
|
67
|
-
def initialize(klass, options = { } )
|
68
|
-
@klass = klass
|
69
|
-
@name = class_to_name(klass)
|
70
|
-
@objects = []
|
71
|
-
load(options[:root_dir] || options[:root] || Fixtures.root_dir)
|
72
|
-
end
|
73
|
-
|
74
|
-
def load(root_dir = Fixtures.root_dir)
|
75
|
-
raise("The fixture root directory '#{root_dir}' doesn't exits") unless File.exist?(root_dir)
|
76
|
-
|
77
|
-
if path = "#{root_dir}/#{@name}.yml" and File.exist?(path)
|
78
|
-
parse_yaml(path)
|
79
|
-
end
|
80
|
-
|
81
|
-
if path = "#{root_dir}/#{@name}.yaml" and File.exist?(path)
|
82
|
-
parse_yaml(path)
|
83
|
-
end
|
84
|
-
|
85
|
-
if path = "#{root_dir}/#{@name}.csv" and File.exist?(path)
|
86
|
-
parse_csv(path)
|
87
|
-
end
|
88
|
-
|
89
|
-
return self
|
90
|
-
end
|
91
|
-
|
92
|
-
# Parse a fixture file in YAML format.
|
93
|
-
|
94
|
-
def parse_yaml(path)
|
95
|
-
require 'yaml'
|
96
|
-
|
97
|
-
str = Nitro::Template.new.render(File.read(path))
|
98
|
-
|
99
|
-
if yaml = YAML::load(str)
|
100
|
-
for name, data in yaml
|
101
|
-
self[name] = instantiate(data)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# sort the objects.
|
106
|
-
|
107
|
-
str.scan(/^(\w*?):$/).each do |key|
|
108
|
-
@objects << self[key.to_s]
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Parse a fixture file in CSV format. Many RDBM systems and
|
113
|
-
# Spreadsheets can export to CVS, so this is a rather useful
|
114
|
-
# format.
|
115
|
-
|
116
|
-
def parse_csv(path)
|
117
|
-
require 'csv'
|
118
|
-
|
119
|
-
str = Nitro::Template.new.render(File.read(path))
|
120
|
-
|
121
|
-
reader = CSV::Reader.create(str)
|
122
|
-
header = reader.shift
|
123
|
-
|
124
|
-
reader.each_with_index do |row, i|
|
125
|
-
data = {}
|
126
|
-
row.each_with_index do |cell, j|
|
127
|
-
data[header[j].to_s.strip] = cell.to_s.strip
|
128
|
-
end
|
129
|
-
self["#{@name}_#{i+1}"] = obj = instantiate(data)
|
130
|
-
@objects << obj
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
private
|
135
|
-
|
136
|
-
# Instantiate an actual object from the Fixture data.
|
137
|
-
|
138
|
-
def instantiate(data)
|
139
|
-
obj = @klass.allocate
|
140
|
-
|
141
|
-
for key, value in data
|
142
|
-
obj.instance_variable_set("@#{key}", value)
|
143
|
-
end
|
144
|
-
|
145
|
-
return obj
|
146
|
-
end
|
147
|
-
|
148
|
-
def class_to_name(klass)
|
149
|
-
klass.to_s.demodulize.underscore
|
150
|
-
end
|
151
|
-
|
152
|
-
end
|
153
|
-
|
154
|
-
end
|