oai 0.4.0 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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'