pupa 0.1.11 → 0.2.0
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 +4 -4
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/.yardopts +0 -1
- data/Gemfile +1 -3
- data/LICENSE +1 -1
- data/PERFORMANCE.md +1 -1
- data/README.md +19 -23
- data/Rakefile +2 -2
- data/lib/pupa.rb +0 -1
- data/lib/pupa/models/concerns/timestamps.rb +1 -1
- data/lib/pupa/processor/connection.rb +1 -1
- data/lib/pupa/processor/connection_adapters/mongodb_adapter.rb +5 -5
- data/lib/pupa/processor/connection_adapters/postgresql_adapter.rb +1 -1
- data/lib/pupa/processor/document_store/file_store.rb +2 -0
- data/lib/pupa/refinements/faraday_middleware.rb +3 -1
- data/lib/pupa/version.rb +1 -1
- data/pupa.gemspec +9 -9
- data/spec/models/area_spec.rb +1 -1
- data/spec/models/concerns/contactable_spec.rb +8 -8
- data/spec/models/concerns/identifiable_spec.rb +7 -7
- data/spec/models/concerns/linkable_spec.rb +3 -3
- data/spec/models/concerns/nameable_spec.rb +3 -3
- data/spec/models/concerns/sourceable_spec.rb +3 -3
- data/spec/models/concerns/timestamps_spec.rb +4 -4
- data/spec/models/contact_detail_list_spec.rb +6 -6
- data/spec/models/identifier_list_spec.rb +2 -2
- data/spec/models/membership_spec.rb +3 -3
- data/spec/models/model_spec.rb +32 -32
- data/spec/models/motion_spec.rb +1 -1
- data/spec/models/organization_spec.rb +3 -3
- data/spec/models/person_spec.rb +3 -3
- data/spec/models/post_spec.rb +2 -2
- data/spec/models/vote_event_spec.rb +8 -8
- data/spec/models/vote_spec.rb +1 -1
- data/spec/processor/client_spec.rb +4 -4
- data/spec/processor/connection_adapters/mongodb_adapter_spec.rb +8 -8
- data/spec/processor/connection_adapters/postgresql_adapter_spec.rb +1 -62
- data/spec/processor/connection_adapters/sqlite_adapter_spec.rb +5 -0
- data/spec/processor/connection_spec.rb +2 -2
- data/spec/processor/document_store/file_store_spec.rb +19 -19
- data/spec/processor/document_store/redis_store_spec.rb +18 -18
- data/spec/processor/document_store_spec.rb +2 -2
- data/spec/processor/middleware/logger_spec.rb +7 -7
- data/spec/processor/middleware/parse_json_spec.rb +1 -1
- data/spec/processor/yielder_spec.rb +4 -4
- data/spec/processor_spec.rb +41 -41
- data/spec/runner_spec.rb +9 -9
- data/spec/spec_helper.rb +9 -1
- data/spec/support/shared_examples_for_connection_adapters.rb +66 -0
- metadata +38 -35
- data/USAGE +0 -1
data/spec/processor_spec.rb
CHANGED
@@ -37,28 +37,28 @@ describe Pupa::Processor do
|
|
37
37
|
|
38
38
|
describe '#get' do
|
39
39
|
it 'should send a GET request' do
|
40
|
-
processor.get('http://httpbin.org/get', 'foo=bar')['args'].
|
40
|
+
expect(processor.get('http://httpbin.org/get', 'foo=bar')['args']).to eq({'foo' => 'bar'})
|
41
41
|
end
|
42
42
|
|
43
43
|
it 'should automatically parse the response' do
|
44
|
-
processor.get('http://httpbin.org/get').
|
44
|
+
expect(processor.get('http://httpbin.org/get')).to be_a(Hash)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
describe '#post' do
|
49
49
|
it 'should send a POST request' do
|
50
|
-
processor.post('http://httpbin.org/post', 'foo=bar')['form'].
|
50
|
+
expect(processor.post('http://httpbin.org/post', 'foo=bar')['form']).to eq({'foo' => 'bar'})
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should automatically parse the response' do
|
54
|
-
processor.post('http://httpbin.org/post').
|
54
|
+
expect(processor.post('http://httpbin.org/post')).to be_a(Hash)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
describe '.add_scraping_task' do
|
59
59
|
it 'should add a scraping task and define a lazy method' do
|
60
|
-
PersonProcessor.tasks.
|
61
|
-
processor.
|
60
|
+
expect(PersonProcessor.tasks).to eq([:people])
|
61
|
+
expect(processor).to respond_to(:people)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -68,7 +68,7 @@ describe Pupa::Processor do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'should return the number of scraped objects by type' do
|
71
|
-
processor.dump_scraped_objects(:people).
|
71
|
+
expect(processor.dump_scraped_objects(:people)).to eq({'pupa/person' => 1})
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'should not overwrite an existing file' do
|
@@ -79,20 +79,20 @@ describe Pupa::Processor do
|
|
79
79
|
|
80
80
|
it 'should dump a JSON document' do
|
81
81
|
processor.dump_scraped_objects(:people)
|
82
|
-
File.exist?(path).
|
83
|
-
io.string.
|
82
|
+
expect(File.exist?(path)).to eq(true)
|
83
|
+
expect(io.string).not_to match("The property '#/")
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'should validate the object' do
|
87
87
|
processor.make_person_invalid
|
88
88
|
processor.dump_scraped_objects(:people)
|
89
|
-
io.string.
|
89
|
+
expect(io.string).to match("The property '#/name' of type array did not match one or more of the following types: string, null")
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'should not validate the object' do
|
93
93
|
novalidate.make_person_invalid
|
94
94
|
novalidate.dump_scraped_objects(:people)
|
95
|
-
io.string.
|
95
|
+
expect(io.string).not_to match("The property '#/name' of type array did not match one or more of the following types: string, null")
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -161,53 +161,53 @@ describe Pupa::Processor do
|
|
161
161
|
end
|
162
162
|
|
163
163
|
it 'should use a dependency graph if possible' do
|
164
|
-
processor.
|
164
|
+
expect(processor).to receive(:load_scraped_objects).and_return(graphable)
|
165
165
|
|
166
|
-
Pupa::Processor::DependencyGraph.
|
166
|
+
expect_any_instance_of(Pupa::Processor::DependencyGraph).to receive(:tsort).and_return(['2', '1'])
|
167
167
|
processor.import
|
168
168
|
end
|
169
169
|
|
170
170
|
it 'should remove duplicate objects and re-assign foreign keys' do
|
171
|
-
processor.
|
171
|
+
expect(processor).to receive(:load_scraped_objects).and_return(graphable)
|
172
172
|
|
173
173
|
processor.import
|
174
174
|
documents = processor.connection.raw_connection[:organizations].find.entries
|
175
|
-
documents.size.
|
176
|
-
documents[0].slice('_id', '_type', 'name', 'parent_id').
|
177
|
-
documents[1].slice('_id', '_type', 'name', 'parent_id').
|
175
|
+
expect(documents.size).to eq(2)
|
176
|
+
expect(documents[0].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '2', '_type' => _type, 'name' => 'Parent'})
|
177
|
+
expect(documents[1].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '1', '_type' => _type, 'name' => 'Child', 'parent_id' => '2'})
|
178
178
|
end
|
179
179
|
|
180
180
|
it 'should not use a dependency graph if not possible' do
|
181
|
-
processor.
|
181
|
+
expect(processor).to receive(:load_scraped_objects).and_return(ungraphable)
|
182
182
|
|
183
|
-
Pupa::Processor::DependencyGraph.
|
183
|
+
expect_any_instance_of(Pupa::Processor::DependencyGraph).not_to receive(:tsort)
|
184
184
|
processor.import
|
185
185
|
end
|
186
186
|
|
187
187
|
it 'should remove duplicate objects and resolve foreign objects' do
|
188
|
-
processor.
|
188
|
+
expect(processor).to receive(:load_scraped_objects).and_return(ungraphable)
|
189
189
|
|
190
190
|
processor.import
|
191
191
|
documents = processor.connection.raw_connection[:organizations].find.entries
|
192
|
-
documents.size.
|
193
|
-
documents[0].slice('_id', '_type', 'name', 'parent_id').
|
194
|
-
documents[1].slice('_id', '_type', 'name', 'parent_id').
|
192
|
+
expect(documents.size).to eq(2)
|
193
|
+
expect(documents[0].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '5', '_type' => _type, 'name' => 'Parent'})
|
194
|
+
expect(documents[1].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '4', '_type' => _type, 'name' => 'Child', 'parent_id' => '5'})
|
195
195
|
end
|
196
196
|
|
197
197
|
it 'should resolve foreign keys on foreign objects' do
|
198
|
-
processor.
|
198
|
+
expect(processor).to receive(:load_scraped_objects).and_return(foreign_keys_on_foreign_objects)
|
199
199
|
|
200
200
|
processor.import
|
201
201
|
documents = processor.connection.raw_connection[:organizations].find.entries
|
202
|
-
documents.size.
|
203
|
-
documents[0].slice('_id', '_type', 'name', 'parent_id').
|
204
|
-
documents[1].slice('_id', '_type', 'name', 'parent_id').
|
205
|
-
documents[2].slice('_id', '_type', 'name', 'parent_id').
|
202
|
+
expect(documents.size).to eq(3)
|
203
|
+
expect(documents[0].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '9', '_type' => _type, 'name' => 'Parent'})
|
204
|
+
expect(documents[1].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '7', '_type' => _type, 'name' => 'Child', 'parent_id' => '9'})
|
205
|
+
expect(documents[2].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '8', '_type' => _type, 'name' => 'Grandchild', 'parent_id' => '7'})
|
206
206
|
end
|
207
207
|
|
208
208
|
context 'with existing documents' do
|
209
209
|
before :each do
|
210
|
-
processor.
|
210
|
+
expect(processor).to receive(:load_scraped_objects).and_return(graphable)
|
211
211
|
processor.import
|
212
212
|
end
|
213
213
|
|
@@ -307,39 +307,39 @@ describe Pupa::Processor do
|
|
307
307
|
end
|
308
308
|
|
309
309
|
it 'should resolve foreign keys' do
|
310
|
-
processor.
|
310
|
+
expect(processor).to receive(:load_scraped_objects).and_return(resolvable_foreign_key)
|
311
311
|
|
312
312
|
processor.import
|
313
313
|
documents = processor.connection.raw_connection[:organizations].find.entries
|
314
|
-
documents.size.
|
315
|
-
documents[0].slice('_id', '_type', 'name', 'parent_id').
|
316
|
-
documents[1].slice('_id', '_type', 'name', 'parent_id').
|
314
|
+
expect(documents.size).to eq(2)
|
315
|
+
expect(documents[0].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '2', '_type' => _type, 'name' => 'Parent'})
|
316
|
+
expect(documents[1].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '1', '_type' => _type, 'name' => 'Child', 'parent_id' => '2'})
|
317
317
|
end
|
318
318
|
|
319
319
|
it 'should raise an error if a foreign key cannot be resolved' do
|
320
|
-
processor.
|
320
|
+
expect(processor).to receive(:load_scraped_objects).and_return(unresolvable_foreign_key)
|
321
321
|
expect{processor.import}.to raise_error(Pupa::Errors::UnprocessableEntity)
|
322
322
|
end
|
323
323
|
|
324
324
|
it 'should raise an error if a foreign object cannot be resolved' do
|
325
|
-
processor.
|
325
|
+
expect(processor).to receive(:load_scraped_objects).and_return(unresolvable_foreign_object)
|
326
326
|
expect{processor.import}.to raise_error(Pupa::Errors::UnprocessableEntity)
|
327
327
|
end
|
328
328
|
|
329
329
|
it 'should raise an error if a duplicate was inadvertently saved' do
|
330
|
-
processor.
|
330
|
+
expect(processor).to receive(:load_scraped_objects).and_return(duplicate_documents)
|
331
331
|
expect{processor.import}.to raise_error(Pupa::Errors::DuplicateDocumentError)
|
332
332
|
end
|
333
333
|
|
334
334
|
it 'should resolve foreign keys on foreign objects' do
|
335
|
-
processor.
|
335
|
+
expect(processor).to receive(:load_scraped_objects).and_return(resolvable_foreign_keys_on_foreign_objects)
|
336
336
|
|
337
337
|
processor.import
|
338
338
|
documents = processor.connection.raw_connection[:organizations].find.entries
|
339
|
-
documents.size.
|
340
|
-
documents[0].slice('_id', '_type', 'name', 'parent_id').
|
341
|
-
documents[1].slice('_id', '_type', 'name', 'parent_id').
|
342
|
-
documents[2].slice('_id', '_type', 'name', 'parent_id').
|
339
|
+
expect(documents.size).to eq(3)
|
340
|
+
expect(documents[0].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '2', '_type' => _type, 'name' => 'Parent'})
|
341
|
+
expect(documents[1].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => '1', '_type' => _type, 'name' => 'Child', 'parent_id' => '2'})
|
342
|
+
expect(documents[2].slice('_id', '_type', 'name', 'parent_id')).to eq({'_id' => 'b', '_type' => _type, 'name' => 'Grandchild', 'parent_id' => '1'})
|
343
343
|
end
|
344
344
|
end
|
345
345
|
end
|
data/spec/runner_spec.rb
CHANGED
@@ -26,13 +26,13 @@ describe Pupa::Runner do
|
|
26
26
|
|
27
27
|
describe '#initialize' do
|
28
28
|
it 'should accept default options' do
|
29
|
-
dry_runner.options.level.
|
29
|
+
expect(dry_runner.options.level).not_to eq('INFO')
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
describe '#add_action' do
|
34
34
|
it 'should add an action' do
|
35
|
-
dry_runner.actions.last.to_h.
|
35
|
+
expect(dry_runner.actions.last.to_h).to eq({name: 'example', description: 'An example action'})
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -47,17 +47,17 @@ describe Pupa::Runner do
|
|
47
47
|
|
48
48
|
it 'should accept overridden options' do
|
49
49
|
dry_run(['--quiet'], level: 'ERROR')
|
50
|
-
dry_runner.options.level.
|
50
|
+
expect(dry_runner.options.level).to eq('ERROR')
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should use default actions if none set' do
|
54
54
|
dry_run
|
55
|
-
dry_runner.options.actions.
|
55
|
+
expect(dry_runner.options.actions).to eq(%w(scrape import))
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'should use default tasks if none set' do
|
59
59
|
dry_run
|
60
|
-
dry_runner.options.tasks.
|
60
|
+
expect(dry_runner.options.tasks).to eq(%i(people organizations))
|
61
61
|
end
|
62
62
|
|
63
63
|
# Unlike an action, it's not possible for a task to be undefined, because
|
@@ -71,14 +71,14 @@ describe Pupa::Runner do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it 'should run actions' do
|
74
|
-
TestProcessor.
|
75
|
-
TestProcessor.
|
74
|
+
expect_any_instance_of(TestProcessor).to receive(:dump_scraped_objects).twice
|
75
|
+
expect_any_instance_of(TestProcessor).to receive(:import)
|
76
76
|
runner.run([])
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'should run tasks' do
|
80
|
-
TestProcessor.
|
81
|
-
TestProcessor.
|
80
|
+
expect_any_instance_of(TestProcessor).to receive(:people).and_return([])
|
81
|
+
expect_any_instance_of(TestProcessor).to receive(:organizations).and_return([])
|
82
82
|
runner.run([])
|
83
83
|
end
|
84
84
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
+
require 'simplecov'
|
3
4
|
require 'coveralls'
|
4
|
-
Coveralls
|
5
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter 'spec'
|
8
|
+
end
|
5
9
|
|
6
10
|
require 'multi_xml'
|
7
11
|
require 'nokogiri'
|
8
12
|
require 'redis-store'
|
9
13
|
require 'rspec'
|
14
|
+
|
15
|
+
Dir["./spec/support/**/*.rb"].each {|f| require f}
|
10
16
|
require File.dirname(__FILE__) + '/../lib/pupa'
|
17
|
+
|
18
|
+
Mongo::Logger.logger.level = Logger::WARN
|
@@ -0,0 +1,66 @@
|
|
1
|
+
shared_examples 'SQL adapter' do |database_url|
|
2
|
+
before :all do
|
3
|
+
connection = Pupa::Processor::Connection::PostgreSQLAdapter.new(database_url)
|
4
|
+
|
5
|
+
connection.raw_connection.drop_table?(:people)
|
6
|
+
connection.raw_connection.create_table(:people) do
|
7
|
+
primary_key :id
|
8
|
+
String :_id
|
9
|
+
String :_type
|
10
|
+
String :name
|
11
|
+
String :email
|
12
|
+
Time :created_at
|
13
|
+
Time :updated_at
|
14
|
+
end
|
15
|
+
|
16
|
+
connection.save(Pupa::Person.new(_id: 'existing', name: 'existing', email: 'existing@example.com'))
|
17
|
+
connection.raw_connection[:people].insert(_type: 'pupa/person', name: 'non-unique')
|
18
|
+
connection.raw_connection[:people].insert(_type: 'pupa/person', name: 'non-unique')
|
19
|
+
end
|
20
|
+
|
21
|
+
let :connection do
|
22
|
+
Pupa::Processor::Connection::PostgreSQLAdapter.new(database_url)
|
23
|
+
end
|
24
|
+
|
25
|
+
let :_type do
|
26
|
+
'pupa/person'
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.find' do
|
30
|
+
it 'should raise an error if selector is empty' do
|
31
|
+
expect{connection.find(_type: _type)}.to raise_error(Pupa::Errors::EmptySelectorError)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should return nil if no matches' do
|
35
|
+
expect(connection.find(_type: _type, name: 'nonexistent')).to eq(nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should return a document if one match' do
|
39
|
+
expect(connection.find(_type: _type, name: 'existing')).to be_a(Hash)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should raise an error if many matches' do
|
43
|
+
expect{connection.find(_type: 'pupa/person', name: 'non-unique')}.to raise_error(Pupa::Errors::TooManyMatches)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.save' do
|
48
|
+
it 'should raise an error if selector is empty' do
|
49
|
+
expect{connection.save(Pupa::Person.new)}.to raise_error(Pupa::Errors::EmptySelectorError)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should insert a document if no matches' do
|
53
|
+
expect(connection.save(Pupa::Person.new(_id: 'new', name: 'new', email: 'new@example.com'))).to eq([true, 'new'])
|
54
|
+
expect(connection.find(_type: _type, name: 'new')['email']).to eq('new@example.com')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should update a document if one match' do
|
58
|
+
expect(connection.save(Pupa::Person.new(_id: 'changed', name: 'existing', email: 'changed@example.com'))).to eq([false, 'existing'])
|
59
|
+
expect(connection.find(_type: _type, name: 'existing')['email']).to eq('changed@example.com')
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should raise an error if many matches' do
|
63
|
+
expect{connection.save(Pupa::Person.new(name: 'non-unique'))}.to raise_error(Pupa::Errors::TooManyMatches)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pupa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- James McKinney
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -44,28 +44,28 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.9.
|
47
|
+
version: 0.9.2
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.9.
|
54
|
+
version: 0.9.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: json-schema
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.
|
61
|
+
version: '2.3'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 2.
|
68
|
+
version: '2.3'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: mail
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,19 +81,19 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: mongo
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 2.0
|
89
|
+
version: '2.0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.0
|
96
|
+
version: '2.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: oj
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,7 +151,7 @@ dependencies:
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: rake
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - ">="
|
@@ -165,19 +165,33 @@ dependencies:
|
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
168
|
+
name: rspec
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
173
|
+
version: '2.10'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
180
|
+
version: '2.10'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: dalli
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: multi_xml
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -221,7 +235,7 @@ dependencies:
|
|
221
235
|
- !ruby/object:Gem::Version
|
222
236
|
version: '0'
|
223
237
|
- !ruby/object:Gem::Dependency
|
224
|
-
name:
|
238
|
+
name: redis-store
|
225
239
|
requirement: !ruby/object:Gem::Requirement
|
226
240
|
requirements:
|
227
241
|
- - ">="
|
@@ -235,7 +249,7 @@ dependencies:
|
|
235
249
|
- !ruby/object:Gem::Version
|
236
250
|
version: '0'
|
237
251
|
- !ruby/object:Gem::Dependency
|
238
|
-
name:
|
252
|
+
name: sqlite3
|
239
253
|
requirement: !ruby/object:Gem::Requirement
|
240
254
|
requirements:
|
241
255
|
- - ">="
|
@@ -248,20 +262,6 @@ dependencies:
|
|
248
262
|
- - ">="
|
249
263
|
- !ruby/object:Gem::Version
|
250
264
|
version: '0'
|
251
|
-
- !ruby/object:Gem::Dependency
|
252
|
-
name: rspec
|
253
|
-
requirement: !ruby/object:Gem::Requirement
|
254
|
-
requirements:
|
255
|
-
- - "~>"
|
256
|
-
- !ruby/object:Gem::Version
|
257
|
-
version: '2.10'
|
258
|
-
type: :development
|
259
|
-
prerelease: false
|
260
|
-
version_requirements: !ruby/object:Gem::Requirement
|
261
|
-
requirements:
|
262
|
-
- - "~>"
|
263
|
-
- !ruby/object:Gem::Version
|
264
|
-
version: '2.10'
|
265
265
|
- !ruby/object:Gem::Dependency
|
266
266
|
name: typhoeus
|
267
267
|
requirement: !ruby/object:Gem::Requirement
|
@@ -277,13 +277,13 @@ dependencies:
|
|
277
277
|
- !ruby/object:Gem::Version
|
278
278
|
version: '0'
|
279
279
|
description:
|
280
|
-
email:
|
281
|
-
- info@opennorth.ca
|
280
|
+
email:
|
282
281
|
executables: []
|
283
282
|
extensions: []
|
284
283
|
extra_rdoc_files: []
|
285
284
|
files:
|
286
285
|
- ".gitignore"
|
286
|
+
- ".rspec"
|
287
287
|
- ".travis.yml"
|
288
288
|
- ".yardopts"
|
289
289
|
- Gemfile
|
@@ -291,7 +291,6 @@ files:
|
|
291
291
|
- PERFORMANCE.md
|
292
292
|
- README.md
|
293
293
|
- Rakefile
|
294
|
-
- USAGE
|
295
294
|
- lib/pupa.rb
|
296
295
|
- lib/pupa/errors.rb
|
297
296
|
- lib/pupa/logger.rb
|
@@ -372,6 +371,7 @@ files:
|
|
372
371
|
- spec/processor/client_spec.rb
|
373
372
|
- spec/processor/connection_adapters/mongodb_adapter_spec.rb
|
374
373
|
- spec/processor/connection_adapters/postgresql_adapter_spec.rb
|
374
|
+
- spec/processor/connection_adapters/sqlite_adapter_spec.rb
|
375
375
|
- spec/processor/connection_spec.rb
|
376
376
|
- spec/processor/dependency_graph_spec.rb
|
377
377
|
- spec/processor/document_store/file_store_spec.rb
|
@@ -386,7 +386,8 @@ files:
|
|
386
386
|
- spec/refinements/json-schema_spec.rb
|
387
387
|
- spec/runner_spec.rb
|
388
388
|
- spec/spec_helper.rb
|
389
|
-
|
389
|
+
- spec/support/shared_examples_for_connection_adapters.rb
|
390
|
+
homepage: https://github.com/jpmckinney/pupa-ruby
|
390
391
|
licenses:
|
391
392
|
- MIT
|
392
393
|
metadata: {}
|
@@ -406,7 +407,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
406
407
|
version: '0'
|
407
408
|
requirements: []
|
408
409
|
rubyforge_project:
|
409
|
-
rubygems_version: 2.
|
410
|
+
rubygems_version: 2.4.5
|
410
411
|
signing_key:
|
411
412
|
specification_version: 4
|
412
413
|
summary: A data scraping framework
|
@@ -435,6 +436,7 @@ test_files:
|
|
435
436
|
- spec/processor/client_spec.rb
|
436
437
|
- spec/processor/connection_adapters/mongodb_adapter_spec.rb
|
437
438
|
- spec/processor/connection_adapters/postgresql_adapter_spec.rb
|
439
|
+
- spec/processor/connection_adapters/sqlite_adapter_spec.rb
|
438
440
|
- spec/processor/connection_spec.rb
|
439
441
|
- spec/processor/dependency_graph_spec.rb
|
440
442
|
- spec/processor/document_store/file_store_spec.rb
|
@@ -449,3 +451,4 @@ test_files:
|
|
449
451
|
- spec/refinements/json-schema_spec.rb
|
450
452
|
- spec/runner_spec.rb
|
451
453
|
- spec/spec_helper.rb
|
454
|
+
- spec/support/shared_examples_for_connection_adapters.rb
|