#317 Rack App from Scratch pro
Rack comes with many helpful utilities such as request and response objects, various middleware, and MockRequest for testing. Here I cover all of these while building a Rack app from scratch.
- Download:
- source codeProject Files in Zip (3.81 KB)
- mp4Full Size H.264 Video (29.8 MB)
- m4vSmaller H.264 Video (16.4 MB)
- webmFull Size VP8 Video (19.8 MB)
- ogvFull Size Theora Video (33.4 MB)
Resources
terminal
gem install rack rackup -Ilib ruby greeter_test.rb
config.ru
require "greeter" use Rack::Reloader, 0 use Rack::Auth::Basic do |username, password| password == "secret" end run Rack::Cascade.new([Rack::File.new("public"), Greeter])
lib/greeter.rb
require "erb" class Greeter def self.call(env) new(env).response.finish end def initialize(env) @request = Rack::Request.new(env) end def response case @request.path when "/" then Rack::Response.new(render("index.html.erb")) when "/change" Rack::Response.new do |response| response.set_cookie("greet", @request.params["name"]) response.redirect("/") end else Rack::Response.new("Not Found", 404) end end def render(template) path = File.expand_path("../views/#{template}", __FILE__) ERB.new(File.read(path)).result(binding) end def greet_name @request.cookies["greet"] || "World" end end
lib/views/index.html.erb
<!DOCTYPE html> <html> <head> <title>Greeter</title> <link rel="stylesheet" href="/stylesheets/application.css" type="text/css" charset="utf-8"> </head> <body> <div id="container"> <h1>Hello <%= greet_name %>!</h1> <form method="post" action="/change"> <input name="name" type="text"> <input type="submit" value="Change Name"> </form> </div> </body> </html>
greeter_test.rb
require "rubygems" require "rack" require "minitest/autorun" require File.expand_path("../lib/greeter", __FILE__) describe Greeter do before do @request = Rack::MockRequest.new(Greeter) end it "returns a 404 response for unknown requests" do @request.get("/unknown").status.must_equal 404 end it "/ displays Hello World by default" do @request.get("/").body.must_include "Hello World!" end it "/ displays the name passed into the cookie" do @request.get("/", "HTTP_COOKIE" => "greet=Ruby").body.must_include "Hello Ruby!" end it "/change sets cookie and redirects to root" do response = @request.post("/change", params: {"name" => "Ruby"}) response.status.must_equal 302 response["Location"].must_equal "/" response["Set-Cookie"].must_include "greet=Ruby" end end