grudge 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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