ro-crate 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28049e56f761e9b8684970817cc4eace0a60c78aee05b6a16688e589a2088357
4
- data.tar.gz: 3e731b4c6039aa74ea34ab7d672fa665b99d4d030598a16ac593877cb0bf306f
3
+ metadata.gz: f2462dcf00e2593cf8ea7108af9f9b6ef54ef773aea01be125f7c79ce67c2850
4
+ data.tar.gz: 40955bc76cd0344b80b727a79f5888ddc99d3874ecf3f8ce4db64ac2a722d713
5
5
  SHA512:
6
- metadata.gz: ac8be2df8a04041f7cafc51e04c2ee67d0e25599b1c7a16716aa0b61a4db132b5fb1e55a1bef48b7c6c83aea6bfaba1826a1ac294f58e3092a35438e1938433c
7
- data.tar.gz: 13a3780ee9ff9c85ac6829b0f93e393df3917e9286468c54cd127d1fdba704d14ced069fafb7bcb76378c6b120c6598e431e905059983f1dcec704efefc038cf
6
+ metadata.gz: 7bd16f57d802a39d378cbcfa663ecc55acfbc77256013a50d7490a652cf383186c99dbbd0c28d5747751c33aa79fe06033e1a90a15cb6f2052139045992afc76
7
+ data.tar.gz: 8a6f755b6fa96e511ca1ff4c034f049c6148acd2fe4f1aa8e7a71ab231217dd2dfc4fdde7cc92cae0d6ab1d077aa36f2d13afe98ee7fbecfe0ccd532a0580325
data/.gitignore CHANGED
@@ -48,3 +48,5 @@ build-iPhoneSimulator/
48
48
 
49
49
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
50
  .rvmrc
51
+
52
+ Gemfile.lock
@@ -2,11 +2,6 @@ module ROCrate
2
2
  ##
3
3
  # A wrapper class for Hash that adds methods to dereference Entities within an RO-Crate.
4
4
  class JSONLDHash < ::Hash
5
- def self.[](graph, content = {})
6
- @graph = graph
7
- super(stringified(content))
8
- end
9
-
10
5
  def initialize(graph, content = {})
11
6
  @graph = graph
12
7
  super()
@@ -59,7 +59,7 @@ module ROCrate
59
59
  # @return [Hash{String => Entry}>] The files/directories that were populated.
60
60
  # The key is the relative path of the file/directory, and the value is an Entry object where data can be read etc.
61
61
  def populate_entries(source_directory, include_hidden: false)
62
- raise 'Not a directory' unless ::File.directory?(source_directory)
62
+ raise TypeError, 'Not a directory' unless ::File.directory?(source_directory)
63
63
  @directory_entries = {}
64
64
  list_all_files(source_directory, include_hidden: include_hidden).each do |rel_path|
65
65
  source_path = Pathname.new(::File.join(source_directory, rel_path)).expand_path
@@ -0,0 +1,15 @@
1
+ module ROCrate
2
+ class Exception < StandardError
3
+ attr_reader :inner_exception
4
+
5
+ def initialize(message, _inner_exception = nil)
6
+ if _inner_exception
7
+ @inner_exception = _inner_exception
8
+ super("#{message}: #{@inner_exception.class.name} - #{@inner_exception.message}")
9
+ set_backtrace(@inner_exception.backtrace)
10
+ else
11
+ super(message)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module ROCrate
2
+ class ReadException < ROCrate::Exception
3
+ end
4
+ end
@@ -9,7 +9,6 @@ module ROCrate
9
9
  # @param target_dir [String, ::File, Pathname] The target directory where the crate should be unzipped (if its a Zip file).
10
10
  # @return [Crate] The RO-Crate.
11
11
  def self.read(source, target_dir: Dir.mktmpdir)
12
- raise "Not a directory!" unless ::File.directory?(target_dir)
13
12
  begin
14
13
  is_dir = ::File.directory?(source)
15
14
  rescue TypeError
@@ -82,6 +81,8 @@ module ROCrate
82
81
  # @param target_dir [String, ::File, Pathname] The target directory where the crate should be unzipped.
83
82
  # @return [Crate] The RO-Crate.
84
83
  def self.read_zip(source, target_dir: Dir.mktmpdir)
84
+ raise ROCrate::ReadException, "Target is not a directory!" unless ::File.directory?(target_dir)
85
+
85
86
  unzip_to(source, target_dir)
86
87
 
87
88
  # Traverse the unzipped directory to try and find the crate's root
@@ -96,7 +97,7 @@ module ROCrate
96
97
  # @param source [String, ::File, Pathname] The location of the directory.
97
98
  # @return [Crate] The RO-Crate.
98
99
  def self.read_directory(source)
99
- raise "Not a directory!" unless ::File.directory?(source)
100
+ raise ROCrate::ReadException, "Source is not a directory!" unless ::File.directory?(source)
100
101
 
101
102
  source = ::File.expand_path(source)
102
103
  metadata_file = Dir.entries(source).detect { |entry| entry == ROCrate::Metadata::IDENTIFIER ||
@@ -104,13 +105,18 @@ module ROCrate
104
105
 
105
106
  if metadata_file
106
107
  metadata_json = ::File.read(::File.join(source, metadata_file))
107
- metadata = JSON.parse(metadata_json)
108
+ begin
109
+ metadata = JSON.parse(metadata_json)
110
+ rescue JSON::ParserError => e
111
+ raise ROCrate::ReadException.new("Error parsing metadata", e)
112
+ end
113
+
108
114
  entities = entities_from_metadata(metadata)
109
115
  context = metadata['@context']
110
116
 
111
117
  build_crate(entities, source, context: context)
112
118
  else
113
- raise 'No metadata found!'
119
+ raise ROCrate::ReadException, "No metadata found!"
114
120
  end
115
121
  end
116
122
 
@@ -131,14 +137,14 @@ module ROCrate
131
137
 
132
138
  # Do some normalization...
133
139
  entities[ROCrate::Metadata::IDENTIFIER] = extract_metadata_entity(entities)
134
- raise "No metadata entity found in @graph!" unless entities[ROCrate::Metadata::IDENTIFIER]
140
+ raise ROCrate::ReadException, "No metadata entity found in @graph!" unless entities[ROCrate::Metadata::IDENTIFIER]
135
141
  entities[ROCrate::Preview::IDENTIFIER] = extract_preview_entity(entities)
136
142
  entities[ROCrate::Crate::IDENTIFIER] = extract_root_entity(entities)
137
- raise "No root entity (with @id: #{entities[ROCrate::Metadata::IDENTIFIER].dig('about', '@id')}) found in @graph!" unless entities[ROCrate::Crate::IDENTIFIER]
143
+ raise ROCrate::ReadException, "No root entity (with @id: #{entities[ROCrate::Metadata::IDENTIFIER].dig('about', '@id')}) found in @graph!" unless entities[ROCrate::Crate::IDENTIFIER]
138
144
 
139
145
  entities
140
146
  else
141
- raise "No @graph found in metadata!"
147
+ raise ROCrate::ReadException, "No @graph found in metadata!"
142
148
  end
143
149
  end
144
150
 
@@ -198,7 +204,7 @@ module ROCrate
198
204
  # @param entity_hash [Hash] A Hash containing all the entities in the @graph, mapped by their @id.
199
205
  # @return [Array<ROCrate::File, ROCrate::Directory>] The extracted DataEntity objects.
200
206
  def self.extract_data_entities(crate, source, entity_hash)
201
- crate.raw_properties['hasPart'].map do |ref|
207
+ (crate.raw_properties['hasPart'] || []).map do |ref|
202
208
  entity_props = entity_hash.delete(ref['@id'])
203
209
  next unless entity_props
204
210
  entity_class = ROCrate::DataEntity.specialize(entity_props)
@@ -234,21 +240,21 @@ module ROCrate
234
240
  # or nil if it referenced a local file that wasn't found.
235
241
  def self.create_data_entity(crate, entity_class, source, entity_props)
236
242
  id = entity_props.delete('@id')
243
+ raise ROCrate::ReadException, "Data Entity missing '@id': #{entity_props.inspect}" unless id
237
244
  decoded_id = URI.decode_www_form_component(id)
238
245
  path = nil
239
246
  uri = URI(id) rescue nil
240
247
  if uri&.absolute?
241
248
  path = uri
242
249
  decoded_id = nil
243
- else
250
+ elsif !id.start_with?('#')
244
251
  [id, decoded_id].each do |i|
245
252
  fullpath = ::File.join(source, i)
246
253
  path = Pathname.new(fullpath) if ::File.exist?(fullpath)
247
254
  end
248
- # unless path
249
- # warn "Missing file/directory: #{id}, skipping..."
250
- # return nil
251
- # end
255
+ if path.nil?
256
+ raise ROCrate::ReadException, "Local Data Entity not found in crate: #{id}"
257
+ end
252
258
  end
253
259
 
254
260
  entity_class.new(crate, path, decoded_id, entity_props)
@@ -290,7 +296,7 @@ module ROCrate
290
296
  # mapped by its @id.
291
297
  def self.extract_root_entity(entities)
292
298
  root_id = entities[ROCrate::Metadata::IDENTIFIER].dig('about', '@id')
293
- raise "Metadata entity does not reference any root entity" unless root_id
299
+ raise ROCrate::ReadException, "Metadata entity does not reference any root entity" unless root_id
294
300
  entities.delete(root_id)
295
301
  end
296
302
 
@@ -1,10 +1,11 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <title><%= name || "New RO-Crate" %></title>
5
5
  <script type="application/ld+json"><%= metadata.generate %></script>
6
- <meta name="generator" content="https://github.com/fbacall/ro-crate-ruby">
6
+ <meta name="generator" content="https://github.com/ResearchObject/ro-crate-ruby">
7
7
  <meta name="keywords" content="RO-Crate">
8
+ <meta charset="utf-8">
8
9
  </head>
9
10
  <body>
10
11
  <h1><%= name || "New RO-Crate" %></h1>
data/lib/ro_crate.rb CHANGED
@@ -6,6 +6,8 @@ require 'zip/filesystem'
6
6
  require 'addressable'
7
7
  require 'open-uri'
8
8
 
9
+ require 'ro_crate/model/exceptions/exception'
10
+ require 'ro_crate/model/exceptions/read_exception'
9
11
  require 'ro_crate/json_ld_hash'
10
12
  require 'ro_crate/model/entity'
11
13
  require 'ro_crate/model/data_entity'
data/ro_crate.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'ro-crate'
3
- s.version = '0.5.1'
3
+ s.version = '0.5.2'
4
4
  s.summary = 'Create, manipulate, read RO-Crates.'
5
5
  s.authors = ['Finn Bacall']
6
6
  s.email = 'finn.bacall@manchester.ac.uk'
data/test/entity_test.rb CHANGED
@@ -72,6 +72,23 @@ class EntityTest < Test::Unit::TestCase
72
72
  assert_equal(person.canonical_id, crate.author.canonical_id)
73
73
  end
74
74
 
75
+ test 'to_json' do
76
+ crate = ROCrate::Crate.new
77
+
78
+ crate['test'] = 'hello'
79
+ crate['test2'] = ['hello']
80
+ crate['test3'] = 123
81
+ crate['test4'] = { a: 'bc' }
82
+
83
+ json = crate.to_json
84
+ parsed = JSON.parse(json)
85
+
86
+ assert_equal 'hello', parsed['test']
87
+ assert_equal ['hello'], parsed['test2']
88
+ assert_equal 123, parsed['test3']
89
+ assert_equal({ 'a' => 'bc' }, parsed['test4'])
90
+ end
91
+
75
92
  test 'format various IDs' do
76
93
  assert_equal "#Hello%20World/Goodbye%20World", ROCrate::ContextualEntity.format_id('#Hello World/Goodbye World')
77
94
  assert_equal "#Hello%20World/Goodbye%20World", ROCrate::ContextualEntity.format_id('Hello World/Goodbye World')
@@ -0,0 +1,110 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ class EntryTest < Test::Unit::TestCase
5
+ setup do
6
+ stub_request(:get, 'http://example.com/dir/file.txt').to_return(status: 200, body: 'file contents')
7
+ stub_request(:get, 'http://example.com/dir/').to_return(status: 200, body: '<html>...')
8
+
9
+ @local_file = ROCrate::Entry.new(fixture_file('info.txt'))
10
+ @local_path = ROCrate::Entry.new(Pathname.new(fixture_dir).join('directory', 'info.txt'))
11
+ @local_io = ROCrate::Entry.new(StringIO.new('stringio'))
12
+ @local_dir = ROCrate::Entry.new(Pathname.new(fixture_dir).join('directory'))
13
+ @local_symlink = ROCrate::Entry.new(Pathname.new(fixture_dir).join('symlink'))
14
+ @local_dir_symlink = ROCrate::Entry.new(Pathname.new(fixture_dir).join('dir_symlink'))
15
+ @remote_file = ROCrate::RemoteEntry.new(URI('http://example.com/dir/file.txt'))
16
+ @remote_dir = ROCrate::RemoteEntry.new(URI('http://example.com/dir/'), directory: true)
17
+ end
18
+
19
+ test 'read' do
20
+ assert_equal "Hello\n", @local_file.read
21
+ assert_equal "1234\n", @local_path.read
22
+ assert_equal "stringio", @local_io.read
23
+ assert_raises(Errno::EISDIR) { @local_dir.read }
24
+ assert_raises(Errno::EISDIR) { @local_dir_symlink.read }
25
+ assert_equal "I have spaces in my name\n", @local_symlink.read
26
+ assert_equal "file contents", @remote_file.read
27
+ assert_equal "<html>...", @remote_dir.read
28
+ end
29
+
30
+ test 'write_to' do
31
+ dest = StringIO.new
32
+ @local_file.write_to(dest)
33
+ dest.rewind
34
+ assert_equal "Hello\n", dest.read
35
+
36
+ dest = StringIO.new
37
+ @local_path.write_to(dest)
38
+ dest.rewind
39
+ assert_equal "1234\n", dest.read
40
+
41
+ dest = StringIO.new
42
+ @local_io.write_to(dest)
43
+ dest.rewind
44
+ assert_equal "stringio", dest.read
45
+
46
+ assert_raises(Errno::EISDIR) { @local_dir.write_to(dest) }
47
+
48
+ assert_raises(Errno::EISDIR) { @local_dir_symlink.write_to(dest) }
49
+
50
+ dest = StringIO.new
51
+ @local_symlink.write_to(dest)
52
+ dest.rewind
53
+ assert_equal "I have spaces in my name\n", dest.read
54
+
55
+ dest = StringIO.new
56
+ @remote_file.write_to(dest)
57
+ dest.rewind
58
+ assert_equal "file contents", dest.read
59
+
60
+ dest = StringIO.new
61
+ @remote_dir.write_to(dest)
62
+ dest.rewind
63
+ assert_equal "<html>...", dest.read
64
+ end
65
+
66
+ test 'directory?' do
67
+ refute @local_file.directory?
68
+ refute @local_path.directory?
69
+ refute @local_io.directory?
70
+ assert @local_dir.directory?
71
+ refute @local_symlink.directory?
72
+ assert @local_dir_symlink.directory?
73
+ refute @remote_file.directory?
74
+ assert @remote_dir.directory?
75
+ end
76
+
77
+ test 'symlink?' do
78
+ refute @local_file.symlink?
79
+ refute @local_path.symlink?
80
+ refute @local_io.symlink?
81
+ refute @local_dir.symlink?
82
+ assert @local_symlink.symlink?
83
+ assert @local_dir_symlink.symlink?
84
+ refute @remote_file.symlink?
85
+ refute @remote_dir.symlink?
86
+ end
87
+
88
+ test 'remote?' do
89
+ refute @local_file.remote?
90
+ refute @local_path.remote?
91
+ refute @local_io.remote?
92
+ refute @local_dir.remote?
93
+ refute @local_symlink.remote?
94
+ refute @local_dir_symlink.remote?
95
+ assert @remote_file.remote?
96
+ assert @remote_dir.remote?
97
+ end
98
+
99
+ test 'path' do
100
+ base = Pathname.new(fixture_dir).expand_path.to_s
101
+ assert_equal "#{base}/info.txt", @local_file.path
102
+ assert_equal "#{base}/directory/info.txt", @local_path.path
103
+ assert_nil @local_io.path
104
+ assert_equal "#{base}/directory", @local_dir.path
105
+ assert_equal "#{base}/symlink", @local_symlink.path
106
+ assert_equal "#{base}/dir_symlink", @local_dir_symlink.path
107
+ assert_nil @remote_file.path
108
+ assert_nil @remote_dir.path
109
+ end
110
+ end
@@ -0,0 +1,21 @@
1
+ {
2
+ "@context": "https://w3id.org/ro/crate/1.1/context",
3
+ "@graph": [
4
+ {
5
+ "@id": "arcp://name,somethingsomething",
6
+ "@type": "Dataset",
7
+ "datePublished": "2024-01-31T10:47:17+00:00"
8
+
9
+ },
10
+ {
11
+ "@id": "ro-crate-metadata.json",
12
+ "@type": "CreativeWork",
13
+ "about": {
14
+ "@id": "arcp://name,somethingsomething"
15
+ },
16
+ "conformsTo": {
17
+ "@id": "https://w3id.org/ro/crate/1.1"
18
+ }
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "@context": "https://w3id.org/ro/crate/1.1/context",
3
+ "@graph": [
4
+ {
5
+ "@id": "ro-crate-metadata.json",
6
+ "@type": "CreativeWork",
7
+ "about": {
8
+ "@id": "./"
9
+ }
10
+ },
11
+ {
12
+ "@id": "./",
13
+ "@type": "Dataset",
14
+ "hasPart": [
15
+ {
16
+ "@id": "file1.txt"
17
+ },
18
+ {
19
+ "@id": "file2.txt"
20
+ }
21
+ ]
22
+ },
23
+ {
24
+ "@id": "file1.txt",
25
+ "@type": "File"
26
+ },
27
+ {
28
+ "@id": "file2.txt",
29
+ "@type": "File"
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "@context": "https://w3id.org/ro/crate/1.1/context"
3
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "@context": "https://w3id.org/ro/crate/1.1/context",
3
+ "@graph": [
4
+
5
+ ]
6
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "@context": "https://w3id.org/ro/crate/1.1/context",
3
+ "@graph": [
4
+ {
5
+ "@id": "ro-crate-metadata.json",
6
+ "@type": "CreativeWork",
7
+ "about": {
8
+ "@id": "./"
9
+ }
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Error</title>
5
+ </head>
6
+ <body>
7
+ Were you expecting JSON?
8
+ </body>
9
+ </html>
@@ -0,0 +1 @@
1
+ directory
@@ -0,0 +1 @@
1
+ file with spaces.txt
data/test/reader_test.rb CHANGED
@@ -116,6 +116,19 @@ class ReaderTest < Test::Unit::TestCase
116
116
  end
117
117
  end
118
118
 
119
+ test 'reading from zip IO' do
120
+ io = StringIO.new(fixture_file('directory.zip').read)
121
+ crate = ROCrate::Reader.read(io)
122
+
123
+ assert crate.payload['fish/info.txt']
124
+ assert_equal '1234', crate.payload['fish/info.txt'].source.read.chomp
125
+ assert crate.payload['fish/root.txt']
126
+ assert crate.payload['fish/data/info.txt']
127
+ assert crate.payload['fish/data/nested.txt']
128
+ assert crate.payload['fish/data/binary.jpg']
129
+ assert_equal ['./', 'fish/', 'ro-crate-metadata.jsonld', 'ro-crate-preview.html'], crate.entities.map(&:id).sort
130
+ end
131
+
119
132
  test 'reading from directory with directories' do
120
133
  crate = ROCrate::Reader.read_directory(fixture_file('directory_crate').path)
121
134
 
@@ -303,4 +316,69 @@ class ReaderTest < Test::Unit::TestCase
303
316
  refute real_file.payload.values.first.remote?
304
317
  refute real_file.payload.values.first.directory?
305
318
  end
319
+
320
+ test 'handles exceptions' do
321
+ e = check_exception(ROCrate::ReadException) do
322
+ ROCrate::Reader.read(fixture_file('broken/no_graph'))
323
+ end
324
+ assert_include e.message, 'No @graph'
325
+
326
+ e = check_exception(ROCrate::ReadException) do
327
+ ROCrate::Reader.read(fixture_file('broken/no_metadata_entity'))
328
+ end
329
+ assert_include e.message, 'No metadata entity'
330
+
331
+ e = check_exception(ROCrate::ReadException) do
332
+ ROCrate::Reader.read(fixture_file('broken/no_metadata_file'))
333
+ end
334
+ assert_include e.message, 'No metadata found'
335
+
336
+ e = check_exception(ROCrate::ReadException) do
337
+ ROCrate::Reader.read(fixture_file('broken/no_root_entity'))
338
+ end
339
+ assert_include e.message, 'No root'
340
+
341
+ e = check_exception(ROCrate::ReadException) do
342
+ ROCrate::Reader.read(fixture_file('broken/not_json'))
343
+ end
344
+ assert_include e.message, 'Error parsing metadata: JSON::ParserError'
345
+ assert_equal JSON::ParserError, e.inner_exception.class
346
+
347
+ e = check_exception(ROCrate::ReadException) do
348
+ ROCrate::Reader.read(fixture_file('workflow-0.2.0.zip'), target_dir: fixture_file('workflow-0.2.0.zip'))
349
+ end
350
+ assert_include e.message, 'Target is not a directory!'
351
+
352
+ e = check_exception(ROCrate::ReadException) do
353
+ ROCrate::Reader.read_directory(fixture_file('workflow-0.2.0.zip'))
354
+ end
355
+ assert_include e.message, 'Source is not a directory!'
356
+
357
+ e = check_exception(ROCrate::ReadException) do
358
+ ROCrate::Reader.read(fixture_file('broken/missing_file'))
359
+ end
360
+ assert_include e.message, 'not found in crate: file1.txt'
361
+ end
362
+
363
+ test 'tolerates arcp identifier on root data entity (and missing hasPart)' do
364
+ crate = ROCrate::Reader.read(fixture_file('arcp').path)
365
+
366
+ assert_equal 'arcp://name,somethingsomething', crate.id
367
+ assert_empty crate.data_entities
368
+ end
369
+
370
+ private
371
+
372
+ def check_exception(exception_class)
373
+ e = nil
374
+ assert_raise(exception_class) do
375
+ begin
376
+ yield
377
+ rescue exception_class => e
378
+ raise e
379
+ end
380
+ end
381
+
382
+ e
383
+ end
306
384
  end
data/test/writer_test.rb CHANGED
@@ -230,36 +230,48 @@ class WriterTest < Test::Unit::TestCase
230
230
 
231
231
  test 'write crate with remote files and directories' do
232
232
  orig = ROCrate::Reader.read(fixture_file('uri_heavy_crate').path)
233
- Tempfile.create do |file|
234
- ROCrate::Writer.new(orig).write_zip(file)
233
+ Tempfile.create do |file|
234
+ ROCrate::Writer.new(orig).write_zip(file)
235
235
 
236
- Zip::File.open(file) do |zipfile|
237
- refute zipfile.find_entry('nih:sha-256;3a2c-8d14-a40b-3755-4abc-5af8-a56d-ba3a-e159-d688-c9b3-f169-6751-4b88-fbd2-6a9f;7')
238
- end
236
+ Zip::File.open(file) do |zipfile|
237
+ refute zipfile.find_entry('nih:sha-256;3a2c-8d14-a40b-3755-4abc-5af8-a56d-ba3a-e159-d688-c9b3-f169-6751-4b88-fbd2-6a9f;7')
238
+ end
239
+
240
+ file.rewind
241
+
242
+ crate = ROCrate::Reader.read(file)
243
+
244
+ dir = crate.get('nih:sha-256;f70e-eb2e-89d0-b3dc-5c99-8541-fa4b-6e64-a194-cf9d-ebd8-ca58-24e7-c47a-553f-86fa;c/')
245
+ assert dir
246
+ assert dir.is_a?(ROCrate::Directory)
247
+ assert dir.remote?
248
+ assert_empty dir.payload
249
+
250
+ file = crate.get('nih:sha-256;3a2c-8d14-a40b-3755-4abc-5af8-a56d-ba3a-e159-d688-c9b3-f169-6751-4b88-fbd2-6a9f;7')
251
+ assert file
252
+ assert file.is_a?(ROCrate::File)
253
+ assert file.remote?
254
+ assert_empty file.payload
255
+
256
+ real_file = crate.get('main.nf')
257
+ assert real_file
258
+ assert real_file.is_a?(ROCrate::File)
259
+ refute real_file.remote?
260
+ assert_not_empty real_file.payload
261
+ refute real_file.payload.values.first.remote?
262
+ refute real_file.payload.values.first.directory?
263
+ end
264
+ end
265
+
266
+ test 'write crate with arcp root identifier' do
267
+ crate = ROCrate::Reader.read(fixture_file('arcp').path)
239
268
 
240
- file.rewind
241
-
242
- crate = ROCrate::Reader.read(file)
243
-
244
- dir = crate.get('nih:sha-256;f70e-eb2e-89d0-b3dc-5c99-8541-fa4b-6e64-a194-cf9d-ebd8-ca58-24e7-c47a-553f-86fa;c/')
245
- assert dir
246
- assert dir.is_a?(ROCrate::Directory)
247
- assert dir.remote?
248
- assert_empty dir.payload
249
-
250
- file = crate.get('nih:sha-256;3a2c-8d14-a40b-3755-4abc-5af8-a56d-ba3a-e159-d688-c9b3-f169-6751-4b88-fbd2-6a9f;7')
251
- assert file
252
- assert file.is_a?(ROCrate::File)
253
- assert file.remote?
254
- assert_empty file.payload
255
-
256
- real_file = crate.get('main.nf')
257
- assert real_file
258
- assert real_file.is_a?(ROCrate::File)
259
- refute real_file.remote?
260
- assert_not_empty real_file.payload
261
- refute real_file.payload.values.first.remote?
262
- refute real_file.payload.values.first.directory?
269
+ assert_equal 'arcp://name,somethingsomething', crate.id
270
+ Dir.mktmpdir do |dir|
271
+ ROCrate::Writer.new(crate).write(dir)
272
+ Dir.chdir(dir) do
273
+ assert File.exist?('ro-crate-metadata.json')
263
274
  end
275
+ end
264
276
  end
265
277
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ro-crate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Finn Bacall
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-12 00:00:00.000000000 Z
11
+ date: 2024-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -139,7 +139,6 @@ files:
139
139
  - ".gitignore"
140
140
  - ".ruby-version"
141
141
  - Gemfile
142
- - Gemfile.lock
143
142
  - LICENSE
144
143
  - README.md
145
144
  - Rakefile
@@ -152,6 +151,8 @@ files:
152
151
  - lib/ro_crate/model/directory.rb
153
152
  - lib/ro_crate/model/entity.rb
154
153
  - lib/ro_crate/model/entry.rb
154
+ - lib/ro_crate/model/exceptions/exception.rb
155
+ - lib/ro_crate/model/exceptions/read_exception.rb
155
156
  - lib/ro_crate/model/file.rb
156
157
  - lib/ro_crate/model/metadata.rb
157
158
  - lib/ro_crate/model/organization.rb
@@ -166,12 +167,22 @@ files:
166
167
  - test/crate_test.rb
167
168
  - test/directory_test.rb
168
169
  - test/entity_test.rb
170
+ - test/entry_test.rb
171
+ - test/fixtures/arcp/ro-crate-metadata.json
169
172
  - test/fixtures/biobb_hpc_workflows-condapack.zip
173
+ - test/fixtures/broken/missing_file/file2.txt
174
+ - test/fixtures/broken/missing_file/ro-crate-metadata.json
175
+ - test/fixtures/broken/no_graph/ro-crate-metadata.json
176
+ - test/fixtures/broken/no_metadata_entity/ro-crate-metadata.json
177
+ - test/fixtures/broken/no_metadata_file/test.txt
178
+ - test/fixtures/broken/no_root_entity/ro-crate-metadata.json
179
+ - test/fixtures/broken/not_json/ro-crate-metadata.json
170
180
  - test/fixtures/conflicting_data_directory/info.txt
171
181
  - test/fixtures/conflicting_data_directory/nested.txt
172
182
  - test/fixtures/crate-spec1.1/file with spaces.txt
173
183
  - test/fixtures/crate-spec1.1/ro-crate-metadata.json
174
184
  - test/fixtures/data.csv
185
+ - test/fixtures/dir_symlink
175
186
  - test/fixtures/directory.zip
176
187
  - test/fixtures/directory/.dir/test.txt
177
188
  - test/fixtures/directory/.dotfile
@@ -210,6 +221,7 @@ files:
210
221
  - test/fixtures/sparse_directory_crate/ro-crate-metadata.jsonld
211
222
  - test/fixtures/sparse_directory_crate/ro-crate-preview.html
212
223
  - test/fixtures/sparse_directory_crate/unlisted_file.txt
224
+ - test/fixtures/symlink
213
225
  - test/fixtures/unlinked_entity_crate/LICENSE
214
226
  - test/fixtures/unlinked_entity_crate/README.md
215
227
  - test/fixtures/unlinked_entity_crate/ro-crate-metadata.json
data/Gemfile.lock DELETED
@@ -1,50 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- ro-crate (0.5.1)
5
- addressable (>= 2.7, < 2.9)
6
- rubyzip (~> 2.0.0)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- addressable (2.8.0)
12
- public_suffix (>= 2.0.2, < 5.0)
13
- crack (0.4.3)
14
- safe_yaml (~> 1.0.0)
15
- docile (1.3.5)
16
- hashdiff (1.0.1)
17
- power_assert (2.0.1)
18
- public_suffix (4.0.6)
19
- rake (13.0.0)
20
- rexml (3.2.5)
21
- rubyzip (2.0.0)
22
- safe_yaml (1.0.5)
23
- simplecov (0.21.2)
24
- docile (~> 1.1)
25
- simplecov-html (~> 0.11)
26
- simplecov_json_formatter (~> 0.1)
27
- simplecov-html (0.12.3)
28
- simplecov_json_formatter (0.1.2)
29
- test-unit (3.5.3)
30
- power_assert
31
- webmock (3.8.3)
32
- addressable (>= 2.3.6)
33
- crack (>= 0.3.2)
34
- hashdiff (>= 0.4.0, < 2.0.0)
35
- yard (0.9.25)
36
-
37
- PLATFORMS
38
- ruby
39
-
40
- DEPENDENCIES
41
- rake (~> 13.0.0)
42
- rexml (~> 3.2.5)
43
- ro-crate!
44
- simplecov (~> 0.21.2)
45
- test-unit (~> 3.5.3)
46
- webmock (~> 3.8.3)
47
- yard (~> 0.9.25)
48
-
49
- BUNDLED WITH
50
- 2.3.6