krikri-spec 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +71 -0
- data/lib/krikri/spec.rb +38 -0
- data/lib/krikri/spec/harvester.rb +136 -0
- data/lib/krikri/spec/matchers.rb +35 -0
- data/lib/krikri/spec/software_agent.rb +73 -0
- data/lib/krikri/spec/version.rb +5 -0
- data/spec/spec_helper.rb +14 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6c90100ad41d132172efa4c7b439ad6d3f7d718e
|
4
|
+
data.tar.gz: 91d6e0a071fc07e6c7ada9b30cc26746806f832d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: efa17e2c29eb457298abfea52916951f090ed7f3029504f16c6f955f79899ba6f8f17ad16501811191b17a91000e6c377f665fbe880af73a1e818c99eade49cd
|
7
|
+
data.tar.gz: 640d3bc1484d119795ca63c7c1bc1730146af9e56a0b7a5bf759abb4ce3025addf13937fbbd86cb332996d2d78308b32be7f3833391cb1268731255e698e3298
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
Krikri::Spec
|
2
|
+
============
|
3
|
+
|
4
|
+
[![Build Status](https://travis-ci.org/dpla/krikri-spec.svg?branch=develop)](https://travis-ci.org/dpla/krikri-spec)
|
5
|
+
|
6
|
+
RSpec extensions and shared examples for Krikri.
|
7
|
+
|
8
|
+
Shared Examples
|
9
|
+
----------------
|
10
|
+
|
11
|
+
Shared examples are included as linters for Krikri contracts. Use the shared
|
12
|
+
examples within individual spec files by invoking them in place:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
require 'krikri/spec/harvester'
|
16
|
+
|
17
|
+
describe MyHarvester do
|
18
|
+
it_behaves_like 'a harvester'
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
Matchers
|
23
|
+
--------
|
24
|
+
|
25
|
+
Matchers for some common patterns within specs for Krikri apps are provided.
|
26
|
+
You can include them in your RSpec enviornment with:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'krikri/spec
|
30
|
+
|
31
|
+
RSpec.configure do |conf|
|
32
|
+
conf.include(Krikri::Spec::Matchers)
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
Development
|
37
|
+
-----------
|
38
|
+
|
39
|
+
When working on the Krikri gem, it is often useful to work directly against a
|
40
|
+
local copy of the `Krikri::Spec` examples. To do this, you can add a local path
|
41
|
+
to your Krikri Gemfile:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
# Gemfile
|
45
|
+
|
46
|
+
gem 'krikri-spec', path: '../krikri-spec'
|
47
|
+
```
|
48
|
+
|
49
|
+
Or run against the `develop` branch on GitHub:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# Gemfile
|
53
|
+
|
54
|
+
gem 'krikri-spec', github: 'dpla/krikri-spec', branch: 'develop'
|
55
|
+
```
|
56
|
+
|
57
|
+
Contribution Guidelines
|
58
|
+
-----------------------
|
59
|
+
Please observe the following guidelines:
|
60
|
+
|
61
|
+
- Write tests for your contributions.
|
62
|
+
- Document methods you add using YARD annotations.
|
63
|
+
- Follow the included style guidelines (i.e. run `rubocop` before committing).
|
64
|
+
- Use well formed commit messages.
|
65
|
+
|
66
|
+
Copyright & License
|
67
|
+
--------------------
|
68
|
+
|
69
|
+
- Copyright Digital Public Library of America, 2016
|
70
|
+
- License: MIT
|
71
|
+
|
data/lib/krikri/spec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
##
|
2
|
+
# `Krikri::Spec` offers RSpec extensions and shared examples for the Krikri
|
3
|
+
# metadata aggregation engine.
|
4
|
+
#
|
5
|
+
# Shared examples must be required explictly for specs that use them. This helps
|
6
|
+
# with clarity of shared example use, and avoids namespace pollution for
|
7
|
+
# `it_behaves_like` directives.
|
8
|
+
#
|
9
|
+
# @example using a shared example
|
10
|
+
# require 'krikri/spec/harvester'
|
11
|
+
#
|
12
|
+
# describe MyHarvester do
|
13
|
+
# it_behaves_like 'a harvester'
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# RSpec matchers are included for common checks within Krikri based
|
18
|
+
# applications.
|
19
|
+
#
|
20
|
+
# @example using a custom matcher
|
21
|
+
# require 'krikri/spec'
|
22
|
+
#
|
23
|
+
# RSpec.configure { |conf| conf.include(Krikri::Spec::Matchers) }
|
24
|
+
#
|
25
|
+
# describe SomeModel do
|
26
|
+
# it 'is an exactMatch for moomin' do
|
27
|
+
# moomin = RDF::URI('http://example.com/moomin')
|
28
|
+
#
|
29
|
+
# expect(subject).to be_exact_match_with moomin
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# @see http://www.rubydoc.info/gems/krikri
|
34
|
+
# @see http://rspec.info/
|
35
|
+
module Krikri::Spec
|
36
|
+
autoload :Matchers, 'krikri/spec/matchers'
|
37
|
+
autoload :VERSION, 'krikri/spec/version'
|
38
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'krikri/spec/software_agent'
|
2
|
+
|
3
|
+
shared_examples 'a harvester' do
|
4
|
+
opts = { uri: 'http://example.org/endpoint' }
|
5
|
+
it_behaves_like 'a software agent', opts
|
6
|
+
|
7
|
+
let(:harvester) { subject }
|
8
|
+
let(:name) { :test_harvester }
|
9
|
+
|
10
|
+
it { expect(described_class.queue_name.to_s).to eq 'harvest' }
|
11
|
+
|
12
|
+
it 'is a harvester' do
|
13
|
+
expect(harvester).to be_a Krikri::Harvester
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'raises an error if no uri is given' do
|
17
|
+
expect { described_class.new }.to raise_error KeyError
|
18
|
+
end
|
19
|
+
|
20
|
+
xit 'has a record count' do
|
21
|
+
expect(harvester.count).to be_a Integer
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#record_ids' do
|
25
|
+
it 'can get its record ids' do
|
26
|
+
expect(harvester.record_ids).to be_a Enumerator
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'gives ids as strings' do
|
30
|
+
harvester.record_ids.each { |i| expect(i).to be_a String }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'local_name creation' do
|
35
|
+
before { harvester.name = name }
|
36
|
+
|
37
|
+
let(:gen_id) { 'my_id' }
|
38
|
+
|
39
|
+
it 'mints md5 identifiers with #records' do
|
40
|
+
expect(Krikri::Md5Minter).to receive(:create)
|
41
|
+
.with(harvester.record_ids.first,
|
42
|
+
harvester.name)
|
43
|
+
.and_return(gen_id)
|
44
|
+
|
45
|
+
expect(harvester.records.first.local_name).to eq gen_id
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'mints md5 identifiers with #get_record' do
|
49
|
+
expect(Krikri::Md5Minter).to receive(:create)
|
50
|
+
.with(harvester.record_ids.first, harvester.name)
|
51
|
+
.and_return(gen_id)
|
52
|
+
expect(harvester.get_record(harvester.record_ids.first).local_name)
|
53
|
+
.to eq gen_id
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.expected_opts' do
|
58
|
+
it 'returns a hash with key and options' do
|
59
|
+
expect(described_class.expected_opts)
|
60
|
+
.to match a_hash_including(:key => an_instance_of(Symbol),
|
61
|
+
:opts => an_instance_of(Hash))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#records' do
|
66
|
+
it 'returns a record enumerator' do
|
67
|
+
expect(subject.records).to be_a Enumerator
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns OriginalRecords' do
|
71
|
+
subject.records.each { |r| expect(r).to be_a Krikri::OriginalRecord }
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'after first harvest' do
|
75
|
+
it 'builds same record' do
|
76
|
+
r = subject.records.first
|
77
|
+
r.save
|
78
|
+
expect(subject.records.first).to be == r
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'idempotent reharvests' do
|
82
|
+
subject.records.each(&:save)
|
83
|
+
records = subject.records
|
84
|
+
records_2 = subject.records
|
85
|
+
loop do
|
86
|
+
r1 = records.next
|
87
|
+
r2 = records_2.next
|
88
|
+
expect(r1).to be == r2
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#get_record' do
|
95
|
+
it 'gets an individual record' do
|
96
|
+
expect(harvester.get_record(harvester.record_ids.first))
|
97
|
+
.to be_a Krikri::OriginalRecord
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'escapes identifiers' do
|
101
|
+
expect(subject.records.first.local_name).not_to include(':')
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns a normalized record' do
|
105
|
+
expect(harvester.get_record(harvester.record_ids.first).content)
|
106
|
+
.to eq harvester.records.first.content
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#run' do
|
111
|
+
before do
|
112
|
+
allow(harvester).to receive(:records)
|
113
|
+
.and_return [double('Original Record 1'),
|
114
|
+
double('Record 2')]
|
115
|
+
end
|
116
|
+
|
117
|
+
let(:activity_uri) { RDF::URI('http://example.org/prov/activity/1') }
|
118
|
+
|
119
|
+
it 'processes the OriginalRecords' do
|
120
|
+
harvester.records.each do |r|
|
121
|
+
expect(harvester).to receive(:process_record).with(r, activity_uri)
|
122
|
+
.and_return(true)
|
123
|
+
end
|
124
|
+
harvester.run(activity_uri)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#name' do
|
129
|
+
it 'has name accessors' do
|
130
|
+
harvester.name = name
|
131
|
+
expect(subject).to have_attributes(:name => name)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it_behaves_like 'a software agent', uri: 'http://example.org/endpoint'
|
136
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rspec/matchers'
|
2
|
+
|
3
|
+
module Krikri::Spec
|
4
|
+
##
|
5
|
+
# Defines matchers for Krikri
|
6
|
+
#
|
7
|
+
# @see http://rubygems.org/gems/rspec
|
8
|
+
# @see http://www.rubydoc.info/gems/rspec-expectations/RSpec/Matchers
|
9
|
+
module Matchers
|
10
|
+
# @!group ActiveTriples Matchers
|
11
|
+
|
12
|
+
##
|
13
|
+
# Match on the `skos:exactMatch` relation.
|
14
|
+
RSpec::Matchers.define :be_exact_match_with do |expected|
|
15
|
+
match do |actual|
|
16
|
+
exact_match = RDF::URI('http://www.w3.org/2004/02/skos/core#exactMatch')
|
17
|
+
!actual.first([actual, exact_match, expected]).nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Match on the `dpla:providedLabel` relation.
|
23
|
+
RSpec::Matchers.define :have_provided_label do |expected|
|
24
|
+
match do |actual|
|
25
|
+
provided_label = RDF::URI('http://dp.la/about/map/providedLabel')
|
26
|
+
pattern = [actual, provided_label, nil]
|
27
|
+
|
28
|
+
expect(actual.query(pattern).map(&:object)).to include(expected)
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @!endgroup
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
|
2
|
+
shared_examples 'a software agent' do |args|
|
3
|
+
subject { args.nil? ? described_class.new : described_class.new(args) }
|
4
|
+
let(:agent_class) { described_class }
|
5
|
+
|
6
|
+
it 'represents its agent name as the correct string, as a class' do
|
7
|
+
expect(agent_class.agent_name)
|
8
|
+
.to eq agent_class.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'represents its agent name as the correct string, as an instance' do
|
12
|
+
expect(subject.agent_name).to eq agent_class.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.agent_name' do
|
16
|
+
it { expect(agent_class.agent_name).to be_a String }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.queue_name' do
|
20
|
+
it { expect(agent_class.queue_name).to respond_to :to_s }
|
21
|
+
|
22
|
+
it 'is lowercase' do
|
23
|
+
expect(agent_class.queue_name).to eq agent_class.queue_name.downcase
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#agent_name' do
|
28
|
+
it { expect(subject.agent_name).to be_a String }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#run' do
|
32
|
+
it 'accepts one or no arguments' do
|
33
|
+
expect(subject.method(:run).arity).to satisfy { |v| v == -1 || v == 0 }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#enqueue' do
|
38
|
+
let(:queue_name) { described_class.queue_name.to_s }
|
39
|
+
|
40
|
+
it 'accepts options hash as first arg' do
|
41
|
+
expect(agent_class.enqueue({})).to be true
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'accepts options hash as second arg' do
|
45
|
+
expect(agent_class.enqueue('my_queue', {})).to be true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'throws an error if too many args are given' do
|
49
|
+
expect { agent_class.enqueue('my_queue', {}, :abc) }
|
50
|
+
.to raise_error ArgumentError
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'throws an error if second arg is not options hash' do
|
54
|
+
expect { agent_class.enqueue(:my_queue, :abc) }
|
55
|
+
.to raise_error ArgumentError
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'enqueues a job' do
|
59
|
+
expect { agent_class.enqueue(args) }
|
60
|
+
.to change { Resque.size(queue_name) }.by(1)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'creates a new activity when it enqueues a job' do
|
64
|
+
expect { agent_class.enqueue(args) }
|
65
|
+
.to change { Krikri::Activity.count }.by(1)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'logs queue creation' do
|
69
|
+
expect(Rails.logger).to receive(:info).exactly(2).times
|
70
|
+
agent_class.enqueue(args)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'krikri/spec'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.color = true
|
7
|
+
config.formatter = :progress
|
8
|
+
config.mock_with :rspec
|
9
|
+
|
10
|
+
config.include FactoryGirl::Syntax::Methods
|
11
|
+
|
12
|
+
config.filter_run focus: true
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: krikri-spec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Audrey Altman
|
8
|
+
- Mark Breedlove
|
9
|
+
- Tom Johnson
|
10
|
+
- Mark Matienzo
|
11
|
+
- Scott Williams
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
date: 2016-06-10 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: krikri
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: yard
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: rspec
|
47
|
+
requirement: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - "~>"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.2'
|
52
|
+
type: :development
|
53
|
+
prerelease: false
|
54
|
+
version_requirements: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - "~>"
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '3.2'
|
59
|
+
description: Sharable test suite components for apps based on the Krikri engine.
|
60
|
+
email:
|
61
|
+
- tech@dp.la
|
62
|
+
executables: []
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- README.md
|
67
|
+
- lib/krikri/spec.rb
|
68
|
+
- lib/krikri/spec/harvester.rb
|
69
|
+
- lib/krikri/spec/matchers.rb
|
70
|
+
- lib/krikri/spec/software_agent.rb
|
71
|
+
- lib/krikri/spec/version.rb
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
homepage: http://github.com/dpla/krikri-spec
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.5.1
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Shared tests for Krikri's metadata aggregation, enhancement, and quality
|
97
|
+
control functionality.
|
98
|
+
test_files:
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
has_rdoc:
|