hglib 0.1.pre20180129173049 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +94 -11
- data/History.md +1 -1
- data/Manifest.txt +12 -0
- data/Rakefile +1 -1
- data/examples/clone.rb +13 -0
- data/integration/commands/clone_spec.rb +52 -0
- data/integration/spec_helper.rb +29 -0
- data/lib/hglib.rb +7 -7
- data/lib/hglib/repo.rb +129 -0
- data/lib/hglib/repo/id.rb +81 -0
- data/lib/hglib/repo/log_entry.rb +128 -0
- data/lib/hglib/server.rb +320 -0
- data/spec/.status +39 -0
- data/spec/hglib/repo/id_spec.rb +182 -0
- data/spec/hglib/repo/log_entry_spec.rb +69 -0
- data/spec/hglib/repo_spec.rb +106 -0
- data/spec/hglib/server_spec.rb +166 -0
- data/spec/spec_helper.rb +6 -1
- metadata +44 -34
- metadata.gz.sig +0 -0
@@ -0,0 +1,182 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd
|
2
|
+
|
3
|
+
require_relative '../../spec_helper'
|
4
|
+
|
5
|
+
require 'hglib/repo/id'
|
6
|
+
|
7
|
+
|
8
|
+
RSpec.describe Hglib::Repo::Id do
|
9
|
+
|
10
|
+
it "can be created for an empty repo" do
|
11
|
+
result = described_class.new( '000000000000', 'tip' )
|
12
|
+
|
13
|
+
expect( result.global ).to eq( '000000000000' )
|
14
|
+
expect( result ).to eq( '000000000000' )
|
15
|
+
expect( result.tags ).to contain_exactly( 'tip' )
|
16
|
+
expect( result.bookmarks ).to be_empty
|
17
|
+
expect( result ).to_not have_uncommitted_changes
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
it "can be created for a repo with commits" do
|
22
|
+
result = described_class.new( 'd03a659966ec', 'tip' )
|
23
|
+
|
24
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
25
|
+
expect( result ).to eq( 'd03a659966ec' )
|
26
|
+
expect( result.tags ).to contain_exactly( 'tip' )
|
27
|
+
expect( result.bookmarks ).to be_empty
|
28
|
+
expect( result ).to_not have_uncommitted_changes
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
it "can be created for a repo with uncommitted changes" do
|
33
|
+
result = described_class.new( 'd03a659966ec', 'tip', uncommitted_changes: true )
|
34
|
+
|
35
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
36
|
+
expect( result ).to have_uncommitted_changes
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
it "can be created for a repo with more than one tag" do
|
41
|
+
result = described_class.new( 'd03a659966ec', 'qbase', 'qtip', 'repo-features.patch', 'tip' )
|
42
|
+
|
43
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
44
|
+
expect( result.tags ).to contain_exactly( 'qbase', 'qtip', 'repo-features.patch', 'tip' )
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
it "can be created for a repo with a bookmark" do
|
49
|
+
result = described_class.new( 'd03a659966ec', 'tip', bookmarks: 'master' )
|
50
|
+
|
51
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
52
|
+
expect( result.bookmarks ).to contain_exactly( 'master' )
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
it "can be created for a repo with more than one bookmark" do
|
57
|
+
result = described_class.new( 'd03a659966ec', 'tip', bookmarks: ['master', 'github/master'] )
|
58
|
+
|
59
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
60
|
+
expect( result.bookmarks ).to contain_exactly( 'master', 'github/master' )
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
describe "equality" do
|
65
|
+
|
66
|
+
it "is equal to an object of the same class with the same values" do
|
67
|
+
id = described_class.new( 'd03a659966ec',
|
68
|
+
'qbase', 'qtip', 'repo-features.patch', 'tip',
|
69
|
+
uncommitted_changes: true,
|
70
|
+
bookmarks: ['master', 'live']
|
71
|
+
)
|
72
|
+
|
73
|
+
copy = id.dup
|
74
|
+
|
75
|
+
expect( id ).to eq( copy )
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
it "is equal to the String that contains the same revision identifier" do
|
80
|
+
id = described_class.new( 'd03a659966ec',
|
81
|
+
'qbase', 'qtip', 'repo-features.patch', 'tip',
|
82
|
+
uncommitted_changes: true,
|
83
|
+
bookmarks: ['master', 'live']
|
84
|
+
)
|
85
|
+
|
86
|
+
expect( id ).to eq( 'd03a659966ec' )
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
describe "parsing server output" do
|
93
|
+
|
94
|
+
it "can parse the server output from an empty repo" do
|
95
|
+
result = described_class.parse( '000000000000 tip' )
|
96
|
+
|
97
|
+
expect( result.global ).to eq( '000000000000' )
|
98
|
+
expect( result ).to eq( '000000000000' )
|
99
|
+
expect( result.tags ).to contain_exactly( 'tip' )
|
100
|
+
expect( result.bookmarks ).to be_empty
|
101
|
+
expect( result ).to_not have_uncommitted_changes
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
it "can be parsed from the server output from a repo with commits" do
|
106
|
+
result = described_class.parse( 'd03a659966ec tip' )
|
107
|
+
|
108
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
109
|
+
expect( result ).to eq( 'd03a659966ec' )
|
110
|
+
expect( result.tags ).to contain_exactly( 'tip' )
|
111
|
+
expect( result.bookmarks ).to be_empty
|
112
|
+
expect( result ).to_not have_uncommitted_changes
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
it "can be parsed from the server output from a repo with uncommitted changes" do
|
117
|
+
result = described_class.parse( 'd03a659966ec+ tip' )
|
118
|
+
|
119
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
120
|
+
expect( result ).to have_uncommitted_changes
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
it "can be parsed from the server output from a repo with more than one tag" do
|
125
|
+
result = described_class.parse( 'd03a659966ec qbase/qtip/repo-features.patch/tip' )
|
126
|
+
|
127
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
128
|
+
expect( result.tags ).to contain_exactly( 'qbase', 'qtip', 'repo-features.patch', 'tip' )
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
it "can be parsed from the server output from a repo with a bookmark" do
|
133
|
+
result = described_class.parse( 'd03a659966ec tip master' )
|
134
|
+
|
135
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
136
|
+
expect( result.bookmarks ).to contain_exactly( 'master' )
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
it "can be parsed from the server output from a repo with more than one bookmark" do
|
141
|
+
result = described_class.parse( 'd03a659966ec tip master/servant' )
|
142
|
+
|
143
|
+
expect( result.global ).to eq( 'd03a659966ec' )
|
144
|
+
expect( result.bookmarks ).to contain_exactly( 'master', 'servant' )
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
describe "stringifying" do
|
151
|
+
|
152
|
+
it "works for the ID of an empty repo" do
|
153
|
+
id = described_class.new( '000000000000', 'tip' )
|
154
|
+
|
155
|
+
expect( id.to_s ).to eq( '000000000000 tip' )
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
it "works for the ID of a repo with uncommitted changes" do
|
160
|
+
id = described_class.new( 'd03a659966ec', 'tip', uncommitted_changes: true )
|
161
|
+
|
162
|
+
expect( id.to_s ).to eq( 'd03a659966ec+ tip' )
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
it "works for the ID of a repo with more than one tag" do
|
167
|
+
id = described_class.new( 'd03a659966ec', 'qbase', 'qtip', 'repo-features.patch', 'tip' )
|
168
|
+
|
169
|
+
expect( id.to_s ).to eq( 'd03a659966ec qbase/qtip/repo-features.patch/tip' )
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
it "works for the ID of a repo with a bookmark" do
|
174
|
+
id = described_class.new( 'd03a659966ec', 'tip', bookmarks: 'master' )
|
175
|
+
|
176
|
+
expect( id.to_s ).to eq( 'd03a659966ec tip master' )
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../../spec_helper'
|
5
|
+
|
6
|
+
require 'hglib/repo/log_entry'
|
7
|
+
|
8
|
+
|
9
|
+
RSpec.describe Hglib::Repo::LogEntry do
|
10
|
+
|
11
|
+
RAW_LOG_ENTRY = {
|
12
|
+
"bookmarks" => ['master'],
|
13
|
+
"branch" => "default",
|
14
|
+
"date" => [1526420446, 25200],
|
15
|
+
"desc" => "Flesh out the features of Repo objects",
|
16
|
+
"node" => "d4af915821dea2feca29288dc16742c0d41cee8c",
|
17
|
+
"parents" => ["a366819bd05b8dd995440105340e057528be25e6"],
|
18
|
+
"phase" => "public",
|
19
|
+
"rev" => 5,
|
20
|
+
"tags" => ['github/master', 'tip'],
|
21
|
+
"user" => "Michael Granger <ged@FaerieMUD.org>"
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
VERBOSE_LOG_ENTRY = RAW_LOG_ENTRY.merge(
|
25
|
+
"files" => %w[.hoerc .ruby-version lib/hglib/repo.rb spec/hglib/repo_spec.rb]
|
26
|
+
).freeze
|
27
|
+
|
28
|
+
|
29
|
+
it "can be created from the JSON log hash" do
|
30
|
+
entry = described_class.new( RAW_LOG_ENTRY )
|
31
|
+
|
32
|
+
expected_time = Time.parse( 'Tue May 15 14:40:46 2018 -0700' )
|
33
|
+
|
34
|
+
expect( entry ).to be_a( described_class )
|
35
|
+
expect( entry.changeset ).to eq( '5:d4af915821de' )
|
36
|
+
expect( entry.rev ).to eq( 5 )
|
37
|
+
expect( entry.node ).to eq( 'd4af915821dea2feca29288dc16742c0d41cee8c' )
|
38
|
+
expect( entry.bookmarks ).to contain_exactly( 'master' )
|
39
|
+
expect( entry.tags ).to contain_exactly( 'github/master', 'tip' )
|
40
|
+
expect( entry.user ).to eq( 'Michael Granger <ged@FaerieMUD.org>' )
|
41
|
+
expect( entry.date ).to be_a( Time ).and( eq(expected_time) )
|
42
|
+
expect( entry.summary ).to eq( 'Flesh out the features of Repo objects' )
|
43
|
+
|
44
|
+
expect( entry.diff ).to be_nil
|
45
|
+
expect( entry.files ).to be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
it "can be created from verbose log entry JSON" do
|
50
|
+
entry = described_class.new( VERBOSE_LOG_ENTRY )
|
51
|
+
|
52
|
+
expected_time = Time.parse( 'Tue May 15 14:40:46 2018 -0700' )
|
53
|
+
|
54
|
+
expect( entry ).to be_a( described_class )
|
55
|
+
expect( entry.changeset ).to eq( '5:d4af915821de' )
|
56
|
+
expect( entry.rev ).to eq( 5 )
|
57
|
+
expect( entry.node ).to eq( 'd4af915821dea2feca29288dc16742c0d41cee8c' )
|
58
|
+
expect( entry.bookmarks ).to contain_exactly( 'master' )
|
59
|
+
expect( entry.tags ).to contain_exactly( 'github/master', 'tip' )
|
60
|
+
expect( entry.user ).to eq( 'Michael Granger <ged@FaerieMUD.org>' )
|
61
|
+
expect( entry.date ).to be_a( Time ).and( eq(expected_time) )
|
62
|
+
expect( entry.summary ).to eq( 'Flesh out the features of Repo objects' )
|
63
|
+
|
64
|
+
expect( entry.diff ).to be_nil
|
65
|
+
expect( entry.files ).to contain_exactly( *VERBOSE_LOG_ENTRY['files'] )
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd
|
2
|
+
|
3
|
+
require_relative '../spec_helper'
|
4
|
+
|
5
|
+
require 'hglib/repo'
|
6
|
+
|
7
|
+
|
8
|
+
RSpec.describe Hglib::Repo do
|
9
|
+
|
10
|
+
let( :repo_dir ) do
|
11
|
+
Dir.mktmpdir( ['hglib', 'repodir'] )
|
12
|
+
end
|
13
|
+
|
14
|
+
let( :server ) { instance_double(Hglib::Server) }
|
15
|
+
|
16
|
+
|
17
|
+
before( :each ) do
|
18
|
+
allow( Hglib::Server ).to receive( :new ).and_return( server )
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
it "can fetch the status of the working directory" do
|
23
|
+
repo = described_class.new( repo_dir )
|
24
|
+
|
25
|
+
expect( server ).to receive( :run ).with( :status, {} ).
|
26
|
+
and_return([
|
27
|
+
"M ",
|
28
|
+
".gems\n",
|
29
|
+
"M ",
|
30
|
+
"lib/hglib/repo.rb\n",
|
31
|
+
"M ",
|
32
|
+
"lib/hglib/server.rb\n",
|
33
|
+
"? ",
|
34
|
+
"coverage/assets/0.10.2/magnify.png\n"
|
35
|
+
])
|
36
|
+
|
37
|
+
result = repo.status
|
38
|
+
|
39
|
+
expect( result ).to be_a( Hash )
|
40
|
+
expect( result ).to include(
|
41
|
+
Pathname('.gems') => 'M',
|
42
|
+
Pathname('lib/hglib/repo.rb') => 'M',
|
43
|
+
Pathname('lib/hglib/server.rb') => 'M',
|
44
|
+
Pathname('coverage/assets/0.10.2/magnify.png') => '?'
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
it "can fetch the identification of the repository's current revision" do
|
50
|
+
repo = described_class.new( repo_dir )
|
51
|
+
|
52
|
+
expect( server ).to receive( :run ).with( :id, {} ).
|
53
|
+
and_return( ["80d775fc1d2c+ qbase/qtip/repo-features.patch/tip master\n"] )
|
54
|
+
|
55
|
+
result = repo.id
|
56
|
+
|
57
|
+
expect( result ).to be_a( Hglib::Repo::Id ).and( eq '80d775fc1d2c' )
|
58
|
+
expect( result.tags ).to eq( %w[qbase qtip repo-features.patch tip] )
|
59
|
+
expect( result.bookmarks ).to eq( %w[master] )
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
it "can fetch the log of the repository" do
|
64
|
+
repo = described_class.new( repo_dir )
|
65
|
+
|
66
|
+
expect( server ).to receive( :run ).with( :log, {T: 'json', graph: false} ).
|
67
|
+
and_return([
|
68
|
+
"[",
|
69
|
+
"\n {\n \"bookmarks\": [],\n \"branch\": \"default\",\n \"date\": " +
|
70
|
+
"[1516812073, 28800],\n \"desc\": \"Make ruby-version less specific\"," +
|
71
|
+
"\n \"node\": \"81f357f730d9f22d560e4bd2790e7cf5aa5b7ec7\",\n \"parents\":" +
|
72
|
+
" [\"d6c97f99b012199d9088e85bb0940147446c6a87\"],\n \"phase\": \"public\",\n " +
|
73
|
+
" \"rev\": 1,\n \"tags\": [],\n \"user\": \"Michael Granger" +
|
74
|
+
" <ged@FaerieMUD.org>\"\n }",
|
75
|
+
",",
|
76
|
+
"\n {\n",
|
77
|
+
" \"bookmarks\": []",
|
78
|
+
",\n",
|
79
|
+
" \"branch\": \"default\"",
|
80
|
+
",\n",
|
81
|
+
" \"date\": [1516811121, 28800]",
|
82
|
+
",\n",
|
83
|
+
" \"desc\": \"Initial commit.\"",
|
84
|
+
",\n",
|
85
|
+
" \"node\": \"d6c97f99b012199d9088e85bb0940147446c6a87\"",
|
86
|
+
",\n",
|
87
|
+
" \"parents\": [\"0000000000000000000000000000000000000000\"]",
|
88
|
+
",\n",
|
89
|
+
" \"phase\": \"public\"",
|
90
|
+
",\n",
|
91
|
+
" \"rev\": 0",
|
92
|
+
",\n",
|
93
|
+
" \"tags\": []",
|
94
|
+
",\n",
|
95
|
+
" \"user\": \"Michael Granger <ged@FaerieMUD.org>\"",
|
96
|
+
"\n }",
|
97
|
+
"\n]\n"
|
98
|
+
])
|
99
|
+
|
100
|
+
result = repo.log
|
101
|
+
|
102
|
+
expect( result ).to be_an( Array ).and( all be_a(Hglib::Repo::LogEntry) )
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
@@ -0,0 +1,166 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd
|
2
|
+
|
3
|
+
require_relative '../spec_helper'
|
4
|
+
|
5
|
+
require 'tmpdir'
|
6
|
+
require 'hglib/server'
|
7
|
+
|
8
|
+
|
9
|
+
RSpec.describe Hglib::Server do
|
10
|
+
|
11
|
+
def cmdserver_message( channel, data='' )
|
12
|
+
return [ channel, data.bytesize, data ].pack( 'A*I>A*' )
|
13
|
+
end
|
14
|
+
|
15
|
+
def cmdserver_header( channel, bytes )
|
16
|
+
return [ channel, bytes ].pack( 'aI>' )
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
let( :repo_dir ) do
|
21
|
+
Dir.mktmpdir( ['hglib', 'repodir'] )
|
22
|
+
end
|
23
|
+
|
24
|
+
let( :parent_reader ) { StringIO.new }
|
25
|
+
let( :child_reader ) { instance_double(IO, close: true) }
|
26
|
+
let( :parent_writer ) { StringIO.new }
|
27
|
+
let( :child_writer ) { instance_double(IO, close: true) }
|
28
|
+
|
29
|
+
let( :hello_message ) do
|
30
|
+
cmdserver_message( 'o', "capabilities: runcommand getencoding\nencoding: UTF-8\n" )
|
31
|
+
end
|
32
|
+
let( :line_input_prompt ) do
|
33
|
+
cmdserver_header( 'L', 4096 )
|
34
|
+
end
|
35
|
+
let( :byte_input_prompt ) do
|
36
|
+
cmdserver_header( 'I', 4096 )
|
37
|
+
end
|
38
|
+
let( :result_message ) do
|
39
|
+
cmdserver_message( 'r', "done" )
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
before( :each ) do
|
44
|
+
allow( Process ).to receive( :spawn ).and_return( 1111 )
|
45
|
+
allow( Process ).to receive( :kill ).with( :TERM, 1111 )
|
46
|
+
allow( Process ).to receive( :wait ).with( 1111, Process::WNOHANG )
|
47
|
+
|
48
|
+
allow( IO ).to receive( :pipe ).and_return(
|
49
|
+
[parent_reader, child_writer],
|
50
|
+
[child_reader, parent_writer]
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
describe "option-mangling" do
|
56
|
+
|
57
|
+
it "mangles single-letter keys into one-hyphen options" do
|
58
|
+
result = described_class.mangle_options( C: true, p: true, g: true )
|
59
|
+
expect( result ).to eq( %w[-C -p -g] )
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
it "mangles multi-letter keys into two-hyphen options" do
|
64
|
+
result = described_class.mangle_options( copies: true, patch: true )
|
65
|
+
expect( result ).to eq( %w[--copies --patch] )
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
it "drops single-letter keys with falsey values" do
|
70
|
+
result = described_class.mangle_options( g: false, p: nil )
|
71
|
+
expect( result ).to eq( [] )
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
it "negates multi-letter keys with falsey values" do
|
76
|
+
result = described_class.mangle_options( graph: false, patch: nil )
|
77
|
+
expect( result ).to eq( %w[--no-graph --no-patch] )
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
it "appends String values onto options with a space for single-letter keys" do
|
82
|
+
result = described_class.mangle_options( P: '165' )
|
83
|
+
expect( result ).to eq( %w[-P 165] )
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
it "appends String values onto options with an equal for multi-letter keys" do
|
88
|
+
result = described_class.mangle_options( prune: '165' )
|
89
|
+
expect( result ).to eq( %w[--prune=165] )
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
it "knows whether or not it has been started" do
|
96
|
+
parent_reader.write( hello_message )
|
97
|
+
parent_reader.rewind
|
98
|
+
|
99
|
+
server = described_class.new( repo_dir )
|
100
|
+
|
101
|
+
expect( server ).to_not be_started
|
102
|
+
server.start
|
103
|
+
expect( server ).to be_started
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
it "calls the on_line_input callback when the command server asks for line input" do
|
108
|
+
parent_reader.write( hello_message )
|
109
|
+
parent_reader.write( line_input_prompt )
|
110
|
+
parent_reader.write( result_message )
|
111
|
+
parent_reader.rewind
|
112
|
+
|
113
|
+
server = described_class.new( repo_dir )
|
114
|
+
server.on_line_input do |max_bytes|
|
115
|
+
"a line of input no more than #{max_bytes} long"
|
116
|
+
end
|
117
|
+
server.run( :record )
|
118
|
+
|
119
|
+
expect( parent_writer.string ).to include(
|
120
|
+
"runcommand\n",
|
121
|
+
"record",
|
122
|
+
"a line of input no more than 4096 long\n"
|
123
|
+
)
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
it "calls the on_byte_input callback when the command server asks for byte input" do
|
128
|
+
parent_reader.write( hello_message )
|
129
|
+
parent_reader.write( byte_input_prompt )
|
130
|
+
parent_reader.write( result_message )
|
131
|
+
parent_reader.rewind
|
132
|
+
|
133
|
+
server = described_class.new( repo_dir )
|
134
|
+
server.on_byte_input do |max_bytes|
|
135
|
+
"bytes of input no more than #{max_bytes} long"
|
136
|
+
end
|
137
|
+
server.run( :import, '-' )
|
138
|
+
|
139
|
+
expect( parent_writer.string ).to include(
|
140
|
+
"runcommand\n",
|
141
|
+
"import\0-",
|
142
|
+
"bytes of input no more than 4096 long"
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
it "can be stopped manually" do
|
148
|
+
parent_reader.write( hello_message )
|
149
|
+
parent_reader.rewind
|
150
|
+
|
151
|
+
server = described_class.new( repo_dir )
|
152
|
+
server.start
|
153
|
+
|
154
|
+
server.stop
|
155
|
+
expect( parent_writer.string ).to be_empty
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
it "doesn't error when told to stop if it hasn't been started" do
|
160
|
+
server = described_class.new( repo_dir )
|
161
|
+
expect( server.stop ).to be_falsey
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
end
|
166
|
+
|