thumblemonks-grudge 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class ConfigTest < Test::Unit::TestCase
4
+ context "config file" do
5
+ setup do
6
+ config_file = StringIO.new({"foo" => {"bar" => "baz"}}.to_yaml)
7
+ @config = Grudge::Config::ConfigFile.new(config_file, :foo)
8
+ end
9
+
10
+ should "scope to specified environment" do
11
+ assert_equal "baz", @config.bar
12
+ end
13
+ end
14
+
15
+ should "return hash as value of repository" do
16
+ assert_kind_of Hash, Grudge::Config.repo
17
+ end
18
+ end
@@ -0,0 +1,193 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class GrudgeTest < Test::Unit::TestCase
4
+ context "grudge" do
5
+ setup do
6
+ Grudge::Repository.stubs(:object).returns(repository_commit)
7
+ end
8
+
9
+ context "/" do
10
+ should "redirect to /recent" do
11
+ assert_redirected_to('/recent') { get_it '/' }
12
+ end
13
+ end # /
14
+
15
+ context "list view" do
16
+ setup do
17
+ @commits = (1..20).map {Factory.build(:commit)}
18
+ end
19
+
20
+ context "/recent" do
21
+ setup do
22
+ Commit.expects(:recent).returns(@commits)
23
+ get_it '/recent'
24
+ @h = Hpricot(@response.body)
25
+ end
26
+
27
+ should "render 20 most recent commits" do
28
+ assert_equal 20, (@h/'.commit').length
29
+ end
30
+
31
+ should "set a title" do
32
+ assert_match %r[Recent commits$], (@h/'title').text
33
+ end
34
+ end # /recent
35
+
36
+ context "/popular" do
37
+ setup do
38
+ Commit.expects(:popular).returns(@commits)
39
+ get_it '/popular'
40
+ @h = Hpricot(@response.body)
41
+ end
42
+
43
+ should "render 20 most recent commits" do
44
+ assert_equal 20, (@h/'.commit').length
45
+ end
46
+
47
+ should "set a title" do
48
+ assert_match %r[Popular commits$], (@h/'title').text
49
+ end
50
+ end # /popular
51
+
52
+ context "/unpopular" do
53
+ setup do
54
+ Commit.expects(:unpopular).returns(@commits)
55
+ get_it '/unpopular'
56
+ @h = Hpricot(@response.body)
57
+ end
58
+
59
+ should "render 20 most recent commits" do
60
+ assert_equal 20, (@h/'.commit').length
61
+ end
62
+
63
+ should "set a title" do
64
+ assert_match %r[Unpopular commits$], (@h/'title').text
65
+ end
66
+ end # /unpopular
67
+ end # list view
68
+
69
+ context "/:sha" do
70
+ context "found an entry" do
71
+ setup do
72
+ @commit = Factory.build(:commit, :sha => 'abc')
73
+ Commit.expects(:first).with(:sha => 'abc').returns(@commit)
74
+ get_it "/#{@commit.sha}"
75
+ @h = Hpricot(@response.body)
76
+ end
77
+
78
+ should "render one commit entry" do
79
+ assert_equal 1, (@h/'.commit').length
80
+ end
81
+
82
+ should "set title to sha" do
83
+ assert_match %r[abc$], (@h/'title').text
84
+ end
85
+ end # found an entry
86
+
87
+ context "no entry found" do
88
+ setup do
89
+ Commit.expects(:first).with(:sha => 'abcdef').returns(nil)
90
+ get_it "/abcdef"
91
+ @h = Hpricot(@response.body)
92
+ end
93
+
94
+ should "render not found page" do
95
+ assert_match %r[I don't even know you anymore], (@h/'body').text
96
+ end
97
+ end # no entry found
98
+ end # /:sha
99
+
100
+ context "voting" do
101
+ context "record found" do
102
+ setup do
103
+ @commit = Factory.build(:commit, :sha => 'abc')
104
+ Commit.expects(:first).with(:sha => 'abc').returns(@commit)
105
+ end
106
+
107
+ context "for /:sha/awesome" do
108
+ setup do
109
+ @commit.expects(:awesome!)
110
+ get_it "/abc/awesome"
111
+ end
112
+ should "redirect to show page" do
113
+ assert_redirected_to '/abc'
114
+ end
115
+ end # for /:sha/awesome
116
+
117
+ context "for /:sha/suck" do
118
+ setup do
119
+ @commit.expects(:suck!)
120
+ get_it "/abc/suck"
121
+ end
122
+ should "redirect to show page" do
123
+ assert_redirected_to '/abc'
124
+ end
125
+ end # for /:sha/suck
126
+ end # record found
127
+
128
+ context "record not found" do
129
+ setup do
130
+ Commit.expects(:first).returns(nil)
131
+ end
132
+
133
+ context "for /:sha/awesome" do
134
+ setup do
135
+ get_it "/abc/awesome"
136
+ @h = Hpricot(@response.body)
137
+ end
138
+ should "render not found page" do
139
+ assert_match %r[I don't even know you anymore], (@h/'body').text
140
+ end
141
+ end # for /:sha/awesome
142
+
143
+ context "for /:sha/suck" do
144
+ setup do
145
+ get_it "/abc/suck"
146
+ @h = Hpricot(@response.body)
147
+ end
148
+ should "render not found page" do
149
+ assert_match %r[I don't even know you anymore], (@h/'body').text
150
+ end
151
+ end # for /:sha/suck
152
+ end # record not found
153
+ end # voting
154
+
155
+ context "/search" do
156
+ context "for existing commit" do
157
+ setup do
158
+ @commit = Factory.build(:commit, :sha => 'abc')
159
+ Commit.expects(:search).with('abc').returns(@commit)
160
+ post_it '/search', {'query' => 'abc'}
161
+ @h = Hpricot(@response.body)
162
+ end
163
+
164
+ should "render page with just one commit" do
165
+ assert_equal 1, (@h/'.commit').length
166
+ end
167
+ end
168
+
169
+ context "for nonexistant commit" do
170
+ setup do
171
+ Commit.expects(:search).with('abc').returns(nil)
172
+ post_it '/search', {'query' => 'abc'}
173
+ @h = Hpricot(@response.body)
174
+ end
175
+ should "render not found page" do
176
+ assert_match %r[I don't even know you anymore], (@h/'body').text
177
+ end
178
+ end
179
+ end # /search
180
+
181
+ context "/repository/pull" do
182
+ setup do
183
+ @commits = (1..2).map {Factory(:commit)}
184
+ Commit.expects(:download!)
185
+ post_it '/repository/pull'
186
+ end
187
+
188
+ should "render blank page" do
189
+ assert_equal '', @response.body
190
+ end
191
+ end # /repository/pull
192
+ end # grudge
193
+ end
@@ -0,0 +1,30 @@
1
+ require 'factory_girl'
2
+ require 'ostruct'
3
+
4
+ # Model stuff
5
+
6
+ Factory.sequence :sha do |n|
7
+ "a#{n}b#{n}c#{n}d#{n}e#{n}f#{n}"
8
+ end
9
+
10
+ Factory.define :commit do |commit|
11
+ commit.sha { Factory.next(:sha) }
12
+ commit.committed_at Time.now
13
+ commit.score 0
14
+ end
15
+
16
+ Factory.define :awesome, :class => Vote do |vote|
17
+ vote.score 1
18
+ end
19
+
20
+ Factory.define :suck, :class => Vote do |vote|
21
+ vote.score -1
22
+ end
23
+
24
+ # Repository stuff
25
+
26
+ def repository_commit(attributes={})
27
+ defaults = {:sha => Factory.next(:sha), :author => O(:name => "Barney"),
28
+ :committer_date => Time.now, :message => "This is the shiznit!"}
29
+ O(defaults.merge(attributes))
30
+ end
@@ -0,0 +1,118 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class RepositoryTest < Test::Unit::TestCase
4
+
5
+ context "origin uri" do
6
+ should "return URI of repository/origin from config" do
7
+ assert_equal URI.parse('test/origin.git'), Grudge::Repository.origin_uri
8
+ end
9
+ end # origin uri
10
+
11
+ context "master path" do
12
+ should "return path from repository/master in config" do
13
+ assert_equal 'test/clone.git', Grudge::Repository.master_path
14
+ end
15
+ end # master path
16
+
17
+ context "open" do
18
+ context "logging" do
19
+ should "write to configured log" do
20
+ Git.expects(:open).with(any_parameters)
21
+ Grudge::Config.expects(:log)
22
+ Grudge::Repository.open
23
+ end
24
+ end # logging
25
+
26
+ context "without valid working directory" do
27
+ should "raise an error" do
28
+ assert_raise(ArgumentError) { Grudge::Repository.open }
29
+ end
30
+ end # without valid working directory
31
+ end # open
32
+
33
+ context "open or clone" do
34
+ should "clone if no master path exists" do
35
+ Git.expects(:clone).with(Grudge::Repository.origin_uri,
36
+ Grudge::Repository.master_path, any_parameters)
37
+ Grudge::Repository.open_or_clone
38
+ end
39
+
40
+ should "open if master_path exists" do
41
+ File.expects(:exists?).with(Grudge::Repository.master_path).returns(true)
42
+ Grudge::Repository.expects(:open)
43
+ Grudge::Repository.open_or_clone
44
+ end
45
+ end # open or clone
46
+
47
+ context "pull" do
48
+ setup do
49
+ git = mock('git repo') do
50
+ expects(:pull).with('origin', 'origin/master', 'grudge origin pull')
51
+ end
52
+ Grudge::Repository.stubs(:open).returns(git)
53
+ end
54
+
55
+ should "fetch from origin and merge from origin/master" do
56
+ Grudge::Repository.pull
57
+ end
58
+ end # pull
59
+
60
+ context "object" do
61
+ setup do
62
+ git = mock('git repo') { expects(:object).with('abc') }
63
+ Grudge::Repository.stubs(:open).returns(git)
64
+ end
65
+
66
+ should "return object for given sha" do
67
+ Grudge::Repository.object('abc')
68
+ end
69
+ end # object
70
+
71
+ context "latest commits" do
72
+ setup do
73
+ @repo_commits = (1..10).map { |i| Factory.next(:sha) }
74
+ Grudge::Repository.expects(:pull)
75
+ end
76
+
77
+ context "when since is provided" do
78
+ should "also provide a between option" do
79
+ since = 'abcdef'
80
+ git = O(:lib => stub('lib'))
81
+ git.lib.expects(:log_commits).with(:between => [since, '']).returns([])
82
+ Grudge::Repository.expects(:open).returns(git)
83
+ Grudge::Repository.latest_commits_since(since)
84
+ end
85
+ end # when since provided
86
+
87
+ context "when since is not provided" do
88
+ should "not provide any options" do
89
+ git = O(:lib => stub('lib'))
90
+ git.lib.expects(:log_commits).with({}).returns([])
91
+ Grudge::Repository.expects(:open).returns(git)
92
+ Grudge::Repository.latest_commits_since(nil)
93
+ end
94
+ end # when since is not provided
95
+
96
+ context "yield" do
97
+ setup do
98
+ git = O(:lib => O(:log_commits => @repo_commits))
99
+ Grudge::Repository.expects(:open).returns(git)
100
+ Grudge::Repository.expects(:object).times(10).with(kind_of(String)).
101
+ returns(repository_commit(:sha => 'abc'))
102
+ end
103
+
104
+ should "for each commit" do
105
+ count = 0
106
+ Grudge::Repository.latest_commits_since { |o| count += 1 }
107
+ assert_equal 10, count
108
+ end
109
+
110
+ should "an object loaded from :sha" do
111
+ Grudge::Repository.latest_commits_since do |o|
112
+ assert_kind_of OpenStruct, o
113
+ end
114
+ end
115
+ end # yield
116
+ end # latest commits since
117
+
118
+ end
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'hpricot'
3
+
4
+ require 'sinatra'
5
+ require 'sinatra/test/unit'
6
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'grudge')
7
+
8
+ require 'mocha'
9
+ require 'shoulda'
10
+ require 'ostruct'
11
+ require File.join(File.dirname(__FILE__), 'model_factory')
12
+
13
+ # TODO: Move to custom_assertions or make a new library for others to use.
14
+ # Gus would want to call it Chicago (as in "Chicago. It's my kind of town.")
15
+
16
+ class Test::Unit::TestCase
17
+ def teardown
18
+ Commit.all.destroy!
19
+ end
20
+
21
+ # Generic test helpers
22
+
23
+ def deny(check, message=nil) assert(!check, message); end
24
+
25
+ def O(*args) OpenStruct.new(*args); end
26
+
27
+ # Controller test helpers
28
+
29
+ def assert_redirected_to(expected_path, &block)
30
+ yield if block_given?
31
+ assert_equal 302, @response.status
32
+ action = expected_path.kind_of?(Regexp) ? 'match' : 'equal'
33
+ send("assert_#{action}", expected_path, @response.headers["Location"])
34
+ end
35
+
36
+ def assert_ok(&block)
37
+ yield
38
+ assert_equal 200, @response.status
39
+ end
40
+
41
+ # Model test helpers
42
+ # Add some of these to a Shoulda::DataMapper::Macros thing
43
+ # def self.should_require_attributes(attributes=[])
44
+ # def self.should_expect_a_default_value :attribute, expected_value
45
+ # def self.should_be_unique :attribute
46
+ end
data/test/vote_test.rb ADDED
@@ -0,0 +1,65 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class VoteTest < Test::Unit::TestCase
4
+ context "required attributes" do
5
+ setup do
6
+ @vote = Vote.new
7
+ @vote.valid?
8
+ @errors = @vote.errors
9
+ end
10
+
11
+ should "include score" do
12
+ assert_contains @errors[:score], "Score must not be blank"
13
+ end
14
+
15
+ should "include commit id" do
16
+ assert_contains @errors[:commit_id], "Commit must not be blank"
17
+ end
18
+ end # required attributes
19
+
20
+ context "associations" do
21
+ should "belong to commit" do
22
+ assert_equal Hash.new, Vote.relationships[:commit].options
23
+ assert_equal Commit, Vote.relationships[:commit].parent_model
24
+ end
25
+ end # associations
26
+
27
+ context "building awesome votes" do
28
+ setup { @vote = Vote.awesome }
29
+ should "create new vote with positive score" do
30
+ assert_equal 1, @vote.score
31
+ end
32
+
33
+ should "create unsaved vote" do
34
+ assert @vote.new_record?
35
+ end
36
+
37
+ should "be awesome?" do
38
+ assert @vote.awesome?
39
+ end
40
+
41
+ should "not suck?" do
42
+ deny @vote.suck?
43
+ end
44
+ end # building awesome votes
45
+
46
+ context "building sucky votes" do
47
+ setup { @vote = Vote.suck }
48
+ should "create new vote with negative score" do
49
+ assert_equal -1, @vote.score
50
+ end
51
+
52
+ should "create unsaved vote" do
53
+ assert @vote.new_record?
54
+ end
55
+
56
+ should "not be awesome?" do
57
+ deny @vote.awesome?
58
+ end
59
+
60
+ should "suck?" do
61
+ assert @vote.suck?
62
+ end
63
+ end # building sucky votes
64
+
65
+ end