oai 0.4.0 → 1.0.0.beta1

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.
Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +36 -10
  3. data/Rakefile +19 -52
  4. data/lib/oai/client.rb +3 -3
  5. data/lib/oai/provider.rb +47 -9
  6. data/lib/oai/provider/model.rb +17 -17
  7. data/lib/oai/provider/model/activerecord_caching_wrapper.rb +9 -10
  8. data/lib/oai/provider/model/activerecord_wrapper.rb +16 -9
  9. data/lib/oai/provider/response.rb +1 -1
  10. data/lib/oai/provider/response/record_response.rb +2 -1
  11. data/test/activerecord_provider/config/connection.rb +18 -1
  12. data/test/activerecord_provider/database/0001_oaipmh_tables.rb +1 -1
  13. data/test/activerecord_provider/helpers/providers.rb +16 -0
  14. data/test/activerecord_provider/models/exclusive_set_dc_field.rb +1 -1
  15. data/test/activerecord_provider/tc_ar_provider.rb +30 -6
  16. data/test/activerecord_provider/tc_ar_sets_provider.rb +1 -1
  17. data/test/activerecord_provider/tc_caching_paging_provider.rb +1 -1
  18. data/test/activerecord_provider/tc_simple_paging_provider.rb +1 -1
  19. data/test/activerecord_provider/{test_helper.rb → test_helper_ar_provider.rb} +0 -7
  20. data/test/client/helpers/provider.rb +8 -8
  21. data/test/client/tc_exception.rb +4 -4
  22. data/test/client/tc_get_record.rb +5 -6
  23. data/test/client/tc_http_client.rb +1 -1
  24. data/test/client/tc_identify.rb +1 -1
  25. data/test/client/tc_libxml.rb +4 -4
  26. data/test/client/tc_list_identifiers.rb +1 -1
  27. data/test/client/tc_list_metadata_formats.rb +3 -3
  28. data/test/client/tc_list_records.rb +1 -1
  29. data/test/client/tc_list_sets.rb +1 -1
  30. data/test/client/tc_low_resolution_dates.rb +5 -5
  31. data/test/client/tc_utf8_escaping.rb +2 -2
  32. data/test/client/tc_xpath.rb +2 -2
  33. data/test/client/test_helper_client.rb +5 -0
  34. data/test/provider/tc_exceptions.rb +8 -6
  35. data/test/provider/tc_functional_tokens.rb +2 -2
  36. data/test/provider/tc_provider.rb +1 -1
  37. data/test/provider/tc_resumption_tokens.rb +2 -2
  38. data/test/provider/tc_simple_provider.rb +8 -8
  39. data/test/provider/{test_helper.rb → test_helper_provider.rb} +0 -7
  40. metadata +42 -10
  41. data/test/client/test_helper.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 87d0fab6e4343a4b7523ee0559687d2490862932
4
- data.tar.gz: 69a74965ef7b9176408befe11bf4a9a9b4e49a74
2
+ SHA256:
3
+ metadata.gz: a21ec21fadefca115987b42ef91f851406c9893ca6f0efc4bd2a1dfa71282514
4
+ data.tar.gz: c3ef94d3b809c4cba4d3ea0a02cfc9cc2db370eadc86f06ea3d259b0e4f8571b
5
5
  SHA512:
6
- metadata.gz: cf7096a011a58d7e37d740d29e0a35195895909356d49af641f9ad80b6e9df2b496da039404371a7a8ab11943e725887b6d251ed804f81a17dd0b3ca1cefac98
7
- data.tar.gz: bdac7716fa083f23cb622b5f6a2b64068b1047322728ce88dd40c37be6596cd12b64511a4e92ebaf8db846ff8f7f868b66f974557fe003ba07a6154bdd0b5b1c
6
+ metadata.gz: b6eba80e5c7c3b2b1ea7512b316796217fbeb45ebf11ec33b22d61790587b84f8a4c78db669eec9bbc38980c6b8a33dd59de3b3f4d5861010aea0c3f737c3c02
7
+ data.tar.gz: bb188698b9e5e5eddb1df8c87db491e312396547e3a8179ee1d4720c96aa4567391e602b93c4f2c33aa28c33134dda585035884e1c0a5f333b34b02f8071ed35
data/README.md CHANGED
@@ -1,17 +1,21 @@
1
1
  ruby-oai
2
2
  ========
3
3
 
