gitdocs 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/.codeclimate.yml +26 -0
- data/.rubocop.yml +8 -2
- data/.travis.yml +8 -0
- data/CHANGELOG +13 -0
- data/Gemfile +1 -1
- data/README.md +7 -6
- data/Rakefile +31 -5
- data/bin/gitdocs +1 -0
- data/config.ru +6 -4
- data/gitdocs.gemspec +22 -19
- data/lib/gitdocs.rb +54 -16
- data/lib/gitdocs/browser_app.rb +34 -41
- data/lib/gitdocs/cli.rb +41 -32
- data/lib/gitdocs/configuration.rb +40 -101
- data/lib/gitdocs/git_notifier.rb +111 -0
- data/lib/gitdocs/initializer.rb +83 -0
- data/lib/gitdocs/manager.rb +90 -60
- data/lib/gitdocs/migration/004_add_index_for_path.rb +1 -1
- data/lib/gitdocs/notifier.rb +70 -104
- data/lib/gitdocs/rendering_helper.rb +3 -0
- data/lib/gitdocs/repository.rb +324 -307
- data/lib/gitdocs/repository/committer.rb +77 -0
- data/lib/gitdocs/repository/path.rb +157 -140
- data/lib/gitdocs/search.rb +40 -25
- data/lib/gitdocs/settings_app.rb +5 -3
- data/lib/gitdocs/share.rb +64 -0
- data/lib/gitdocs/synchronizer.rb +40 -0
- data/lib/gitdocs/version.rb +1 -1
- data/lib/gitdocs/views/_header.haml +2 -2
- data/lib/gitdocs/views/dir.haml +3 -3
- data/lib/gitdocs/views/edit.haml +1 -1
- data/lib/gitdocs/views/file.haml +1 -1
- data/lib/gitdocs/views/home.haml +3 -3
- data/lib/gitdocs/views/layout.haml +13 -13
- data/lib/gitdocs/views/revisions.haml +3 -3
- data/lib/gitdocs/views/search.haml +1 -1
- data/lib/gitdocs/views/settings.haml +6 -6
- data/test/integration/cli/full_sync_test.rb +83 -0
- data/test/integration/cli/share_management_test.rb +29 -0
- data/test/integration/cli/status_test.rb +14 -0
- data/test/integration/test_helper.rb +185 -151
- data/test/integration/{browse_test.rb → web/browse_test.rb} +11 -29
- data/test/integration/web/share_management_test.rb +46 -0
- data/test/support/git_factory.rb +276 -0
- data/test/unit/browser_app_test.rb +346 -0
- data/test/unit/configuration_test.rb +8 -70
- data/test/unit/git_notifier_test.rb +116 -0
- data/test/unit/gitdocs_test.rb +90 -0
- data/test/unit/manager_test.rb +36 -0
- data/test/unit/notifier_test.rb +60 -124
- data/test/unit/repository_committer_test.rb +111 -0
- data/test/unit/repository_path_test.rb +92 -76
- data/test/unit/repository_test.rb +243 -356
- data/test/unit/search_test.rb +15 -0
- data/test/unit/settings_app_test.rb +80 -0
- data/test/unit/share_test.rb +97 -0
- data/test/unit/test_helper.rb +17 -3
- metadata +114 -108
- data/lib/gitdocs/runner.rb +0 -108
- data/lib/gitdocs/server.rb +0 -62
- data/test/integration/full_sync_test.rb +0 -66
- data/test/integration/share_management_test.rb +0 -95
- data/test/integration/status_test.rb +0 -21
- data/test/unit/runner_test.rb +0 -122
data/lib/gitdocs/runner.rb
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
module Gitdocs
|
4
|
-
class Runner
|
5
|
-
def self.start_all(shares)
|
6
|
-
runners = shares.map { |share| Runner.new(share) }
|
7
|
-
runners.each(&:run)
|
8
|
-
runners
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(share)
|
12
|
-
@share = share
|
13
|
-
@polling_interval = share.polling_interval
|
14
|
-
@notifier = Gitdocs::Notifier.new(@share.notification)
|
15
|
-
@repository = Gitdocs::Repository.new(share)
|
16
|
-
end
|
17
|
-
|
18
|
-
def root
|
19
|
-
@repository.root
|
20
|
-
end
|
21
|
-
|
22
|
-
def run
|
23
|
-
return false unless @repository.valid?
|
24
|
-
|
25
|
-
@last_synced_revision = @repository.current_oid
|
26
|
-
|
27
|
-
mutex = Mutex.new
|
28
|
-
|
29
|
-
@notifier.info('Running gitdocs!', "Running gitdocs in '#{root}'")
|
30
|
-
|
31
|
-
# Pull changes from remote repository
|
32
|
-
syncer = proc do
|
33
|
-
EM.defer(proc do
|
34
|
-
mutex.synchronize { sync_changes }
|
35
|
-
end, proc do
|
36
|
-
EM.add_timer(@polling_interval) do
|
37
|
-
syncer.call
|
38
|
-
end
|
39
|
-
end)
|
40
|
-
end
|
41
|
-
syncer.call
|
42
|
-
# Listen for changes in local repository
|
43
|
-
|
44
|
-
EM.defer(proc do
|
45
|
-
listener = Guard::Listener.select_and_init(
|
46
|
-
root, watch_all_modifications: true
|
47
|
-
)
|
48
|
-
listener.on_change do |directories|
|
49
|
-
directories.uniq!
|
50
|
-
directories.delete_if { |d| d =~ /\/\.git/ }
|
51
|
-
unless directories.empty?
|
52
|
-
EM.next_tick do
|
53
|
-
EM.defer(proc do
|
54
|
-
mutex.synchronize { sync_changes }
|
55
|
-
end, proc {})
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
listener.start
|
60
|
-
end, proc { EM.stop_reactor })
|
61
|
-
end
|
62
|
-
|
63
|
-
def clear_state
|
64
|
-
@state = nil
|
65
|
-
end
|
66
|
-
|
67
|
-
def sync_changes
|
68
|
-
# Commit #################################################################
|
69
|
-
@repository.commit if @share.sync_type == 'full'
|
70
|
-
|
71
|
-
# Fetch ##################################################################
|
72
|
-
fetch_result = @repository.fetch
|
73
|
-
return unless fetch_result == :ok
|
74
|
-
return if @share.sync_type == 'fetch'
|
75
|
-
|
76
|
-
# Merge ##################################################################
|
77
|
-
merge_result = @repository.merge
|
78
|
-
merge_result = latest_author_count if merge_result == :ok
|
79
|
-
@notifier.merge_notification(merge_result, root)
|
80
|
-
return if merge_result.is_a?(String)
|
81
|
-
|
82
|
-
# Push ###################################################################
|
83
|
-
result = @repository.push
|
84
|
-
result = latest_author_count if result == :ok
|
85
|
-
@notifier.push_notification(result, root)
|
86
|
-
rescue => e
|
87
|
-
# Rescue any standard exceptions which come from the push related
|
88
|
-
# commands. This will prevent problems on a single share from killing
|
89
|
-
# the entire daemon.
|
90
|
-
@notifier.error("Unexpected error syncing changes in #{root}", "#{e}")
|
91
|
-
end
|
92
|
-
|
93
|
-
############################################################################
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
# Update the author count for the last synced changes, and then update the
|
98
|
-
# last synced revision id.
|
99
|
-
#
|
100
|
-
# @return [Hash<String,Int>]
|
101
|
-
def latest_author_count
|
102
|
-
last_oid = @last_synced_revision
|
103
|
-
@last_synced_revision = @repository.current_oid
|
104
|
-
|
105
|
-
@repository.author_count(last_oid)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
data/lib/gitdocs/server.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
require 'thin'
|
4
|
-
require 'gitdocs/browser_app'
|
5
|
-
require 'gitdocs/settings_app'
|
6
|
-
|
7
|
-
module Gitdocs
|
8
|
-
class Server
|
9
|
-
def initialize(manager, port = 8888, repositories)
|
10
|
-
@manager = manager
|
11
|
-
@port = port.to_i
|
12
|
-
@repositories = repositories
|
13
|
-
@search = Gitdocs::Search.new(repositories)
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.start_and_wait(manager, override_port, repositories)
|
17
|
-
return false unless manager.start_web_frontend
|
18
|
-
|
19
|
-
web_port = override_port || manager.web_frontend_port
|
20
|
-
server = Server.new(manager, web_port, repositories)
|
21
|
-
server.start
|
22
|
-
server.wait_for_start
|
23
|
-
true
|
24
|
-
end
|
25
|
-
|
26
|
-
def start
|
27
|
-
Gitdocs::SettingsApp.set :manager, @manager
|
28
|
-
Gitdocs::BrowserApp.set :repositories, @repositories
|
29
|
-
|
30
|
-
Thin::Logging.debug = @manager.debug
|
31
|
-
Thin::Server.start('127.0.0.1', @port) do
|
32
|
-
use Rack::Static,
|
33
|
-
urls: %w(/css /js /img /doc),
|
34
|
-
root: File.expand_path('../public', __FILE__)
|
35
|
-
use Rack::MethodOverride
|
36
|
-
|
37
|
-
map('/settings') { run Gitdocs::SettingsApp }
|
38
|
-
map('/') { run Gitdocs::BrowserApp }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def wait_for_start
|
43
|
-
wait_for_web_server = proc do
|
44
|
-
i = 0
|
45
|
-
begin
|
46
|
-
TCPSocket.open('127.0.0.1', @port).close
|
47
|
-
@manager.log('Web server running!')
|
48
|
-
rescue Errno::ECONNREFUSED
|
49
|
-
sleep 0.2
|
50
|
-
i += 1
|
51
|
-
if i <= 20
|
52
|
-
@manager.log('Retrying web server loop...')
|
53
|
-
retry
|
54
|
-
else
|
55
|
-
@manager.log('Web server failed to start')
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
EM.defer(wait_for_web_server)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
require File.expand_path('../test_helper', __FILE__)
|
4
|
-
|
5
|
-
describe 'fully synchronizing repositories' do
|
6
|
-
before do
|
7
|
-
git_clone_and_gitdocs_add(git_init_remote, 'clone1', 'clone2', 'clone3')
|
8
|
-
start_daemon
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'should sync new files' do
|
12
|
-
write_file('clone1/newfile', 'testing')
|
13
|
-
wait_for_clean_workdir('clone1')
|
14
|
-
|
15
|
-
wait_for_exact_file_content('clone1/newfile', 'testing')
|
16
|
-
wait_for_exact_file_content('clone2/newfile', 'testing')
|
17
|
-
wait_for_exact_file_content('clone3/newfile', 'testing')
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should sync changes to an existing file' do
|
21
|
-
write_file('clone1/file', 'testing')
|
22
|
-
wait_for_clean_workdir('clone1')
|
23
|
-
|
24
|
-
wait_for_exact_file_content('clone3/file', 'testing')
|
25
|
-
append_to_file('clone3/file', "\nfoobar")
|
26
|
-
wait_for_clean_workdir('clone3')
|
27
|
-
|
28
|
-
wait_for_exact_file_content('clone1/file', "testing\nfoobar")
|
29
|
-
wait_for_exact_file_content('clone2/file', "testing\nfoobar")
|
30
|
-
wait_for_exact_file_content('clone3/file', "testing\nfoobar")
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should sync empty directories' do
|
34
|
-
in_current_dir { _mkdir('clone1/empty_dir') }
|
35
|
-
wait_for_clean_workdir('clone1')
|
36
|
-
|
37
|
-
wait_for_directory('clone1/empty_dir')
|
38
|
-
wait_for_directory('clone2/empty_dir')
|
39
|
-
wait_for_directory('clone3/empty_dir')
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should mark unresolvable conflicts' do
|
43
|
-
write_file('clone1/file', 'testing')
|
44
|
-
wait_for_clean_workdir('clone1')
|
45
|
-
|
46
|
-
append_to_file('clone2/file', 'foobar')
|
47
|
-
append_to_file('clone3/file', 'deadbeef')
|
48
|
-
wait_for_clean_workdir('clone2')
|
49
|
-
wait_for_clean_workdir('clone3')
|
50
|
-
|
51
|
-
# HACK: Leaving in the sleep and standard checks.
|
52
|
-
# Trying to wait for the conflicts to be resolved does not seem to
|
53
|
-
# be working consistently when run on TravisCI. Hopefully this will.
|
54
|
-
sleep(6)
|
55
|
-
in_current_dir do
|
56
|
-
# Remember expected file counts include '.', '..', and '.git'
|
57
|
-
assert_includes(5..6, Dir.entries('clone1').count)
|
58
|
-
assert_includes(5..6, Dir.entries('clone2').count)
|
59
|
-
assert_includes(5..6, Dir.entries('clone3').count)
|
60
|
-
end
|
61
|
-
# TODO: Want to convert to these methods in the future
|
62
|
-
# wait_for_conflict_markers('clone1/file')
|
63
|
-
# wait_for_conflict_markers('clone2/file')
|
64
|
-
# wait_for_conflict_markers('clone3/file')
|
65
|
-
end
|
66
|
-
end
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
require File.expand_path('../test_helper', __FILE__)
|
4
|
-
|
5
|
-
describe 'Manage which shares are being watched' do
|
6
|
-
it 'should add a local repository' do
|
7
|
-
git_init_local
|
8
|
-
gitdocs_add
|
9
|
-
gitdocs_status
|
10
|
-
assert_gitdocs_status_contains(abs_current_dir('local'))
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should add a remote repository' do
|
14
|
-
git_init_remote
|
15
|
-
abs_remote_path = abs_current_dir('remote')
|
16
|
-
cmd = "gitdocs create local #{abs_remote_path} --pid=gitdocs.pid"
|
17
|
-
run_simple(cmd, true, 15)
|
18
|
-
assert_success(true)
|
19
|
-
assert_partial_output('Added path local to doc list', output_from(cmd))
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should update a share through the UI' do
|
23
|
-
git_init_local
|
24
|
-
gitdocs_add
|
25
|
-
start_daemon
|
26
|
-
visit('http://localhost:7777/')
|
27
|
-
click_link('Settings')
|
28
|
-
|
29
|
-
within('#settings') do
|
30
|
-
within('#share-0') do
|
31
|
-
fill_in('share[0][polling_interval]', with: '0.2')
|
32
|
-
select('Fetch only', from: 'share[0][sync_type]')
|
33
|
-
end
|
34
|
-
click_button('Save')
|
35
|
-
end
|
36
|
-
|
37
|
-
# Allow the asynchronous portion of the update finish before checking
|
38
|
-
# the result.
|
39
|
-
sleep(1)
|
40
|
-
|
41
|
-
click_link('Settings')
|
42
|
-
within('#settings') do
|
43
|
-
within('#share-0') do
|
44
|
-
page.must_have_field('share[0][polling_interval]', with: '0.2')
|
45
|
-
page.must_have_field('share[0][sync_type]', with: 'fetch')
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe 'remove a share' do
|
51
|
-
before do
|
52
|
-
git_init_local
|
53
|
-
gitdocs_add
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'through CLI' do
|
57
|
-
cmd = 'gitdocs rm local --pid=gitdocs.pid'
|
58
|
-
run_simple(cmd, true, 15)
|
59
|
-
assert_success(true)
|
60
|
-
assert_partial_output('Removed path local from doc list', output_from(cmd))
|
61
|
-
|
62
|
-
gitdocs_status
|
63
|
-
assert_gitdocs_status_not_contain(abs_current_dir('local'))
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'through UI' do
|
67
|
-
start_daemon
|
68
|
-
visit('http://localhost:7777/')
|
69
|
-
click_link('Settings')
|
70
|
-
|
71
|
-
within('#settings') do
|
72
|
-
within('#share-0') { click_link('Delete') }
|
73
|
-
|
74
|
-
page.must_have_css('.share', count: 0)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'should clear all existing shares' do
|
80
|
-
%w(local1 local2 local3).each do |path|
|
81
|
-
git_init_local(path)
|
82
|
-
gitdocs_add(path)
|
83
|
-
end
|
84
|
-
|
85
|
-
cmd = 'gitdocs clear --pid=gitdocs.pid'
|
86
|
-
run_simple(cmd, true, 15)
|
87
|
-
assert_success(true)
|
88
|
-
assert_partial_output('Cleared paths from gitdocs', output_from(cmd))
|
89
|
-
|
90
|
-
gitdocs_status
|
91
|
-
assert_gitdocs_status_not_contain(abs_current_dir('local1'))
|
92
|
-
assert_gitdocs_status_not_contain(abs_current_dir('local2'))
|
93
|
-
assert_gitdocs_status_not_contain(abs_current_dir('local3'))
|
94
|
-
end
|
95
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
require File.expand_path('../test_helper', __FILE__)
|
4
|
-
|
5
|
-
describe 'CLI with display daemon and share status' do
|
6
|
-
it 'should display information about the daemon' do
|
7
|
-
gitdocs_status
|
8
|
-
assert_gitdocs_status_contains(Gitdocs::VERSION)
|
9
|
-
assert_gitdocs_status_contains('Running: false')
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'should display information about the shares' do
|
13
|
-
git_clone_and_gitdocs_add(git_init_remote, 'clone1', 'clone2', 'clone3')
|
14
|
-
|
15
|
-
gitdocs_status
|
16
|
-
|
17
|
-
assert_gitdocs_status_contains(abs_current_dir('clone1'))
|
18
|
-
assert_gitdocs_status_contains(abs_current_dir('clone2'))
|
19
|
-
assert_gitdocs_status_contains(abs_current_dir('clone3'))
|
20
|
-
end
|
21
|
-
end
|
data/test/unit/runner_test.rb
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
require File.expand_path('../test_helper', __FILE__)
|
4
|
-
|
5
|
-
describe 'gitdocs runner' do
|
6
|
-
let(:runner) { Gitdocs::Runner.new(share) }
|
7
|
-
|
8
|
-
let(:share) { stub(polling_interval: 1, notification: true) }
|
9
|
-
let(:notifier) { stub }
|
10
|
-
let(:repository) { stub(root: 'root_path') }
|
11
|
-
before do
|
12
|
-
Gitdocs::Notifier.stubs(:new).with(true).returns(notifier)
|
13
|
-
Gitdocs::Repository.stubs(:new).with(share).returns(repository)
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#root' do
|
17
|
-
subject { runner.root }
|
18
|
-
it { subject.must_equal 'root_path' }
|
19
|
-
end
|
20
|
-
|
21
|
-
describe '#sync_changes' do
|
22
|
-
subject { runner.sync_changes }
|
23
|
-
|
24
|
-
describe 'fetch sync' do
|
25
|
-
before do
|
26
|
-
share.stubs(:sync_type).returns('fetch')
|
27
|
-
repository.expects(:fetch).returns(fetch_result)
|
28
|
-
end
|
29
|
-
|
30
|
-
describe('fetch failure') { let(:fetch_result) { :not_ok } ; it { subject } }
|
31
|
-
describe('fetch success') { let(:fetch_result) { :ok } ; it { subject } }
|
32
|
-
end
|
33
|
-
|
34
|
-
describe 'full sync' do
|
35
|
-
before do
|
36
|
-
share.stubs(:sync_type).returns('full')
|
37
|
-
repository.expects(:commit)
|
38
|
-
repository.expects(:fetch).returns(fetch_result)
|
39
|
-
end
|
40
|
-
|
41
|
-
describe 'fetch failure' do
|
42
|
-
let(:fetch_result) { :not_ok }
|
43
|
-
it { subject }
|
44
|
-
end
|
45
|
-
|
46
|
-
describe 'when merge error' do
|
47
|
-
let(:fetch_result) { :ok }
|
48
|
-
before do
|
49
|
-
repository.expects(:merge).returns('error')
|
50
|
-
notifier.expects(:merge_notification).with('error', 'root_path')
|
51
|
-
end
|
52
|
-
it { subject }
|
53
|
-
end
|
54
|
-
|
55
|
-
describe 'when merge not_ok' do
|
56
|
-
let(:fetch_result) { :ok }
|
57
|
-
before do
|
58
|
-
repository.expects(:merge).returns(:not_ok)
|
59
|
-
notifier.expects(:merge_notification).with(:not_ok, 'root_path')
|
60
|
-
repository.expects(:push).returns(push_result)
|
61
|
-
end
|
62
|
-
|
63
|
-
describe 'and push is not_ok' do
|
64
|
-
let(:push_result) { :not_ok }
|
65
|
-
before { notifier.expects(:push_notification).with(:not_ok, 'root_path') }
|
66
|
-
it { subject }
|
67
|
-
end
|
68
|
-
|
69
|
-
describe 'and push is ok' do
|
70
|
-
let(:push_result) { :ok }
|
71
|
-
before do
|
72
|
-
runner.instance_variable_set(:@last_synced_revision, :oid)
|
73
|
-
repository.stubs(:current_oid).returns(:next_oid)
|
74
|
-
changes = { 'Alice' => 1, 'Bob' => 2 }
|
75
|
-
repository.stubs(:author_count).with(:oid).returns(changes)
|
76
|
-
notifier.expects(:push_notification).with(changes, 'root_path')
|
77
|
-
|
78
|
-
subject
|
79
|
-
end
|
80
|
-
it { runner.instance_variable_get(:@last_synced_revision).must_equal :next_oid }
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe 'merge ok' do
|
85
|
-
let(:fetch_result) { :ok }
|
86
|
-
|
87
|
-
before do
|
88
|
-
repository.stubs(:current_oid).returns(:merge_oid, :push_oid)
|
89
|
-
|
90
|
-
repository.expects(:merge).returns(:ok)
|
91
|
-
runner.instance_variable_set(:@last_synced_revision, :oid)
|
92
|
-
changes = { 'Alice' => 1, 'Bob' => 3 }
|
93
|
-
repository.stubs(:author_count).with(:oid).returns(changes)
|
94
|
-
notifier.expects(:merge_notification).with(changes, 'root_path')
|
95
|
-
repository.expects(:push).returns(push_result)
|
96
|
-
end
|
97
|
-
|
98
|
-
describe 'and push is not_ok' do
|
99
|
-
let(:push_result) { :not_ok }
|
100
|
-
before do
|
101
|
-
notifier.expects(:push_notification).with(:not_ok, 'root_path')
|
102
|
-
|
103
|
-
subject
|
104
|
-
end
|
105
|
-
it { runner.instance_variable_get(:@last_synced_revision).must_equal :merge_oid }
|
106
|
-
end
|
107
|
-
|
108
|
-
describe 'and push is ok' do
|
109
|
-
let(:push_result) { :ok }
|
110
|
-
before do
|
111
|
-
changes = { 'Charlie' => 5, 'Dan' => 7 }
|
112
|
-
repository.stubs(:author_count).with(:merge_oid).returns(changes)
|
113
|
-
notifier.expects(:push_notification).with(changes, 'root_path')
|
114
|
-
|
115
|
-
subject
|
116
|
-
end
|
117
|
-
it { runner.instance_variable_get(:@last_synced_revision).must_equal :push_oid }
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|