Agile Web Development with Rails, Edition 4
12.1 Iteration G1: Capturing an Order
11.5 Iteration F5: Making Images Clickable
11.6 Iteration F6: Testing AJAX changes
32 (tests|runs), 80 assertions, 0 failures, 0 errors.
<0> expected to be
>=
<1>.
Traceback:
/home/rubys/git/awdwr/edition4/checkdepot.rb:36:in `assert_test_summary'
/home/rubys/git/awdwr/edition4/checkdepot.rb:223:in `block in <class:DepotTest>'
Verify that yes, indeed, the product index is broken.
get /products
NoMethodError in
Products#index
Showing /home/rubys/git/awdwr/edition4/work-220/depot/app/views/layouts/application.html.erb where line #21 raised:
undefined method `line_items' for nil:NilClass
Extracted source (around line #21):
19
20
21
22
23
24
|
<!-- START_HIGHLIGHT -->
<!-- START:hidden_div -->
<%= hidden_div_if(@cart.line_items.empty?, id: 'cart') do %>
<%= render @cart %>
<% end %>
<!-- END:hidden_div -->
|
Extracted source (around line #159):
157
158
159
160
161
162
|
instrument("!render_template") do
compile!(view)
view.send(method_name, locals, buffer, &block)
end
rescue => e
handle_render_error(view, e)
|
Extracted source (around line #166):
164
165
166
167
168
169
|
instrumenter.instrument(name, payload) { yield payload if block_given? }
else
yield payload if block_given?
end
end
|
Extracted source (around line #351):
349
350
351
352
353
354
|
def instrument(action, &block)
payload = { virtual_path: @virtual_path, identifier: @identifier }
ActiveSupport::Notifications.instrument("#{action}.action_view", payload, &block)
end
def extract_resource_cache_call_name
|
Extracted source (around line #157):
155
156
157
158
159
160
|
# consume this in production. This is only slow if it's being listened to.
def render(view, locals, buffer=nil, &block)
instrument("!render_template") do
compile!(view)
view.send(method_name, locals, buffer, &block)
end
|
Extracted source (around line #66):
64
65
66
67
68
69
|
view = @view
view.view_flow.set(:layout, content)
layout.render(view, locals){ |*name| view._layout_for(*name) }
else
content
end
|
Extracted source (around line #52):
50
51
52
53
54
55
|
view, locals = @view, locals || {}
render_with_layout(layout_name, locals) do |layout|
instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do
template.render(view, locals) { |*name| view._layout_for(*name) }
end
|
Extracted source (around line #14):
12
13
14
15
16
17
|
@lookup_context.rendered_format ||= (template.formats.first || formats.first)
render_template(template, options[:layout], options[:locals])
end
private
|
Extracted source (around line #42):
40
41
42
43
44
45
|
# Direct access to template rendering.
def render_template(context, options) #:nodoc:
TemplateRenderer.new(@lookup_context).render(context, options)
end
# Direct access to partial rendering.
|
Extracted source (around line #23):
21
22
23
24
25
26
|
render_partial(context, options)
else
render_template(context, options)
end
end
|
Extracted source (around line #103):
101
102
103
104
105
106
|
lookup_context.variants = variant if variant
view_renderer.render(context, options)
end
# Assign the rendered format to lookup context.
|
Extracted source (around line #217):
215
216
217
218
219
220
|
Rack::Chunked::Body.new view_renderer.render_body(view_context, options)
else
super
end
end
end
|
Extracted source (around line #83):
81
82
83
84
85
86
|
def render_to_body(options = {})
_process_options(options)
_render_template(options)
end
def rendered_format
|
Extracted source (around line #43):
41
42
43
44
45
46
|
def render_to_body(options = {})
super || _render_in_priorities(options) || ' '
end
private
|
Extracted source (around line #37):
35
36
37
38
39
40
|
def render_to_body(options)
_render_to_body_with_renderer(options) || super
end
def _render_to_body_with_renderer(options)
|
Extracted source (around line #25):
23
24
25
26
27
28
|
def render(*args, &block)
options = _normalize_render(*args, &block)
self.response_body = render_to_body(options)
_process_format(rendered_format, options) if rendered_format
self.response_body
end
|
Extracted source (around line #27):
25
26
27
28
29
30
|
def render(*args) #:nodoc:
raise ::AbstractController::DoubleRenderError if self.response_body
super
end
# Overwrite render_to_string because body can now be set to a rack body.
|
Extracted source (around line #44):
42
43
44
45
46
47
|
render_output = nil
self.view_runtime = cleanup_view_runtime do
Benchmark.ms { render_output = super }
end
render_output
end
|
Extracted source (around line #12):
10
11
12
13
14
|
# # => 0.074
def ms
1000 * realtime { yield }
end
end
|
Extracted source (around line #303):
301
302
303
304
305
306
|
def realtime # :yield:
r0 = Process.clock_gettime(BENCHMARK_CLOCK)
yield
Process.clock_gettime(BENCHMARK_CLOCK) - r0
end
|
Extracted source (around line #12):
10
11
12
13
14
|
# # => 0.074
def ms
1000 * realtime { yield }
end
end
|
Extracted source (around line #44):
42
43
44
45
46
47
|
render_output = nil
self.view_runtime = cleanup_view_runtime do
Benchmark.ms { render_output = super }
end
render_output
end
|
Extracted source (around line #87):
85
86
87
88
89
90
|
# :api: plugin
def cleanup_view_runtime #:nodoc:
yield
end
# Every time after an action is processed, this method is invoked
|
Extracted source (around line #25):
23
24
25
26
27
28
|
db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
self.db_runtime = (db_runtime || 0) + db_rt_before_render
runtime = super
db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
self.db_runtime += db_rt_after_render
runtime - db_rt_after_render
|
Extracted source (around line #43):
41
42
43
44
45
46
|
def render(*args)
render_output = nil
self.view_runtime = cleanup_view_runtime do
Benchmark.ms { render_output = super }
end
render_output
|
Extracted source (around line #10):
8
9
10
11
12
13
|
def default_render(*args)
render(*args)
end
def method_for_action(action_name)
|
Extracted source (around line #5):
3
4
5
6
7
8
|
def send_action(method, *args)
ret = super
default_render unless performed?
ret
end
|
Extracted source (around line #189):
187
188
189
190
191
192
|
# which is *not* necessarily the same as the action name.
def process_action(method_name, *args)
send_action(method_name, *args)
end
# Actually call the method associated with the action. Override
|
Extracted source (around line #21):
19
20
21
22
23
24
|
def process_action(*) #:nodoc:
self.formats = request.formats.map(&:ref).compact
super
end
# Check for double render errors and set the content_type after rendering.
|
Extracted source (around line #20):
18
19
20
21
22
23
|
def process_action(*args)
run_callbacks(:process_action) do
super
end
end
|
Extracted source (around line #119):
117
118
119
120
121
122
|
def call(env)
block = env.run_block
env.value = !env.halted && (!block || block.call)
env
end
end
|
Extracted source (around line #119):
117
118
119
120
121
122
|
def call(env)
block = env.run_block
env.value = !env.halted && (!block || block.call)
env
end
end
|
Extracted source (around line #560):
558
559
560
561
562
563
|
def compile
@callbacks || @mutex.synchronize do
final_sequence = CallbackSequence.new { |env| Filters::ENDING.call(env) }
@callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
callback.apply callback_sequence
end
|
Extracted source (around line #503):
501
502
503
504
505
506
|
def call(arg)
@before.each { |b| b.call(arg) }
value = @call.call(arg)
@after.each { |a| a.call(arg) }
value
end
|
Extracted source (around line #503):
501
502
503
504
505
506
|
def call(arg)
@before.each { |b| b.call(arg) }
value = @call.call(arg)
@after.each { |a| a.call(arg) }
value
end
|
Extracted source (around line #94):
92
93
94
95
96
97
|
runner = callbacks.compile
e = Filters::Environment.new(self, false, nil, block)
runner.call(e).value
end
end
|
Extracted source (around line #804):
802
803
804
805
806
807
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
def _run_#{name}_callbacks(&block)
_run_callbacks(_#{name}_callbacks, &block)
end
RUBY
end
|
Extracted source (around line #83):
81
82
83
84
85
86
|
# end
def run_callbacks(kind, &block)
send "_run_#{kind}_callbacks", &block
end
private
|
Extracted source (around line #19):
17
18
19
20
21
22
|
# process_action callbacks around the normal behavior.
def process_action(*args)
run_callbacks(:process_action) do
super
end
end
|
Extracted source (around line #29):
27
28
29
30
31
32
|
private
def process_action(*args)
super
rescue Exception => exception
request.env['action_dispatch.show_detailed_exceptions'] ||= show_detailed_exceptions?
rescue_with_handler(exception) || raise(exception)
|
Extracted source (around line #32):
30
31
32
33
34
35
|
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
begin
result = super
payload[:status] = response.status
result
ensure
|
Extracted source (around line #164):
162
163
164
165
166
167
|
def instrument(name, payload = {})
if notifier.listening?(name)
instrumenter.instrument(name, payload) { yield payload if block_given? }
else
yield payload if block_given?
end
|
Extracted source (around line #20):
18
19
20
21
22
23
|
start name, payload
begin
yield payload
rescue Exception => e
payload[:exception] = [e.class.name, e.message]
raise e
|
Extracted source (around line #164):
162
163
164
165
166
167
|
def instrument(name, payload = {})
if notifier.listening?(name)
instrumenter.instrument(name, payload) { yield payload if block_given? }
else
yield payload if block_given?
end
|
Extracted source (around line #30):
28
29
30
31
32
33
|
ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
begin
result = super
payload[:status] = response.status
|
Extracted source (around line #249):
247
248
249
250
251
252
|
request.filtered_parameters.merge! wrapped_filtered_hash
end
super
end
private
|
Extracted source (around line #18):
16
17
18
19
20
21
|
# and it won't be cleaned up by the method below.
ActiveRecord::LogSubscriber.reset_runtime
super
end
def cleanup_view_runtime
|
Extracted source (around line #128):
126
127
128
129
130
131
|
@_response_body = nil
process_action(action_name, *args)
end
# Delegates to the class' ::controller_path
|
Extracted source (around line #30):
28
29
30
31
32
33
|
def process(*) #:nodoc:
old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
super
ensure
I18n.config = old_config
end
|
Extracted source (around line #194):
192
193
194
195
196
197
|
def dispatch(name, request) #:nodoc:
set_request!(request)
process(name)
to_a
end
|
Extracted source (around line #241):
239
240
241
242
243
244
|
end
else
lambda { |env| new.dispatch(name, klass.new(env)) }
end
end
end
|
Extracted source (around line #73):
71
72
73
74
75
76
|
def dispatch(controller, action, env)
controller.action(action).call(env)
end
def normalize_controller!(params)
|
Extracted source (around line #73):
71
72
73
74
75
76
|
def dispatch(controller, action, env)
controller.action(action).call(env)
end
def normalize_controller!(params)
|
Extracted source (around line #42):
40
41
42
43
44
45
|
end
dispatch(controller, params[:action], req.env)
end
def prepare_params!(params)
|
Extracted source (around line #43):
41
42
43
44
45
46
|
req.path_parameters = set_params.merge parameters
status, headers, body = route.app.serve(req)
if 'pass' == headers['X-Cascade']
req.script_name = script_name
|
Extracted source (around line #30):
28
29
30
31
32
33
|
def serve(req)
find_routes(req).each do |match, parameters, route|
set_params = req.path_parameters
path_info = req.path_info
script_name = req.script_name
|
Extracted source (around line #30):
28
29
30
31
32
33
|
def serve(req)
find_routes(req).each do |match, parameters, route|
set_params = req.path_parameters
path_info = req.path_info
script_name = req.script_name
|
Extracted source (around line #769):
767
768
769
770
771
772
|
req = request_class.new(env)
req.path_info = Journey::Router::Utils.normalize_path(req.path_info)
@router.serve(req)
end
def recognize_path(path, environment = {})
|
Extracted source (around line #24):
22
23
24
25
26
27
|
def call(env)
status, headers, body = @app.call(env)
if etag_status?(status) && etag_body?(body) && !skip_caching?(headers)
original_body = body
|
Extracted source (around line #25):
23
24
25
26
27
28
|
case env[REQUEST_METHOD]
when "GET", "HEAD"
status, headers, body = @app.call(env)
headers = Utils::HeaderHash.new(headers)
if status == 200 && fresh?(env, headers)
status = 304
|
Extracted source (around line #13):
11
12
13
14
15
16
|
def call(env)
status, headers, body = @app.call(env)
if env[REQUEST_METHOD] == HEAD
[
|
Extracted source (around line #27):
25
26
27
28
29
30
|
end
@app.call(env)
end
private
|
Extracted source (around line #266):
264
265
266
267
268
269
|
def call(env)
@app.call(env)
ensure
session = Request::Session.find(env) || {}
flash_hash = env[KEY]
|
Extracted source (around line #225):
223
224
225
226
227
228
|
def context(env, app=@app)
prepare_session(env)
status, headers, body = app.call(env)
commit_session(env, status, headers, body)
end
|
Extracted source (around line #220):
218
219
220
221
222
223
|
def call(env)
context(env)
end
def context(env, app=@app)
|
Extracted source (around line #560):
558
559
560
561
562
563
|
def call(env)
status, headers, body = @app.call(env)
if cookie_jar = env['action_dispatch.cookies']
unless cookie_jar.committed?
|
Extracted source (around line #36):
34
35
36
37
38
39
|
connection.enable_query_cache!
response = @app.call(env)
response[2] = Rack::BodyProxy.new(response[2]) do
restore_query_cache_settings(connection_id, enabled)
end
|
Extracted source (around line #642):
640
641
642
643
644
645
|
testing = env['rack.test']
response = @app.call(env)
response[2] = ::Rack::BodyProxy.new(response[2]) do
ActiveRecord::Base.clear_active_connections! unless testing
end
|
Extracted source (around line #378):
376
377
378
379
380
381
|
end
end
@app.call(env)
end
private
|
Extracted source (around line #29):
27
28
29
30
31
32
|
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
end
end
|
Extracted source (around line #90):
88
89
90
91
92
93
|
def _run_callbacks(callbacks, &block)
if callbacks.empty?
block.call if block
else
runner = callbacks.compile
e = Filters::Environment.new(self, false, nil, block)
|
Extracted source (around line #90):
88
89
90
91
92
93
|
def _run_callbacks(callbacks, &block)
if callbacks.empty?
block.call if block
else
runner = callbacks.compile
e = Filters::Environment.new(self, false, nil, block)
|
Extracted source (around line #804):
802
803
804
805
806
807
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
def _run_#{name}_callbacks(&block)
_run_callbacks(_#{name}_callbacks, &block)
end
RUBY
end
|
Extracted source (around line #83):
81
82
83
84
85
86
|
# end
def run_callbacks(kind, &block)
send "_run_#{kind}_callbacks", &block
end
private
|
Extracted source (around line #27):
25
26
27
28
29
30
|
def call(env)
error = nil
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
|
Extracted source (around line #73):
71
72
73
74
75
76
|
prepare!
response = @app.call(env)
response[2] = ::Rack::BodyProxy.new(response[2]) { cleanup! }
response
|
Extracted source (around line #78):
76
77
78
79
80
81
|
def call(env)
env["action_dispatch.remote_ip"] = GetIp.new(env, self)
@app.call(env)
end
# The GetIp class exists as a way to defer processing of the request data
|
Extracted source (around line #47):
45
46
47
48
49
50
|
def call(env)
_, headers, body = response = @app.call(env)
if headers['X-Cascade'] == 'pass'
body.close if body.respond_to?(:close)
|
Extracted source (around line #37):
35
36
37
38
39
40
|
end
status, headers, body = @app.call(env)
if exception = env['web_console.exception']
session = Session.from_exception(exception)
|
Extracted source (around line #30):
28
29
30
31
32
33
|
def call(env)
@app.call(env)
rescue Exception => exception
if env['action_dispatch.show_exceptions'] == false
raise exception
|
Extracted source (around line #38):
36
37
38
39
40
41
|
instrumenter.start 'request.action_dispatch', request: request
logger.info { started_request_message(request) }
resp = @app.call(env)
resp[2] = ::Rack::BodyProxy.new(resp[2]) { finish(request) }
resp
rescue Exception
|
Extracted source (around line #20):
18
19
20
21
22
23
|
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
|
Extracted source (around line #70):
68
69
70
71
72
73
|
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
|
Extracted source (around line #26):
24
25
26
27
28
29
|
def tagged(*tags)
new_tags = push_tags(*tags)
yield self
ensure
pop_tags(new_tags.size)
end
|
Extracted source (around line #70):
68
69
70
71
72
73
|
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
|
Extracted source (around line #20):
18
19
20
21
22
23
|
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
|
Extracted source (around line #25):
23
24
25
26
27
28
|
def call(env)
env[ACTION_DISPATCH_REQUEST_ID] = external_request_id(env) || internal_request_id
@app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = env[ACTION_DISPATCH_REQUEST_ID] }
end
private
|
Extracted source (around line #22):
20
21
22
23
24
25
|
end
@app.call(env)
end
def method_override(env)
|
Extracted source (around line #18):
16
17
18
19
20
21
|
def call(env)
start_time = Time.now
status, headers, body = @app.call(env)
request_time = Time.now - start_time
if !headers.has_key?(@header_name)
|
Extracted source (around line #28):
26
27
28
29
30
31
|
def call(env)
LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new)
response = @app.call(env)
response[2] = ::Rack::BodyProxy.new(response[2]) do
LocalCacheRegistry.set_cache_for(local_cache_key, nil)
end
|
Extracted source (around line #17):
15
16
17
18
19
20
|
old, env[FLAG] = env[FLAG], false
@mutex.lock
response = @app.call(env)
body = BodyProxy.new(response[2]) { @mutex.unlock }
response[2] = body
response
|
Extracted source (around line #115):
113
114
115
116
117
118
|
end
@app.call(env)
end
end
end
|
Extracted source (around line #113):
111
112
113
114
115
116
|
def call(env)
status, headers, body = @app.call(env)
if body.respond_to?(:to_path)
case type = variation(env)
when 'X-Accel-Redirect'
|
Extracted source (around line #518):
516
517
518
519
520
521
|
env[routes.env_key] = env['SCRIPT_NAME'].dup
end
app.call(env)
end
# Defines additional Rack env configuration that is added on each call.
|
Extracted source (around line #165):
163
164
165
166
167
168
|
env["ORIGINAL_FULLPATH"] = req.fullpath
env["ORIGINAL_SCRIPT_NAME"] = req.script_name
super(env)
end
# Reload application routes regardless if they changed or not.
|
Extracted source (around line #17):
15
16
17
18
19
20
|
old, env[FLAG] = env[FLAG], false
@mutex.lock
response = @app.call(env)
body = BodyProxy.new(response[2]) { @mutex.unlock }
response[2] = body
response
|
Extracted source (around line #15):
13
14
15
16
17
18
|
def call(env)
status, headers, body = @app.call(env)
headers = HeaderHash.new(headers)
if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
|
Extracted source (around line #89):
87
88
89
90
91
92
|
env["REQUEST_PATH"] ||= [env["SCRIPT_NAME"], env[PATH_INFO]].join
status, headers, body = @app.call(env)
begin
res.status = status.to_i
headers.each { |k, vs|
|
Extracted source (around line #138):
136
137
138
139
140
141
|
si = servlet.get_instance(self, *options)
@logger.debug(format("%s is invoked.", si.class.name))
si.service(req, res)
end
##
|
Extracted source (around line #94):
92
93
94
95
96
97
|
callback.call(req, res)
end
server.service(req, res)
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
res.set_error(ex)
rescue HTTPStatus::Error => ex
|
Extracted source (around line #297):
295
296
297
298
299
300
|
end
call_callback(:AcceptCallback, sock)
block ? block.call(sock) : run(sock)
rescue Errno::ENOTCONN
@logger.debug "Errno::ENOTCONN raised"
rescue ServerError => ex
|
Rails.root: /home/rubys/git/awdwr/edition4/work-220/depot
Request
Parameters:
None
_csrf_token: "YqRzjzaaBuCfr/mg1Zv8lJTMmeNCaXdh7sHwaZ5l9VY="
cart_id: 4
session_id: "a581e31c60d5803defd0c93f5071c210"
GATEWAY_INTERFACE: "CGI/1.1"
HTTP_ACCEPT: "text/html"
HTTP_ACCEPT_ENCODING: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
REMOTE_ADDR: "127.0.0.1"
REMOTE_HOST: "127.0.0.1"
SERVER_NAME: "localhost"
SERVER_PROTOCOL: "HTTP/1.1"
Response
Headers:
None
Conditionally display the cart.
edit app/views/layouts/application.html.erb
<% if @cart %>
<%= hidden_div_if(@cart.line_items.empty?, id: 'cart') do %>
<%= render @cart %>
<% end %>
<% end %>
Update the redirect test.
edit test/controllers/line_items_controller_test.rb
test "should create line_item" do
assert_difference('LineItem.count') do
post :create, params: { product_id: products(:ruby).id
end
assert_redirected_to store_path
end
Add an XHR test.
edit test/controllers/line_items_controller_test.rb
test "should create line_item via ajax" do
assert_difference('LineItem.count') do
xhr :post, :create, product_id: products(:ruby).id
end
assert_response :success
assert_select_jquery :html, '#cart' do
assert_select 'tr#current_item td', /Programming Ruby 1.9/
end
end
Add an test in support for the coffeescript changes.
edit test/controllers/store_controller_test.rb
test "markup needed for store.js.coffee is in place" do
get :index
assert_select '.store .entry > img', 3
assert_select '.entry input[type=submit]', 3
end
Run the tests again.
rake test
DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super. (called from rescue in <class:Exception> at /home/rubys/.rvm/gems/ruby-head-n50123/gems/web-console-2.1.2/lib/web_console/integration/cruby.rb:37)
DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super. (called from block in <top (required)> at /home/rubys/.rvm/gems/ruby-head-n50123/gems/web-console-2.1.2/lib/web_console/extensions.rb:18)
DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super. (called from included at /home/rubys/.rvm/gems/ruby-head-n50123/gems/turbolinks-2.5.3/lib/turbolinks/xhr_url_for.rb:7)
rake aborted!
SyntaxError: /home/rubys/git/awdwr/edition4/work-220/depot/test/controllers/line_items_controller_test.rb:23: syntax error, unexpected keyword_end, expecting '}'
/home/rubys/git/awdwr/edition4/work-220/depot/test/controllers/line_items_controller_test.rb:68: syntax error, unexpected end-of-input, expecting keyword_end
/home/rubys/git/rails/activesupport/lib/active_support/dependencies.rb:274:in `require'
/home/rubys/git/rails/activesupport/lib/active_support/dependencies.rb:274:in `block in require'
/home/rubys/git/rails/activesupport/lib/active_support/dependencies.rb:240:in `load_dependency'
/home/rubys/git/rails/activesupport/lib/active_support/dependencies.rb:274:in `require'
/home/rubys/git/rails/railties/lib/rails/test_unit/runner.rb:118:in `block in run_tests'
/home/rubys/git/rails/railties/lib/rails/test_unit/runner.rb:117:in `each'
/home/rubys/git/rails/railties/lib/rails/test_unit/runner.rb:117:in `run_tests'
/home/rubys/git/rails/railties/lib/rails/test_unit/runner.rb:88:in `run'
/home/rubys/git/rails/railties/lib/rails/test_unit/runner.rb:82:in `run'
/home/rubys/git/rails/railties/lib/rails/test_unit/testing.rake:9:in `block in <top (required)>'
Tasks: TOP => test
(See full trace by running task with --trace)
Save our progress
git commit -a -m "AJAX"
[master efbb837] AJAX
5 files changed, 48 insertions(+), 19 deletions(-)
git tag iteration-f
12.1 Iteration G1: Capturing an Order
11.5 Iteration F5: Making Images Clickable