homeschool 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +3 -0
- data/Rakefile +72 -0
- data/bin/bfight +31 -0
- data/bin/gfight +12 -0
- data/bin/homeschool +2 -0
- data/bin/svm +388 -0
- data/lib/fight.rb +26 -0
- data/lib/form_buildr.rb +48 -0
- data/lib/homeschool.rb +136 -0
- data/lib/standardized_test.rb +71 -0
- data/lib/tame_rails.rb +19 -0
- metadata +73 -0
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
task :default => :package
|
5
|
+
|
6
|
+
#REV = File.read(".svn/entries")[/committed-rev="(\d+)"/, 1] rescue nil
|
7
|
+
#VERS = ENV['VERSION'] || "0.1" + (REV ? ".#{REV}" : "")
|
8
|
+
|
9
|
+
PKG_VERSION = '0.0.1' #{}`ruby -Ilib bin/homeschool -v`.chomp
|
10
|
+
|
11
|
+
summary = "The homeschool gem"
|
12
|
+
dependencies = [
|
13
|
+
# ['rails', '>= 1.2.2'],
|
14
|
+
['metaid', '>= 1.0']
|
15
|
+
]
|
16
|
+
|
17
|
+
spec = Gem::Specification.new do |s|
|
18
|
+
s.name = 'homeschool'
|
19
|
+
s.version = PKG_VERSION
|
20
|
+
s.platform = Gem::Platform::RUBY
|
21
|
+
s.author = ['Paul Nicholson', 'Austin Taylor']
|
22
|
+
s.email = 'paul@webpowerdesign.net'
|
23
|
+
s.homepage = 'http://homeschool.rubyforge.org/'
|
24
|
+
s.rubyforge_project = 'homeschool'
|
25
|
+
s.summary = summary
|
26
|
+
s.description = <<EOF
|
27
|
+
The Homeschool Way
|
28
|
+
EOF
|
29
|
+
# s.test_file = "test/test_homeschool.rb"
|
30
|
+
|
31
|
+
s.has_rdoc = true
|
32
|
+
s.rdoc_options << '--title' << 'homeschool' << '--main' << 'README' << '--line-numbers' << '--inline-source'
|
33
|
+
s.extra_rdoc_files = %w(README)
|
34
|
+
|
35
|
+
s.required_ruby_version = '>= 1.8.4'
|
36
|
+
dependencies.each do |dep|
|
37
|
+
s.add_dependency(*dep)
|
38
|
+
end
|
39
|
+
s.requirements << 'none'
|
40
|
+
s.require_path = 'lib'
|
41
|
+
s.autorequire = "homeschool"
|
42
|
+
|
43
|
+
s.bindir = "bin"
|
44
|
+
s.executables = Dir.glob('bin/*').collect{|f| File.basename(f)}.flatten
|
45
|
+
s.default_executable = "homeschool"
|
46
|
+
|
47
|
+
s.files = %w(README Rakefile) + Dir.glob("{bin,doc,test,lib}/**/*")
|
48
|
+
end
|
49
|
+
|
50
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
51
|
+
pkg.need_zip = true
|
52
|
+
pkg.need_tar = true
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "Run homeschool with ENV['ARGS']"
|
56
|
+
task :run do
|
57
|
+
ruby %(-Ilib bin/homeschool #{ENV['ARGS']})
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Run svm with ENV['ARGS']"
|
61
|
+
task :svm do
|
62
|
+
ruby %(-Ilib bin/svm #{ENV['ARGS']})
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Install the homeschool gem package"
|
66
|
+
task :install => :package do
|
67
|
+
if RUBY_PLATFORM =~ /mswin32/
|
68
|
+
sh %(gem.bat install pkg\\homeschool-#{PKG_VERSION}.gem)
|
69
|
+
else
|
70
|
+
sh %(sudo gem install pkg/homeschool-#{PKG_VERSION}.gem)
|
71
|
+
end
|
72
|
+
end
|
data/bin/bfight
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/fight')
|
3
|
+
class BibleFight < Fight
|
4
|
+
TRANSLATIONS = {
|
5
|
+
:niv => 31,
|
6
|
+
:nasb => 49,
|
7
|
+
:nlt => 51,
|
8
|
+
:kjv => 9,
|
9
|
+
:esv => 47,
|
10
|
+
:nkjv => 50,
|
11
|
+
:asv => 8,
|
12
|
+
:hcsb => 77,
|
13
|
+
}
|
14
|
+
def url_for(contestant)
|
15
|
+
"http://www.biblegateway.com/quicksearch/?quicksearch=#{CGI::escape(contestant)}&qs_version=#{@translation[1]}"
|
16
|
+
end
|
17
|
+
def pattern
|
18
|
+
/Keyword search results<\/div><span[^>]*>([\d]+) Results<\/span>/
|
19
|
+
end
|
20
|
+
def process_options
|
21
|
+
@translation = TRANSLATIONS.detect(lambda{[:kjv, 9]}) do |pair|
|
22
|
+
ARGV.delete("-#{pair[0]}")
|
23
|
+
end
|
24
|
+
super
|
25
|
+
end
|
26
|
+
def fight!
|
27
|
+
super
|
28
|
+
puts "(#{@translation[0].to_s.upcase})"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
BibleFight.new
|
data/bin/gfight
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/fight')
|
3
|
+
# TODO: +suffix
|
4
|
+
class GoogleFight < Fight
|
5
|
+
def url_for(contestant)
|
6
|
+
"http://google.com/search?q=#{CGI::escape(contestant)}"
|
7
|
+
end
|
8
|
+
def pattern
|
9
|
+
/Results <b>1<\/b> - <b>\d+<\/b> of (?:about )?<b>([\d,]+)<\/b>/
|
10
|
+
end
|
11
|
+
end
|
12
|
+
GoogleFight.new
|
data/bin/homeschool
ADDED
data/bin/svm
ADDED
@@ -0,0 +1,388 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'homeschool'
|
3
|
+
require 'svn/core'
|
4
|
+
require 'svn/client'
|
5
|
+
require 'svn/wc'
|
6
|
+
require 'svn/repos'
|
7
|
+
require 'rubygems'
|
8
|
+
gem 'activesupport'
|
9
|
+
require 'active_support'
|
10
|
+
# Copyright (c) 2006 Nathaniel Talbott and Terralien. All Rights Reserved.
|
11
|
+
# Licensed under the RUBY license.
|
12
|
+
require 'optparse'
|
13
|
+
class CoolOptions
|
14
|
+
def self.parse!(*args)
|
15
|
+
o = new
|
16
|
+
yield o
|
17
|
+
o.parse!(*args)
|
18
|
+
rescue RuntimeError => e
|
19
|
+
puts e.message
|
20
|
+
o.help true
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@options = []
|
25
|
+
end
|
26
|
+
|
27
|
+
def on(key, long, message, default=nil, short=nil)
|
28
|
+
unless short
|
29
|
+
short = if /^\[/ =~ long
|
30
|
+
long.split(/\]/).last
|
31
|
+
else
|
32
|
+
long
|
33
|
+
end[0,1]
|
34
|
+
end
|
35
|
+
@options << [key, short, long, message, default]
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse!(banner="[options]", version = nil)
|
39
|
+
result = {}
|
40
|
+
required = []
|
41
|
+
OptionParser.new do |o|
|
42
|
+
@o = o
|
43
|
+
o.banner = "Usage: #{File.basename($0)} #{banner}"
|
44
|
+
|
45
|
+
@options.each do |(key, short, long, message, default)|
|
46
|
+
if short != ''
|
47
|
+
args = ["-#{short}", "--#{long}", message]
|
48
|
+
else
|
49
|
+
args = ["--#{long}", message]
|
50
|
+
end
|
51
|
+
if default.nil?
|
52
|
+
required << key
|
53
|
+
else
|
54
|
+
result[key] = default == '' ? nil : default
|
55
|
+
args << "Default is: #{default}" unless default == ''
|
56
|
+
end
|
57
|
+
o.on(*args){|e| result[key] = e}
|
58
|
+
end
|
59
|
+
|
60
|
+
o.on('--version', "Version info."){puts version; exit(0)} if version
|
61
|
+
o.on('-h', '--help', "This help info."){help}
|
62
|
+
end.parse!
|
63
|
+
required.reject!{|e| result.key?(e)}
|
64
|
+
raise "Missing required options: #{required.join(', ')}" unless required.empty?
|
65
|
+
result[:help] = method(:help).to_proc
|
66
|
+
@after.call(result) if @after
|
67
|
+
result
|
68
|
+
end
|
69
|
+
|
70
|
+
def after(&after)
|
71
|
+
@after = after
|
72
|
+
end
|
73
|
+
|
74
|
+
def help(error=false)
|
75
|
+
puts @o
|
76
|
+
exit (error ? 1 : 0)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class SVM
|
81
|
+
def self.run
|
82
|
+
new
|
83
|
+
end
|
84
|
+
|
85
|
+
def initialize
|
86
|
+
@argv = ARGV.dup
|
87
|
+
@options = CoolOptions.parse!("<subcommand> [options] [args]", '0.0.1') do |o|
|
88
|
+
SVM.send(%{options_for_#{ARGV.first}}.to_sym, o) if SVM.respond_to?(%{options_for_#{ARGV.first}}.to_sym)
|
89
|
+
o.on :show_updates, 'show-updates', 'display update information', false, 'u'
|
90
|
+
o.on :non_recursive, 'non-recursive', 'operate on single directory only', false, 'N'
|
91
|
+
o.on :ignore_externals, 'ignore-externals', 'ignore externals definitions', false, ''
|
92
|
+
o.on :verbose, 'verbose', 'print extra information', false, 'v'
|
93
|
+
o.on :repository, "repository URL", "Remote subversion repository.", ''
|
94
|
+
#
|
95
|
+
o.after do |options|
|
96
|
+
@subcommand = ARGV.first
|
97
|
+
@args = ARGV[1...ARGV.length]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
send(@subcommand || :help)
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.options_for_ignore(cool_opts)
|
104
|
+
cool_opts.on :recursive, 'recursive', 'descend recursively', false, 'R'
|
105
|
+
end
|
106
|
+
|
107
|
+
def add
|
108
|
+
if @args.first == ':all'
|
109
|
+
p 'all'
|
110
|
+
else
|
111
|
+
SVN.add(File.expand_path(@args.first||""), @options)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def ignore
|
116
|
+
puts @args.inspect
|
117
|
+
path = File.expand_path(@args.first||"")
|
118
|
+
SVN.ignore(path, @options)
|
119
|
+
end
|
120
|
+
|
121
|
+
def proplist
|
122
|
+
SVN.proplist(File.expand_path(@args.first||""), @options)
|
123
|
+
end
|
124
|
+
|
125
|
+
def update
|
126
|
+
SVN.update(File.expand_path(@args.first||""), @options)
|
127
|
+
end
|
128
|
+
alias :up :update
|
129
|
+
|
130
|
+
def method_missing(method)
|
131
|
+
exec "svn #{@argv.join ' '}"
|
132
|
+
rescue
|
133
|
+
help
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
class SVN
|
138
|
+
class << self
|
139
|
+
def ignore(path, options={})
|
140
|
+
svn_client.propset('svn:ignore', File.basename(path), File.dirname(path), *options.list(:recursive, :force))
|
141
|
+
rescue
|
142
|
+
puts exception($!, path)
|
143
|
+
end
|
144
|
+
|
145
|
+
def notify(msg)
|
146
|
+
p msg.inspect
|
147
|
+
p msg.action
|
148
|
+
p clean_path(msg.path)
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
def svn_client
|
153
|
+
@svn_client ||= initialize_client
|
154
|
+
end
|
155
|
+
|
156
|
+
def initialize_client
|
157
|
+
ctx = Svn::Client::Context.new
|
158
|
+
ctx.add_simple_provider
|
159
|
+
ctx.set_notify_func(&method(:notify))
|
160
|
+
ctx
|
161
|
+
end
|
162
|
+
|
163
|
+
def exception(type, path=nil)
|
164
|
+
case type
|
165
|
+
when Svn::Error::ENTRY_EXISTS
|
166
|
+
%(svm: warning: '#{clean_path(path)}' is already under version control)
|
167
|
+
when Svn::Error::WC_PATH_NOT_FOUND
|
168
|
+
%(svm: warning: '#{clean_path(path)}' not found)
|
169
|
+
when Svn::Error::WC_NOT_DIRECTORY
|
170
|
+
%(svm: '#{clean_path(path)}' is not a working copy)
|
171
|
+
else
|
172
|
+
raise
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def clean_path(path)
|
177
|
+
path.gsub!(%{#{Dir.getwd}/}, '')
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.method_missing(method, *args)
|
182
|
+
new.send(method, *args)
|
183
|
+
end
|
184
|
+
|
185
|
+
def initialize
|
186
|
+
@svn_client = ctx = Svn::Client::Context.new
|
187
|
+
ctx.add_simple_provider
|
188
|
+
ctx.set_notify_func(&method(:notify))
|
189
|
+
end
|
190
|
+
|
191
|
+
def initialize_statuses
|
192
|
+
SvnStatus.add(0, :default => { :short_status => ' ' })
|
193
|
+
end
|
194
|
+
|
195
|
+
def add(path, options={})
|
196
|
+
@svn_client.add(path)
|
197
|
+
rescue
|
198
|
+
puts exception($!, path)
|
199
|
+
end
|
200
|
+
|
201
|
+
def update(path, options={})
|
202
|
+
p 'update'
|
203
|
+
end
|
204
|
+
|
205
|
+
def notify(msg)
|
206
|
+
p msg.action
|
207
|
+
p clean_path(msg.path)
|
208
|
+
end
|
209
|
+
|
210
|
+
def exception(type, path=nil)
|
211
|
+
case type
|
212
|
+
when Svn::Error::ENTRY_EXISTS
|
213
|
+
%(svm: warning: '#{clean_path(path)}' is already under version control)
|
214
|
+
when Svn::Error::WC_PATH_NOT_FOUND
|
215
|
+
%(svm: warning: '#{clean_path(path)}' not found)
|
216
|
+
else
|
217
|
+
raise
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
private
|
222
|
+
def clean_path(path)
|
223
|
+
path.gsub!(%{#{Dir.getwd}/}, '')
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
# class SVNproxy
|
228
|
+
# def initialize
|
229
|
+
# @argv = ARGV.dup
|
230
|
+
# @options = CoolOptions.parse!("<subcommand> [options] [args]", '0.0.1') do |o|
|
231
|
+
# o.on :show_updates, 'show-updates', 'display update information', false, 'u'
|
232
|
+
# o.on :non_recursive, 'non-recursive', 'operate on single directory only', false, 'N'
|
233
|
+
# o.on :ignore_externals, 'ignore-externals', 'ignore externals definitions', false, ''
|
234
|
+
# o.on :verbose, 'verbose', 'print extra information', false, 'v'
|
235
|
+
# o.on :repository, "repository URL", "Remote subversion repository.", ''
|
236
|
+
# #
|
237
|
+
# o.after do |options|
|
238
|
+
# @subcommand = ARGV.first
|
239
|
+
# @args = ARGV[1...ARGV.length]
|
240
|
+
# end
|
241
|
+
# end
|
242
|
+
# @status = [
|
243
|
+
# :none,
|
244
|
+
# :unversioned,
|
245
|
+
# :normal,
|
246
|
+
# :added,
|
247
|
+
# :missing,
|
248
|
+
# :deleted,
|
249
|
+
# :replaced,
|
250
|
+
# :modified,
|
251
|
+
# :merged,
|
252
|
+
# :conflicted,
|
253
|
+
# :ignored,
|
254
|
+
# :obstructed,
|
255
|
+
# :external,
|
256
|
+
# :incomplete
|
257
|
+
# ]
|
258
|
+
# @svn_client = ctx = Svn::Client::Context.new
|
259
|
+
# ctx.add_simple_provider
|
260
|
+
# send(@subcommand || :help)
|
261
|
+
# end
|
262
|
+
#
|
263
|
+
# def add
|
264
|
+
# #support :all
|
265
|
+
# end
|
266
|
+
#
|
267
|
+
# def remove
|
268
|
+
# #support :all
|
269
|
+
# end
|
270
|
+
#
|
271
|
+
# def commit
|
272
|
+
# #prompt
|
273
|
+
# #prompt if new_files?
|
274
|
+
# end
|
275
|
+
# alias ci commit
|
276
|
+
#
|
277
|
+
# def revert
|
278
|
+
# #support :all
|
279
|
+
# end
|
280
|
+
#
|
281
|
+
# def update
|
282
|
+
# #update externals in background
|
283
|
+
# end
|
284
|
+
# def status(type=nil)
|
285
|
+
# modified, unversioned = [], []
|
286
|
+
# #status(path, rev=nil, recurse=true, get_all=false, update=true, no_ignore=false, ignore_externals=false, &status_func)
|
287
|
+
# @svn_client.status(File.expand_path(@args.first||""), 'HEAD', !@options[:non_recursive], false, *@options.list(:show_updates, :no_ignore, :ignore_externals)) do |path, status|
|
288
|
+
# path.gsub!(%{#{Dir.getwd}/}, '')
|
289
|
+
# case get_status(status.text_status, status.repos_text_status)
|
290
|
+
# when [:added, :none]
|
291
|
+
# puts status_line('A', status) + path
|
292
|
+
# when [:modified, :none]
|
293
|
+
# puts status_line('M', status) + path
|
294
|
+
# modified << path
|
295
|
+
# when [:conflicted, :none]
|
296
|
+
# puts status_line('C', status) + path
|
297
|
+
# conflicted << path
|
298
|
+
# when [:external, :none]
|
299
|
+
# puts status_line('X', status) + path
|
300
|
+
# external << path
|
301
|
+
# when [:unversioned, :none]
|
302
|
+
# puts status_line('?', status) + path
|
303
|
+
# unversioned << path
|
304
|
+
# when [:normal, :none]
|
305
|
+
# puts status_line(' ', status) + path
|
306
|
+
# else
|
307
|
+
# puts %{#{path} :: #{get_status(status.text_status, status.repos_text_status).inspect} :: #{status.entry.nil?}}
|
308
|
+
# end
|
309
|
+
# if verbose?
|
310
|
+
# puts get_status(status.text_status, status.repos_text_status).inspect
|
311
|
+
# $stdout.puts path
|
312
|
+
# status.public_methods.each{|name|
|
313
|
+
# puts(".....#{name}: #{status.send(name)}") unless name =~/=$/ || Object.new.public_methods.include?(name) || [].include?(name)
|
314
|
+
# }
|
315
|
+
# puts "\n"
|
316
|
+
# status.entry.public_methods.each{|name|
|
317
|
+
# puts(".....#{name}: #{status.entry.send(name)}") unless name =~/=$/ || Object.new.public_methods.include?(name) || ['conflicted?','conflicted','prop_conflicted?','text_conflicted?'].include?(name)
|
318
|
+
# } unless status.entry.nil?
|
319
|
+
# puts "\n"
|
320
|
+
#
|
321
|
+
# status.repos_lock.public_methods.each{|name|
|
322
|
+
# puts(".....#{name}: #{status.repos_lock.send(name)}") unless name =~/=$/ || Object.new.public_methods.include?(name) || [].include?(name)
|
323
|
+
# } if status.repos_lock
|
324
|
+
# end
|
325
|
+
# [unversioned, modified]
|
326
|
+
# end
|
327
|
+
# end
|
328
|
+
# alias st status
|
329
|
+
#
|
330
|
+
# def help
|
331
|
+
# @options[:help].call
|
332
|
+
# end
|
333
|
+
#
|
334
|
+
# def verbose?
|
335
|
+
# return @options[:verbose]
|
336
|
+
# end
|
337
|
+
#
|
338
|
+
# def method_missing(method)
|
339
|
+
# #exec "svn #{@argv.join ' '}"
|
340
|
+
# rescue
|
341
|
+
# help
|
342
|
+
# end
|
343
|
+
# private
|
344
|
+
# def get_status(*status_ids)
|
345
|
+
# status_ids.collect{|status_id| @status[status_id -1]}.flatten
|
346
|
+
# end
|
347
|
+
#
|
348
|
+
# def status_line(text, status)
|
349
|
+
# %{#{text} #{status.switched ? 'S' : ' '}#{lock_type(status)} }
|
350
|
+
# end
|
351
|
+
#
|
352
|
+
# def locked?
|
353
|
+
#
|
354
|
+
# end
|
355
|
+
#
|
356
|
+
# def lock_type(status)
|
357
|
+
# case true
|
358
|
+
# when !status.entry.nil? && !status.entry.lock_token.nil?
|
359
|
+
# 'K'
|
360
|
+
# when status.repos_lock && status.entry.lock_token.nil?
|
361
|
+
# 'O'
|
362
|
+
# else
|
363
|
+
# '$'
|
364
|
+
# end
|
365
|
+
# end
|
366
|
+
# end
|
367
|
+
SVM.run
|
368
|
+
#SVNproxy.new
|
369
|
+
|
370
|
+
class SvnStatus
|
371
|
+
class << self
|
372
|
+
def add(integer, status)
|
373
|
+
statuses[integer].update(status)
|
374
|
+
end
|
375
|
+
|
376
|
+
def short_status(integer, type)
|
377
|
+
statuses[integer][type||:default][:short_status]
|
378
|
+
end
|
379
|
+
|
380
|
+
def status(integer, type)
|
381
|
+
statuses[integer][type||:default][:status]
|
382
|
+
end
|
383
|
+
|
384
|
+
def statuses
|
385
|
+
@statuses || []
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
data/lib/fight.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
class Fight
|
5
|
+
def initialize
|
6
|
+
process_options
|
7
|
+
fight!
|
8
|
+
end
|
9
|
+
def process_options
|
10
|
+
@quote = !!ARGV.delete("-q")
|
11
|
+
end
|
12
|
+
def contestants
|
13
|
+
ARGV.to_a
|
14
|
+
end
|
15
|
+
def fight!
|
16
|
+
contestants.collect do |contestant|
|
17
|
+
contestant = %{"#{contestant}"} if @quote
|
18
|
+
page = open(url_for(contestant)).read
|
19
|
+
match = page.match(pattern)
|
20
|
+
count = match ? match[1] : '0'
|
21
|
+
[count, contestant]
|
22
|
+
end.sort_by {|result| result[0].gsub(',', '').to_i}.reverse.each do |result|
|
23
|
+
puts result * ' -- '
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/form_buildr.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#
|
2
|
+
# == Provides an additional set of methods for working with forms.
|
3
|
+
# See ActionView::Helpers::FormHelper in the Rails API docs
|
4
|
+
#
|
5
|
+
# Author:: Paul Nicholson (mailto:paul@webpowerdesign.net)
|
6
|
+
# Co-Author:: Austin Taylor
|
7
|
+
# Copyright:: Copyright (c) 2006 Paul Nicholson & Austin Taylor
|
8
|
+
# License:: Distributes under the same terms as Rails
|
9
|
+
#
|
10
|
+
# ==== Usage
|
11
|
+
# <% form_for :person, @person, :url => { :action => "update" } do |f| %>
|
12
|
+
# <%= f.label_for :first_name %> <%= f.text_field :first_name %>
|
13
|
+
# <%= f.labeled_text_field :last_name %>
|
14
|
+
# <% end %>
|
15
|
+
#
|
16
|
+
# === Methods
|
17
|
+
# ==== label_for(method, options={})
|
18
|
+
# Returns a label opening and closing tag set tailored for accessing a specified form element(identified by
|
19
|
+
# Additional options on the label tag can be passed as a hash with options.
|
20
|
+
#
|
21
|
+
# ====== Additional Options
|
22
|
+
# * :label => The text used as the label(default is method.humanize)
|
23
|
+
#
|
24
|
+
# ====== Example (call, result):
|
25
|
+
# label_for(:name)
|
26
|
+
# <label class="fieldLabel" for="person_name">Name:</label>
|
27
|
+
#
|
28
|
+
# ==== labeled_*(method, options={})
|
29
|
+
# Returns a label opening and closing tag set and calls the referenced form builder method
|
30
|
+
#
|
31
|
+
# ====== Additional Options
|
32
|
+
# * See <tt>label_for</tt> and the form builder method docs
|
33
|
+
#
|
34
|
+
# ====== Example (call, result):
|
35
|
+
# labeled_text_field(:name)
|
36
|
+
# <label class="fieldLabel" for="person_name">Name:</label>
|
37
|
+
# <input id="person_name" name="person[name]" size="30" type="text" />
|
38
|
+
#
|
39
|
+
class ActionView::Helpers::FormBuilder
|
40
|
+
rdef(/labeled_(.*)/) do |match, *args|
|
41
|
+
return send(:label_for, *args) + send(match[1].to_sym, *args)
|
42
|
+
end
|
43
|
+
|
44
|
+
def label_for(method, options={})
|
45
|
+
options = {:label => options} if options.is_a? String
|
46
|
+
%{<label class="fieldLabel" for="#{@object_name}_#{method}">#{options[:label] || method.to_s.humanize.singularize}#{":" if !options[:no_colon]}</label>}
|
47
|
+
end
|
48
|
+
end
|
data/lib/homeschool.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'metaid'
|
3
|
+
require 'active_support'
|
4
|
+
|
5
|
+
class Symbol
|
6
|
+
def self.pattern(name, pattern, &formation)
|
7
|
+
define_method(name) {to_s.match(pattern) ? self : formation.call(self).to_sym}
|
8
|
+
define_method(name.question) {to_s.match(pattern)}
|
9
|
+
end
|
10
|
+
pattern(:question, /\?$/) {|s| "#{s}?"}
|
11
|
+
pattern(:bang, /!$/) {|s| "#{s}!"}
|
12
|
+
pattern(:writer, /=$/) {|s| "#{s}="}
|
13
|
+
pattern(:iv, /^@[^@]/) {|s| "@#{s}"}
|
14
|
+
end
|
15
|
+
|
16
|
+
class Range
|
17
|
+
def intersect?(other)
|
18
|
+
include?(other.first) || include?(other.last)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Object
|
23
|
+
def iv_cache(method)
|
24
|
+
method = method.to_sym.iv
|
25
|
+
instance_variable_set(method, yield) unless instance_variable_get(method)
|
26
|
+
instance_variable_get(method)
|
27
|
+
end
|
28
|
+
|
29
|
+
def dom_ids
|
30
|
+
@dom_ids ||= Hash.new
|
31
|
+
end
|
32
|
+
def dom_id(*suffixes)
|
33
|
+
name = suffixes.empty? ? 'element' : suffixes.collect(&:to_s).join('_')
|
34
|
+
dom_ids[name] = [self.class.name.underscore, self.id, *suffixes].compact.join('_')
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.pattern_methods
|
38
|
+
@pattern_methods ||= (superclass && superclass.pattern_methods && superclass.pattern_methods.dup) || []
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.rdef(pattern, &block)
|
42
|
+
pattern_methods << [/^#{pattern.source}$/, block]
|
43
|
+
end
|
44
|
+
private
|
45
|
+
def method_missing(method, *args, &block)
|
46
|
+
match = self.class.pattern_methods.detect do |(pattern, block)|
|
47
|
+
method.to_s =~ pattern
|
48
|
+
end
|
49
|
+
raise super unless match
|
50
|
+
match[1].bind(self).call(*([$~] + args), &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def once(*args)
|
54
|
+
args << :called_once
|
55
|
+
key = args.map(&:to_s).join('_').to_sym.iv
|
56
|
+
yield unless instance_variable_get(key)
|
57
|
+
ensure
|
58
|
+
instance_variable_set(key, true)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Module
|
63
|
+
def attr_with_default(name, default=nil, &block)
|
64
|
+
attr_writer name
|
65
|
+
define_method(name) do
|
66
|
+
once(name, :set_default) do
|
67
|
+
instance_variable_set(name.iv, block_given? ? block.call : default.dup) unless instance_variable_get(name.iv)
|
68
|
+
end
|
69
|
+
instance_variable_get(name.iv)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def pattern_methods
|
74
|
+
@pattern_methods ||= []
|
75
|
+
end
|
76
|
+
def rdef(pattern, &block)
|
77
|
+
pattern_methods << [/^#{pattern.source}$/, block]
|
78
|
+
end
|
79
|
+
def append_features_with_pattern_methods(target)
|
80
|
+
append_features_without_pattern_methods(target)
|
81
|
+
target.pattern_methods.push(*pattern_methods) if (@pattern_methods)
|
82
|
+
end
|
83
|
+
alias_method :append_features_without_pattern_methods, :append_features
|
84
|
+
alias_method :append_features, :append_features_with_pattern_methods
|
85
|
+
end
|
86
|
+
|
87
|
+
module Enumerable
|
88
|
+
def without(*args)
|
89
|
+
reject &args.method(:include?)
|
90
|
+
end
|
91
|
+
def intersect(other)
|
92
|
+
select &other.method(:include?)
|
93
|
+
end
|
94
|
+
def min_by(&block)
|
95
|
+
min {|a,b| block.call(a) <=> block.call(b)}
|
96
|
+
end
|
97
|
+
def max_by(&block)
|
98
|
+
max {|a,b| block.call(a) <=> block.call(b)}
|
99
|
+
end
|
100
|
+
def average(&block)
|
101
|
+
sum(&block)/length
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class Array
|
106
|
+
def includes_any?(array)
|
107
|
+
array.any? &method(:include?)
|
108
|
+
end
|
109
|
+
def includes_all?(array)
|
110
|
+
array.all? &method(:include?)
|
111
|
+
end
|
112
|
+
def includes_only?(array)
|
113
|
+
array.length == length && includes_all?(array)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class Hash
|
118
|
+
def to_obj
|
119
|
+
returning Object.new do |obj|
|
120
|
+
each do |key, value|
|
121
|
+
obj.meta_def key.to_sym do value end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
def filter(*keys)
|
126
|
+
keys.inject({}) do |h, key|
|
127
|
+
h[key] = self[key]; h
|
128
|
+
end
|
129
|
+
end
|
130
|
+
def list(*keys)
|
131
|
+
keys.collect &method(:[])
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
require 'standardized_test' if defined?(RAILS_ENV) && RAILS_ENV == 'test'
|
136
|
+
require 'tame_rails' if defined?(RAILS_ENV)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
module Test::Unit::Assertions
|
3
|
+
def diff(one, two)
|
4
|
+
prefix = 0
|
5
|
+
(0...[one, two].min_by(&:length).length).each do |i|
|
6
|
+
if one[i] == two[i]
|
7
|
+
prefix = i + 1
|
8
|
+
else
|
9
|
+
break
|
10
|
+
end
|
11
|
+
end
|
12
|
+
"Expected <#{diff_format(one, prefix)}> but was <#{diff_format(two, prefix)}>"
|
13
|
+
end
|
14
|
+
def diff_format(string, prefix)
|
15
|
+
prefix > 0 ? "...#{string[prefix..-1]}" : string
|
16
|
+
end
|
17
|
+
def assert_equal_with_diffing(expected, actual, message=nil)
|
18
|
+
if message == :diff
|
19
|
+
assert_block(diff(expected, actual)) {expected == actual}
|
20
|
+
else
|
21
|
+
assert_equal_without_diffing(expected, actual, message)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
alias_method :assert_equal_without_diffing, :assert_equal
|
25
|
+
alias_method :assert_equal, :assert_equal_with_diffing
|
26
|
+
end
|
27
|
+
|
28
|
+
module HomeschoolTestHelper
|
29
|
+
def assert_json(expected, actual)
|
30
|
+
assert_equal JSON.parse(expected), JSON.parse(actual)
|
31
|
+
end
|
32
|
+
def assert_difference(klass, method, difference=1, &block)
|
33
|
+
old = klass.send(method)
|
34
|
+
block.call
|
35
|
+
assert_equal old + difference, klass.send(method)
|
36
|
+
end
|
37
|
+
def assert_no_difference(klass, method, &block)
|
38
|
+
assert_difference(klass, method, 0, &block)
|
39
|
+
end
|
40
|
+
def assert_fails
|
41
|
+
yield
|
42
|
+
passed = true
|
43
|
+
rescue
|
44
|
+
ensure
|
45
|
+
assert !passed
|
46
|
+
end
|
47
|
+
|
48
|
+
def HomeschoolTestHelper.included(klass)
|
49
|
+
klass.rdef(/last_(.*)/) do |match|
|
50
|
+
match[1].classify.constantize.find(:all).last
|
51
|
+
end
|
52
|
+
class << klass; alias_method :old_fixtures, :fixtures; end if klass.respond_to?(:fixtures)
|
53
|
+
class << klass
|
54
|
+
def fixtures(*fixtures)
|
55
|
+
old_fixtures(*fixtures) if respond_to?(:old_fixtures) && !fixtures.delete(:ignore_old_fixtures)
|
56
|
+
fixtures.each do |fixture|
|
57
|
+
fixture_class = fixture.to_s.classify.constantize
|
58
|
+
rdef(/.*#{fixture_class.name.underscore}.*/) do |match, *options|
|
59
|
+
iv_cache(match[0]) do
|
60
|
+
options = {:save => true}.merge(options[0] || {})
|
61
|
+
save = options.delete(:save)
|
62
|
+
instance = fixture_class.new(options)
|
63
|
+
instance.save if save && instance.respond_to?(:save)
|
64
|
+
instance
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/tame_rails.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'form_buildr'
|
2
|
+
|
3
|
+
# Add find_object, model_name
|
4
|
+
class ActionController::Base
|
5
|
+
def self.find_object(options={})
|
6
|
+
find_by_id(model_name, {:only => [:update, :edit, :show, :destroy]}.merge(options))
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.find_by_id(klass, options={})
|
10
|
+
options = {:name => klass.name.underscore, :param => :id}.merge(options)
|
11
|
+
before_filter options.filter(:only, :except) do |controller|
|
12
|
+
controller.send(:instance_variable_set, options[:name].to_sym.iv, klass.find(controller.params[options[:param]]))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.model_name
|
17
|
+
name.sub(/Controller$/, '').singularize.constantize
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: homeschool
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-08-24 00:00:00 -04:00
|
8
|
+
summary: The homeschool gem
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: paul@webpowerdesign.net
|
12
|
+
homepage: http://homeschool.rubyforge.org/
|
13
|
+
rubyforge_project: homeschool
|
14
|
+
description: The Homeschool Way
|
15
|
+
autorequire: homeschool
|
16
|
+
default_executable: homeschool
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.4
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- - Paul Nicholson
|
31
|
+
- Austin Taylor
|
32
|
+
files:
|
33
|
+
- README
|
34
|
+
- Rakefile
|
35
|
+
- bin/bfight
|
36
|
+
- bin/gfight
|
37
|
+
- bin/homeschool
|
38
|
+
- bin/svm
|
39
|
+
- lib/fight.rb
|
40
|
+
- lib/form_buildr.rb
|
41
|
+
- lib/homeschool.rb
|
42
|
+
- lib/standardized_test.rb
|
43
|
+
- lib/tame_rails.rb
|
44
|
+
test_files: []
|
45
|
+
|
46
|
+
rdoc_options:
|
47
|
+
- --title
|
48
|
+
- homeschool
|
49
|
+
- --main
|
50
|
+
- README
|
51
|
+
- --line-numbers
|
52
|
+
- --inline-source
|
53
|
+
extra_rdoc_files:
|
54
|
+
- README
|
55
|
+
executables:
|
56
|
+
- bfight
|
57
|
+
- gfight
|
58
|
+
- homeschool
|
59
|
+
- svm
|
60
|
+
extensions: []
|
61
|
+
|
62
|
+
requirements:
|
63
|
+
- none
|
64
|
+
dependencies:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: metaid
|
67
|
+
version_requirement:
|
68
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "1.0"
|
73
|
+
version:
|