homeschool 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +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:
|