case_model 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +4 -0
  3. data/Gemfile +11 -0
  4. data/Gemfile.lock +61 -0
  5. data/README.md +27 -0
  6. data/Rakefile +9 -0
  7. data/case_model.gemspec +17 -0
  8. data/lib/case_model.rb +3 -0
  9. data/lib/descriptions/states.n3 +47 -0
  10. data/lib/models/action.rb +48 -0
  11. data/lib/models/answer.rb +25 -0
  12. data/lib/models/application.rb +57 -0
  13. data/lib/models/capability.rb +23 -0
  14. data/lib/models/deployment_plan.rb +44 -0
  15. data/lib/models/device.rb +26 -0
  16. data/lib/models/ecosystem_host.rb +5 -0
  17. data/lib/models/http_request.rb +27 -0
  18. data/lib/models/location.rb +17 -0
  19. data/lib/models/ontology.rb +52 -0
  20. data/lib/models/question.rb +51 -0
  21. data/lib/models/question_reply_type.rb +14 -0
  22. data/lib/models/requirement.rb +17 -0
  23. data/lib/models/selection.rb +32 -0
  24. data/lib/models/state_change.rb +19 -0
  25. data/lib/models/temperature.rb +17 -0
  26. data/lib/ontology/http_vocabulary.rb +17 -0
  27. data/lib/ontology/local_vocabulary.rb +26 -0
  28. data/lib/ontology/math_vocabulary.rb +15 -0
  29. data/lib/ontology/rdf_vocabulary.rb +11 -0
  30. data/lib/ontology/state_vocabulary.rb +9 -0
  31. data/lib/services/application_by_capability_finder.rb +37 -0
  32. data/lib/services/eye_serializer.rb +19 -0
  33. data/lib/services/node_builder.rb +34 -0
  34. data/lib/services/node_query.rb +55 -0
  35. data/lib/services/question_references.rb +19 -0
  36. data/lib/services/reasoner.rb +77 -0
  37. data/lib/services/repository_proxy.rb +26 -0
  38. data/spec/spec_helper.rb +8 -0
  39. data/spec/unit/models/answer_spec.rb +43 -0
  40. data/spec/unit/models/application_spec.rb +43 -0
  41. data/spec/unit/models/deployment_plan_spec.rb +28 -0
  42. data/spec/unit/models/http_request_spec.rb +42 -0
  43. data/spec/unit/models/location_spec.rb +36 -0
  44. data/spec/unit/models/question_spec.rb +89 -0
  45. data/spec/unit/models/requirement_spec.rb +29 -0
  46. data/spec/unit/models/selection_spec.rb +48 -0
  47. data/spec/unit/models/state_change_spec.rb +33 -0
  48. data/spec/unit/ontology/local_vocabulary_spec.rb +9 -0
  49. data/spec/unit/ontology/ontology_spec.rb +62 -0
  50. data/spec/unit/services/application_by_capability_finder_spec.rb +81 -0
  51. data/spec/unit/services/eye_serializer_spec.rb +34 -0
  52. data/spec/unit/services/node_builder_spec.rb +56 -0
  53. data/spec/unit/services/node_query_spec.rb +74 -0
  54. data/spec/unit/services/reasoner_spec.rb +76 -0
  55. data/spec/unit/spec_helper.rb +1 -0
  56. metadata +117 -0