4
+ [![Build Status](https://travis-ci.org/code4lib/ruby-oai.svg?branch=master)](https://travis-ci.org/code4lib/ruby-oai)
5
+
6
+ [![Gem Version](https://badge.fury.io/rb/kithe.svg)](https://badge.fury.io/rb/oai)
7
+
4
8
  ruby-oai is a Open Archives Protocol for Metadata Harvesting (OAI-PMH)
5
- library for Ruby. [OAI-PMH](http://openarchives.org) is a somewhat
6
- archaic protocol for sharing metadata between digital library repositories.
9
+ library for Ruby. [OAI-PMH](http://openarchives.org) is a somewhat
10
+ archaic protocol for sharing metadata between digital library repositories.
7
11
  If you are looking to share metadata on the web you are probably better off
8
- using a feed format like [RSS](http://www.rssboard.org/rss-specification) or
9
- [Atom](http://www.atomenabled.org/). If have to work with a backwards
10
- digital repository that only offers OAI-PMH access then ruby-oai is your
12
+ using a feed format like [RSS](http://www.rssboard.org/rss-specification) or
13
+ [Atom](http://www.atomenabled.org/). If have to work with a backwards
14
+ digital repository that only offers OAI-PMH access then ruby-oai is your
11
15
  friend.
12
16
 
13
- The [OAI-PMH](http://openarchives.org) spec defines six verbs
14
- (`Identify`, `ListIdentifiers`, `ListRecords`,
17
+ The [OAI-PMH](http://openarchives.org) spec defines six verbs
18
+ (`Identify`, `ListIdentifiers`, `ListRecords`,
15
19
  `GetRecords`, `ListSets`, `ListMetadataFormat`) used for discovery and sharing of
16
20
  metadata.
17
21
 
@@ -21,7 +25,7 @@ a interactive harvesting shell.
21
25
  Client
22
26
  ------
23
27
 
24
- The OAI client library is used for harvesting metadata from repositories.
28
+ The OAI client library is used for harvesting metadata from repositories.
25
29
  For example to initiate a ListRecords request to pubmed you can:
26
30
 
27
31
  ```ruby
@@ -29,7 +33,7 @@ For example to initiate a ListRecords request to pubmed you can:
29
33
  client = OAI::Client.new 'http://www.pubmedcentral.gov/oai/oai.cgi', :headers => { "From" => "oai@example.com" }
30
34
  response = client.list_records
31
35
  # Get the first page of records
32
- response.each do |record|
36
+ response.each do |record|
33
37
  puts record.metadata
34
38
  end
35
39
  # Get the second page of records
@@ -60,7 +64,7 @@ The OAI provider library handles serving local content to other clients. Here's
60
64
  end
61
65
  ```
62
66
 
63
- See {OAI::Provider} for more details
67
+ See comment docs at top of [OAI::Provider](./lib/oai/provider.rb) for more details, including discussion of the `OAI::Provider::ActiveRecordWrapper` class for quich setup of an OAI provider for an ActiveRecord model class (single database table)
64
68
 
65
69
  Interactive Harvester
66
70
  ---------------------
@@ -81,6 +85,28 @@ Alternately it can be installed globally using RubyGems:
81
85
 
82
86
  $ gem install oai
83
87
 
88
+ Running tests
89
+ -------------
90
+
91
+ Tests are with Test::Unit, in a somewhat archaic/legacy style. Test setup especially is not how we would do things today. Run all tests with:
92
+
93
+ $ bundle exec rake test
94
+
95
+ There are also convenience tasks to run subsets of tests.
96
+
97
+ We use [appraisal](https://github.com/thoughtbot/appraisal) to test ActiveRecord-related functionality under multiple versions of ActiveRecord. While the above commands will test with latest ActiveRecord (allowed in our .gemspec development dependency), you can test under a particular version defined in the [Appraisals](./Appraisals) file like so:
98
+
99
+ $ bundle exec appraisal rails-52 rake test
100
+ $ bundle exec appraisal rails-60 rake test
101
+
102
+ If you run into trouble with appraisal's gemfiles getting out of date and bundler complaining,
103
+ try:
104
+
105
+ $ bundle exec appraisal clean
106
+ $ appraisal generate
107
+
108
+ That may make changes to appraisal gemfiles that you should commit to repo.
109
+
84
110
  License
85
111
  -------
86
112
 
data/Rakefile CHANGED
@@ -14,73 +14,40 @@ require 'yard'
14
14
 
15
15
  task :default => ["test", "yard"]
16
16
 
17
- task :test => ["test:client", "test:provider", "test:activerecord_provider"]
17
+ Rake::TestTask.new('test') do |t|
18
+ t.description = "Run all Test::Unit tests"
18
19
 
20
+ t.libs << ['lib', 'test/client', 'test/provider', 'test/activerecord_provider']
21
+
22
+ t.pattern = 'test/{client,provider,activerecord_provider}/tc_*.rb'
23
+ #t.verbose = true
24
+ t.warning = false
25
+ end
26
+
27
+
28
+ # To run just subsets of tests
19
29
  namespace :test do
20
30
  Rake::TestTask.new('client') do |t|
21
31
  t.libs << ['lib', 'test/client']
22
32
  t.pattern = 'test/client/tc_*.rb'
23
- t.verbose = true
33
+ #t.verbose = true
34
+ t.warning = false
24
35
  end
25
36
 
26
37
  Rake::TestTask.new('provider') do |t|
27
38
  t.libs << ['lib', 'test/provider']
28
39
  t.pattern = 'test/provider/tc_*.rb'
29
- t.verbose = true
40
+ #t.verbose = true
41
+ t.warning = false
30
42
  end
31
43
 
32
- desc "Active Record base Provider Tests"
33
44
  Rake::TestTask.new('activerecord_provider') do |t|
45
+ t.description = "Active Record base Provider Tests"
46
+
34
47
  t.libs << ['lib', 'test/activerecord_provider']
35
48
  t.pattern = 'test/activerecord_provider/tc_*.rb'
36
- t.verbose = true
37
- end
38
-
39
- desc 'Measures test coverage'
40
- # borrowed from here: http://clarkware.com/cgi/blosxom/2007/01/05#RcovRakeTask
41
- task :coverage do
42
- rm_f "coverage"
43
- rm_f "coverage.data"
44
- if RUBY_VERSION =~ /^1.8/
45
- Rake::Task['rcov:client'].invoke
46
- Rake::Task['rcov:provider'].invoke
47
- Rake::Task['rcov:activerecord_provider'].invoke
48
- else
49
- ENV['COVERAGE'] = 'true'
50
- Rake::Task['test:client'].invoke
51
- Rake::Task['test:provider'].invoke
52
- Rake::Task['test:activerecord_provider'].invoke
53
- end
54
-
55
- system("open coverage/index.html") if (PLATFORM['darwin'] if Kernel.const_defined? :PLATFORM) || (RUBY_PLATFORM =~ /darwin/ if Kernel.const_defined? :RUBY_PLATFORM)
56
- end
57
-
58
- end
59
-
60
- if RUBY_VERSION =~ /^1.8/
61
- require 'rcov/rcovtask'
62
- namespace :rcov do
63
- Rcov::RcovTask.new do |t|
64
- t.name = 'client'
65
- t.libs << ['lib', 'test/client']
66
- t.pattern = 'test/client/tc_*.rb'
67
- t.verbose = true
68
- t.rcov_opts = ['--aggregate coverage.data', '--text-summary']
69
- end
70
-
71
- Rcov::RcovTask.new('provider') do |t|
72
- t.libs << ['lib', 'test/provider']
73
- t.pattern = 'test/provider/tc_*.rb'
74
- t.verbose = true
75
- t.rcov_opts = ['--aggregate coverage.data', '--text-summary']
76
- end
77
-
78
- Rcov::RcovTask.new('activerecord_provider') do |t|
79
- t.libs << ['lib', 'test/activerecord_provider']
80
- t.pattern = 'test/activerecord_provider/tc_*.rb'
81
- t.verbose = true
82
- t.rcov_opts = ['--aggregate coverage.data', '--text-summary']
83
- end
49
+ #t.verbose = true
50
+ t.warning = false
84
51
  end
85
52
  end
86
53
 
data/lib/oai/client.rb CHANGED
@@ -92,11 +92,11 @@ module OAI
92
92
  @http_client = options.fetch(:http) do
93
93
  Faraday.new(:url => @base.clone) do |builder|
94
94
  follow_redirects = options.fetch(:redirects, true)
95
- if follow_redirects
96
- count = follow_redirects.is_a?(Fixnum) ? follow_redirects : 5
95
+ follow_redirects = 5 if follow_redirects == true
97
96
 
97
+ if follow_redirects
98
98
  require 'faraday_middleware'
99
- builder.response :follow_redirects, :limit => count
99
+ builder.response :follow_redirects, :limit => follow_redirects.to_i
100
100
  end
101
101
  builder.adapter :net_http
102
102
  end
data/lib/oai/provider.rb CHANGED
@@ -58,7 +58,9 @@ end
58
58
  # repository_url 'http://localhost/provider'
59
59
  # record_prefix 'oai:localhost'
60
60
  # admin_email 'root@localhost'
61
- # sample_identifier 'oai:pubmedcentral.gov:13900'
61
+ # # record_prefix will be automatically prepended to sample_id, so in this
62
+ # # case it becomes: oai:localhost:13900
63
+ # sample_id '13900'
62
64
  # source_model MyModel.new
63
65
  # end
64
66
  # ```
@@ -107,7 +109,7 @@ end
107
109
  # record_prefix 'oai:blog'
108
110
  # admin_email 'root@localhost'
109
111
  # source_model OAI::Provider::ActiveRecordWrapper.new(Post)
110
- # sample_identifier 'oai:pubmedcentral.gov:13900'
112
+ # sample_id '13900' # record prefix used, so becomes oai:blog:13900
111
113
  # end
112
114
  # ```
113
115
  #
@@ -116,15 +118,25 @@ end
116
118
  # ```ruby
117
119
  # class OaiController < ApplicationController
118
120
  # def index
119
- # # Remove controller and action from the options. Rails adds them automatically.
120
- # options = params.delete_if { |k,v| %w{controller action}.include?(k) }
121
121
  # provider = BlogProvider.new
122
- # response = provider.process_request(options)
123
- # render :text => response, :content_type => 'text/xml'
122
+ # response = provider.process_request(oai_params.to_h)
123
+ # render :body => response, :content_type => 'text/xml'
124
+ # end
125
+ #
126
+ # private
127
+ #
128
+ # def oai_params
129
+ # params.permit(:verb, :identifier, :metadataPrefix, :set, :from, :until, :resumptionToken)
124
130
  # end
125
131
  # end
126
132
  # ```
127
133
  #
134
+ # And route to it in your `config/routes.rb` file:
135
+ #
136
+ # ```ruby
137
+ # match 'oai', to: "oai#index", via: [:get, :post]
138
+ # ```
139
+ #
128
140
  # Special thanks to Jose Hales-Garcia for this solution.
129
141
  #
130
142
  # ## Supporting custom metadata formats
@@ -137,13 +149,19 @@ end
137
149
  # It takes one required paramater, the class name of the AR class to wrap,
138
150
  # and optional hash of options.
139
151
  #
152
+ # As of `oai` gem 1.0.0, Rails 5.2.x and Rails 6.0.x are supported.
153
+ # Please check the .travis.yml file at root of repo to see what versions of ruby/rails
154
+ # are being tested, in case this is out of date.
155
+ #
140
156
  # Valid options include:
141
157
  #
142
- # * `timestamp_field` - Specifies the model field to use as the update
158
+ # * `timestamp_field` - Specifies the model field/method to use as the update
143
159
  # filter. Defaults to `updated_at`.
160
+ # * `identifier_field` -- specifies the model field/method to use to get value to use
161
+ # as oai identifier (method return value should not include prefix)
144
162
  # * `limit` - Maximum number of records to return in each page/set.
145
- # Defaults to 100.
146
- # The wrapper will paginate the result via resumption tokens.
163
+ # Defaults to 100, set to `nil` for all records in one page. Otherwise
164
+ # the wrapper will paginate the result via resumption tokens.
147
165
  # _Caution: specifying too large a limit will adversely affect performance._
148
166
  #
149
167
  # Mapping from a ActiveRecord object to a specific metadata format follows
@@ -197,6 +215,26 @@ end
197
215
  # end
198
216
  # end
199
217
  # ```
218
+ # ### Scopes for restrictions or eager-loading
219
+ #
220
+ # Instead of passing in a Model class to OAI::Provider::ActiveRecordWrapper, you can actually
221
+ # pass in any scope (or ActiveRecord::Relation). This means you can use it for restrictions:
222
+ #
223
+ # OAI::Provider::ActiveRecordWrapper.new(Post.where(published: true))
224
+ #
225
+ # Or eager-loading an association you will need to create serialization, to avoid n+1 query
226
+ # performance problems:
227
+ #
228
+ # OAI::Provider::ActiveRecordWrapper.new(Post.includes(:categories))
229
+ #
230
+ # Or both of those in combination, or anything else that returns an ActiveRecord::Relation,
231
+ # including using custom scopes, etc.
232
+ #
233
+ # ### Sets?
234
+ #
235
+ # There is some code written to support oai-pmh "sets" in the ActiveRecord::Wrapper, but
236
+ # it's somewhat inflexible, and not well-documented, and as I write this I don't understand
237
+ # it enough to say more. See https://github.com/code4lib/ruby-oai/issues/67
200
238
  #
201
239
  module OAI::Provider
202
240
  class Base
@@ -1,12 +1,12 @@
1
1
  module OAI::Provider
2
2
  # = OAI::Provider::Model
3
3
  #
4
- # Model implementers should subclass OAI::Provider::Model and override
4
+ # Model implementers should subclass OAI::Provider::Model and override
5
5
  # Model#earliest, Model#latest, and Model#find. Optionally Model#sets and
6
- # Model#deleted? can be used to support sets and record deletions. It
7
- # is also the responsibility of the model implementer to account for
8
- # resumption tokens if support is required. Models that don't support
9
- # resumption tokens should raise an exception if a limit is requested
6
+ # Model#deleted? can be used to support sets and record deletions. It
7
+ # is also the responsibility of the model implementer to account for
8
+ # resumption tokens if support is required. Models that don't support
9
+ # resumption tokens should raise an exception if a limit is requested
10
10
  # during initialization.
11
11
  #
12
12
  # earliest - should return the earliest update time in the repository.
@@ -14,8 +14,8 @@ module OAI::Provider
14
14
  # sets - should return an array of sets supported by the repository.
15
15
  # deleted? - individual records returned should respond true or false
16
16
  # when sent the deleted? message.
17
- # available_formats - if overridden, individual records should return an
18
- # array of prefixes for all formats in which that record is available,
17
+ # available_formats - if overridden, individual records should return an
18
+ # array of prefixes for all formats in which that record is available,
19
19
  # if other than ["oai_dc"]
20
20
  # about - if overridden, should return a String or Array of XML Strings to
21
21
  # insert into the OAI Record <about> chunks.
@@ -28,12 +28,12 @@ module OAI::Provider
28
28
  # There are several helper models for dealing with resumption tokens please
29
29
  # see the ResumptionToken class for more details.
30
30
  #
31
-
32
31
  class Model
33
- attr_reader :timestamp_field
34
-
35
- def initialize(limit = nil, timestamp_field = 'updated_at')
32
+ attr_reader :timestamp_field, :identifier_field
33
+
34
+ def initialize(limit = nil, timestamp_field = 'updated_at', identifier_field = 'id')
36
35
  @limit = limit
36
+ @identifier_field = identifier_field
37
37
  @timestamp_field = timestamp_field
38
38
  end
39
39
 
@@ -41,16 +41,16 @@ module OAI::Provider
41
41
  def earliest
42
42
  raise NotImplementedError.new
43
43
  end
44
-
44
+
45
45
  # should return the latest timestamp available from this model.
46
46
  def latest
47
47
  raise NotImplementedError.new
48
48
  end
49
-
49
+
50
50
  def sets
51
51
  nil
52
52
  end
53
-
53
+
54
54
  # find is the core method of a model, it returns records from the model
55
55
  # bases on the parameters passed in.
56
56
  #
@@ -61,12 +61,12 @@ module OAI::Provider
61
61
  # * :from => earliest timestamp to be included in the results
62
62
  # * :until => latest timestamp to be included in the results
63
63
  # * :set => the set from which to retrieve the results
64
- # * :metadata_prefix => type of metadata requested (this may be useful if
64
+ # * :metadata_prefix => type of metadata requested (this may be useful if
65
65
  # not all records are available in all formats)
66
66
  def find(selector, options={})
67
67
  raise NotImplementedError.new
68
68
  end
69
-
69
+
70
70
  def deleted?
71
71
  false
72
72
  end
@@ -76,5 +76,5 @@ module OAI::Provider
76
76
  nil
77
77
  end
78
78
  end
79
-
79
+
80
80
  end
@@ -90,17 +90,16 @@ module OAI::Provider
90
90
  # select a subset of the result set, and return it with a
91
91
  # resumption token to get the next subset
92
92
  def select_partial(token)
93
- if 0 == token.last
94
- oaitoken = OaiToken.find_or_create_by(token: token.to_s)
95
- if oaitoken.new_record_before_save?
96
- OaiToken.connection.execute("insert into " +
97
- "#{OaiEntry.table_name} (oai_token_id, record_id) " +
98
- "select #{oaitoken.id}, id from #{model.table_name} where " +
99
- "#{OaiToken.sanitize_sql(token_conditions(token))}")
100
- end
93
+ oaitoken = OaiToken.find_by(token: token.to_s)
94
+
95
+ if 0 == token.last && oaitoken.nil?
96
+ oaitoken = OaiToken.create!(token: token.to_s)
97
+ OaiToken.connection.execute("insert into " +
98
+ "#{OaiEntry.table_name} (oai_token_id, record_id) " +
99
+ "select #{oaitoken.id}, id from #{model.table_name} where " +
100
+ "#{OaiToken.sanitize_sql(token_conditions(token))}")
101
101
  end
102
102
 
103
- oaitoken = OaiToken.find_by_token(token.to_s)
104
103
  raise ResumptionTokenException.new unless oaitoken
105
104
 
106
105
  PartialResult.new(
@@ -111,7 +110,7 @@ module OAI::Provider
111
110
  end
112
111
 
113
112
  def sweep_cache
114
- OaiToken.destroy_all(["created_at < ?", Time.now - expire])
113
+ OaiToken.where(["created_at < ?", Time.now - expire]).destroy_all
115
114
  end
116
115
 
117
116
  def hydrate_records(records)
@@ -10,12 +10,19 @@ module OAI::Provider
10
10
  #
11
11
  class ActiveRecordWrapper < Model
12
12
 
13
- attr_reader :model, :timestamp_field
14
-
13
+ attr_reader :model, :timestamp_field, :identifier_field
14
+
15
+ # If custom 'timestamp_field' is used, be aware this will be an ActiveRecord
16
+ # attribute that we will limit on, so perhaps should be indexe appropriately.
17
+ #
18
+ # If custom `identifier_field` is used, be aware this will be an ActiveRecord
19
+ # attribute that we will sort on, and use in WHERE clauses with `=` as well as
20
+ # greater than/less than, so should be indexed appropriately.
15
21
  def initialize(model, options={})
16
22
  @model = model
17
23
  @timestamp_field = options.delete(:timestamp_field) || 'updated_at'
18
- @limit = options.delete(:limit)
24
+ @identifier_field = options.delete(:identifier_field) || model.primary_key || "id"
25
+ @limit = options.delete(:limit) || 100
19
26
 
20
27
  unless options.empty?
21
28
  raise ArgumentError.new(
@@ -54,7 +61,7 @@ module OAI::Provider
54
61
  find_scope.where(conditions)
55
62
  end
56
63
  else
57
- find_scope.where(conditions).find(selector)
64
+ find_scope.where(conditions).find_by!(identifier_field => selector)
58
65
  end
59
66
  end
60
67
 
@@ -105,7 +112,7 @@ module OAI::Provider
105
112
  model.where(set: options[:set])
106
113
  else
107
114
  # Default to empty set, as we've tried everything else
108
- model.scoped(:limit => 0)
115
+ model.none
109
116
  end
110
117
  end
111
118
 
@@ -129,7 +136,7 @@ module OAI::Provider
129
136
  else # end of result set
130
137
  find_scope.where(token_conditions(token))
131
138
  .limit(@limit)
132
- .order("#{model.primary_key} asc")
139
+ .order("#{identifier_field} asc")
133
140
  end
134
141
  end
135
142
 
@@ -138,9 +145,9 @@ module OAI::Provider
138
145
  def select_partial(find_scope, token)
139
146
  records = find_scope.where(token_conditions(token))
140
147
  .limit(@limit)
141
- .order("#{model.primary_key} asc")
148
+ .order("#{identifier_field} asc")
142
149
  raise OAI::ResumptionTokenException.new unless records
143
- offset = records.last.send(model.primary_key.to_sym)
150
+ offset = records.last.send(identifier_field)
144
151
 
145
152
  PartialResult.new(records, token.next(offset))
146
153
  end
@@ -157,7 +164,7 @@ module OAI::Provider
157
164
 
158
165
  return sql if 0 == last
159
166
  # Now add last id constraint
160
- sql.first << " AND #{model.primary_key} > :id"
167
+ sql.first << " AND #{identifier_field} > :id"
161
168
  sql.last[:id] = last
162
169
 
163
170
  return sql
@@ -51,7 +51,7 @@ module OAI
51
51
  }
52
52
  end
53
53
  def extract_identifier(id)
54
- id.sub("#{provider.prefix}/", '')
54
+ id.sub("#{provider.prefix}:", '')
55
55
  end
56
56
 
57
57
  def valid?
@@ -48,8 +48,9 @@ module OAI::Provider::Response
48
48
 
49
49
  private
50
50
 
51
+ # Namespace syntax suggested in http://www.openarchives.org/OAI/2.0/guidelines-oai-identifier.htm
51
52
  def identifier_for(record)
52
- "#{provider.prefix}/#{record.id}"
53
+ "#{provider.prefix}:#{record.send( provider.model.identifier_field )}"
53
54
  end
54
55
 
55
56
  def timestamp_for(record)
@@ -3,7 +3,24 @@ require 'logger'
3
3
 
4
4
  # Configure AR connection
5
5
  #ActiveRecord::Base.logger = Logger.new(STDOUT)
6
+
7
+ if RUBY_PLATFORM == "java"
8
+ require 'jdbc/sqlite3'
9
+ Jdbc::SQLite3.load_driver
10
+ end
11
+
6
12
  ActiveRecord::Migration.verbose = false
7
13
  ActiveRecord::Base.establish_connection :adapter => "sqlite3",
8
14
  :database => ":memory:"
9
- ActiveRecord::Migrator.up File.join(File.dirname(__FILE__), '..', 'database')
15
+
16
+ if ActiveRecord.version < Gem::Version.new("6.0.0")
17
+ ActiveRecord::MigrationContext.new(
18
+ File.join(File.dirname(__FILE__), '..', 'database')
19
+ ).migrate
20
+ else
21
+ ActiveRecord::MigrationContext.new(
22
+ File.join(File.dirname(__FILE__), '..', 'database'),
23
+ ActiveRecord::Base.connection.schema_migration
24
+ ).migrate
25
+ end
26
+
@@ -1,4 +1,4 @@
1
- class OaipmhTables < ActiveRecord::Migration
1
+ class OaipmhTables < ActiveRecord::Migration[5.2]
2
2
  def self.up
3
3
  create_table :oai_tokens do |t|
4
4
  t.column :token, :string, :null => false
@@ -12,6 +12,22 @@ class ARProvider < OAI::Provider::Base
12
12
  source_model ActiveRecordWrapper.new(DCField)
13
13
  end
14
14
 
15
+ class ARProviderCustomIdentifierField < OAI::Provider::Base
16
+ repository_name 'ActiveRecord Based Provider'
17
+ repository_url 'http://localhost'
18
+ record_prefix 'oai:test'
19
+ source_model ActiveRecordWrapper.new(DCField, identifier_field: "source")
20
+ end
21
+
22
+ class ARProviderWithScope < OAI::Provider::Base
23
+ DATE_LESS_THAN_RESTRICTION = Time.parse("2007-03-12 19:30:22 UTC")
24
+
25
+ repository_name 'ActiveRecord Based Provider'
26
+ repository_url 'http://localhost'
27
+ record_prefix 'oai:test'
28
+ source_model ActiveRecordWrapper.new(DCField.where("date < ?", DATE_LESS_THAN_RESTRICTION).includes(:sets))
29
+ end
30
+
15
31
  class SimpleResumptionProvider < OAI::Provider::Base
16
32
  repository_name 'ActiveRecord Resumption Provider'
17
33
  repository_url 'http://localhost'
@@ -3,7 +3,7 @@ class ExclusiveSetDCField < ActiveRecord::Base
3
3
 
4
4
  def self.sets
5
5
  klass = Struct.new(:name, :spec)
6
- self.uniq.pluck('`set`').compact.map do |spec|
6
+ self.distinct.pluck(:set).compact.map do |spec|
7
7
  klass.new("Set #{spec}", spec)
8
8
  end
9
9
  end
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_ar_provider'
2
2
 
3
3
  class ActiveRecordProviderTest < TransactionalTestCase
4
4
 
@@ -14,7 +14,7 @@ class ActiveRecordProviderTest < TransactionalTestCase
14
14
 
15
15
  def test_metadata_formats_for_record
16
16
  record_id = DCField.first.id
17
- assert_nothing_raised { REXML::Document.new(@provider.list_metadata_formats(:identifier => "oai:test/#{record_id}")) }
17
+ assert_nothing_raised { REXML::Document.new(@provider.list_metadata_formats(:identifier => "oai:test:#{record_id}")) }
18
18
  doc = REXML::Document.new(@provider.list_metadata_formats)
19
19
  assert doc.elements['/OAI-PMH/ListMetadataFormats/metadataFormat/metadataPrefix'].text == 'oai_dc'
20
20
  end
@@ -28,6 +28,30 @@ class ActiveRecordProviderTest < TransactionalTestCase
28
28
  assert_equal 100, doc.elements['OAI-PMH/ListRecords'].to_a.size
29
29
  end
30
30
 
31
+ def test_list_records_scope
32
+ @provider = ARProviderWithScope.new
33
+
34
+ doc = nil
35
+ assert_nothing_raised do
36
+ doc = REXML::Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
37
+ end
38
+
39
+ expected_count = DCField.where("date < ?", ARProviderWithScope::DATE_LESS_THAN_RESTRICTION).count
40
+ assert_equal expected_count, doc.elements['OAI-PMH/ListRecords'].to_a.size
41
+ end
42
+
43
+
44
+ def test_get_record_alternate_identifier_column
45
+ @provider = ARProviderCustomIdentifierField.new
46
+
47
+ record_id = DCField.first.send(@provider.class.model.identifier_field)
48
+
49
+ doc = REXML::Document.new(@provider.get_record(
50
+ :identifier => "oai:test:#{record_id}", :metadata_prefix => 'oai_dc'))
51
+
52
+ assert_equal "oai:test:#{record_id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
53
+ end
54
+
31
55
  def test_list_identifiers
32
56
  assert_nothing_raised { REXML::Document.new(@provider.list_identifiers) }
33
57
  doc = REXML::Document.new(@provider.list_identifiers)
@@ -38,11 +62,11 @@ class ActiveRecordProviderTest < TransactionalTestCase
38
62
  record_id = DCField.first.id
39
63
  assert_nothing_raised do
40
64
  REXML::Document.new(@provider.get_record(
41
- :identifier => "oai:test/#{record_id}", :metadata_prefix => 'oai_dc'))
65
+ :identifier => "oai:test:#{record_id}", :metadata_prefix => 'oai_dc'))
42
66
  end
43
67
  doc = REXML::Document.new(@provider.get_record(
44
68
  :identifier => "#{record_id}", :metadata_prefix => 'oai_dc'))
45
- assert_equal "oai:test/#{record_id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
69
+ assert_equal "oai:test:#{record_id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
46
70
  end
47
71
 
48
72
  def test_deleted
@@ -50,8 +74,8 @@ class ActiveRecordProviderTest < TransactionalTestCase
50
74
  record.deleted = true;
51
75
  record.save
52
76
  doc = REXML::Document.new(@provider.get_record(
53
- :identifier => "oai:test/#{record.id}", :metadata_prefix => 'oai_dc'))
54
- assert_equal "oai:test/#{record.id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
77
+ :identifier => "oai:test:#{record.id}", :metadata_prefix => 'oai_dc'))
78
+ assert_equal "oai:test:#{record.id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
55
79
  assert_equal 'deleted', doc.elements['OAI-PMH/GetRecord/record/header'].attributes["status"]
56
80
  end
57
81
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_ar_provider'
2
2
 
3
3
  class ActiveRecordSetProviderTest < TransactionalTestCase
4
4
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_ar_provider'
2
2
 
3
3
  class CachingPagingProviderTest < TransactionalTestCase
4
4
  include REXML
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_ar_provider'
2
2
 
3
3
  class SimpleResumptionProviderTest < TransactionalTestCase
4
4
  include REXML
@@ -1,12 +1,5 @@
1
1
  require 'rubygems'
2
2
 
3
- if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.9/
4
- require 'simplecov'
5
- require 'simplecov-rcov'
6
-
7
- SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
8
- SimpleCov.start
9
- end
10
3
  require 'test/unit'
11
4
  require File.dirname(__FILE__) + '/config/connection'
12
5
  require File.dirname(__FILE__) + '/helpers/providers'
@@ -1,20 +1,20 @@
1
1
  require 'webrick'
2
2
  require File.dirname(__FILE__) + '/../../provider/models'
3
3
 
4
- class ComplexProvider < OAI::Provider::Base
5
- repository_name 'Complex Provider'
6
- repository_url 'http://localhost'
7
- record_prefix 'oai:test'
8
- source_model ComplexModel.new(100)
9
- end
10
4
 
11
5
  class ProviderServer
6
+ class ComplexClientProvider < OAI::Provider::Base
7
+ repository_name 'Complex Provider'
8
+ repository_url 'http://localhost'
9
+ record_prefix 'oai:test'
10
+ source_model ComplexModel.new(100)
11
+ end
12
12
 
13
13
  attr_reader :consumed, :server
14
14
 
15
15
  def initialize(port, mount_point)
16
16
  @consumed = []
17
- @provider = ComplexProvider.new
17
+ @provider = ComplexClientProvider.new
18
18
  @server = WEBrick::HTTPServer.new(
19
19
  :BindAddress => '127.0.0.1',
20
20
  :Logger => WEBrick::Log.new('/dev/null'),
@@ -62,4 +62,4 @@ class ProviderServer
62
62
  end
63
63
  end
64
64
 
65
- end
65
+ end
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class ExceptionTest < Test::Unit::TestCase
4
4
 
@@ -9,7 +9,7 @@ class ExceptionTest < Test::Unit::TestCase
9
9
 
10
10
  def test_xml_error
11
11
  client = OAI::Client.new 'http://www.yahoo.com'
12
- begin
12
+ begin
13
13
  client.identify
14
14
  rescue OAI::Exception => e
15
15
  assert_match /response not well formed XML/, e.to_s, 'xml error'
@@ -23,7 +23,7 @@ class ExceptionTest < Test::Unit::TestCase
23
23
  end
24
24
  end
25
25
 
26
- # must pass in options as a hash
26
+ # must pass in options as a hash
27
27
  def test_parameter_error
28
28
  client = OAI::Client.new 'http://localhost:3333/oai'
29
29
  assert_raises(OAI::ArgumentException) {client.get_record('foo')}
@@ -32,5 +32,5 @@ class ExceptionTest < Test::Unit::TestCase
32
32
  assert_raises(OAI::ArgumentException) {client.list_metadata_formats('foo')}
33
33
  assert_raises(OAI::ArgumentException) {client.list_sets('foo')}
34
34
  end
35
-
35
+
36
36
  end
@@ -1,10 +1,10 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class GetRecordTest < Test::Unit::TestCase
4
-
4
+
5
5
  def test_get_one
6
6
  client = OAI::Client.new 'http://localhost:3333/oai'
7
- response = client.get_record :identifier => 'oai:test/3'
7
+ response = client.get_record :identifier => 'oai:test:3'
8
8
  assert_kind_of OAI::GetRecordResponse, response
9
9
  assert_kind_of OAI::Record, response.record
10
10
  assert_kind_of REXML::Element, response.record._source
@@ -13,8 +13,7 @@ class GetRecordTest < Test::Unit::TestCase
13
13
  assert_kind_of REXML::Element, response.record.about
14
14
 
15
15
  # minimal check that the header is working
16
- assert_equal 'oai:test/3',
17
- response.record.header.identifier
16
+ assert_equal 'oai:test:3', response.record.header.identifier
18
17
 
19
18
  # minimal check that the metadata is working
20
19
  #assert 'en', response.record.metadata.elements['.//dc:language'].text
@@ -33,7 +32,7 @@ class GetRecordTest < Test::Unit::TestCase
33
32
 
34
33
  def test_deleted_record
35
34
  client = OAI::Client.new 'http://localhost:3333/oai'
36
- record = client.get_record :identifier => 'oai:test/275'
35
+ record = client.get_record :identifier => 'oai:test:275'
37
36
  assert record.deleted?
38
37
  end
39
38
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
  require 'webrick'
3
3
 
4
4
  class HttpClientTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class IdentifyTest < Test::Unit::TestCase
4
4
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class LibXMLTest < Test::Unit::TestCase
4
4
 
@@ -13,7 +13,7 @@ class LibXMLTest < Test::Unit::TestCase
13
13
  def test_list_records
14
14
  return unless have_libxml
15
15
 
16
- # since there is regex magic going on to remove default oai namespaces
16
+ # since there is regex magic going on to remove default oai namespaces
17
17
  # it's worth trying a few different oai targets
18
18
  oai_targets = %w{
19
19
  http://localhost:3333/oai
@@ -43,10 +43,10 @@ class LibXMLTest < Test::Unit::TestCase
43
43
 
44
44
  uri = 'http://localhost:3333/oai'
45
45
  client = OAI::Client.new(uri, :parser => 'libxml')
46
- response = client.get_record :identifier => 'oai:test/275'
46
+ response = client.get_record :identifier => 'oai:test:275'
47
47
  assert response.record.deleted?
48
48
  end
49
-
49
+
50
50
  private
51
51
 
52
52
  def have_libxml
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class ListIdentifiersTest < Test::Unit::TestCase
4
4
 
@@ -1,8 +1,8 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class ListMetadataFormatsTest < Test::Unit::TestCase
4
4
  def test_list
5
- client = OAI::Client.new 'http://localhost:3333/oai'
5
+ client = OAI::Client.new 'http://localhost:3333/oai'
6
6
  response = client.list_metadata_formats
7
7
  assert_kind_of OAI::ListMetadataFormatsResponse, response
8
8
  assert response.entries.size > 0
@@ -13,6 +13,6 @@ class ListMetadataFormatsTest < Test::Unit::TestCase
13
13
  assert_equal 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd', format.schema
14
14
  assert_equal 'http://www.openarchives.org/OAI/2.0/oai_dc/', format.namespace
15
15
  end
16
-
16
+
17
17
  end
18
18
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class ListRecordsTest < Test::Unit::TestCase
4
4
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class ListSetsTest < Test::Unit::TestCase
4
4
 
@@ -1,14 +1,14 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class LowResolutionDatesTest < Test::Unit::TestCase
4
4
 
5
5
  def test_low_res_date_parsing
6
- client = OAI::Client.new 'http://authors.library.caltech.edu/cgi/oai2'
6
+ client = OAI::Client.new 'http://authors.library.caltech.edu/cgi/oai2'
7
7
 
8
8
  date = Date.new 2003, 1, 1
9
-
9
+
10
10
  # get a list of identifier headers
11
- assert_nothing_raised { client.list_identifiers :from => date }
11
+ assert_nothing_raised { client.list_identifiers :from => date }
12
12
  end
13
-
13
+
14
14
  end
@@ -1,7 +1,7 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class UTF8Test < Test::Unit::TestCase
4
-
4
+
5
5
  def test_escaping_invalid_utf_8_characters
6
6
  client = OAI::Client.new 'http://localhost:3333/oai' #, :parser => 'libxml'
7
7
  invalid_utf_8 = [2, 3, 4, 104, 5, 101, 6, 108, 66897, 108, 66535, 111, 1114112, 33, 55234123, 33].pack("U*")
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_client'
2
2
 
3
3
  class XpathTest < Test::Unit::TestCase
4
4
  include OAI::XPath
@@ -11,7 +11,7 @@ class XpathTest < Test::Unit::TestCase
11
11
  end
12
12
 
13
13
  def test_libxml
14
- begin
14
+ begin
15
15
  require 'xml/libxml'
16
16
  rescue LoadError
17
17
  # libxml not available so nothing to test!
@@ -0,0 +1,5 @@
1
+ require 'oai'
2
+ require 'test/unit'
3
+
4
+ require File.dirname(__FILE__) + '/helpers/provider'
5
+ require File.dirname(__FILE__) + '/helpers/test_wrapper'
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_provider'
2
2
 
3
3
  class ProviderExceptions < Test::Unit::TestCase
4
4
 
@@ -36,7 +36,7 @@ class ProviderExceptions < Test::Unit::TestCase
36
36
 
37
37
  def test_bad_format_raises_exception
38
38
  assert_raise(OAI::FormatException) do
39
- @provider.get_record(:identifier => 'oai:test/1', :metadata_prefix => 'html')
39
+ @provider.get_record(:identifier => 'oai:test:1', :metadata_prefix => 'html')
40
40
  end
41
41
  end
42
42
 
@@ -45,16 +45,18 @@ class ProviderExceptions < Test::Unit::TestCase
45
45
  @provider.list_records()
46
46
  end
47
47
  assert_raise(OAI::ArgumentException) do
48
- @provider.get_record(:identifier => 'oai:test/1')
48
+ @provider.get_record(:identifier => 'oai:test:1')
49
49
  end
50
50
  end
51
51
 
52
52
  def test_bad_id_raises_exception
53
53
  badIdentifiers = [
54
- 'oai:test/5000',
55
- 'oai:test/-1',
54
+ 'oai:test:5000',
55
+ 'oai:test:-1',
56
+ 'oai:test:one',
56
57
  'oai:test/one',
57
- 'oai:test/\\$1\1!']
58
+ 'oai:test/1',
59
+ 'oai:test:\\$1\1!']
58
60
  badIdentifiers.each do |id|
59
61
  assert_raise(OAI::IdException) do
60
62
  @provider.get_record(:identifier => id, :metadata_prefix => 'oai_dc')
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_provider'
2
2
 
3
3
  class ResumptionTokenFunctionalTest < Test::Unit::TestCase
4
4
  include REXML
@@ -44,4 +44,4 @@ class ResumptionTokenFunctionalTest < Test::Unit::TestCase
44
44
  assert_equal 100, doc.elements["/OAI-PMH/ListRecords"].to_a.size
45
45
  end
46
46
 
47
- end
47
+ end
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_provider'
2
2
 
3
3
  class OaiTest < Test::Unit::TestCase
4
4
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_provider'
2
2
 
3
3
  class ResumptionTokenTest < Test::Unit::TestCase
4
4
  include REXML
@@ -43,4 +43,4 @@ class ResumptionTokenTest < Test::Unit::TestCase
43
43
  assert_equal "#{@token.to_s}:#{@token.last}", doc.elements['/resumptionToken'].text
44
44
  end
45
45
 
46
- end
46
+ end
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper_provider'
2
2
 
3
3
  class TestSimpleProvider < Test::Unit::TestCase
4
4
 
@@ -35,7 +35,7 @@ class TestSimpleProvider < Test::Unit::TestCase
35
35
  end
36
36
 
37
37
  def test_metadata_formats_for_document
38
- assert_nothing_raised { REXML::Document.new(@simple_provider.list_metadata_formats(:identifier => "oai:test/1")) }
38
+ assert_nothing_raised { REXML::Document.new(@simple_provider.list_metadata_formats(:identifier => "oai:test:1")) }
39
39
  doc = REXML::Document.new(@simple_provider.list_metadata_formats)
40
40
  assert_equal "oai_dc",
41
41
  doc.elements['/OAI-PMH/ListMetadataFormats/metadataFormat/metadataPrefix'].text
@@ -85,18 +85,18 @@ class TestSimpleProvider < Test::Unit::TestCase
85
85
  assert_nothing_raised do
86
86
  REXML::Document.new(
87
87
  @simple_provider.get_record(
88
- :identifier => 'oai:test/1',
88
+ :identifier => 'oai:test:1',
89
89
  :metadataPrefix => 'oai_dc'
90
90
  )
91
91
  )
92
92
  end
93
93
  doc = REXML::Document.new(
94
94
  @simple_provider.get_record(
95
- :identifier => 'oai:test/1',
95
+ :identifier => 'oai:test:1',
96
96
  :metadataPrefix => 'oai_dc'
97
97
  )
98
98
  )
99
- assert_equal 'oai:test/1',
99
+ assert_equal 'oai:test:1',
100
100
  doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
101
101
  end
102
102
 
@@ -104,18 +104,18 @@ class TestSimpleProvider < Test::Unit::TestCase
104
104
  assert_nothing_raised do
105
105
  REXML::Document.new(
106
106
  @simple_provider.get_record(
107
- :identifier => 'oai:test/6',
107
+ :identifier => 'oai:test:6',
108
108
  :metadataPrefix => 'oai_dc'
109
109
  )
110
110
  )
111
111
  end
112
112
  doc = REXML::Document.new(
113
113
  @simple_provider.get_record(
114
- :identifier => 'oai:test/5',
114
+ :identifier => 'oai:test:5',
115
115
  :metadataPrefix => 'oai_dc'
116
116
  )
117
117
  )
118
- assert_equal 'oai:test/5', doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
118
+ assert_equal 'oai:test:5', doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
119
119
  assert_equal 'deleted', doc.elements['OAI-PMH/GetRecord/record/header'].attributes["status"]
120
120
  end
121
121
 
@@ -1,10 +1,3 @@
1
- if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.9/
2
- require 'simplecov'
3
- require 'simplecov-rcov'
4
-
5
- SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
6
- SimpleCov.start
7
- end
8
1
  require 'oai'
9
2
  require 'test/unit'
10
3
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ed Summers
8
8
  autorequire: oai
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-08 00:00:00.000000000 Z
11
+ date: 2019-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -52,6 +52,40 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 5.2.0
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '6.1'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 5.2.0
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '6.1'
75
+ - !ruby/object:Gem::Dependency
76
+ name: appraisal
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
55
89
  description:
56
90
  email: ehs@pobox.com
57
91
  executables:
@@ -119,7 +153,7 @@ files:
119
153
  - test/activerecord_provider/tc_ar_sets_provider.rb
120
154
  - test/activerecord_provider/tc_caching_paging_provider.rb
121
155
  - test/activerecord_provider/tc_simple_paging_provider.rb
122
- - test/activerecord_provider/test_helper.rb
156
+ - test/activerecord_provider/test_helper_ar_provider.rb
123
157
  - test/client/helpers/provider.rb
124
158
  - test/client/helpers/test_wrapper.rb
125
159
  - test/client/tc_exception.rb
@@ -134,14 +168,14 @@ files:
134
168
  - test/client/tc_low_resolution_dates.rb
135
169
  - test/client/tc_utf8_escaping.rb
136
170
  - test/client/tc_xpath.rb
137
- - test/client/test_helper.rb
171
+ - test/client/test_helper_client.rb
138
172
  - test/provider/models.rb
139
173
  - test/provider/tc_exceptions.rb
140
174
  - test/provider/tc_functional_tokens.rb
141
175
  - test/provider/tc_provider.rb
142
176
  - test/provider/tc_resumption_tokens.rb
143
177
  - test/provider/tc_simple_provider.rb
144
- - test/provider/test_helper.rb
178
+ - test/provider/test_helper_provider.rb
145
179
  - test/test.xml
146
180
  homepage: http://github.com/code4lib/ruby-oai
147
181
  licenses: []
@@ -157,15 +191,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
157
191
  version: '0'
158
192
  required_rubygems_version: !ruby/object:Gem::Requirement
159
193
  requirements:
160
- - - ">="
194
+ - - ">"
161
195
  - !ruby/object:Gem::Version
162
- version: '0'
196
+ version: 1.3.1
163
197
  requirements: []
164
- rubyforge_project:
165
- rubygems_version: 2.2.1
198
+ rubygems_version: 3.0.3
166
199
  signing_key:
167
200
  specification_version: 4
168
201
  summary: A ruby library for working with the Open Archive Initiative Protocol for
169
202
  Metadata Harvesting (OAI-PMH)
170
203
  test_files: []
171
- has_rdoc:
@@ -1,13 +0,0 @@
1
- if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.9/
2
- require 'simplecov'
3
- require 'simplecov-rcov'
4
-
5
- SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
6
- SimpleCov.start
7
- end
8
-
9
- require 'oai'
10
- require 'test/unit'
11
-
12
- require File.dirname(__FILE__) + '/helpers/provider'
13
- require File.dirname(__FILE__) + '/helpers/test_wrapper'