## # An attempt at writing BDD specs for Camping. # # Will be extracted into a stand-alone helper library. # # Author: Geoffrey Grosenbach # http://topfunky.com require 'rubygems' require 'camping' require File.dirname(__FILE__) + "/../lib/backpack" require File.dirname(__FILE__) + "/../public/thief" ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ":memory:") ActiveRecord::Base.logger = Logger.new("spec/spec.log") Thief.create include Thief::Models include Thief::Controllers include Thief::Views module ThiefSpecHelper def mock_backpack xml = File.read(File.dirname(__FILE__) + "/fixtures/backpack-export.xml") @backpack = mock(Backpack) @backpack.should_receive(:export).and_return(Hpricot.XML(xml)) @backpack.stub!(:domain).and_return('http://camping.backpackit.com') Backpack.should_receive(:new).and_return(@backpack) @backpack end # -- For Views -- def render(&block) @response = Markaby::Builder.new(assigns, &block).to_s end def response @response end def assigns @assigns ||= {} end # -- For Controllers -- def setup @class_name_abbr = self.class.name.gsub(/^Test/, '') @request = MockRequest.new @cookies = @response = {} end def get(url='/', vars={}) send_request url, vars, 'GET' end def post(url, post_vars={}) send_request url, post_vars, 'POST' end def delete(url, vars={}) send_request url, vars, 'DELETE' end def put(url, vars={}) send_request url, vars, 'PUT' end def send_request(url, post_vars, method) @request['REQUEST_METHOD'] = method @request['SCRIPT_NAME'] = '/' + @class_name_abbr.downcase @request['PATH_INFO'] = '/' + url @request['REQUEST_URI'] = [@request.SCRIPT_NAME, @request.PATH_INFO].join('') @request['HTTP_COOKIE'] = @cookies.map {|k,v| "#{k}=#{v}" }.join('; ') if @cookies @response = eval("#{@class_name_abbr}.run StringIO.new('#{qs_build(post_vars)}'), @request") @cookies = @response.headers['Set-Cookie'].inject(@cookies||{}) do |res,header| data = header.split(';').first name, value = data.split('=') res[name] = value res end @cookies = H[@cookies] session = Camping::Models::Session.persist @cookies app = @class_name_abbr.gsub(/^(\w+)::.+$/, '\1') @state = (session[app] ||= Camping::H[]) if @response.headers['X-Sendfile'] @response.body = File.read(@response.headers['X-Sendfile']) end end def qs_build(var_hash) var_hash.map do |k, v| [Camping.escape(k.to_s), Camping.escape(v.to_s)].join('=') end.join('&') end end class MockRequest def initialize @headers = { 'SERVER_NAME' => 'localhost', 'PATH_INFO' => '', 'HTTP_ACCEPT_ENCODING' => 'gzip,deflate', 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.0.1) Gecko/20060214 Camino/1.0', 'SCRIPT_NAME' => '/', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'HTTP_CACHE_CONTROL' => 'max-age=0', 'HTTP_ACCEPT_LANGUAGE' => 'en,ja;q=0.9,fr;q=0.9,de;q=0.8,es;q=0.7,it;q=0.7,nl;q=0.6,sv;q=0.5,nb;q=0.5,da;q=0.4,fi;q=0.3,pt;q=0.3,zh-Hans;q=0.2,zh-Hant;q=0.1,ko;q=0.1', 'HTTP_HOST' => 'localhost', 'REMOTE_ADDR' => '127.0.0.1', 'SERVER_SOFTWARE' => 'Mongrel 0.3.12.4', 'HTTP_KEEP_ALIVE' => '300', 'HTTP_REFERER' => 'http://localhost/', 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'HTTP_VERSION' => 'HTTP/1.1', 'REQUEST_URI' => '/', 'SERVER_PORT' => '80', 'GATEWAY_INTERFACE' => 'CGI/1.2', 'HTTP_ACCEPT' => 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5', 'HTTP_CONNECTION' => 'keep-alive', 'REQUEST_METHOD' => 'GET', } end def set(key, val) @headers[key] = val end def to_hash @headers end def [](key) @headers[key] end def []=(key, value) @headers[key] = value end ## # Allow getters like this: # o.REQUEST_METHOD def method_missing(method_name, *args) if @headers.has_key?(method_name.to_s) return @headers[method_name.to_s] else super(method_name, args) end end end # Models describe Page, "model" do include ThiefSpecHelper before do @backpack = mock_backpack Page.update @page = Page.find :first end it "should set md5" do @page.md5.should eql('1788a0df2e7e54d2b3b35f5938c8c2cd') end it "should set title" do @page.title.should eql('Boyscout Motto') end it "should set link" do @page.link.should eql("http://camping.backpackit.com/page/100000") end it "should set backpack_id" do @page.backpack_id.should eql(100000) end end describe "index view with no pages" do include ThiefSpecHelper it "should render with empty pages" do assigns[:pages] = [] render { index } response.should match(/No pages/) end end describe "index view with pages" do include ThiefSpecHelper it "should render with pages" do @page = stub(Page, { :title => "Knot Tying", :updated_at => Date.today, :link => "http://camping.backpackit.com" }) assigns[:pages] = [@page] render { index } response.should match(/#{@page.title}/) end end # describe Index do # # include ThiefSpecHelper # # it "should description" do # get '/' # end # # end