verso 0.0.2 → 0.0.3
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.
- data/.gitignore +2 -0
- data/README.md +10 -22
- data/lib/verso.rb +10 -2
- data/lib/verso/base.rb +50 -0
- data/lib/verso/cluster.rb +55 -25
- data/lib/verso/cluster_list.rb +15 -10
- data/lib/verso/correlation_list.rb +30 -40
- data/lib/verso/course.rb +106 -43
- data/lib/verso/course_list.rb +57 -21
- data/lib/verso/credential.rb +94 -20
- data/lib/verso/credential_list.rb +30 -15
- data/lib/verso/duty_area.rb +23 -10
- data/lib/verso/edition_list.rb +18 -10
- data/lib/verso/emphasis.rb +26 -12
- data/lib/verso/emphasis_list.rb +18 -10
- data/lib/verso/examination_list.rb +28 -12
- data/lib/verso/extra.rb +34 -32
- data/lib/verso/extras_list.rb +28 -12
- data/lib/verso/frontmatter.rb +43 -11
- data/lib/verso/hash.rb +19 -0
- data/lib/verso/http_gettable.rb +31 -0
- data/lib/verso/occupation.rb +36 -14
- data/lib/verso/occupation_data.rb +35 -14
- data/lib/verso/occupation_list.rb +23 -20
- data/lib/verso/pathway.rb +32 -14
- data/lib/verso/program_area.rb +42 -21
- data/lib/verso/program_area_list.rb +15 -11
- data/lib/verso/standard.rb +45 -23
- data/lib/verso/standards_list.rb +41 -30
- data/lib/verso/task.rb +52 -17
- data/lib/verso/task_list.rb +40 -17
- data/lib/verso/version.rb +1 -1
- data/spec/cluster_list_spec.rb +78 -5
- data/spec/cluster_spec.rb +106 -9
- data/spec/correlation_list_spec.rb +108 -50
- data/spec/course_list_spec.rb +112 -23
- data/spec/course_spec.rb +321 -127
- data/spec/credential_list_spec.rb +83 -52
- data/spec/credential_spec.rb +358 -19
- data/spec/duty_area_spec.rb +47 -17
- data/spec/edition_list_spec.rb +90 -4
- data/spec/emphasis_list_spec.rb +75 -11
- data/spec/emphasis_spec.rb +37 -21
- data/spec/examination_list_spec.rb +146 -20
- data/spec/extra_spec.rb +61 -22
- data/spec/extras_list_spec.rb +80 -17
- data/spec/frontmatter_spec.rb +141 -6
- data/spec/hash_spec.rb +49 -0
- data/spec/occupation_data_spec.rb +31 -13
- data/spec/occupation_list_spec.rb +88 -15
- data/spec/occupation_spec.rb +72 -28
- data/spec/pathway_spec.rb +47 -27
- data/spec/program_area_list_spec.rb +78 -4
- data/spec/program_area_spec.rb +70 -22
- data/spec/standard_spec.rb +94 -36
- data/spec/standards_list_spec.rb +130 -36
- data/spec/task_list_spec.rb +160 -51
- data/spec/task_spec.rb +120 -33
- data/verso.gemspec +3 -1
- metadata +41 -17
- data/lib/verso/http_get.rb +0 -9
- data/lib/verso/sol_correlation_list.rb +0 -53
- data/spec/sol_correlation_list_spec.rb +0 -74
data/lib/verso/course_list.rb
CHANGED
@@ -1,36 +1,72 @@
|
|
1
1
|
module Verso
|
2
|
-
|
2
|
+
# Search Verso courses by :text, :cluster, :program_area, :code, :edition,
|
3
|
+
# or any combination and get back an Array-like collection of
|
4
|
+
# {Verso::Course} objects.
|
5
|
+
#
|
6
|
+
# @see http://api.cteresource.org/docs/courses
|
7
|
+
#
|
8
|
+
# @example Search by text
|
9
|
+
# courses = Verso::CourseList.new(:text => "golf") # => <Verso::CourseList:0x007fa5a10bbb68 @attrs={:text=>"golf"}>
|
10
|
+
# courses.first.title # => "Turf Grass Applications, Advanced"
|
11
|
+
#
|
12
|
+
# @example Search by cluster
|
13
|
+
# course = Verso::CourseList.new(:cluster => "Information Technology).first
|
14
|
+
# course.title # => "Computer Applications"
|
15
|
+
#
|
16
|
+
# @example Search by program area
|
17
|
+
# course = Verso::CourseList.new(:program_area => "Career Connections").last
|
18
|
+
# course.title # => "Career Investigation Phase I"
|
19
|
+
#
|
20
|
+
# @example Search by code
|
21
|
+
# courses = Verso::CourseList.new(:code => "6320") # => <Verso::CourseList:0x007fa5a1f27a08 @attrs={:code=>"6320"}>
|
22
|
+
# courses.first # => <Verso::Course:0x007fa5a1f3e5c8 @attrs={:duration=>36, :edition=>"2012", :code=>"6320" . . . }>
|
23
|
+
# courses.first.code # => "6320"
|
24
|
+
#
|
25
|
+
# @example Search by edition
|
26
|
+
# all_2012 = Verso::CourseList.new(:edition => "2012")
|
27
|
+
#
|
28
|
+
# @example Search by combination
|
29
|
+
# courses = Verso::CourseList.new(:text => "internet", :cluster => "Marketing") # => <Verso::CourseList:0x007fa5a19b6c90 @attrs={ . . . }>
|
30
|
+
# courses.count # => 1
|
31
|
+
#
|
32
|
+
# @example An empty search returns an empty list
|
33
|
+
# courses = Verso::CourseList.new
|
34
|
+
# courses.count # => 0
|
35
|
+
#
|
36
|
+
# @overload initialize(attrs={})
|
37
|
+
# @option attrs [String] :code Course code
|
38
|
+
# @option attrs [String] :edition Edition year
|
39
|
+
# @option attrs [String] :text Free text
|
40
|
+
# @option attrs [String] :cluster Cluster title
|
41
|
+
# @option attrs [String] :program_area Program Area title
|
42
|
+
class CourseList < Verso::Base
|
3
43
|
include Enumerable
|
4
|
-
include
|
44
|
+
include HTTPGettable
|
45
|
+
extend Forwardable
|
46
|
+
def_delegators :courses, :[], :each, :empty?, :last, :length
|
5
47
|
|
6
|
-
|
7
|
-
@q_uri = Addressable::URI.new(
|
8
|
-
:path => '/courses',
|
9
|
-
:query_values => raw_query.
|
10
|
-
select { |k, v| v }.
|
11
|
-
reject { |k, v| v.to_s.empty? }
|
12
|
-
)
|
13
|
-
end
|
48
|
+
private
|
14
49
|
|
15
50
|
def courses
|
16
|
-
@courses ||= if
|
17
|
-
|
18
|
-
collect { |c| Course.new(c) }
|
51
|
+
@courses ||= if q_uri.query_values.values.any?
|
52
|
+
get_attr(:courses).collect { |c| Course.new(c) }
|
19
53
|
else
|
20
54
|
[]
|
21
55
|
end
|
22
56
|
end
|
23
57
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
58
|
+
def q_uri
|
59
|
+
Addressable::URI.new(
|
60
|
+
:path => '/courses',
|
61
|
+
:query_values => attrs.
|
62
|
+
reject { |k, v| k == :courses }.
|
63
|
+
select { |k, v| v }.
|
64
|
+
reject { |k, v| v.to_s.empty? }
|
65
|
+
)
|
30
66
|
end
|
31
67
|
|
32
|
-
def
|
33
|
-
|
68
|
+
def path
|
69
|
+
q_uri.request_uri
|
34
70
|
end
|
35
71
|
end
|
36
72
|
end
|
data/lib/verso/credential.rb
CHANGED
@@ -1,34 +1,108 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
2
|
+
# Credential Resource
|
3
|
+
#
|
4
|
+
# The usual way to get a Credential would be to use {Verso::CredentialList}
|
5
|
+
# or to get one from a related object, such as a {Verso::Course} object.
|
6
|
+
#
|
7
|
+
# @see http://api.cteresource.org/docs/credentials/credential
|
8
|
+
#
|
9
|
+
# @!attribute [r] admin_notes
|
10
|
+
# @return [String] HTML-formatted test administration notes
|
11
|
+
# @!attribute [r] amt_seal
|
12
|
+
# @return [Booelean] Advanced Math and Technology seal
|
13
|
+
# @!attribute [r] contact_info
|
14
|
+
# @return [String] Contractor contact information
|
15
|
+
# @!attribute [r] cost
|
16
|
+
# @return [String] Cost
|
17
|
+
# @!attribute [r] cte_seal
|
18
|
+
# @return [Boolean] CTE seal
|
19
|
+
# @!attribute [r] description
|
20
|
+
# @return [String] HTML-formatted text describing the credential.
|
21
|
+
# @!attribute [r] has_ancestor
|
22
|
+
# @return [Boolean] Did this credential exist in an earlier edition?
|
23
|
+
# @!attribute [r] how_to_earn_it
|
24
|
+
# @return [String] HTML-formatted text about how to earn it.
|
25
|
+
# @!attribute [r] id
|
26
|
+
# @return [Fixnum] Credential id
|
27
|
+
# @!attribute [r] items
|
28
|
+
# @return [String] Number of test items
|
29
|
+
# @!attribute [r] passing_score
|
30
|
+
# @return [Sring] Passing score
|
31
|
+
# @!attribute [r] pretest
|
32
|
+
# @return [Boolean,nil] Is a pre-test, study guide, or blueprint available?
|
33
|
+
# @!attribute [r] proctor
|
34
|
+
# @return [String] Test examiner/proctor
|
35
|
+
# @!attribute [r] program_area
|
36
|
+
# @return [String] Title of associated program area
|
37
|
+
# @!attribute [r] retired
|
38
|
+
# @return [Boolean] Is this credential slated for deletion?
|
39
|
+
# @!attribute [r] site
|
40
|
+
# @return [String] Allowed testing site
|
41
|
+
# @!attribute [r] time
|
42
|
+
# @return [String] Time allowed
|
43
|
+
# @!attribute [r] title
|
44
|
+
# @return [String] Credential title
|
45
|
+
# @!attribute [r] type
|
46
|
+
# @return ['Certification','License'] Credential type
|
47
|
+
# @!attribute [r] verified_credit
|
48
|
+
# @return [Boolean] Verified credit
|
49
|
+
#
|
50
|
+
# @overload initialize(attrs={})
|
51
|
+
# @note Any attributes may be set upon instantiation, using Options Hash.
|
52
|
+
# The following are required:
|
53
|
+
# @option attrs [Fixnum] :id Credential id *Required*
|
54
|
+
class Credential < Verso::Base
|
55
|
+
include HTTPGettable
|
56
|
+
attr_reader :admin_notes, :amt_seal, :contact_info, :cost, :cte_seal,
|
57
|
+
:description, :has_ancestor, :how_to_earn_it, :id, :items, :passing_score,
|
58
|
+
:pretest, :proctor, :program_area, :retired, :site, :time, :title, :type,
|
59
|
+
:verified_credit
|
60
|
+
alias amt_seal? amt_seal
|
61
|
+
alias cte_seal? cte_seal
|
62
|
+
alias has_ancestor? has_ancestor
|
63
|
+
alias retired? retired
|
64
|
+
alias verified_credit? verified_credit
|
4
65
|
|
5
|
-
|
6
|
-
|
66
|
+
# VDOE contacts, each responding to #name, #email, and #phone, all Strings.
|
67
|
+
#
|
68
|
+
# @return [Array] VDOE contacts
|
69
|
+
def contacts
|
70
|
+
@contacts ||= get_attr(:contacts).collect { |c| OpenStruct.new(c) }
|
7
71
|
end
|
8
72
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
JSON.parse(http_get("/credentials/#{id}"))["credential"]
|
13
|
-
)
|
14
|
-
end
|
15
|
-
@raw_credential[mname.to_s]
|
73
|
+
# @return [String] Contractor name
|
74
|
+
def contractor_name
|
75
|
+
get_attr(:contractor_name).to_s
|
16
76
|
end
|
17
77
|
|
18
|
-
|
19
|
-
|
78
|
+
# @return [String] Details
|
79
|
+
def details
|
80
|
+
get_attr(:details).to_s # #to_s b/c API sometimes returns nil
|
20
81
|
end
|
21
82
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
83
|
+
# Source. Responds to #title, #url, and #contact_info. All are Strings or
|
84
|
+
# nil. The last is HTML-formatted.
|
85
|
+
#
|
86
|
+
# @return [OpenStruct] Source
|
87
|
+
def source
|
88
|
+
# force update if we only have part of source
|
89
|
+
attrs.merge!(fetch) unless attrs[:source] && attrs[:source].has_key?(:url)
|
90
|
+
OpenStruct.new(get_attr(:source))
|
28
91
|
end
|
29
92
|
|
93
|
+
# @return [Array] Collection of related {Verso::Course} objects
|
30
94
|
def related_courses
|
31
|
-
|
95
|
+
@courses ||= get_attr(:related_courses).collect { |rc| Course.new(rc) }
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def path
|
101
|
+
"/credentials/#{id}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def fetch
|
105
|
+
super[:credential]
|
32
106
|
end
|
33
107
|
end
|
34
108
|
end
|
@@ -1,28 +1,43 @@
|
|
1
1
|
module Verso
|
2
|
-
|
2
|
+
# Credential list resource
|
3
|
+
#
|
4
|
+
# Search for {Verso::Credential} objects using free text, or get back the
|
5
|
+
# list of all of them.
|
6
|
+
#
|
7
|
+
# @see http://api.cteresource.org/docs/credentials
|
8
|
+
#
|
9
|
+
# @example All
|
10
|
+
# creds = Verso::CredentialList.new # => everything
|
11
|
+
# creds.first # => <Verso::Credential:0x007fb1a39e4038 . . . >
|
12
|
+
#
|
13
|
+
# @example Search
|
14
|
+
# creds = Verso::CredentialList.new(:text => "nocti")
|
15
|
+
# creds.first.source.title # => "National Occupational Competency Testing Institute (NOCTI)"
|
16
|
+
#
|
17
|
+
# @overload initialize(attrs={})
|
18
|
+
# @option attrs [String] :text Free text
|
19
|
+
class CredentialList < Verso::Base
|
3
20
|
include Enumerable
|
4
|
-
include
|
21
|
+
include HTTPGettable
|
22
|
+
extend Forwardable
|
23
|
+
def_delegators :credentials, :[], :each, :empty?, :last, :length
|
5
24
|
|
6
|
-
|
25
|
+
private
|
7
26
|
|
8
|
-
def
|
9
|
-
@
|
10
|
-
@q_uri.query_values = opts unless opts[:text].to_s.empty?
|
11
|
-
@credentials = JSON.parse(http_get(@q_uri.request_uri))["credentials"].
|
27
|
+
def credentials
|
28
|
+
@credentials ||= get_attr(:credentials).
|
12
29
|
collect { |c| Credential.new(c) }.
|
13
30
|
sort_by { |c| c.title }
|
14
31
|
end
|
15
32
|
|
16
|
-
def
|
17
|
-
|
33
|
+
def path
|
34
|
+
q_uri ||= Addressable::URI.new(:path => '/credentials')
|
35
|
+
q_uri.query_values = { :text => text } unless text.empty?
|
36
|
+
q_uri.request_uri
|
18
37
|
end
|
19
38
|
|
20
|
-
def
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def empty?
|
25
|
-
credentials.empty?
|
39
|
+
def text
|
40
|
+
attrs[:text] ? attrs[:text] : ''
|
26
41
|
end
|
27
42
|
end
|
28
43
|
end
|
data/lib/verso/duty_area.rb
CHANGED
@@ -1,16 +1,29 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
# Duty Area
|
3
|
+
#
|
4
|
+
# A group of tasks in a {Verso::TaskList}.
|
5
|
+
#
|
6
|
+
# @see http://api.cteresource.org/docs/courses/course/tasks
|
7
|
+
#
|
8
|
+
# @!attribute [r] code
|
9
|
+
# @return [String] Course code
|
10
|
+
# @!attribute [r] edition
|
11
|
+
# @return [String] Course edition year
|
12
|
+
# @!attribute [r] title
|
13
|
+
# @return [String] Duty Area title
|
14
|
+
#
|
15
|
+
# @note A DutyArea is created for you by {Verso::TaskList}. It corresponds
|
16
|
+
# to a portion of the Task List resource. You should never need to
|
17
|
+
# instantiate one yourself.
|
18
|
+
class DutyArea < Verso::Base
|
19
|
+
attr_reader :code, :edition, :title
|
10
20
|
|
21
|
+
# Tasks within this Duty Area
|
22
|
+
#
|
23
|
+
# @return [Array] {Verso::Task} objects
|
11
24
|
def tasks
|
12
|
-
@tasks ||=
|
13
|
-
Task.new(t.merge(
|
25
|
+
@tasks ||= get_attr(:tasks).collect do |t|
|
26
|
+
Task.new(t.merge(:code => code, :edition => edition))
|
14
27
|
end
|
15
28
|
end
|
16
29
|
end
|
data/lib/verso/edition_list.rb
CHANGED
@@ -1,19 +1,27 @@
|
|
1
1
|
module Verso
|
2
|
-
|
2
|
+
# Edition List resource
|
3
|
+
#
|
4
|
+
# A collection of Edition proxies that respond to #year, returning a string
|
5
|
+
# year like '2012'.
|
6
|
+
#
|
7
|
+
# @example Get a list
|
8
|
+
# editions = Verso::EditionList.new
|
9
|
+
# editions.first.year => # "2012"
|
10
|
+
#
|
11
|
+
class EditionList < Verso::Base
|
3
12
|
include Enumerable
|
4
|
-
include
|
13
|
+
include HTTPGettable
|
14
|
+
extend Forwardable
|
15
|
+
def_delegators :editions, :[], :each, :empty?, :last, :length
|
5
16
|
|
6
|
-
|
7
|
-
@editions ||= JSON.parse(http_get('/editions/'))["editions"].
|
8
|
-
collect { |e| OpenStruct.new(e) }
|
9
|
-
end
|
17
|
+
private
|
10
18
|
|
11
|
-
def
|
12
|
-
editions.
|
19
|
+
def editions
|
20
|
+
@editions ||= get_attr(:editions).collect { |e| OpenStruct.new(e) }
|
13
21
|
end
|
14
22
|
|
15
|
-
def
|
16
|
-
editions
|
23
|
+
def path
|
24
|
+
"/editions/"
|
17
25
|
end
|
18
26
|
end
|
19
27
|
end
|
data/lib/verso/emphasis.rb
CHANGED
@@ -1,21 +1,35 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
2
|
+
# Academic Emphasis resource
|
3
|
+
#
|
4
|
+
# @see http://api.cteresource.org/docs/academics/emphasis
|
5
|
+
#
|
6
|
+
# @!attribute [r] id
|
7
|
+
# @return [Fixnum] Academic Emphasis id
|
8
|
+
# @!attribute [r] title
|
9
|
+
# @return Academic Emphasis title
|
10
|
+
#
|
11
|
+
# @overload initialize(attrs={})
|
12
|
+
# @note Any attributes may be set upon instantiation, using Options Hash.
|
13
|
+
# The following are required:
|
14
|
+
# @option attrs [Fixnum] :id Academic Emphasis id *Required*
|
15
|
+
class Emphasis < Verso::Base
|
16
|
+
include HTTPGettable
|
17
|
+
attr_reader :id, :title
|
4
18
|
|
5
|
-
|
6
|
-
|
19
|
+
# @return [Array] Collection of related {Verso::OccupationData} objects
|
20
|
+
def occupation_data
|
21
|
+
@occupation_data ||= get_attr(:occupation_data).
|
22
|
+
collect { |od| OccupationData.new(od) }
|
7
23
|
end
|
8
24
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@raw_emphasis[mname.to_s]
|
25
|
+
private
|
26
|
+
|
27
|
+
def fetch
|
28
|
+
super[:emphasis]
|
14
29
|
end
|
15
30
|
|
16
|
-
def
|
17
|
-
|
18
|
-
collect { |od| OccupationData.new(od) }
|
31
|
+
def path
|
32
|
+
"/academics/#{id}"
|
19
33
|
end
|
20
34
|
end
|
21
35
|
end
|
data/lib/verso/emphasis_list.rb
CHANGED
@@ -1,19 +1,27 @@
|
|
1
1
|
module Verso
|
2
|
-
|
2
|
+
# Academic Emphasis List resource
|
3
|
+
#
|
4
|
+
# A collection of all {Verso::Emphasis} objects.
|
5
|
+
#
|
6
|
+
# @see http://api.cteresource.org/docs/academics
|
7
|
+
#
|
8
|
+
# @example Get a list
|
9
|
+
# emphases = Verso::EmphasisList.new # => all of them
|
10
|
+
# emphases.first.title # => "Algebra"
|
11
|
+
class EmphasisList < Verso::Base
|
3
12
|
include Enumerable
|
4
|
-
include
|
13
|
+
include HTTPGettable
|
14
|
+
extend Forwardable
|
15
|
+
def_delegators :emphases, :[], :each, :empty?, :last, :length
|
5
16
|
|
6
|
-
|
7
|
-
@emphases ||= JSON.parse(http_get('/academics/'))["emphases"].
|
8
|
-
collect { |em| Emphasis.new(em) }
|
9
|
-
end
|
17
|
+
private
|
10
18
|
|
11
|
-
def
|
12
|
-
emphases.
|
19
|
+
def emphases
|
20
|
+
@emphases ||= get_attr(:emphases).collect { |em| Emphasis.new(em) }
|
13
21
|
end
|
14
22
|
|
15
|
-
def
|
16
|
-
|
23
|
+
def path
|
24
|
+
"/academics/"
|
17
25
|
end
|
18
26
|
end
|
19
27
|
end
|
@@ -1,21 +1,37 @@
|
|
1
1
|
module Verso
|
2
|
-
|
2
|
+
# Examination List resource
|
3
|
+
#
|
4
|
+
# A collection of Examination stand-in objects that respond to:
|
5
|
+
# * #amt_seal @return [Boolean] AMT Seal
|
6
|
+
# * #passing_score @return [String] Passing score
|
7
|
+
# * #retired @return [Boolean] Slated to be deleted?
|
8
|
+
# * #source @return [String] Title of exam source
|
9
|
+
# * #title @return [String] Exam title
|
10
|
+
# * #verified_credit @return [Booelean] Verified credit
|
11
|
+
#
|
12
|
+
# The attributes of the Examination stand-ins are similar to
|
13
|
+
# {Verso::Credential}.
|
14
|
+
#
|
15
|
+
# @example Get the list
|
16
|
+
# exams = Verso::ExaminationList.new # => everything
|
17
|
+
# exams.first.title # => "Advanced Placement Computer Science A"
|
18
|
+
#
|
19
|
+
# @see http://api.cteresource.org/docs/examinations
|
20
|
+
class ExaminationList < Verso::Base
|
3
21
|
include Enumerable
|
4
|
-
include
|
22
|
+
include HTTPGettable
|
23
|
+
extend Forwardable
|
24
|
+
def_delegators :examinations, :[], :each, :empty?, :last, :length
|
5
25
|
|
6
|
-
|
26
|
+
private
|
7
27
|
|
8
|
-
def
|
9
|
-
@examinations
|
10
|
-
|
28
|
+
def examinations
|
29
|
+
@examinations ||= get_attr(:examinations).
|
30
|
+
collect { |e| OpenStruct.new(e) }
|
11
31
|
end
|
12
32
|
|
13
|
-
def
|
14
|
-
examinations
|
15
|
-
end
|
16
|
-
|
17
|
-
def last
|
18
|
-
examinations[-1]
|
33
|
+
def path
|
34
|
+
"/examinations/"
|
19
35
|
end
|
20
36
|
end
|
21
37
|
end
|