mosquito 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2005 Geoffrey Grosenbach boss@topfunky.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/Manifest.txt ADDED
@@ -0,0 +1,25 @@
1
+ Rakefile
2
+ README
3
+ MIT-LICENSE
4
+ Manifest.txt
5
+ lib
6
+ lib/mosquito.rb
7
+ public
8
+
9
+ public/blog
10
+ public/blog.rb
11
+ public/blog/controllers.rb
12
+ public/blog/models.rb
13
+ public/blog/views.rb
14
+
15
+ public/homepage.rb
16
+
17
+ test
18
+ test/test_blog.rb
19
+
20
+ test/test_homepage.rb
21
+
22
+ test/fixtures
23
+ test/fixtures/blog_comments.yml
24
+ test/fixtures/blog_posts.yml
25
+ test/fixtures/blog_users.yml
data/README ADDED
@@ -0,0 +1,104 @@
1
+ Mosquito, for Bug-Free Camping
2
+ =============================
3
+
4
+ A testing helper for those times when you go Camping.
5
+
6
+ Apply on the face, neck, and any exposed areas such as your Models and Controllers.
7
+
8
+ == Usage
9
+
10
+ Make a few files and directories like this:
11
+
12
+ public/
13
+ blog.rb
14
+ test/
15
+ test_blog.rb
16
+ fixtures/
17
+ blog_comments.yml
18
+ blog_posts.yml
19
+ blog_users.yml
20
+
21
+ Setup +test_blog.rb+ like this:
22
+
23
+ require 'rubygems'
24
+ require 'mosquito'
25
+ require File.dirname(__FILE__) + "/../public/blog"
26
+
27
+ Blog.create
28
+ include Blog::Models
29
+
30
+ class TestBlog < Camping::FunctionalTest
31
+
32
+ fixtures :blog_posts, :blog_users, :blog_comments
33
+
34
+ def setup
35
+ super
36
+ # Do other stuff here
37
+ end
38
+
39
+ def test_index
40
+ get
41
+ assert_response :success
42
+ assert_match_body %r!>blog<!
43
+ end
44
+
45
+ def test_view
46
+ get '/view/1'
47
+ assert_response :success
48
+ assert_match_body %r!The quick fox jumped over the lazy dog!
49
+ end
50
+
51
+ end
52
+
53
+ # A unit test
54
+ class TestPost < Camping::UnitTest
55
+
56
+ fixtures :blog_posts, :blog_users, :blog_comments
57
+
58
+ def test_create
59
+ post = Post.create( :user_id => 1,
60
+ :title => "Title",
61
+ :body => "Body")
62
+ assert post.valid?
63
+ end
64
+
65
+ def test_assoc
66
+ post = Post.find :first
67
+ assert_kind_of User, post.user
68
+ assert_equal 1, post.user.id
69
+ end
70
+
71
+ end
72
+
73
+
74
+ == Details
75
+
76
+ Inherit from +Camping::FunctionalTest+ or +Camping::UnitTest+. If you define +setup+, be sure to call +super+ so the parent class can do its thing.
77
+
78
+ You should also call the +MyApp.create+ method if you have one. You will also need to +include MyApp::Models+ at the top of your test file if you want to use Models in your assertions.
79
+
80
+ Make fixtures in +test/fixtures+. Remember that Camping models use the name of the mount plus the model name: +blog_posts+ for the +Post+ model.
81
+
82
+ See +blog_test.rb+ for an example of both Functional and Unit tests.
83
+
84
+ == Warning: Your are Camping, not Rail-riding
85
+
86
+ Test files start with +test_+ (test_blog.rb). Test classes start with +Test+ (TestBlog).
87
+
88
+ Model and Controller test classes can both go in the same file.
89
+
90
+ A Sqlite3 :memory: database is automatically used for tests that require a database.
91
+
92
+ You can run your tests by executing the test file with Ruby or by running the autotest command with no arguments (from the ZenTest gem).
93
+
94
+ ruby test/test_blog.rb
95
+
96
+ or
97
+
98
+ autotest
99
+
100
+
101
+ == Author
102
+
103
+ Geoffrey Grosenbach http://nubyonrails.com
104
+
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require 'lib/mosquito'
4
+
5
+ Hoe.new('Mosquito', Mosquito::VERSION) do |p|
6
+ p.name = "mosquito"
7
+ p.author = "Geoffrey Grosenbach"
8
+ p.description = "A library for writing tests for your Camping app."
9
+ p.email = 'boss@topfunky.com'
10
+ p.summary = "A Camping test library."
11
+ p.url = "http://mosquito.rubyforge.org"
12
+ end
13
+
14
+
data/lib/mosquito.rb ADDED
@@ -0,0 +1,215 @@
1
+ %w(
2
+ rubygems
3
+ test/unit
4
+ active_record
5
+ active_record/fixtures
6
+ active_support/binding_of_caller
7
+ camping
8
+ fileutils
9
+ stringio
10
+ cgi
11
+ ).each { |lib| require lib }
12
+
13
+ module Mosquito
14
+ VERSION = '0.1.0'
15
+ end
16
+
17
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ":memory:")
18
+ ActiveRecord::Base.logger = Logger.new("test/test.log")
19
+
20
+ Test::Unit::TestCase.fixture_path = "test/fixtures/"
21
+
22
+ class Test::Unit::TestCase #:nodoc:
23
+ def create_fixtures(*table_names)
24
+ if block_given?
25
+ Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield }
26
+ else
27
+ Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
28
+ end
29
+ end
30
+
31
+ # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
32
+ self.use_transactional_fixtures = true
33
+ # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
34
+ self.use_instantiated_fixtures = false
35
+ end
36
+
37
+ class MockRequest
38
+ def initialize
39
+ @headers = {
40
+ 'SERVER_NAME' => 'localhost',
41
+ 'PATH_INFO' => '',
42
+ 'HTTP_ACCEPT_ENCODING' => 'gzip,deflate',
43
+ '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',
44
+ 'SCRIPT_NAME' => '/',
45
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
46
+ 'HTTP_CACHE_CONTROL' => 'max-age=0',
47
+ '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',
48
+ 'HTTP_HOST' => 'localhost',
49
+ 'REMOTE_ADDR' => '127.0.0.1',
50
+ 'SERVER_SOFTWARE' => 'Mongrel 0.3.12.4',
51
+ 'HTTP_KEEP_ALIVE' => '300',
52
+ 'HTTP_REFERER' => 'http://localhost/',
53
+ 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
54
+ 'HTTP_VERSION' => 'HTTP/1.1',
55
+ 'REQUEST_URI' => '/',
56
+ 'SERVER_PORT' => '80',
57
+ 'GATEWAY_INTERFACE' => 'CGI/1.2',
58
+ 'HTTP_ACCEPT' => 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
59
+ 'HTTP_CONNECTION' => 'keep-alive',
60
+ 'REQUEST_METHOD' => 'GET',
61
+ }
62
+ end
63
+
64
+ def set(key, val)
65
+ @headers[key] = val
66
+ end
67
+
68
+ def to_hash
69
+ @headers
70
+ end
71
+
72
+ def [](key)
73
+ @headers[key]
74
+ end
75
+
76
+ def []=(key, value)
77
+ @headers[key] = value
78
+ end
79
+
80
+ ##
81
+ # Allow getters like this:
82
+ # o.REQUEST_METHOD
83
+
84
+ def method_missing(method_name, *args)
85
+ if @headers.has_key?(method_name.to_s)
86
+ return @headers[method_name.to_s]
87
+ else
88
+ super(method_name, args)
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+
95
+ module Camping
96
+
97
+ class Test < Test::Unit::TestCase
98
+
99
+ def test_dummy; end
100
+
101
+ def deny(condition, message='')
102
+ assert !condition, message
103
+ end
104
+
105
+ # http://project.ioni.st/post/217#post-217
106
+ #
107
+ # def test_new_publication
108
+ # assert_difference(Publication, :count) do
109
+ # post :create, :publication_title => ...
110
+ # # ...
111
+ # end
112
+ # end
113
+ #
114
+ # Is the number of items different?
115
+ #
116
+ # Can be used for increment and decrement.
117
+ #
118
+ def assert_difference(object, method = :count, difference = 1)
119
+ initial_value = object.send(method)
120
+ yield
121
+ assert_equal initial_value + difference, object.send(method), "#{object}##{method}"
122
+ end
123
+ def assert_no_difference(object, method, &block)
124
+ assert_difference object, method, 0, &block
125
+ end
126
+
127
+ end
128
+
129
+ class FunctionalTest < Test
130
+
131
+ def setup
132
+ @class_name_abbr = self.class.name.gsub(/^Test/, '')
133
+ @request = MockRequest.new
134
+ @cookies = @response = {}
135
+ end
136
+
137
+ def get(url='/')
138
+ send_request url, {}, 'GET'
139
+ end
140
+
141
+ def post(url, post_vars={})
142
+ send_request url, post_vars, 'POST'
143
+ end
144
+
145
+ def send_request(url, post_vars, method)
146
+ @request['REQUEST_METHOD'] = method
147
+ @request['SCRIPT_NAME'] = '/' + @class_name_abbr.downcase
148
+ @request['PATH_INFO'] = '/' + url
149
+ @request['REQUEST_URI'] = [@request.SCRIPT_NAME, @request.PATH_INFO].join('')
150
+
151
+ @request['HTTP_COOKIE'] = @cookies.map {|k,v| "#{k}=#{v}" }.join('; ') if @cookies
152
+
153
+ @response = eval("#{@class_name_abbr}.run StringIO.new('#{qs_build(post_vars)}'), @request")
154
+
155
+ @cookies = @response.headers['Set-Cookie'].inject(@cookies||{}) do |res,header|
156
+ data = header.split(';').first
157
+ name, value = data.split('=')
158
+ res[name] = value
159
+ res
160
+ end
161
+
162
+ if @response.headers['X-Sendfile']
163
+ @response.body = File.read(@response.headers['X-Sendfile'])
164
+ end
165
+ end
166
+
167
+ def assert_response(status_code)
168
+ case status_code
169
+ when :success
170
+ assert_equal 200, @response.status
171
+ when :redirect
172
+ assert_equal 302, @response.status
173
+ when :error
174
+ assert @response.status >= 500
175
+ else
176
+ assert_equal status_code, @response.status
177
+ end
178
+ end
179
+
180
+ def assert_match_body(regex, message=nil)
181
+ assert_match regex, @response.body, message
182
+ end
183
+ def assert_no_match_body(regex, message=nil)
184
+ assert_no_match regex, @response.body, message
185
+ end
186
+
187
+ def assert_redirected_to(url, message=nil)
188
+ assert_equal url,
189
+ @response.headers['Location'].path.gsub(%r!/#{@class_name_abbr.downcase}!, ''),
190
+ message
191
+ end
192
+
193
+ def assert_cookie(name, pat, message=nil)
194
+ assert_match pat, @cookies[name], message
195
+ end
196
+
197
+ def test_dummy; end
198
+
199
+ private
200
+
201
+ def qs_build(var_hash)
202
+ var_hash.map do |k, v|
203
+ [Camping.escape(k.to_s), Camping.escape(v.to_s)].join('=')
204
+ end.join('&')
205
+ end
206
+
207
+ end
208
+
209
+ class UnitTest < Test
210
+
211
+ def test_dummy; end
212
+
213
+ end
214
+
215
+ end
data/public/blog.rb ADDED
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require_gem 'camping', '>=1.4'
5
+ require 'camping'
6
+ require 'camping/session'
7
+
8
+ Camping.goes :Blog
9
+
10
+ require File.dirname(__FILE__) + '/blog/models'
11
+ require File.dirname(__FILE__) + '/blog/views'
12
+ require File.dirname(__FILE__) + '/blog/controllers'
13
+
14
+ module Blog
15
+ include Camping::Session
16
+ end
17
+
18
+ Blog::Models.schema do
19
+ create_table :blog_posts, :force => true do |t|
20
+ t.column :id, :integer, :null => false
21
+ t.column :user_id, :integer, :null => false
22
+ t.column :title, :string, :limit => 255
23
+ t.column :body, :text
24
+ end
25
+ create_table :blog_users, :force => true do |t|
26
+ t.column :id, :integer, :null => false
27
+ t.column :username, :string
28
+ t.column :password, :string
29
+ end
30
+ create_table :blog_comments, :force => true do |t|
31
+ t.column :id, :integer, :null => false
32
+ t.column :post_id, :integer, :null => false
33
+ t.column :username, :string
34
+ t.column :body, :text
35
+ end
36
+ execute "INSERT INTO blog_users (username, password) VALUES ('admin', 'camping')"
37
+ end
38
+
39
+ def Blog.create
40
+ Camping::Models::Session.create_schema
41
+ unless Blog::Models::Post.table_exists?
42
+ ActiveRecord::Schema.define(&Blog::Models.schema)
43
+ end
44
+ end
45
+
46
+ if __FILE__ == $0
47
+ require 'mongrel/camping'
48
+
49
+ Blog::Models::Base.establish_connection :adapter => 'sqlite3', :database => 'blog.db'
50
+ Blog::Models::Base.logger = Logger.new('camping.log')
51
+ Blog::Models::Base.threaded_connections=false
52
+ Blog.create
53
+
54
+ server = Mongrel::Camping::start("0.0.0.0",3002,"/blog",Blog)
55
+ puts "** Blog example is running at http://localhost:3002/blog"
56
+ puts "** Default username is `admin', password is `camping'"
57
+ server.run.join
58
+ end
@@ -0,0 +1,107 @@
1
+
2
+ module Blog::Controllers
3
+ class Index < R '/'
4
+ def get
5
+ @posts = Post.find :all
6
+ render :index
7
+ end
8
+ end
9
+
10
+ class Add
11
+ def get
12
+ unless @state.user_id.blank?
13
+ @user = User.find @state.user_id
14
+ @post = Post.new
15
+ end
16
+ render :add
17
+ end
18
+ def post
19
+ post = Post.create :title => input.post_title,
20
+ :body => input.post_body,
21
+ :user_id => @state.user_id
22
+ redirect View, post
23
+ end
24
+ end
25
+
26
+ class Info < R '/info/(\d+)', '/info/(\w+)/(\d+)', '/info', '/info/(\d+)/(\d+)/(\d+)/([\w-]+)'
27
+ def get(*args)
28
+ div do
29
+ code args.inspect; br; br
30
+ code ENV.inspect; br
31
+ code "Link: #{R(Info, 1, 2)}"
32
+ end
33
+ end
34
+ end
35
+
36
+ class View < R '/view/(\d+)'
37
+ def get post_id
38
+ @post = Post.find post_id
39
+ @comments = Models::Comment.find_all_by_post_id post_id
40
+ render :view
41
+ end
42
+ end
43
+
44
+ class Edit < R '/edit/(\d+)', '/edit'
45
+ def get post_id
46
+ unless @state.user_id.blank?
47
+ @user = User.find @state.user_id
48
+ end
49
+ @post = Post.find post_id
50
+ render :edit
51
+ end
52
+
53
+ def post
54
+ @post = Post.find input.post_id
55
+ @post.update_attributes :title => input.post_title, :body => input.post_body
56
+ redirect View, @post
57
+ end
58
+ end
59
+
60
+ class Comment
61
+ def post
62
+ Models::Comment.create( :username => input.post_username,
63
+ :body => input.post_body,
64
+ :post_id => input.post_id)
65
+ redirect View, input.post_id
66
+ end
67
+ end
68
+
69
+ class Login
70
+ def post
71
+ @user = User.find :first, :conditions => ['username = ? AND password = ?', input.username, input.password]
72
+
73
+ if @user
74
+ @login = 'login success !'
75
+ @state.user_id = @user.id
76
+ else
77
+ @login = 'wrong user name or password'
78
+ end
79
+ render :login
80
+ end
81
+ end
82
+
83
+ class Logout
84
+ def get
85
+ @state.user_id = nil
86
+ render :logout
87
+ end
88
+ end
89
+
90
+ class Style < R '/styles.css'
91
+ def get
92
+ @headers["Content-Type"] = "text/css; charset=utf-8"
93
+ @body = %{
94
+ body {
95
+ font-family: Utopia, Georgia, serif;
96
+ }
97
+ h1.header {
98
+ background-color: #fef;
99
+ margin: 0; padding: 10px;
100
+ }
101
+ div.content {
102
+ padding: 10px;
103
+ }
104
+ }
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,12 @@
1
+
2
+ module Blog::Models
3
+ def self.schema(&block)
4
+ @@schema = block if block_given?
5
+ @@schema
6
+ end
7
+
8
+ class Post < Base; belongs_to :user; end
9
+ class Comment < Base; belongs_to :user; end
10
+ class User < Base; validates_presence_of :username; end
11
+ end
12
+
@@ -0,0 +1,115 @@
1
+
2
+ module Blog::Views
3
+
4
+ def layout
5
+ html do
6
+ head do
7
+ title 'blog'
8
+ link :rel => 'stylesheet', :type => 'text/css',
9
+ :href => '/styles.css', :media => 'screen'
10
+ end
11
+ body do
12
+ h1.header { a 'blog', :href => R(Index) }
13
+ div.content do
14
+ self << yield
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def index
21
+ if @posts.empty?
22
+ p 'No posts found.'
23
+ p { a 'Add', :href => R(Add) }
24
+ else
25
+ for post in @posts
26
+ _post(post)
27
+ end
28
+ end
29
+ end
30
+
31
+ def login
32
+ p { b @login }
33
+ p { a 'Continue', :href => R(Add) }
34
+ end
35
+
36
+ def logout
37
+ p "You have been logged out."
38
+ p { a 'Continue', :href => R(Index) }
39
+ end
40
+
41
+ def add
42
+ if @user
43
+ _form(post, :action => R(Add))
44
+ else
45
+ _login
46
+ end
47
+ end
48
+
49
+ def edit
50
+ if @user
51
+ _form(post, :action => R(Edit))
52
+ else
53
+ _login
54
+ end
55
+ end
56
+
57
+ def view
58
+ _post(post)
59
+
60
+ p "Comment for this post:"
61
+ for c in @comments
62
+ h1 c.username
63
+ p c.body
64
+ end
65
+
66
+ form :action => R(Comment), :method => 'post' do
67
+ label 'Name', :for => 'post_username'; br
68
+ input :name => 'post_username', :type => 'text'; br
69
+ label 'Comment', :for => 'post_body'; br
70
+ textarea :name => 'post_body' do; end; br
71
+ input :type => 'hidden', :name => 'post_id', :value => post.id
72
+ input :type => 'submit'
73
+ end
74
+ end
75
+
76
+ # partials
77
+ def _login
78
+ form :action => R(Login), :method => 'post' do
79
+ label 'Username', :for => 'username'; br
80
+ input :name => 'username', :type => 'text'; br
81
+
82
+ label 'Password', :for => 'password'; br
83
+ input :name => 'password', :type => 'text'; br
84
+
85
+ input :type => 'submit', :name => 'login', :value => 'Login'
86
+ end
87
+ end
88
+
89
+ def _post(post)
90
+ h1 post.title
91
+ p post.body
92
+ p do
93
+ a "Edit", :href => R(Edit, post)
94
+ a "View", :href => R(View, post)
95
+ end
96
+ end
97
+
98
+ def _form(post, opts)
99
+ p do
100
+ text "You are logged in as #{@user.username} | "
101
+ a 'Logout', :href => R(Logout)
102
+ end
103
+ form({:method => 'post'}.merge(opts)) do
104
+ label 'Title', :for => 'post_title'; br
105
+ input :name => 'post_title', :type => 'text',
106
+ :value => post.title; br
107
+
108
+ label 'Body', :for => 'post_body'; br
109
+ textarea post.body, :name => 'post_body'; br
110
+
111
+ input :type => 'hidden', :name => 'post_id', :value => post.id
112
+ input :type => 'submit'
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,64 @@
1
+ #!/usr/local/bin/ruby -rubygems
2
+ require 'camping'
3
+
4
+ Camping.goes :HomePage
5
+
6
+ module HomePage::Controllers
7
+
8
+ # The root slash shows the `index' view.
9
+ class Index < R '/'
10
+ def get
11
+ render :index
12
+ end
13
+ end
14
+
15
+ # Any other page name gets sent to the view
16
+ # of the same name.
17
+ #
18
+ # /index -> Views#index
19
+ # /sample -> Views#sample
20
+ #
21
+ class Page < R '/(\w+)'
22
+ def get(page_name)
23
+ render page_name
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ module HomePage::Views
30
+
31
+ # If you have a `layout' method like this, it
32
+ # will wrap the HTML in the other methods. The
33
+ # `self << yield' is where the HTML is inserted.
34
+ def layout
35
+ html do
36
+ title { 'My HomePage' }
37
+ body { self << yield }
38
+ end
39
+ end
40
+
41
+ # The `index' view. Inside your views, you express
42
+ # the HTML in Ruby. See http://code.whytheluckystiff.net/markaby/.
43
+ def index
44
+ p 'Hi my name is Charles.'
45
+ p 'Here are some links:'
46
+ ul do
47
+ li { a 'Google', :href => 'http://google.com' }
48
+ li { a 'A sample page', :href => '/sample' }
49
+ end
50
+ end
51
+
52
+ # The `sample' view.
53
+ def sample
54
+ p 'A sample page'
55
+ end
56
+ end
57
+
58
+ if __FILE__ == $0
59
+ require 'mongrel/camping'
60
+
61
+ server = Mongrel::Camping::start("0.0.0.0",3002,"/homepage",HomePage)
62
+ puts "** HomePage example is running at http://localhost:3002/homepage"
63
+ server.run.join
64
+ end
@@ -0,0 +1,6 @@
1
+
2
+ fox:
3
+ id: 1
4
+ post_id: 1
5
+ username: phil
6
+ body: That is a boring story.
@@ -0,0 +1,11 @@
1
+ quick_fox:
2
+ id: 1
3
+ user_id: 1
4
+ title: News for Today
5
+ body: The quick fox jumped over the lazy dog.
6
+
7
+ quick_dog:
8
+ id: 2
9
+ user_id: 2
10
+ title: News for Tomorrow
11
+ body: The quick dog jumped over the lazy fox.
@@ -0,0 +1,6 @@
1
+
2
+ quentin:
3
+ id: 1
4
+ username: quentin
5
+ password: password
6
+
data/test/test_blog.rb ADDED
@@ -0,0 +1,110 @@
1
+ require File.dirname(__FILE__) + "/../lib/mosquito"
2
+ require File.dirname(__FILE__) + "/../public/blog"
3
+
4
+ Blog.create
5
+ include Blog::Models
6
+
7
+ class TestBlog < Camping::FunctionalTest
8
+
9
+ fixtures :blog_posts, :blog_users, :blog_comments
10
+
11
+ def setup
12
+ super
13
+ # Do other stuff here
14
+ end
15
+
16
+ def test_index
17
+ get
18
+ assert_response :success
19
+ assert_match_body %r!>blog<!
20
+ end
21
+
22
+ def test_view
23
+ get '/view/1'
24
+ assert_response :success
25
+ assert_match_body %r!The quick fox jumped over the lazy dog!
26
+ end
27
+
28
+ def test_styles
29
+ get 'styles.css'
30
+ assert_match_body %r!Utopia!
31
+ end
32
+
33
+ def test_edit_should_require_login
34
+ get '/edit/1'
35
+ assert_response :success
36
+ assert_match_body 'login'
37
+ end
38
+
39
+ def test_login
40
+ post 'login', :username => 'quentin', :password => 'password'
41
+ assert_match_body 'login success'
42
+ end
43
+
44
+ def test_comment
45
+ assert_difference(Comment) {
46
+ post 'comment', :post_username => 'jim',
47
+ :post_body => 'Nice article.',
48
+ :post_id => 1
49
+ assert_response :redirect
50
+ assert_redirected_to '/view/1'
51
+ }
52
+ end
53
+
54
+ end
55
+
56
+ class TestPost < Camping::UnitTest
57
+
58
+ fixtures :blog_posts, :blog_users, :blog_comments
59
+
60
+ def test_create
61
+ post = create
62
+ assert post.valid?
63
+ end
64
+
65
+ def test_assoc
66
+ post = Post.find :first
67
+ assert_kind_of User, post.user
68
+ assert_equal 1, post.user.id
69
+ end
70
+
71
+ def test_destroy
72
+ original_count = Post.count
73
+ Post.destroy 1
74
+ assert_equal original_count - 1, Post.count
75
+ end
76
+
77
+ private
78
+
79
+ def create(options={})
80
+ Post.create({ :user_id => 1,
81
+ :title => "Title",
82
+ :body => "Body"}.merge(options))
83
+ end
84
+
85
+ end
86
+
87
+ class TestUser < Camping::UnitTest
88
+
89
+ fixtures :blog_posts, :blog_users, :blog_comments
90
+
91
+ def test_create
92
+ user = create
93
+ assert user.valid?
94
+ end
95
+
96
+ def test_required
97
+ user = create(:username => nil)
98
+ deny user.valid?
99
+ assert_not_nil user.errors.on(:username)
100
+ end
101
+
102
+ private
103
+
104
+ def create(options={})
105
+ User.create({ :username => 'godfrey',
106
+ :password => 'password' }.merge(options))
107
+ end
108
+
109
+ end
110
+
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + "/../lib/mosquito"
2
+ require File.dirname(__FILE__) + "/../public/homepage"
3
+
4
+ class TestHomePage < Camping::FunctionalTest
5
+
6
+ def setup
7
+ super
8
+ # Do other stuff here
9
+ end
10
+
11
+ def test_index
12
+ get '/'
13
+ assert_response :success
14
+ assert_match_body %r!Charles!
15
+ end
16
+
17
+ def test_page
18
+ get '/sample'
19
+ assert_response :success
20
+ assert_match_body %r!<p>A sample page</p>!
21
+ end
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: mosquito
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2006-11-15 00:00:00 +11:00
8
+ summary: A Camping test library.
9
+ require_paths:
10
+ - lib
11
+ - test
12
+ email: boss@topfunky.com
13
+ homepage: http://mosquito.rubyforge.org
14
+ rubyforge_project: mosquito
15
+ description: A library for writing tests for your Camping app.
16
+ autorequire:
17
+ default_executable:
18
+ bindir: bin
19
+ has_rdoc: true
20
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
21
+ requirements:
22
+ - - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ post_install_message:
30
+ authors:
31
+ - Geoffrey Grosenbach
32
+ files:
33
+ - Rakefile
34
+ - README
35
+ - MIT-LICENSE
36
+ - Manifest.txt
37
+ - lib
38
+ - lib/mosquito.rb
39
+ - public
40
+ - public/blog
41
+ - public/blog.rb
42
+ - public/blog/controllers.rb
43
+ - public/blog/models.rb
44
+ - public/blog/views.rb
45
+ - public/homepage.rb
46
+ - test
47
+ - test/test_blog.rb
48
+ - test/test_homepage.rb
49
+ - test/fixtures
50
+ - test/fixtures/blog_comments.yml
51
+ - test/fixtures/blog_posts.yml
52
+ - test/fixtures/blog_users.yml
53
+ test_files:
54
+ - test/test_blog.rb
55
+ - test/test_homepage.rb
56
+ rdoc_options: []
57
+
58
+ extra_rdoc_files: []
59
+
60
+ executables: []
61
+
62
+ extensions: []
63
+
64
+ requirements: []
65
+
66
+ dependencies:
67
+ - !ruby/object:Gem::Dependency
68
+ name: hoe
69
+ version_requirement:
70
+ version_requirements: !ruby/object:Gem::Version::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.1.3
75
+ version: