percy-client 1.12.0 → 1.13.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.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/lib/percy.rb +9 -2
- data/lib/percy/client.rb +3 -1
- data/lib/percy/client/builds.rb +5 -0
- data/lib/percy/client/connection.rb +49 -2
- data/lib/percy/client/version.rb +1 -1
- data/spec/lib/percy/client/builds_spec.rb +1 -0
- data/spec/lib/percy/client/connection_spec.rb +103 -74
- data/spec/lib/percy/client/environment_spec.rb +45 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/support/vcr_setup.rb +4 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b94954861b98e83a57b9320d28682b66a66e49ee
|
4
|
+
data.tar.gz: b6b9a044bab771d3f3fa37ab4922a865c3cc465a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c70290afed751c1612eb3dec8024511c4bc5cb127f3919f84eb1ccec87e30ad2df515153d7c1d0ed4be78423f026ca021847d43bc8a21b20b62f9fa9278573a
|
7
|
+
data.tar.gz: 0637dcf07a4c97a5f8904bb4653ce9d6bfac3aa8f576c39a550a35a1cc0fd5716a84d074f62bef4980d67aa13b4b4fe9492dd9ee7fbf7349edd4228ede60c8da
|
data/Gemfile
CHANGED
data/lib/percy.rb
CHANGED
@@ -15,8 +15,15 @@ module Percy
|
|
15
15
|
# API client based on configured options.
|
16
16
|
#
|
17
17
|
# @return [Percy::Client] API client.
|
18
|
-
def self.client
|
19
|
-
|
18
|
+
def self.client(options = {})
|
19
|
+
if !defined?(@client) || !@client
|
20
|
+
@client = Percy::Client.new(
|
21
|
+
config: config,
|
22
|
+
client_info: options[:client_info],
|
23
|
+
environment_info: options[:environment_info],
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
20
27
|
@client
|
21
28
|
end
|
22
29
|
|
data/lib/percy/client.rb
CHANGED
@@ -45,10 +45,12 @@ module Percy
|
|
45
45
|
class BadGatewayError < ServerError; end # 502.
|
46
46
|
class ServiceUnavailableError < ServerError; end # 503.
|
47
47
|
|
48
|
-
attr_reader :config
|
48
|
+
attr_reader :config, :client_info, :environment_info
|
49
49
|
|
50
50
|
def initialize(options = {})
|
51
51
|
@config = options[:config] || Percy::Config.new
|
52
|
+
@client_info = options[:client_info]
|
53
|
+
@environment_info = options[:environment_info]
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
data/lib/percy/client/builds.rb
CHANGED
@@ -14,6 +14,7 @@ module Percy
|
|
14
14
|
# Only pass parallelism data if it all exists and there is more than 1 shard.
|
15
15
|
in_parallel_environment = parallel_nonce && \
|
16
16
|
parallel_total_shards && parallel_total_shards > 1
|
17
|
+
|
17
18
|
unless in_parallel_environment
|
18
19
|
parallel_nonce = nil
|
19
20
|
parallel_total_shards = nil
|
@@ -44,6 +45,7 @@ module Percy
|
|
44
45
|
raise ArgumentError,
|
45
46
|
'resources argument must be an iterable of Percy::Client::Resource objects'
|
46
47
|
end
|
48
|
+
|
47
49
|
relationships_data = {
|
48
50
|
'relationships' => {
|
49
51
|
'resources' => {
|
@@ -51,16 +53,19 @@ module Percy
|
|
51
53
|
},
|
52
54
|
},
|
53
55
|
}
|
56
|
+
|
54
57
|
data['data'].merge!(relationships_data)
|
55
58
|
end
|
56
59
|
|
57
60
|
build_data = post("#{config.api_url}/repos/#{repo}/builds/", data)
|
58
61
|
Percy.logger.debug { "Build #{build_data['data']['id']} created" }
|
62
|
+
|
59
63
|
parallelism_msg = if parallel_total_shards
|
60
64
|
"#{parallel_total_shards} shards detected (nonce: #{parallel_nonce.inspect})"
|
61
65
|
else
|
62
66
|
'not detected'
|
63
67
|
end
|
68
|
+
|
64
69
|
Percy.logger.debug { "Parallel test environment: #{parallelism_msg}" }
|
65
70
|
build_data
|
66
71
|
end
|
@@ -20,6 +20,7 @@ module Percy
|
|
20
20
|
|
21
21
|
def on_complete(env)
|
22
22
|
error_class = nil
|
23
|
+
|
23
24
|
case env[:status]
|
24
25
|
when 400
|
25
26
|
error_class = Percy::Client::BadRequestError
|
@@ -42,7 +43,9 @@ module Percy
|
|
42
43
|
when CLIENT_ERROR_STATUS_RANGE # Catchall.
|
43
44
|
error_class = Percy::Client::HttpError
|
44
45
|
end
|
46
|
+
|
45
47
|
return unless error_class
|
48
|
+
|
46
49
|
raise error_class.new(
|
47
50
|
env.status, env.method.upcase, env.url, env.body,
|
48
51
|
"Got #{env.status} (#{env.method.upcase} #{env.url}):\n#{env.body}",
|
@@ -52,23 +55,27 @@ module Percy
|
|
52
55
|
|
53
56
|
def connection
|
54
57
|
return @connection if defined?(@connection)
|
58
|
+
|
55
59
|
parsed_uri = URI.parse(config.api_url)
|
56
60
|
base_url = "#{parsed_uri.scheme}://#{parsed_uri.host}:#{parsed_uri.port}"
|
61
|
+
|
57
62
|
@connection = Faraday.new(url: base_url) do |faraday|
|
58
63
|
faraday.request :token_auth, config.access_token if config.access_token
|
59
64
|
|
60
65
|
faraday.use Percy::Client::Connection::NoCookiesHTTPClientAdapter
|
61
66
|
faraday.use Percy::Client::Connection::NiceErrorMiddleware
|
62
67
|
end
|
68
|
+
|
63
69
|
@connection
|
64
70
|
end
|
65
71
|
|
66
72
|
def get(path, options = {})
|
67
73
|
retries = options[:retries] || 3
|
74
|
+
|
68
75
|
begin
|
69
76
|
response = connection.get do |request|
|
70
77
|
request.url(path)
|
71
|
-
request.headers
|
78
|
+
request.headers.merge! _headers
|
72
79
|
end
|
73
80
|
rescue Faraday::TimeoutError
|
74
81
|
raise Percy::Client::TimeoutError
|
@@ -87,10 +94,11 @@ module Percy
|
|
87
94
|
|
88
95
|
def post(path, data, options = {})
|
89
96
|
retries = options[:retries] || 3
|
97
|
+
|
90
98
|
begin
|
91
99
|
response = connection.post do |request|
|
92
100
|
request.url(path)
|
93
|
-
request.headers
|
101
|
+
request.headers.merge! _headers
|
94
102
|
request.body = data.to_json
|
95
103
|
end
|
96
104
|
rescue Faraday::TimeoutError
|
@@ -102,10 +110,49 @@ module Percy
|
|
102
110
|
sleep(rand(1..3))
|
103
111
|
retry
|
104
112
|
end
|
113
|
+
|
105
114
|
raise e
|
106
115
|
end
|
116
|
+
|
107
117
|
JSON.parse(response.body)
|
108
118
|
end
|
119
|
+
|
120
|
+
def _headers
|
121
|
+
{
|
122
|
+
'Content-Type' => 'application/vnd.api+json',
|
123
|
+
'User-Agent' => _user_agent,
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
def _user_agent
|
128
|
+
@_user_agent ||= begin
|
129
|
+
client = [
|
130
|
+
"Percy/#{_api_version}",
|
131
|
+
client_info,
|
132
|
+
"percy-client/#{VERSION}",
|
133
|
+
].compact.join(' ')
|
134
|
+
|
135
|
+
environment = [
|
136
|
+
environment_info,
|
137
|
+
"ruby/#{_ruby_version}",
|
138
|
+
Percy::Client::Environment.current_ci,
|
139
|
+
].compact.join('; ')
|
140
|
+
|
141
|
+
"#{client} (#{environment})"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def _reset_user_agent
|
146
|
+
@_user_agent = nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def _api_version
|
150
|
+
config.api_url.match(/\w+$/).to_s
|
151
|
+
end
|
152
|
+
|
153
|
+
def _ruby_version
|
154
|
+
"#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
|
155
|
+
end
|
109
156
|
end
|
110
157
|
end
|
111
158
|
end
|
data/lib/percy/client/version.rb
CHANGED
@@ -55,6 +55,7 @@ RSpec.describe Percy::Client::Builds, :vcr do
|
|
55
55
|
expect(build['data']['relationships']['missing-resources']['data']).to be
|
56
56
|
expect(build['data']['relationships']['missing-resources']['data'].length).to eq(1)
|
57
57
|
end
|
58
|
+
|
58
59
|
context 'with env vars configured' do
|
59
60
|
before(:each) do
|
60
61
|
ENV['PERCY_BRANCH'] = 'foo-branch'
|
@@ -1,114 +1,143 @@
|
|
1
1
|
RSpec.describe Percy::Client::Connection do
|
2
|
+
let(:user_agent) do
|
3
|
+
"Percy/#{api_version} #{client_info} percy-client/#{Percy::Client::VERSION} "\
|
4
|
+
"(#{environment_info}; ruby/#{ruby_version}; #{ci_name})"
|
5
|
+
end
|
6
|
+
let(:content_type) { 'application/vnd.api+json' }
|
7
|
+
let(:api_version) { 'v1' }
|
8
|
+
let(:ruby_version) { '2.2.6p396' }
|
9
|
+
let(:client_info) { 'percy-capybara/3.1.0' }
|
10
|
+
let(:environment_info) { 'Rails/4.2.1' }
|
11
|
+
let(:ci_name) { 'buildkite' }
|
12
|
+
let(:uri) { "#{Percy.config.api_url}/test" }
|
13
|
+
|
2
14
|
describe '#connection' do
|
3
15
|
it 'disables cookies on faraday httpclient adapter' do
|
4
16
|
expect(Percy.client.connection.builder.app.client.cookie_manager).to be_nil
|
5
17
|
end
|
6
18
|
end
|
19
|
+
|
20
|
+
shared_examples_for 'a connection that sets headers with HTTP method' do |http_method|
|
21
|
+
it 'sets headers' do
|
22
|
+
stub_request(http_method, uri)
|
23
|
+
.with(headers: {'User-Agent' => user_agent, 'Content-Type' => content_type})
|
24
|
+
.to_return(body: {foo: true}.to_json)
|
25
|
+
|
26
|
+
expect(Percy.client).to receive(:_api_version).and_return(api_version)
|
27
|
+
expect(Percy.client).to receive(:_ruby_version).and_return(ruby_version)
|
28
|
+
|
29
|
+
expect(Percy.client).to receive(:client_info).and_return(client_info)
|
30
|
+
expect(Percy.client).to receive(:environment_info).and_return(environment_info)
|
31
|
+
|
32
|
+
expect(Percy::Client::Environment).to receive(:current_ci).and_return(ci_name)
|
33
|
+
|
34
|
+
expect(response).to eq('foo' => true)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
7
38
|
describe '#get' do
|
39
|
+
subject(:response) { Percy.client.get(uri) }
|
40
|
+
|
41
|
+
it_behaves_like 'a connection that sets headers with HTTP method', :get
|
42
|
+
|
8
43
|
it 'performs a GET request to the api_url and parses response' do
|
9
|
-
stub_request(:get,
|
10
|
-
|
11
|
-
expect(data).to eq('foo' => true)
|
44
|
+
stub_request(:get, uri).to_return(body: {foo: true}.to_json)
|
45
|
+
expect(response).to eq('foo' => true)
|
12
46
|
end
|
47
|
+
|
13
48
|
it 'raises customized timeout errors' do
|
14
|
-
stub_request(:get,
|
15
|
-
expect
|
16
|
-
Percy.client.get("#{Percy.config.api_url}/test")
|
17
|
-
end.to raise_error(Percy::Client::TimeoutError)
|
49
|
+
stub_request(:get, uri).to_raise(Faraday::TimeoutError)
|
50
|
+
expect { response }.to raise_error(Percy::Client::TimeoutError)
|
18
51
|
end
|
52
|
+
|
19
53
|
it 'raises customized connection failed errors' do
|
20
|
-
stub_request(:get,
|
21
|
-
expect
|
22
|
-
Percy.client.get("#{Percy.config.api_url}/test")
|
23
|
-
end.to raise_error(Percy::Client::ConnectionFailed)
|
54
|
+
stub_request(:get, uri).to_raise(Faraday::ConnectionFailed)
|
55
|
+
expect { response }.to raise_error(Percy::Client::ConnectionFailed)
|
24
56
|
end
|
57
|
+
|
25
58
|
it 'retries on 502 errors' do
|
26
|
-
stub_request(:get,
|
59
|
+
stub_request(:get, uri)
|
27
60
|
.to_return(body: {foo: true}.to_json, status: 502)
|
28
61
|
.then.to_return(body: {foo: true}.to_json, status: 200)
|
29
62
|
|
30
|
-
|
31
|
-
expect(data).to eq('foo' => true)
|
63
|
+
expect(response).to eq('foo' => true)
|
32
64
|
end
|
65
|
+
|
33
66
|
it 'raises error after 3 retries' do
|
34
|
-
stub_request(:get,
|
67
|
+
stub_request(:get, uri)
|
35
68
|
.to_return(body: {foo: true}.to_json, status: 502).times(3)
|
36
|
-
|
37
|
-
|
38
|
-
end.to raise_error(Percy::Client::BadGatewayError)
|
69
|
+
|
70
|
+
expect { response }.to raise_error(Percy::Client::BadGatewayError)
|
39
71
|
end
|
40
72
|
end
|
73
|
+
|
41
74
|
describe '#post' do
|
75
|
+
subject(:response) { Percy.client.post(uri, {}) }
|
76
|
+
|
77
|
+
it_behaves_like 'a connection that sets headers with HTTP method', :post
|
78
|
+
|
42
79
|
it 'performs a POST request to the api_url and parses response' do
|
43
|
-
stub_request(:post,
|
44
|
-
|
45
|
-
|
80
|
+
stub_request(:post, uri).to_return(body: {foo: true}.to_json)
|
81
|
+
expect(response).to eq('foo' => true)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'passes through arguments' do
|
85
|
+
stub_request(:post, uri)
|
86
|
+
.with(headers: {'User-Agent' => user_agent, 'Content-Type' => content_type})
|
87
|
+
.to_return(body: {foo: true}.to_json)
|
88
|
+
|
89
|
+
expect(Percy.client).to receive(:_user_agent).and_return(user_agent)
|
90
|
+
expect(response).to eq('foo' => true)
|
46
91
|
end
|
92
|
+
|
47
93
|
it 'raises customized timeout errors' do
|
48
|
-
stub_request(:post,
|
49
|
-
expect
|
50
|
-
Percy.client.post("#{Percy.config.api_url}/test", {})
|
51
|
-
end.to raise_error(Percy::Client::TimeoutError)
|
94
|
+
stub_request(:post, uri).to_raise(Faraday::TimeoutError)
|
95
|
+
expect { response }.to raise_error(Percy::Client::TimeoutError)
|
52
96
|
end
|
97
|
+
|
53
98
|
it 'raises customized connection failed errors' do
|
54
|
-
stub_request(:post,
|
55
|
-
expect
|
56
|
-
Percy.client.post("#{Percy.config.api_url}/test", {})
|
57
|
-
end.to raise_error(Percy::Client::ConnectionFailed)
|
99
|
+
stub_request(:post, uri).to_raise(Faraday::ConnectionFailed)
|
100
|
+
expect { response }.to raise_error(Percy::Client::ConnectionFailed)
|
58
101
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
.
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
Percy.client.post("#{Percy.config.api_url}/test", {}, retries: 0)
|
84
|
-
end.to raise_error(Percy::Client::NotFoundError)
|
85
|
-
expect do
|
86
|
-
Percy.client.post("#{Percy.config.api_url}/test", {}, retries: 0)
|
87
|
-
end.to raise_error(Percy::Client::ConflictError)
|
88
|
-
expect do
|
89
|
-
Percy.client.post("#{Percy.config.api_url}/test", {}, retries: 0)
|
90
|
-
end.to raise_error(Percy::Client::InternalServerError)
|
91
|
-
expect do
|
92
|
-
Percy.client.post("#{Percy.config.api_url}/test", {}, retries: 0)
|
93
|
-
end.to raise_error(Percy::Client::BadGatewayError)
|
94
|
-
expect do
|
95
|
-
Percy.client.post("#{Percy.config.api_url}/test", {}, retries: 0)
|
96
|
-
end.to raise_error(Percy::Client::ServiceUnavailableError)
|
102
|
+
|
103
|
+
shared_examples_for 'HTTP status raises custom error class' do |http_status, error_class|
|
104
|
+
subject(:request) { Percy.client.post(uri, {}, retries: 0) }
|
105
|
+
|
106
|
+
it 'raises custom error classes for some HTTP errors' do
|
107
|
+
stub_request(:post, uri).to_return(body: {foo: true}.to_json, status: http_status.to_i)
|
108
|
+
expect { request }.to raise_error(error_class)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
http_errors = {
|
113
|
+
'400' => Percy::Client::BadRequestError,
|
114
|
+
'401' => Percy::Client::UnauthorizedError,
|
115
|
+
'402' => Percy::Client::PaymentRequiredError,
|
116
|
+
'403' => Percy::Client::ForbiddenError,
|
117
|
+
'404' => Percy::Client::NotFoundError,
|
118
|
+
'409' => Percy::Client::ConflictError,
|
119
|
+
'500' => Percy::Client::InternalServerError,
|
120
|
+
'502' => Percy::Client::BadGatewayError,
|
121
|
+
'503' => Percy::Client::ServiceUnavailableError,
|
122
|
+
}
|
123
|
+
|
124
|
+
http_errors.each do |http_status, error_class|
|
125
|
+
include_examples 'HTTP status raises custom error class', http_status, error_class
|
97
126
|
end
|
127
|
+
|
98
128
|
it 'retries on server errors' do
|
99
|
-
stub_request(:post,
|
129
|
+
stub_request(:post, uri)
|
100
130
|
.to_return(body: {foo: true}.to_json, status: 500)
|
101
131
|
.then.to_return(body: {foo: true}.to_json, status: 200)
|
102
132
|
|
103
|
-
|
104
|
-
expect(data).to eq('foo' => true)
|
133
|
+
expect(response).to eq('foo' => true)
|
105
134
|
end
|
135
|
+
|
106
136
|
it 'raises error after 3 retries' do
|
107
|
-
stub_request(:post,
|
137
|
+
stub_request(:post, uri)
|
108
138
|
.to_return(body: {foo: true}.to_json, status: 502).times(3)
|
109
|
-
|
110
|
-
|
111
|
-
end.to raise_error(Percy::Client::BadGatewayError)
|
139
|
+
|
140
|
+
expect { response }.to raise_error(Percy::Client::BadGatewayError)
|
112
141
|
end
|
113
142
|
end
|
114
143
|
end
|
@@ -88,6 +88,7 @@ RSpec.describe Percy::Client::Environment do
|
|
88
88
|
}
|
89
89
|
clear_env_vars
|
90
90
|
end
|
91
|
+
|
91
92
|
after(:each) do
|
92
93
|
clear_env_vars
|
93
94
|
ENV['TRAVIS_BUILD_ID'] = @original_env['TRAVIS_BUILD_ID']
|
@@ -106,41 +107,50 @@ RSpec.describe Percy::Client::Environment do
|
|
106
107
|
expect(Percy::Client::Environment.current_ci).to be_nil
|
107
108
|
end
|
108
109
|
end
|
110
|
+
|
109
111
|
describe '#branch' do
|
110
112
|
it 'returns master if not in a git repo' do
|
111
113
|
expect(Percy::Client::Environment).to receive(:_raw_branch_output).and_return('')
|
112
114
|
expect(Percy::Client::Environment.branch).to eq('master')
|
113
115
|
end
|
116
|
+
|
114
117
|
it 'reads from the current local repo' do
|
115
118
|
expect(Percy::Client::Environment.branch).to_not be_empty
|
116
119
|
end
|
120
|
+
|
117
121
|
it 'can be overridden with PERCY_BRANCH' do
|
118
122
|
ENV['PERCY_BRANCH'] = 'test-branch'
|
119
123
|
expect(Percy::Client::Environment.branch).to eq('test-branch')
|
120
124
|
end
|
121
125
|
end
|
126
|
+
|
122
127
|
describe '#target_branch' do
|
123
128
|
it 'returns nil if unset' do
|
124
129
|
expect(Percy::Client::Environment.target_branch).to be_nil
|
125
130
|
end
|
131
|
+
|
126
132
|
it 'can be set with PERCY_TARGET_BRANCH' do
|
127
133
|
ENV['PERCY_TARGET_BRANCH'] = 'test-target-branch'
|
128
134
|
expect(Percy::Client::Environment.target_branch).to eq('test-target-branch')
|
129
135
|
end
|
130
136
|
end
|
137
|
+
|
131
138
|
describe '#_commit_sha' do
|
132
139
|
it 'returns nil if no environment info can be found' do
|
133
140
|
expect(Percy::Client::Environment._commit_sha).to be_nil
|
134
141
|
end
|
142
|
+
|
135
143
|
it 'can be overridden with PERCY_COMMIT' do
|
136
144
|
ENV['PERCY_COMMIT'] = 'test-commit'
|
137
145
|
expect(Percy::Client::Environment._commit_sha).to eq('test-commit')
|
138
146
|
end
|
139
147
|
end
|
148
|
+
|
140
149
|
describe '#pull_request_number' do
|
141
150
|
it 'returns nil if no CI environment' do
|
142
151
|
expect(Percy::Client::Environment.pull_request_number).to be_nil
|
143
152
|
end
|
153
|
+
|
144
154
|
it 'can be overridden with PERCY_PULL_REQUEST' do
|
145
155
|
ENV['PERCY_PULL_REQUEST'] = '123'
|
146
156
|
ENV['TRAVIS_BUILD_ID'] = '1234'
|
@@ -148,18 +158,22 @@ RSpec.describe Percy::Client::Environment do
|
|
148
158
|
expect(Percy::Client::Environment.pull_request_number).to eq('123')
|
149
159
|
end
|
150
160
|
end
|
161
|
+
|
151
162
|
describe '#repo' do
|
152
163
|
it 'returns the current local repo name' do
|
153
164
|
expect(Percy::Client::Environment.repo).to eq('percy/percy-client')
|
154
165
|
end
|
166
|
+
|
155
167
|
it 'can be overridden with PERCY_PROJECT' do
|
156
168
|
ENV['PERCY_PROJECT'] = 'percy/slug'
|
157
169
|
expect(Percy::Client::Environment.repo).to eq('percy/slug')
|
158
170
|
end
|
171
|
+
|
159
172
|
it 'can be overridden with PERCY_REPO_SLUG (deprecated)' do
|
160
173
|
ENV['PERCY_REPO_SLUG'] = 'percy/slug'
|
161
174
|
expect(Percy::Client::Environment.repo).to eq('percy/slug')
|
162
175
|
end
|
176
|
+
|
163
177
|
it 'handles git ssh urls' do
|
164
178
|
expect(Percy::Client::Environment).to receive(:_get_origin_url)
|
165
179
|
.once.and_return('git@github.com:org-name/repo-name.git')
|
@@ -173,6 +187,7 @@ RSpec.describe Percy::Client::Environment do
|
|
173
187
|
.once.and_return('git@custom-local-hostname:org-name/repo-name.org')
|
174
188
|
expect(Percy::Client::Environment.repo).to eq('org-name/repo-name.org')
|
175
189
|
end
|
190
|
+
|
176
191
|
it 'handles git https urls' do
|
177
192
|
expect(Percy::Client::Environment).to receive(:_get_origin_url)
|
178
193
|
.once.and_return('https://github.com/org-name/repo-name.git')
|
@@ -186,6 +201,7 @@ RSpec.describe Percy::Client::Environment do
|
|
186
201
|
.once.and_return("https://github.com/org-name/repo-name.org\n")
|
187
202
|
expect(Percy::Client::Environment.repo).to eq('org-name/repo-name.org')
|
188
203
|
end
|
204
|
+
|
189
205
|
it 'errors if unable to parse local repo name' do
|
190
206
|
expect(Percy::Client::Environment).to receive(:_get_origin_url).once.and_return('foo')
|
191
207
|
expect { Percy::Client::Environment.repo }.to raise_error(
|
@@ -193,25 +209,38 @@ RSpec.describe Percy::Client::Environment do
|
|
193
209
|
)
|
194
210
|
end
|
195
211
|
end
|
212
|
+
|
196
213
|
describe '#parallel_nonce' do
|
197
214
|
it 'returns nil' do
|
198
215
|
expect(Percy::Client::Environment.parallel_nonce).to be_nil
|
199
216
|
end
|
217
|
+
|
200
218
|
it 'can be set with environment var' do
|
201
219
|
ENV['PERCY_PARALLEL_NONCE'] = 'nonce'
|
202
220
|
expect(Percy::Client::Environment.parallel_nonce).to eq('nonce')
|
203
221
|
end
|
204
222
|
end
|
223
|
+
|
205
224
|
describe '#parallel_total_shards' do
|
206
225
|
it 'returns nil' do
|
207
226
|
expect(Percy::Client::Environment.parallel_nonce).to be_nil
|
208
227
|
end
|
228
|
+
|
209
229
|
it 'can be set with environment var' do
|
210
230
|
ENV['PERCY_PARALLEL_TOTAL'] = '3'
|
211
231
|
expect(Percy::Client::Environment.parallel_total_shards).to eq(3)
|
212
232
|
end
|
213
233
|
end
|
214
234
|
end
|
235
|
+
|
236
|
+
RSpec.shared_examples 'an environment user agent that includes CI' do |ci_name|
|
237
|
+
it 'returns a user_agent that includes CI name' do
|
238
|
+
user_agent = "Percy/v1 percy-client/#{Percy::Client::VERSION} "\
|
239
|
+
"(ruby/#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}; #{ci_name})"
|
240
|
+
expect(Percy::Client::Environment.user_agent).to eq user_agent
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
215
244
|
context 'in Jenkins CI' do
|
216
245
|
before(:each) do
|
217
246
|
ENV['JENKINS_URL'] = 'http://localhost:8080/'
|
@@ -228,6 +257,7 @@ RSpec.describe Percy::Client::Environment do
|
|
228
257
|
expect(Percy::Client::Environment.repo).to eq('percy/percy-client')
|
229
258
|
end
|
230
259
|
end
|
260
|
+
|
231
261
|
context 'in Travis CI' do
|
232
262
|
before(:each) do
|
233
263
|
ENV['TRAVIS_BUILD_ID'] = '1234'
|
@@ -250,28 +280,33 @@ RSpec.describe Percy::Client::Environment do
|
|
250
280
|
expect(Percy::Client::Environment.parallel_nonce).to eq('build-number')
|
251
281
|
expect(Percy::Client::Environment.parallel_total_shards).to be_nil
|
252
282
|
end
|
283
|
+
|
253
284
|
context 'Pull Request build' do
|
254
285
|
before(:each) do
|
255
286
|
ENV['TRAVIS_PULL_REQUEST'] = '256'
|
256
287
|
ENV['TRAVIS_PULL_REQUEST_BRANCH'] = 'travis-pr-branch'
|
257
288
|
ENV['TRAVIS_PULL_REQUEST_SHA'] = 'travis-pr-head-commit-sha'
|
258
289
|
end
|
290
|
+
|
259
291
|
it 'has the correct properties' do
|
260
292
|
expect(Percy::Client::Environment.branch).to eq('travis-pr-branch')
|
261
293
|
expect(Percy::Client::Environment._commit_sha).to eq('travis-pr-head-commit-sha')
|
262
294
|
expect(Percy::Client::Environment.pull_request_number).to eq('256')
|
263
295
|
end
|
264
296
|
end
|
297
|
+
|
265
298
|
context 'parallel build' do
|
266
299
|
before(:each) do
|
267
300
|
ENV['CI_NODE_TOTAL'] = '3'
|
268
301
|
end
|
302
|
+
|
269
303
|
it 'has the correct properties' do
|
270
304
|
expect(Percy::Client::Environment.parallel_nonce).to eq('build-number')
|
271
305
|
expect(Percy::Client::Environment.parallel_total_shards).to eq(3)
|
272
306
|
end
|
273
307
|
end
|
274
308
|
end
|
309
|
+
|
275
310
|
context 'in Circle CI' do
|
276
311
|
before(:each) do
|
277
312
|
ENV['CIRCLECI'] = 'true'
|
@@ -293,16 +328,19 @@ RSpec.describe Percy::Client::Environment do
|
|
293
328
|
expect(Percy::Client::Environment.parallel_nonce).to eq('build-number')
|
294
329
|
expect(Percy::Client::Environment.parallel_total_shards).to be_nil
|
295
330
|
end
|
331
|
+
|
296
332
|
context 'parallel build' do
|
297
333
|
before(:each) do
|
298
334
|
ENV['CIRCLE_NODE_TOTAL'] = '3'
|
299
335
|
end
|
336
|
+
|
300
337
|
it 'has the correct properties' do
|
301
338
|
expect(Percy::Client::Environment.parallel_nonce).to eq('build-number')
|
302
339
|
expect(Percy::Client::Environment.parallel_total_shards).to eq(3)
|
303
340
|
end
|
304
341
|
end
|
305
342
|
end
|
343
|
+
|
306
344
|
context 'in Codeship' do
|
307
345
|
before(:each) do
|
308
346
|
ENV['CI_NAME'] = 'codeship'
|
@@ -322,16 +360,19 @@ RSpec.describe Percy::Client::Environment do
|
|
322
360
|
expect(Percy::Client::Environment.parallel_nonce).to eq('codeship-build-number')
|
323
361
|
expect(Percy::Client::Environment.parallel_total_shards).to be_nil
|
324
362
|
end
|
363
|
+
|
325
364
|
context 'parallel build' do
|
326
365
|
before(:each) do
|
327
366
|
ENV['CI_NODE_TOTAL'] = '3'
|
328
367
|
end
|
368
|
+
|
329
369
|
it 'has the correct properties' do
|
330
370
|
expect(Percy::Client::Environment.parallel_nonce).to eq('codeship-build-number')
|
331
371
|
expect(Percy::Client::Environment.parallel_total_shards).to eq(3)
|
332
372
|
end
|
333
373
|
end
|
334
374
|
end
|
375
|
+
|
335
376
|
context 'in Drone' do
|
336
377
|
before(:each) do
|
337
378
|
ENV['DRONE'] = 'true'
|
@@ -348,6 +389,7 @@ RSpec.describe Percy::Client::Environment do
|
|
348
389
|
expect(Percy::Client::Environment.repo).to eq('percy/percy-client')
|
349
390
|
end
|
350
391
|
end
|
392
|
+
|
351
393
|
context 'in Semaphore CI' do
|
352
394
|
before(:each) do
|
353
395
|
ENV['SEMAPHORE'] = 'true'
|
@@ -368,16 +410,19 @@ RSpec.describe Percy::Client::Environment do
|
|
368
410
|
expect(Percy::Client::Environment.parallel_nonce).to eq('semaphore-build-number')
|
369
411
|
expect(Percy::Client::Environment.parallel_total_shards).to be_nil
|
370
412
|
end
|
413
|
+
|
371
414
|
context 'parallel build' do
|
372
415
|
before(:each) do
|
373
416
|
ENV['SEMAPHORE_THREAD_COUNT'] = '3'
|
374
417
|
end
|
418
|
+
|
375
419
|
it 'has the correct properties' do
|
376
420
|
expect(Percy::Client::Environment.parallel_nonce).to eq('semaphore-build-number')
|
377
421
|
expect(Percy::Client::Environment.parallel_total_shards).to eq(3)
|
378
422
|
end
|
379
423
|
end
|
380
424
|
end
|
425
|
+
|
381
426
|
context 'in Buildkite' do
|
382
427
|
before(:each) do
|
383
428
|
ENV['BUILDKITE'] = 'true'
|
data/spec/spec_helper.rb
CHANGED
@@ -28,4 +28,10 @@ RSpec.configure do |config|
|
|
28
28
|
# test failures related to randomization by passing the same `--seed` value
|
29
29
|
# as the one that triggered the failure.
|
30
30
|
Kernel.srand config.seed
|
31
|
+
|
32
|
+
config.after(:each) do |_example|
|
33
|
+
# After each run, clear the memoized `_user_agent` property to avoid polluting
|
34
|
+
# other tests with the incorrect values.
|
35
|
+
Percy.client._reset_user_agent
|
36
|
+
end
|
31
37
|
end
|
data/spec/support/vcr_setup.rb
CHANGED
@@ -5,6 +5,10 @@ VCR.configure do |c|
|
|
5
5
|
c.cassette_library_dir = 'spec/cassettes'
|
6
6
|
c.hook_into :webmock
|
7
7
|
|
8
|
+
# Uncomment this to get VCR logger debugging.
|
9
|
+
# Run: `rspec spec vcr.log` to get debugging output to vcr.log
|
10
|
+
# c.debug_logger = File.open(ARGV[1], 'w')
|
11
|
+
|
8
12
|
c.default_cassette_options = {
|
9
13
|
record: ENV['RECORD'] ? :new_episodes : :none,
|
10
14
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: percy-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Perceptual Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -189,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
189
|
version: '0'
|
190
190
|
requirements: []
|
191
191
|
rubyforge_project:
|
192
|
-
rubygems_version: 2.
|
192
|
+
rubygems_version: 2.4.5.2
|
193
193
|
signing_key:
|
194
194
|
specification_version: 4
|
195
195
|
summary: Percy::Client
|