ezid-client 1.5.0 → 1.9.0.rc1
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 +5 -5
- data/.github/workflows/ruby.yml +35 -0
- data/README.md +59 -13
- data/Rakefile +6 -6
- data/VERSION +1 -1
- data/ezid-client.gemspec +5 -3
- data/lib/ezid/batch.rb +42 -0
- data/lib/ezid/batch_download.rb +35 -21
- data/lib/ezid/client.rb +11 -10
- data/lib/ezid/configuration.rb +11 -4
- data/lib/ezid/error.rb +2 -0
- data/lib/ezid/identifier.rb +57 -20
- data/lib/ezid/metadata.rb +11 -1
- data/lib/ezid/metadata_transforms/datacite.rb +72 -0
- data/lib/ezid/requests/request.rb +22 -9
- data/lib/ezid/responses/response.rb +13 -0
- data/spec/fixtures/anvl_batch.txt +39 -0
- data/spec/fixtures/datacite_xml/empty.xml +1 -0
- data/spec/fixtures/datacite_xml/populated.xml +1 -0
- data/spec/integration/batch_download_spec.rb +21 -0
- data/spec/integration/client_spec.rb +1 -1
- data/spec/integration/identifier_spec.rb +3 -2
- data/spec/spec_helper.rb +4 -2
- data/spec/unit/batch_spec.rb +34 -0
- data/spec/unit/client_spec.rb +35 -3
- data/spec/unit/identifier_spec.rb +54 -15
- data/spec/unit/metadata_spec.rb +2 -0
- data/spec/unit/metadata_transform_datacite_spec.rb +169 -0
- metadata +60 -21
- data/.travis.yml +0 -9
- data/spec/unit/batch_download_spec.rb +0 -5
data/lib/ezid/identifier.rb
CHANGED
@@ -65,10 +65,25 @@ module Ezid
|
|
65
65
|
# @return [Ezid::Identifier] the identifier
|
66
66
|
# @raise [Ezid::IdentifierNotFoundError]
|
67
67
|
def modify(id, metadata)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
allocate.tap do |i|
|
69
|
+
i.id = id
|
70
|
+
i.update_metadata(metadata)
|
71
|
+
i.modify!
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Loads an identifier with provided remote metadata
|
76
|
+
# The main purpose is to provide an API in a batch processing
|
77
|
+
# context to instantiate Identifiers from a BatchDownload.
|
78
|
+
# @see #load_metadata!
|
79
|
+
# @param id [String] the EZID identifier
|
80
|
+
# @param metadata [String, Hash, Ezid::Metadata] the provided metadata
|
81
|
+
# @return [Ezid::Identifier] the identifier
|
82
|
+
def load(id, metadata = nil)
|
83
|
+
allocate.tap do |i|
|
84
|
+
i.id = id
|
85
|
+
i.load_metadata!(metadata)
|
86
|
+
end
|
72
87
|
end
|
73
88
|
|
74
89
|
# Retrieves an identifier
|
@@ -76,9 +91,10 @@ module Ezid
|
|
76
91
|
# @return [Ezid::Identifier] the identifier
|
77
92
|
# @raise [Ezid::IdentifierNotFoundError] if the identifier does not exist in EZID
|
78
93
|
def find(id)
|
79
|
-
|
80
|
-
|
81
|
-
|
94
|
+
allocate.tap do |i|
|
95
|
+
i.id = id
|
96
|
+
i.load_metadata
|
97
|
+
end
|
82
98
|
end
|
83
99
|
end
|
84
100
|
|
@@ -132,9 +148,14 @@ module Ezid
|
|
132
148
|
# @return [Ezid::Metadata] the metadata
|
133
149
|
def metadata(_=nil)
|
134
150
|
if !_.nil?
|
135
|
-
warn "[DEPRECATION] The parameter of `metadata` is
|
151
|
+
warn "[DEPRECATION] The parameter of `metadata` is ignored and will be removed in 2.0. " \
|
152
|
+
"(called from #{caller.first})"
|
136
153
|
end
|
137
|
-
|
154
|
+
remote_metadata.merge(local_metadata).freeze
|
155
|
+
end
|
156
|
+
|
157
|
+
def local_metadata
|
158
|
+
@local_metadata ||= Metadata.new
|
138
159
|
end
|
139
160
|
|
140
161
|
def remote_metadata
|
@@ -172,7 +193,7 @@ module Ezid
|
|
172
193
|
# @param attrs [Hash] the metadata
|
173
194
|
# @return [Ezid::Identifier] the identifier
|
174
195
|
def update_metadata(attrs={})
|
175
|
-
|
196
|
+
local_metadata.update(attrs)
|
176
197
|
self
|
177
198
|
end
|
178
199
|
|
@@ -203,13 +224,25 @@ module Ezid
|
|
203
224
|
load_metadata
|
204
225
|
end
|
205
226
|
|
206
|
-
# Loads the metadata from EZID
|
227
|
+
# Loads the metadata from EZID and marks the identifier as persisted.
|
207
228
|
# @return [Ezid::Identifier] the identifier
|
208
|
-
# @raise [Ezid::Error]
|
229
|
+
# @raise [Ezid::Error] the identifier is not found or other error.
|
209
230
|
def load_metadata
|
210
231
|
response = client.get_identifier_metadata(id)
|
211
|
-
|
212
|
-
|
232
|
+
load_remote_metadata(response.metadata)
|
233
|
+
persists!
|
234
|
+
self
|
235
|
+
end
|
236
|
+
|
237
|
+
# Loads provided metadata and marks the identifier as persisted.
|
238
|
+
# The main purpose is to provide an API in a batch processing
|
239
|
+
# context to instantiate Identifiers from a BatchDownload.
|
240
|
+
# @see Ezid::BatchEnumerator
|
241
|
+
# @see .load
|
242
|
+
# @param metadata [String, Hash, Ezid::Metadata] the provided metadata
|
243
|
+
# @return [Ezid::Identifier] the identifier
|
244
|
+
def load_metadata!(metadata)
|
245
|
+
load_remote_metadata(metadata)
|
213
246
|
persists!
|
214
247
|
self
|
215
248
|
end
|
@@ -287,8 +320,8 @@ module Ezid
|
|
287
320
|
end
|
288
321
|
|
289
322
|
def reset_metadata
|
290
|
-
|
291
|
-
remote_metadata.clear
|
323
|
+
local_metadata.clear
|
324
|
+
remote_metadata.clear
|
292
325
|
end
|
293
326
|
|
294
327
|
protected
|
@@ -302,7 +335,7 @@ module Ezid
|
|
302
335
|
private
|
303
336
|
|
304
337
|
def local_or_remote_metadata(*args)
|
305
|
-
value =
|
338
|
+
value = local_metadata.send(*args)
|
306
339
|
if value.nil? && persisted?
|
307
340
|
load_metadata if remote_metadata.empty?
|
308
341
|
value = remote_metadata.send(*args)
|
@@ -311,7 +344,7 @@ module Ezid
|
|
311
344
|
end
|
312
345
|
|
313
346
|
def modify
|
314
|
-
client.modify_identifier(id,
|
347
|
+
client.modify_identifier(id, local_metadata)
|
315
348
|
end
|
316
349
|
|
317
350
|
def create_or_mint
|
@@ -319,12 +352,12 @@ module Ezid
|
|
319
352
|
end
|
320
353
|
|
321
354
|
def mint
|
322
|
-
response = client.mint_identifier(shoulder,
|
355
|
+
response = client.mint_identifier(shoulder, local_metadata)
|
323
356
|
self.id = response.id
|
324
357
|
end
|
325
358
|
|
326
359
|
def create
|
327
|
-
client.create_identifier(id,
|
360
|
+
client.create_identifier(id, local_metadata)
|
328
361
|
end
|
329
362
|
|
330
363
|
def persist
|
@@ -340,5 +373,9 @@ module Ezid
|
|
340
373
|
update_metadata(self.class.defaults)
|
341
374
|
end
|
342
375
|
|
376
|
+
def load_remote_metadata(metadata)
|
377
|
+
remote_metadata.replace(metadata)
|
378
|
+
end
|
379
|
+
|
343
380
|
end
|
344
381
|
end
|
data/lib/ezid/metadata.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "hashie"
|
2
|
+
require_relative "metadata_transforms/datacite"
|
2
3
|
|
3
4
|
module Ezid
|
4
5
|
#
|
@@ -85,7 +86,12 @@ module Ezid
|
|
85
86
|
end
|
86
87
|
|
87
88
|
def replace(data)
|
88
|
-
|
89
|
+
hsh = coerce(data)
|
90
|
+
|
91
|
+
# Perform additional profile transforms
|
92
|
+
MetadataTransformDatacite.inverse(hsh) if hsh["_profile"] == "datacite"
|
93
|
+
|
94
|
+
super hsh
|
89
95
|
end
|
90
96
|
|
91
97
|
# Output metadata in EZID ANVL format
|
@@ -94,6 +100,10 @@ module Ezid
|
|
94
100
|
def to_anvl(include_readonly = true)
|
95
101
|
hsh = to_h
|
96
102
|
hsh.reject! { |k, v| READONLY.include?(k) } unless include_readonly
|
103
|
+
|
104
|
+
# Perform additional profile transforms
|
105
|
+
MetadataTransformDatacite.transform(hsh) if profile == "datacite"
|
106
|
+
|
97
107
|
lines = hsh.map do |name, value|
|
98
108
|
element = [escape(ESCAPE_NAMES_RE, name), escape(ESCAPE_VALUES_RE, value)]
|
99
109
|
element.join(ANVL_SEPARATOR)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
|
3
|
+
module Ezid
|
4
|
+
class MetadataTransformDatacite
|
5
|
+
|
6
|
+
# Transforms the provided metadata hash into the appropriate format for datacite. Removes all "datacite.*" keys
|
7
|
+
# and transforms these to the appropriate datacite xml. The resultant xml is then added to a single "datacite" key.
|
8
|
+
def self.transform(hsh)
|
9
|
+
# Render the datacite xml
|
10
|
+
resource_opts = {
|
11
|
+
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
12
|
+
"xmlns" => "http://datacite.org/schema/kernel-4",
|
13
|
+
"xsi:schemaLocation" => "http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4/metadata.xsd"
|
14
|
+
}
|
15
|
+
xml_builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") { |builder|
|
16
|
+
builder.resource(resource_opts) {
|
17
|
+
builder.identifier(identifierType: hsh["datacite.identifiertype"] || "DOI") {
|
18
|
+
builder.text hsh["datacite.identifier"]
|
19
|
+
}
|
20
|
+
builder.creators {
|
21
|
+
builder.creator {
|
22
|
+
builder.creatorName hsh["datacite.creator"]
|
23
|
+
}
|
24
|
+
}
|
25
|
+
builder.titles {
|
26
|
+
builder.title hsh["datacite.title"]
|
27
|
+
}
|
28
|
+
builder.publisher hsh["datacite.publisher"]
|
29
|
+
builder.publicationYear hsh["datacite.publicationyear"]
|
30
|
+
builder.resourceType(resourceTypeGeneral: hsh["datacite.resourcetypegeneral"]) {
|
31
|
+
builder.text hsh["datacite.resourcetype"]
|
32
|
+
}
|
33
|
+
builder.descriptions {
|
34
|
+
builder.description(descriptionType: "Abstract") {
|
35
|
+
builder.text hsh["datacite.description"]
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
# Using this save option to prevent NG from rendering new lines and tabs
|
41
|
+
# between nodes. This to help with a cleaner anvl conversion. Similarly,
|
42
|
+
# the sub should just remove the new line after the xml header that NG
|
43
|
+
# adds, ex:
|
44
|
+
# <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<resource ...
|
45
|
+
xml = xml_builder
|
46
|
+
.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
|
47
|
+
.sub("\n", "")
|
48
|
+
|
49
|
+
|
50
|
+
# Transform the hash
|
51
|
+
hsh.reject! { |k, v| k =~ /^datacite\./ }
|
52
|
+
hsh["datacite"] = xml
|
53
|
+
end
|
54
|
+
|
55
|
+
# Transforms the provided datacite metadata hash into the format appropriate for the Metadata class.
|
56
|
+
# Extracts appropriate fields from the datacite xml and creates the corresponding "datacite.*" keys
|
57
|
+
def self.inverse(hsh)
|
58
|
+
xml = Nokogiri::XML(hsh["datacite"])
|
59
|
+
xmlns = "http://datacite.org/schema/kernel-4"
|
60
|
+
hsh["datacite.identifier"] = xml.at_xpath("/ns:resource/ns:identifier/text()", ns: xmlns).to_s
|
61
|
+
hsh["datacite.identifiertype"] = xml.at_xpath("/ns:resource/ns:identifier/attribute::identifierType", ns: xmlns).to_s
|
62
|
+
hsh["datacite.creator"] = xml.at_xpath("/ns:resource/ns:creators/ns:creator/ns:creatorName/text()", ns: xmlns).to_s
|
63
|
+
hsh["datacite.title"] = xml.at_xpath("/ns:resource/ns:titles/ns:title/text()", ns: xmlns).to_s
|
64
|
+
hsh["datacite.publisher"] = xml.at_xpath("/ns:resource/ns:publisher/text()", ns: xmlns).to_s
|
65
|
+
hsh["datacite.publicationyear"] = xml.at_xpath("/ns:resource/ns:publicationYear/text()", ns: xmlns).to_s
|
66
|
+
hsh["datacite.resourcetype"] = xml.at_xpath("/ns:resource/ns:resourceType/text()", ns: xmlns).to_s
|
67
|
+
hsh["datacite.resourcetypegeneral"] = xml.at_xpath("/ns:resource/ns:resourceType/attribute::resourceTypeGeneral", ns: xmlns).to_s
|
68
|
+
hsh["datacite.description"] = xml.at_xpath("/ns:resource/ns:descriptions/ns:description/text()", ns: xmlns).to_s
|
69
|
+
hsh.delete("datacite")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require 'delegate'
|
2
|
+
require 'uri'
|
3
|
+
require 'net/http'
|
4
|
+
require 'forwardable'
|
5
|
+
require 'date'
|
5
6
|
|
6
|
-
require_relative
|
7
|
+
require_relative '../responses/response'
|
7
8
|
|
8
9
|
module Ezid
|
9
10
|
#
|
@@ -31,7 +32,7 @@ module Ezid
|
|
31
32
|
end
|
32
33
|
|
33
34
|
def short_name
|
34
|
-
name.split(
|
35
|
+
name.split('::').last.sub('Request', '')
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
@@ -42,13 +43,24 @@ module Ezid
|
|
42
43
|
def initialize(client, *args)
|
43
44
|
@client = client
|
44
45
|
super build_request
|
45
|
-
set_content_type(
|
46
|
+
set_content_type('text/plain', charset: 'UTF-8')
|
46
47
|
end
|
47
48
|
|
48
49
|
# Executes the request and returns the response
|
49
50
|
# @return [Ezid::Response] the response
|
50
51
|
def execute
|
51
|
-
|
52
|
+
retries = 0
|
53
|
+
begin
|
54
|
+
response_class.new(get_response_for_request)
|
55
|
+
rescue Net::HTTPServerException, UnexpectedResponseError => e
|
56
|
+
if retries < 2
|
57
|
+
sleep 15
|
58
|
+
retries += 1
|
59
|
+
retry
|
60
|
+
else
|
61
|
+
raise
|
62
|
+
end
|
63
|
+
end
|
52
64
|
end
|
53
65
|
|
54
66
|
# The request URI
|
@@ -91,6 +103,7 @@ module Ezid
|
|
91
103
|
|
92
104
|
def get_response_for_request
|
93
105
|
connection.start do |conn|
|
106
|
+
self['Accept'] = 'text/plain'
|
94
107
|
add_authentication if authentication_required?
|
95
108
|
add_metadata if has_metadata?
|
96
109
|
conn.request(__getobj__)
|
@@ -113,7 +126,7 @@ module Ezid
|
|
113
126
|
# Adds authentication data to the request
|
114
127
|
def add_authentication
|
115
128
|
if session.open?
|
116
|
-
self[
|
129
|
+
self['Cookie'] = session.cookie
|
117
130
|
else
|
118
131
|
basic_auth(user, password)
|
119
132
|
end
|
@@ -14,6 +14,19 @@ module Ezid
|
|
14
14
|
# Error response status
|
15
15
|
ERROR = "error".freeze
|
16
16
|
|
17
|
+
def initialize(http_response)
|
18
|
+
super
|
19
|
+
|
20
|
+
unless __getobj__.code =~ /2\d\d/
|
21
|
+
raise Error, "HTTP response error: %s %s" %
|
22
|
+
[ __getobj__.code, __getobj__.message ]
|
23
|
+
end
|
24
|
+
|
25
|
+
unless status_line =~ /^(#{SUCCESS}|#{ERROR}): /
|
26
|
+
raise UnexpectedResponseError, __getobj__.body
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
17
30
|
# The response status -- "success" or "error"
|
18
31
|
# @return [String] the status
|
19
32
|
def status
|
@@ -0,0 +1,39 @@
|
|
1
|
+
:: ark:/99999/fk4086hs23
|
2
|
+
_updated: 1488227717
|
3
|
+
_target: http://example.com
|
4
|
+
_profile: erc
|
5
|
+
_ownergroup: apitest
|
6
|
+
_owner: apitest
|
7
|
+
_export: yes
|
8
|
+
_created: 1488227717
|
9
|
+
_status: public
|
10
|
+
|
11
|
+
:: ark:/99999/fk4086hs23/123
|
12
|
+
_updated: 1488227718
|
13
|
+
_target: http://ezid.cdlib.org/id/ark:/99999/fk4086hs23/123
|
14
|
+
_profile: erc
|
15
|
+
_ownergroup: apitest
|
16
|
+
_owner: apitest
|
17
|
+
_export: yes
|
18
|
+
_created: 1488227718
|
19
|
+
_status: public
|
20
|
+
|
21
|
+
:: ark:/99999/fk40p1bb85
|
22
|
+
_updated: 1488303565
|
23
|
+
_target: http://ezid.cdlib.org/id/ark:/99999/fk40p1bb85
|
24
|
+
_profile: erc
|
25
|
+
_ownergroup: apitest
|
26
|
+
_owner: apitest
|
27
|
+
_export: yes
|
28
|
+
_created: 1488303565
|
29
|
+
_status: public
|
30
|
+
|
31
|
+
:: ark:/99999/fk40z7fh7x
|
32
|
+
_updated: 1488232856
|
33
|
+
_target: http://ezid.cdlib.org/id/ark:/99999/fk40z7fh7x
|
34
|
+
_profile: erc
|
35
|
+
_ownergroup: apitest
|
36
|
+
_owner: apitest
|
37
|
+
_export: yes
|
38
|
+
_created: 1488232856
|
39
|
+
_status: public
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://datacite.org/schema/kernel-4" xsi:schemaLocation="http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4/metadata.xsd"><identifier identifierType="DOI"></identifier><creators><creator><creatorName/></creator></creators><titles><title/></titles><publisher/><publicationYear/><resourceType resourceTypeGeneral=""></resourceType><descriptions><description descriptionType="Abstract"></description></descriptions></resource>
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://datacite.org/schema/kernel-4" xsi:schemaLocation="http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4/metadata.xsd"><identifier identifierType="TestIdentifierType">TestIdentifier</identifier><creators><creator><creatorName>TestCreatorName</creatorName></creator></creators><titles><title>TestTitle</title></titles><publisher>TestPublisher</publisher><publicationYear>TestPublicationYear</publicationYear><resourceType resourceTypeGeneral="TestResourceTypeGeneral">TestResourceType</resourceType><descriptions><description descriptionType="Abstract">TestDescription</description></descriptions></resource>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
module Ezid
|
4
|
+
RSpec.describe BatchDownload, ezid: true do
|
5
|
+
|
6
|
+
subject do
|
7
|
+
a_week_ago = (Time.now - (7*24*60*60)).to_i
|
8
|
+
described_class.new(:anvl, compression: "zip", permanence: "test", status: "public", createdAfter: a_week_ago)
|
9
|
+
end
|
10
|
+
|
11
|
+
specify {
|
12
|
+
expect(subject.download_url).to match(/\Ahttps:\/\/ezid\.cdlib\.org\/download\/\w+\.zip\z/)
|
13
|
+
expect(subject.url).to match(/\Ahttps:\/\/ezid\.cdlib\.org\/download\/\w+\.zip\z/)
|
14
|
+
Dir.mktmpdir do |tmpdir|
|
15
|
+
expect(subject.file(path: tmpdir))
|
16
|
+
.to match(/\A#{tmpdir}\/\w+\.zip\z/)
|
17
|
+
end
|
18
|
+
}
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Ezid
|
2
|
-
RSpec.describe Identifier,
|
2
|
+
RSpec.describe Identifier, ezid: true do
|
3
3
|
|
4
4
|
before {
|
5
5
|
@identifier = described_class.mint(TEST_ARK_SHOULDER, target: "http://example.com")
|
@@ -38,7 +38,8 @@ module Ezid
|
|
38
38
|
end
|
39
39
|
describe "delete" do
|
40
40
|
subject { described_class.mint(TEST_ARK_SHOULDER, status: "reserved") }
|
41
|
-
|
41
|
+
# Getting 400 Bad Request response - DCS 3/22/21
|
42
|
+
xit "deletes the identifier" do
|
42
43
|
subject.delete
|
43
44
|
expect(subject).to be_deleted
|
44
45
|
expect { described_class.find(subject.id) }.to raise_error(IdentifierNotFoundError)
|
data/spec/spec_helper.rb
CHANGED
@@ -15,6 +15,8 @@
|
|
15
15
|
#
|
16
16
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
17
17
|
|
18
|
+
require "byebug"
|
19
|
+
|
18
20
|
require "rspec/its"
|
19
21
|
|
20
22
|
require "ezid/test_helper"
|
@@ -61,7 +63,7 @@ RSpec.configure do |config|
|
|
61
63
|
|
62
64
|
# This setting enables warnings. It's recommended, but in some cases may
|
63
65
|
# be too noisy due to issues in dependencies.
|
64
|
-
config.warnings =
|
66
|
+
config.warnings = false
|
65
67
|
|
66
68
|
# Many RSpec users commonly either run the entire suite or an individual
|
67
69
|
# file, and it's useful to allow more verbose output when running an
|
@@ -76,7 +78,7 @@ RSpec.configure do |config|
|
|
76
78
|
# Print the 10 slowest examples and example groups at the
|
77
79
|
# end of the spec run, to help surface which specs are running
|
78
80
|
# particularly slow.
|
79
|
-
config.profile_examples = 5
|
81
|
+
#config.profile_examples = 5
|
80
82
|
|
81
83
|
# Run specs in random order to surface order dependencies. If you find an
|
82
84
|
# order dependency and want to debug it, you can fix the order by providing
|