@@ -0,0 +1,48 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Question do
4
+ let(:repo) do
5
+ RDF::Repository.new do |r|
6
+ r << [:a, RDF.type, QV.Application]
7
+ r << [:question, RDF.type, QV.question_type]
8
+ r << [:question, QV.text, 'Are you OK?']
9
+ r << [:question, QV.replyType, QV.Select]
10
+ end
11
+ end
12
+
13
+ let(:ontology) { Ontology.new(repo) }
14
+ let(:question) { Question.new(:question, repo) }
15
+ let(:answer) { question.answer! }
16
+
17
+ context '#options' do
18
+ subject { answer.options }
19
+
20
+ describe 'options as a list of strings' do
21
+ before do
22
+ options = RDF::List[ 'opt1', 'opt2' ]
23
+ repo << options
24
+ repo << [:question, LV.options, options]
25
+ end
26
+
27
+ it { is_expected.to eq [ 'opt1', 'opt2' ] }
28
+ end
29
+
30
+ describe 'options as a set of strings' do
31
+ before do
32
+ repo << [:question, LV.option, 'opt1']
33
+ repo << [:question, LV.option, 'opt2']
34
+ end
35
+
36
+ it { is_expected.to eq [ 'opt1', 'opt2' ] }
37
+ end
38
+
39
+ describe 'options as a set of nodes' do
40
+ before do
41
+ repo << [:question, LV.option, LV.opt1]
42
+ repo << [:question, LV.option, LV.opt2]
43
+ end
44
+
45
+ it { is_expected.to eq [ LV.opt1, LV.opt2 ] }
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,33 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe StateChange do
4
+ let(:repo) { RDF::Repository.new }
5
+ let(:ontology) { Ontology.new(repo) }
6
+ let(:state_change) { StateChange.new(:state_change, ontology) }
7
+
8
+ before do
9
+ repo << [ :state, RDF.type, StateVocabulary.State ]
10
+ repo << [ :state_change, RDF.type, StateVocabulary.StateChange ]
11
+ repo << [ :state_change, StateVocabulary.added, :added ]
12
+ repo << [ :state_change, StateVocabulary.removed, :removed ]
13
+ repo << [ :state_change, StateVocabulary.parent, :state ]
14
+
15
+ repo << [ :app, RDF.type, LV.Application, :added ]
16
+ repo << [ :app, LV.description, 'A new app', :added ]
17
+ end
18
+
19
+ describe 'before applying the state change' do
20
+ let(:app) { ontology.applications.first }
21
+
22
+ subject { app.nil? }
23
+ pending { is_expected.to eq true }
24
+ end
25
+
26
+ context '#apply' do
27
+ let(:new_ontology) { state_change.apply }
28
+ let(:app) { new_ontology.applications.first }
29
+
30
+ subject { app.description }
31
+ it { is_expected.to eq 'A new app' }
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe LocalVocabulary do
4
+ it 'returns a URI with the called method name' do
5
+ uri = LocalVocabulary.Application.to_s
6
+ expect(uri).to include('Application')
7
+ expect(uri).to include('http')
8
+ end
9
+ end
@@ -0,0 +1,62 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Ontology do
4
+ let(:repo) { RDF::Repository.new }
5
+ let(:ontology) { Ontology.new(repo) }
6
+
7
+ before do
8
+ # APPS
9
+ repo << [:app1, RDF.type, LV.Application]
10
+ repo << [:app1, RDF::Vocab::FOAF.name, 'App 1']
11
+ repo << [:app2, RDF.type, LV.Application]
12
+ repo << [:app2, RDF::Vocab::FOAF.name, 'App 2']
13
+
14
+ # DEVICES
15
+ repo << [:dev1, RDF.type, LV.Device]
16
+ repo << [:dev1, LV.manufacturerName, 'Grundfos']
17
+ repo << [:dev2, RDF.type, LV.Device]
18
+ repo << [:dev2, LV.manufacturerName, 'Danfoss']
19
+ end
20
+
21
+ context '#applications' do
22
+ let(:apps) { ontology.applications }
23
+
24
+ it 'finds 2 applications' do
25
+ expect(apps.size).to eq(2)
26
+ end
27
+
28
+ it 'gives the right names' do
29
+ expect(apps.first.name).to eq('App 1')
30
+ expect(apps.last.name).to eq('App 2')
31
+ end
32
+ end
33
+
34
+ context '#devices' do
35
+ let(:devices) { ontology.devices }
36
+
37
+ it 'finds 2 devices' do
38
+ expect(devices.size).to eq(2)
39
+ end
40
+
41
+ it 'gives the right names' do
42
+ expect(devices.first.manufacturer_name).to eq('Grundfos')
43
+ expect(devices.last.manufacturer_name).to eq('Danfoss')
44
+ end
45
+ end
46
+
47
+ context '#refresh' do
48
+ let(:n3_input) { '@prefix c: <http://matus.tomlein.org/case/>.
49
+ { ?a c:knows ?b. } => { ?b c:knows ?a. }.' }
50
+ before { ontology.load_and_process_n3(n3_input) }
51
+
52
+ it 'executes the rule after refresh' do
53
+ any = lambda { ontology.query([ LV.marry, LV.knows, LV.john ]).any? }
54
+
55
+ ontology << [ LV.john, LV.knows, LV.marry ]
56
+ expect(any.call).to eq false
57
+
58
+ ontology.refresh
59
+ expect(any.call).to eq true
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,81 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe ApplicationByCapabilityFinder do
4
+ let(:repo) { RDF::Repository.new }
5
+ let(:ontology) { Ontology.new repo }
6
+ let(:finder) { ApplicationByCapabilityFinder.new ontology }
7
+
8
+ before do
9
+ repo << [ :app1, RDF.type, LV.Application ]
10
+ repo << [ :app1, LV.description, 'Some app' ]
11
+ repo << [ :app1, LV.hasDeploymentPlan, :dp1 ]
12
+ repo << [ :dp1, LV.capability, :capability1 ]
13
+ repo << [ :capability1, RDF.type, LV.Irrigation ]
14
+ repo << [ :capability1, LV.actuator, :irrigator1 ]
15
+ repo << [ :irrigator1, LV.description, 'The irrigator' ]
16
+
17
+ repo << [ :app2, RDF.type, LV.Application ]
18
+ repo << [ :app2, LV.description, 'Some other app' ]
19
+ repo << [ :app2, LV.hasDeploymentPlan, :dp2 ]
20
+ repo << [ :dp2, LV.capability, :capability2 ]
21
+ repo << [ :capability2, RDF.type, LV.SmartHome ]
22
+ repo << [ :capability2, LV.actuator, LV.light ]
23
+ repo << [ LV.light, LV.description, 'Light' ]
24
+ end
25
+
26
+ context '#find' do
27
+ describe 'by the capability type' do
28
+ let(:applications) do
29
+ finder.find({
30
+ RDF.type => LV.Irrigation
31
+ })
32
+ end
33
+
34
+ context '#size' do
35
+ subject { applications.size }
36
+ it { is_expected.to eq 1 }
37
+ end
38
+
39
+ context '#description' do
40
+ subject { applications.first.description }
41
+ it { is_expected.to eq 'Some app' }
42
+ end
43
+ end
44
+ end
45
+
46
+ context '#find_by_actuator' do
47
+ describe 'by actuator node' do
48
+ let(:applications) do
49
+ finder.find_by_actuator(LV.light)
50
+ end
51
+
52
+ context '#size' do
53
+ subject { applications.size }
54
+ it { is_expected.to eq 1 }
55
+ end
56
+
57
+ context '#description' do
58
+ subject { applications.first.description }
59
+ it { is_expected.to eq 'Some other app' }
60
+ end
61
+ end
62
+
63
+ describe 'by the actuator type' do
64
+ let(:applications) do
65
+ finder.find_by_actuator({
66
+ LV.description => 'Light'
67
+ })
68
+ end
69
+
70
+ context '#size' do
71
+ subject { applications.size }
72
+ it { is_expected.to eq 1 }
73
+ end
74
+
75
+ context '#description' do
76
+ subject { applications.first.description }
77
+ it { is_expected.to eq 'Some other app' }
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,34 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe EyeSerializer do
4
+ let(:p1) { RDF::Query::Variable.new(:p1) }
5
+ let(:p2) { RDF::Query::Variable.new(:p2) }
6
+ let(:facts) do
7
+ RDF::Graph.new do |g|
8
+ g << [LV.john, LV.knows, LV.jane]
9
+ end
10
+ end
11
+ let(:precondition) do
12
+ RDF::Graph.new do |g|
13
+ g << [p1, LV.knows, p2]
14
+ end
15
+ end
16
+ let(:postcondition) do
17
+ RDF::Graph.new do |g|
18
+ g << [p2, LV.knows, p1]
19
+ end
20
+ end
21
+
22
+ context '.serialize_implication' do
23
+
24
+ subject { EyeSerializer.serialize_implication(facts, precondition, postcondition) }
25
+
26
+ it do
27
+ is_expected.to eq('<http://matus.tomlein.org/case/john> <http://matus.tomlein.org/case/knows> <http://matus.tomlein.org/case/jane> .
28
+ {?p1 <http://matus.tomlein.org/case/knows> ?p2 .
29
+ } => {?p2 <http://matus.tomlein.org/case/knows> ?p1 .
30
+ }.
31
+ ')
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,56 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe NodeBuilder do
4
+ let(:repo) do
5
+ RDF::Repository.new do |repo|
6
+ repo << [LV.john, LV.knows, LV.jane]
7
+ end
8
+ end
9
+
10
+ context '.create' do
11
+ describe 'generate a device node' do
12
+ let(:node) do
13
+ NodeBuilder.create({
14
+ RDF.type => [
15
+ LV.Device,
16
+ LV.Irrigator,
17
+ LV.EcosystemHost
18
+ ],
19
+ LV.manufacturerName => 'Apple',
20
+ LV.description => 'Insanely great',
21
+ LV.locatedAt => {
22
+ LV.locationName => 'Cupertino'
23
+ }
24
+ },
25
+ repo)
26
+ end
27
+ let(:device) { Device.new(node, repo) }
28
+
29
+ context '#manufacturer_name' do
30
+ subject { device.manufacturer_name }
31
+ it { is_expected.to eq 'Apple' }
32
+ end
33
+
34
+ context '#description' do
35
+ subject { device.description }
36
+ it { is_expected.to eq 'Insanely great' }
37
+ end
38
+
39
+ context '#location' do
40
+ let(:location) { device.location }
41
+
42
+ context '#name' do
43
+ subject { location.name }
44
+ it { is_expected.to eq 'Cupertino' }
45
+ end
46
+ end
47
+
48
+ context '#types' do
49
+ subject do
50
+ NodeQuery.new(node, repo).values(RDF.type).size
51
+ end
52
+ it { is_expected.to eq 3 }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,74 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe NodeQuery do
4
+ let(:repo) do
5
+ RDF::Repository.new do |repo|
6
+ repo << [LV.john, LV.knows, LV.jane]
7
+ end
8
+ end
9
+ let(:query) { NodeQuery.new(LV.john, repo) }
10
+
11
+ context '#value' do
12
+ subject { query.value(LV.knows) }
13
+ it { is_expected.to eq(LV.jane) }
14
+
15
+ describe 'unset value' do
16
+ subject { query.value(LV.hates) }
17
+ it { is_expected.to eq(nil) }
18
+ end
19
+ end
20
+
21
+ context '#values' do
22
+ before :each do
23
+ repo << [ LV.john, LV.knows, LV.emily ]
24
+ end
25
+ let(:values) { query.values(LV.knows) }
26
+
27
+ context '#size' do
28
+ subject { values.size }
29
+ it { is_expected.to eq(2) }
30
+ end
31
+
32
+ context '#first' do
33
+ subject { values.first }
34
+ it { is_expected.to eq(LV.jane) }
35
+ end
36
+
37
+ context '#last' do
38
+ subject { values.last }
39
+ it { is_expected.to eq(LV.emily) }
40
+ end
41
+
42
+ describe 'size when unset value' do
43
+ subject { query.values(LV.hates).size }
44
+ it { is_expected.to eq(0) }
45
+ end
46
+ end
47
+
48
+ context '#set_value' do
49
+ before :each do
50
+ query.set_value LV.loves, LV.jane
51
+ end
52
+
53
+ context '#value' do
54
+ subject { query.value(LV.loves) }
55
+ it { is_expected.to eq(LV.jane) }
56
+ end
57
+
58
+ describe 'overwrites previous value' do
59
+ before :each do
60
+ query.set_value LV.loves, LV.emily
61
+ end
62
+
63
+ context '#value' do
64
+ subject { query.value(LV.loves) }
65
+ it { is_expected.to eq(LV.emily) }
66
+ end
67
+
68
+ context '#values.size' do
69
+ subject { query.values(LV.loves).size }
70
+ it { is_expected.to eq(1) }
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,76 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Reasoner do
4
+ let(:repo) { RDF::Repository.new }
5
+ let(:reasoner) { Reasoner.new(Ontology.new(repo)) }
6
+ let(:person1) { RDF::Query::Variable.new(:p1) }
7
+ let(:person2) { RDF::Query::Variable.new(:p2) }
8
+
9
+ before do
10
+ repo << [LV.john, LV.knows, LV.jane]
11
+ repo << [person1, LV.knows, person2, :precondition]
12
+ repo << [person1, LV.doesnt_know, person2, :wrong_precondition]
13
+ end
14
+
15
+ context '#check_condition' do
16
+ describe 'correct condition' do
17
+ subject { reasoner.check_condition(:precondition) }
18
+ it { is_expected.to eq true }
19
+ end
20
+
21
+ describe 'wrong condition' do
22
+ subject { reasoner.check_condition(:wrong_precondition) }
23
+ it { is_expected.to eq false }
24
+ end
25
+ end
26
+
27
+ context '#imply' do
28
+ before :each do
29
+ repo << [person2, LV.knows, person1, :postcondition]
30
+ end
31
+
32
+ describe 'correct precondition' do
33
+ let!(:result) { reasoner.imply(:precondition, :postcondition) }
34
+
35
+ it 'should find that Jane knows John' do
36
+ expect(result.query([LV.jane, LV.knows, LV.john]).size).
37
+ to eq(1)
38
+ end
39
+
40
+ it 'should not modify the source repository' do
41
+ expect(repo.query([LV.jane, LV.knows, LV.john]).size).
42
+ to eq(0)
43
+ expect(repo.query([LV.john, LV.knows, LV.jane]).size).
44
+ to eq(1)
45
+ end
46
+ end
47
+
48
+ describe 'wrong precondition' do
49
+ let!(:result) { reasoner.imply(:wrong_precondition, :postcondition) }
50
+
51
+ it 'should not find that Jane knows John' do
52
+ expect(result.query([LV.jane, LV.knows, LV.john]).size).
53
+ to eq(0)
54
+ end
55
+ end
56
+ end
57
+
58
+ context '#load_and_process_n3' do
59
+ let(:n3_input) { '@prefix c: <http://matus.tomlein.org/case/>.
60
+ c:dog c:likes c:cat.
61
+ { ?dog c:likes ?cat } => { ?cat c:likes ?dog }.' }
62
+ let(:repo) { RDF::Repository.new }
63
+
64
+ before { reasoner.load_and_process_n3(n3_input) }
65
+
66
+ describe 'the known fact' do
67
+ subject { repo.query([LV.dog, LV.likes, LV.cat]).any? }
68
+ it { is_expected.to eq true }
69
+ end
70
+
71
+ describe 'the implied fact' do
72
+ subject { repo.query([LV.cat, LV.likes, LV.dog]).any? }
73
+ it { is_expected.to eq true }
74
+ end
75
+ end
76
+ end
@@ -0,0 +1 @@
1
+ require_relative '../spec_helper'
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: case_model
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Matus Tomlein
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Built for the Context-Aware Software Ecosystem. Resolves application
14
+ model requirements using semantic reasoning.
15
+ email: matus@cs.au.dk
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".travis.yml"
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - README.md
24
+ - Rakefile
25
+ - case_model.gemspec
26
+ - lib/case_model.rb
27
+ - lib/descriptions/states.n3
28
+ - lib/models/action.rb
29
+ - lib/models/answer.rb
30
+ - lib/models/application.rb
31
+ - lib/models/capability.rb
32
+ - lib/models/deployment_plan.rb
33
+ - lib/models/device.rb
34
+ - lib/models/ecosystem_host.rb
35
+ - lib/models/http_request.rb
36
+ - lib/models/location.rb
37
+ - lib/models/ontology.rb
38
+ - lib/models/question.rb
39
+ - lib/models/question_reply_type.rb
40
+ - lib/models/requirement.rb
41
+ - lib/models/selection.rb
42
+ - lib/models/state_change.rb
43
+ - lib/models/temperature.rb
44
+ - lib/ontology/http_vocabulary.rb
45
+ - lib/ontology/local_vocabulary.rb
46
+ - lib/ontology/math_vocabulary.rb
47
+ - lib/ontology/rdf_vocabulary.rb
48
+ - lib/ontology/state_vocabulary.rb
49
+ - lib/services/application_by_capability_finder.rb
50
+ - lib/services/eye_serializer.rb
51
+ - lib/services/node_builder.rb
52
+ - lib/services/node_query.rb
53
+ - lib/services/question_references.rb
54
+ - lib/services/reasoner.rb
55
+ - lib/services/repository_proxy.rb
56
+ - spec/spec_helper.rb
57
+ - spec/unit/models/answer_spec.rb
58
+ - spec/unit/models/application_spec.rb
59
+ - spec/unit/models/deployment_plan_spec.rb
60
+ - spec/unit/models/http_request_spec.rb
61
+ - spec/unit/models/location_spec.rb
62
+ - spec/unit/models/question_spec.rb
63
+ - spec/unit/models/requirement_spec.rb
64
+ - spec/unit/models/selection_spec.rb
65
+ - spec/unit/models/state_change_spec.rb
66
+ - spec/unit/ontology/local_vocabulary_spec.rb
67
+ - spec/unit/ontology/ontology_spec.rb
68
+ - spec/unit/services/application_by_capability_finder_spec.rb
69
+ - spec/unit/services/eye_serializer_spec.rb
70
+ - spec/unit/services/node_builder_spec.rb
71
+ - spec/unit/services/node_query_spec.rb
72
+ - spec/unit/services/reasoner_spec.rb
73
+ - spec/unit/spec_helper.rb
74
+ homepage: https://github.com/case-iot/app_model
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.2.2
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Resolver for the CASE ecosystem application models
98
+ test_files:
99
+ - spec/spec_helper.rb
100
+ - spec/unit/models/answer_spec.rb
101
+ - spec/unit/models/application_spec.rb
102
+ - spec/unit/models/deployment_plan_spec.rb
103
+ - spec/unit/models/http_request_spec.rb
104
+ - spec/unit/models/location_spec.rb
105
+ - spec/unit/models/question_spec.rb
106
+ - spec/unit/models/requirement_spec.rb
107
+ - spec/unit/models/selection_spec.rb
108
+ - spec/unit/models/state_change_spec.rb
109
+ - spec/unit/ontology/local_vocabulary_spec.rb
110
+ - spec/unit/ontology/ontology_spec.rb
111
+ - spec/unit/services/application_by_capability_finder_spec.rb
112
+ - spec/unit/services/eye_serializer_spec.rb
113
+ - spec/unit/services/node_builder_spec.rb
114
+ - spec/unit/services/node_query_spec.rb
115
+ - spec/unit/services/reasoner_spec.rb
116
+ - spec/unit/spec_helper.rb
117
+ has_rdoc: