ro-crate 0.5.1 → 0.5.2

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 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