rtrail 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/README.md +26 -6
- data/Rakefile +42 -0
- data/lib/rtrail/case.rb +5 -1
- data/lib/rtrail/client.rb +1 -1
- data/lib/rtrail/entity.rb +20 -10
- data/lib/rtrail/entry.rb +9 -0
- data/lib/rtrail/helpers.rb +25 -0
- data/lib/rtrail/methods.rb +51 -0
- data/lib/rtrail/plan.rb +5 -0
- data/lib/rtrail/project.rb +14 -5
- data/lib/rtrail/result.rb +1 -1
- data/lib/rtrail/run.rb +6 -1
- data/lib/rtrail/section.rb +82 -1
- data/lib/rtrail/suite.rb +40 -1
- data/lib/rtrail/test.rb +3 -0
- data/mock/app.rb +5 -0
- data/rtrail.gemspec +16 -12
- data/spec/methods_spec.rb +8 -0
- data/spec/project_spec.rb +5 -7
- data/spec/run_spec.rb +2 -2
- data/spec/spec_helper.rb +6 -0
- data/spec/suite_spec.rb +11 -1
- data/spec/support/matchers.rb +19 -0
- data/spec/test_spec.rb +1 -1
- metadata +97 -48
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YWYxZmE0ZjUyMWQ2OTRhOGViYTljMGZiNGY2ODJlNDNkMjU0MzAzMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDZhMTUwZDgyNzNmMGQ0NDMzNTllYzZjM2QzM2VhMmNkMGYwY2Q4NQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjgyMTUzNDU3YWQzMmM4NTVhZGE3M2FkYjY0ZmQ0M2U3ZWI4ZmU3YWIxZGJm
|
10
|
+
NzlhOTE2Yzc3YTI2NzRkMzQyMWI5ZDYwYWQ4ZGNhYTJhMDVjNmZmOWM5Mzli
|
11
|
+
MjdlNDQwOGEzODQ2MjAxNjBkNGRiMTFhOTNiNjcwMzg5ZGQ3Nzg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZWVhYTkxMzhjNTcyNzRhZGE5YjhmYWE1MzBiNTg3N2UwZWYxOGYyNjc1ODky
|
14
|
+
Y2ExY2VjZTBiZjJkZDYyYmEzMzdmYzkzMGE5YTQyMTBhNDlhMDRlYmZiZTY4
|
15
|
+
MjY0ZWU1NDcwYzgzN2I2N2YzOWYyYTI4NzM3ZmEwYWM4ZWY1NzI=
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,11 +1,20 @@
|
|
1
1
|
RTrail
|
2
2
|
======
|
3
3
|
|
4
|
-
|
4
|
+
[![Build Status](https://travis-ci.org/a-e/rtrail.svg?branch=master)](https://travis-ci.org/a-e/rtrail)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/a-e/rtrail/badge.png)](https://coveralls.io/r/a-e/rtrail)
|
5
6
|
|
6
|
-
|
7
|
-
which means you must use TestRail 3.x or later.
|
7
|
+
Ruby object wrapper for the [TestRail][1] [API v2][2]
|
8
8
|
|
9
|
+
Please use the [issue tracker][3] to report bugs or request improvements, and
|
10
|
+
[fork this repository][4] if you'd like to hack on it.
|
11
|
+
|
12
|
+
|
13
|
+
[1]: http://www.gurock.com/testrail/ "TestRail Homepage"
|
14
|
+
[2]: http://docs.gurock.com/testrail-api2/start "TestRail API v2 docs"
|
15
|
+
|
16
|
+
[3]: https://github.com/a-e/rtrail/issues "RTrail Issue Tracker"
|
17
|
+
[4]: https://github.com/a-e/rtrail/fork "Fork RTrail on Github"
|
9
18
|
|
10
19
|
Installation
|
11
20
|
------------
|
@@ -14,11 +23,12 @@ Run from a console:
|
|
14
23
|
|
15
24
|
$ gem install rtrail
|
16
25
|
|
17
|
-
Or add to your `Gemfile`:
|
26
|
+
Or add to your `Gemfile` before a `bundle install`:
|
18
27
|
|
19
28
|
gem 'rtrail'
|
20
29
|
|
21
30
|
|
31
|
+
|
22
32
|
Overview
|
23
33
|
--------
|
24
34
|
|
@@ -85,8 +95,18 @@ use; for instance:
|
|
85
95
|
Development
|
86
96
|
-----------
|
87
97
|
|
88
|
-
To contribute, please fork this repository,
|
89
|
-
|
98
|
+
To contribute, please [fork this repository](https://github.com/a-e/rtrail/fork),
|
99
|
+
develop your code and write spec tests that cover it, commit to your fork
|
100
|
+
and submit a pull request with your changes.
|
101
|
+
|
102
|
+
|
103
|
+
References
|
104
|
+
----------
|
105
|
+
|
106
|
+
- TestRail homepage: http://www.gurock.com/testrail/
|
107
|
+
- Another TestRail Ruby client: https://github.com/krobi64/testrail
|
108
|
+
- Official TestRail API examples: https://github.com/gurock/testrail-api
|
109
|
+
- TestRail API v2 docs: http://docs.gurock.com/testrail-api2/start
|
90
110
|
|
91
111
|
|
92
112
|
License
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
ROOT_DIR = File.expand_path(File.dirname(__FILE__))
|
5
|
+
MOCK_APP = File.join(ROOT_DIR, 'mock', 'app.rb')
|
6
|
+
|
7
|
+
namespace :mock do
|
8
|
+
desc "Start the mock TestRail app in the background"
|
9
|
+
task :start do
|
10
|
+
puts "Starting the mock TestRail app: #{MOCK_APP}"
|
11
|
+
system("ruby #{MOCK_APP} &")
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Stop the mock TestRail app"
|
15
|
+
task :stop do
|
16
|
+
puts "Stopping the mock TestRail app..."
|
17
|
+
begin
|
18
|
+
Net::HTTP.get('localhost', '/shutdown', 8080)
|
19
|
+
rescue EOFError
|
20
|
+
# This is expected
|
21
|
+
puts "Mock TestRail app stopped."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Run spec tests (requires mock TestRail app to be running)"
|
27
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
28
|
+
t.pattern = 'spec/**/*_spec.rb'
|
29
|
+
t.rspec_opts = ['--color', '--format doc']
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Start the mock TestRail app, run specs, then stop the mock app"
|
33
|
+
task :test do
|
34
|
+
begin
|
35
|
+
Rake::Task['mock:start'].invoke
|
36
|
+
Rake::Task['spec'].invoke
|
37
|
+
ensure
|
38
|
+
Rake::Task['mock:stop'].invoke
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
task :default => [:test]
|
data/lib/rtrail/case.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require_relative 'entity'
|
2
|
+
require_relative 'methods'
|
2
3
|
|
3
4
|
module RTrail
|
4
5
|
class Case < Entity
|
5
|
-
include HasCreateTime
|
6
|
+
include Helpers::HasCreateTime
|
7
|
+
include Methods::Get
|
8
|
+
include Methods::Update
|
9
|
+
include Methods::Delete
|
6
10
|
end
|
7
11
|
end # module RTrail
|
8
12
|
|
data/lib/rtrail/client.rb
CHANGED
data/lib/rtrail/entity.rb
CHANGED
@@ -5,6 +5,7 @@ module RTrail
|
|
5
5
|
class Entity
|
6
6
|
include Helpers
|
7
7
|
|
8
|
+
# FIXME: Find a better way to do this hinky @@client stuff
|
8
9
|
class << self
|
9
10
|
def client=(client)
|
10
11
|
@@client = client
|
@@ -26,25 +27,34 @@ module RTrail
|
|
26
27
|
return self.class.client
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
# Create a new Entity with the given field data.
|
31
|
+
#
|
32
|
+
# @param [Hash, Entity] data
|
33
|
+
# Field values to store in the Entity instance, or an
|
34
|
+
# Entity instance to clone.
|
35
|
+
#
|
36
|
+
def initialize(data={})
|
37
|
+
if data.is_a?(Hash)
|
38
|
+
@data = Hashie::Mash.new(data)
|
39
|
+
elsif data.is_a?(Entity)
|
40
|
+
@data = Hashie::Mash.new(data.data)
|
32
41
|
else
|
33
|
-
|
42
|
+
raise ArgumentError.new("data must be a Hash or Entity.")
|
34
43
|
end
|
35
44
|
end
|
36
45
|
attr_accessor :data
|
37
46
|
|
38
|
-
# Fetch data for a derived class object.
|
39
|
-
def fetch(id)
|
40
|
-
return client.get("get_#{self.class.basename}/#{id}")
|
41
|
-
end
|
42
|
-
|
43
47
|
# Pass-through to Hashie::Mash for attribute access
|
44
48
|
def method_missing(meth, *args, &block)
|
45
|
-
|
49
|
+
if data.respond_to?(meth)
|
50
|
+
return data.send(meth, *args, &block)
|
51
|
+
else
|
52
|
+
super
|
53
|
+
end
|
46
54
|
end
|
47
55
|
|
56
|
+
# TODO: Factor these out into helper modules
|
57
|
+
|
48
58
|
# Return a list of entities retrieved from `get_<thing>s/<id>`.
|
49
59
|
def get_entities(klass, parent_id, params={})
|
50
60
|
path = path_with_params(
|
data/lib/rtrail/entry.rb
ADDED
data/lib/rtrail/helpers.rb
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
module RTrail
|
2
2
|
module Helpers
|
3
|
+
# ----------------
|
4
|
+
# Class methods
|
5
|
+
# ----------------
|
6
|
+
|
7
|
+
# Allow `include` to pull in both class and instance methods
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def has_post(*actions)
|
14
|
+
actions.each do |action|
|
15
|
+
define_method(action) do |data|
|
16
|
+
kind = self.class.basename
|
17
|
+
puts "in POST #{action}_#{kind}/#{self.id}, data = #{data.inspect}"
|
18
|
+
#return client.post("#{action}_#{kind}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# ----------------
|
25
|
+
# Instance methods
|
26
|
+
# ----------------
|
27
|
+
|
3
28
|
# Return true if `name_or_id` appears to be a numeric id,
|
4
29
|
# false otherwise.
|
5
30
|
def is_id?(name_or_id)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module RTrail
|
2
|
+
module Methods
|
3
|
+
# Add a `get_<entity>/:id` wrapper to any class.
|
4
|
+
module Get
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
# Get data for the entity with the given ID, and return a new
|
11
|
+
# Entity subclass instance.
|
12
|
+
# Wraps `GET get_<entity>/<id>`
|
13
|
+
#
|
14
|
+
def get(entity_id)
|
15
|
+
entity_data = client.get("get_#{self.basename}/#{entity_id}")
|
16
|
+
return self.new(entity_data)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end # module Get
|
20
|
+
|
21
|
+
module Update
|
22
|
+
# Update TestRail with local changes to this Entity.
|
23
|
+
# Wraps `POST update_<entity>/<id>`
|
24
|
+
#
|
25
|
+
# @param [Hash] fields
|
26
|
+
# Individual fields to update. If omitted, the data currently
|
27
|
+
# stored in the local Entity instance is posted.
|
28
|
+
#
|
29
|
+
def update(fields={})
|
30
|
+
fields = @data.merge(fields)
|
31
|
+
client.post("update_#{self.class.basename}/#{self.id}", fields)
|
32
|
+
end
|
33
|
+
end # module Update
|
34
|
+
|
35
|
+
module Delete
|
36
|
+
# Delete this Entity from TestRail.
|
37
|
+
# Wraps `POST delete_<entity>/<id>`.
|
38
|
+
#
|
39
|
+
def delete
|
40
|
+
client.post("delete_#{self.class.basename}/#{self.id}")
|
41
|
+
end
|
42
|
+
end # module Delete
|
43
|
+
|
44
|
+
module Close
|
45
|
+
def close
|
46
|
+
client.post("close_#{self.class.basename}/#{self.id}")
|
47
|
+
end
|
48
|
+
end # module Close
|
49
|
+
end
|
50
|
+
end # module RTrail
|
51
|
+
|
data/lib/rtrail/plan.rb
CHANGED
data/lib/rtrail/project.rb
CHANGED
@@ -2,9 +2,14 @@ require_relative 'entity'
|
|
2
2
|
require_relative 'suite'
|
3
3
|
require_relative 'run'
|
4
4
|
require_relative 'plan'
|
5
|
+
require_relative 'methods'
|
5
6
|
|
6
7
|
module RTrail
|
7
8
|
class Project < Entity
|
9
|
+
include Methods::Get
|
10
|
+
include Methods::Update
|
11
|
+
include Methods::Delete
|
12
|
+
|
8
13
|
def self.all
|
9
14
|
return client.get("get_projects").map do |project|
|
10
15
|
self.new(project)
|
@@ -15,17 +20,15 @@ module RTrail
|
|
15
20
|
result = Project.all.find do |project|
|
16
21
|
project.name == project_name
|
17
22
|
end
|
18
|
-
|
19
23
|
if result.nil?
|
20
24
|
raise RTrail::NotFound.new("Project '#{project_name}' not found in TestRail")
|
21
|
-
else
|
22
|
-
return self.new(result)
|
23
25
|
end
|
26
|
+
return self.new(result)
|
24
27
|
end
|
25
28
|
|
26
29
|
# Return a suite with the given name in the current project.
|
27
30
|
def suite_by_name(suite_name)
|
28
|
-
suite =
|
31
|
+
suite = suites.find do |s|
|
29
32
|
s.name == suite_name
|
30
33
|
end
|
31
34
|
if suite.nil?
|
@@ -38,7 +41,7 @@ module RTrail
|
|
38
41
|
# Return a suite with the given name or id in the current project.
|
39
42
|
def suite(suite_name_or_id)
|
40
43
|
if is_id?(suite_name_or_id)
|
41
|
-
return Suite.
|
44
|
+
return Suite.get(suite_name_or_id)
|
42
45
|
else
|
43
46
|
return suite_by_name(suite_name_or_id)
|
44
47
|
end
|
@@ -78,6 +81,12 @@ module RTrail
|
|
78
81
|
})
|
79
82
|
return add_entity(Run, data.id, run_data)
|
80
83
|
end
|
84
|
+
|
85
|
+
# Add a new Suite to the Project.
|
86
|
+
# Requires :name
|
87
|
+
def add_suite(fields={})
|
88
|
+
return add_entity(Suite, data.id, fields)
|
89
|
+
end
|
81
90
|
end
|
82
91
|
end # module RTrail
|
83
92
|
|
data/lib/rtrail/result.rb
CHANGED
data/lib/rtrail/run.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
require_relative 'entity'
|
2
2
|
require_relative 'test'
|
3
3
|
require_relative 'helpers'
|
4
|
+
require_relative 'methods'
|
4
5
|
|
5
6
|
module RTrail
|
6
7
|
class Run < Entity
|
7
|
-
include
|
8
|
+
include Methods::Get
|
9
|
+
include Methods::Update
|
10
|
+
include Methods::Delete
|
11
|
+
include Methods::Close
|
12
|
+
include Helpers::HasCreateTime
|
8
13
|
|
9
14
|
# Return a one-line summary of this Run
|
10
15
|
def summary
|
data/lib/rtrail/section.rb
CHANGED
@@ -1,7 +1,88 @@
|
|
1
1
|
require_relative 'entity'
|
2
|
+
require_relative 'case'
|
3
|
+
require_relative 'suite'
|
4
|
+
require_relative 'methods'
|
2
5
|
|
3
6
|
module RTrail
|
4
7
|
class Section < Entity
|
5
|
-
|
8
|
+
include Methods::Get
|
9
|
+
include Methods::Update
|
10
|
+
include Methods::Delete
|
11
|
+
|
12
|
+
# Return the Suite this Section is in
|
13
|
+
def suite
|
14
|
+
return Suite.get(data.suite_id)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Return the Cases in this Section
|
18
|
+
def cases
|
19
|
+
return suite.cases(data.id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def case_by_title(case_title)
|
23
|
+
kase = cases.find do |c|
|
24
|
+
c.title == case_title
|
25
|
+
end
|
26
|
+
if kase.nil?
|
27
|
+
raise RTrail::NotFound.new(
|
28
|
+
"Case '#{case_title}' not found in Section '#{data.name}'")
|
29
|
+
end
|
30
|
+
return kase
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return the Case matching a title or ID
|
34
|
+
def case(case_title_or_id)
|
35
|
+
if is_id?(case_title_or_id)
|
36
|
+
return Case.get(case_title_or_id)
|
37
|
+
else
|
38
|
+
return case_by_title(case_title_or_id)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Add a new Case to the Section
|
43
|
+
# Requires :title, :custom_steps_separated, :custom_expected
|
44
|
+
# :custom_steps_separated => [ {'content' => 'Action', 'expected' => 'Expectation'}, ... ]
|
45
|
+
def add_case(fields={})
|
46
|
+
return add_entity(Case, data.id, fields)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Add a Section within this Section
|
50
|
+
def add_subsection(fields={})
|
51
|
+
_suite = suite
|
52
|
+
subsection_data = fields.merge({
|
53
|
+
:suite_id => _suite.id,
|
54
|
+
:parent_id => data.id
|
55
|
+
})
|
56
|
+
return add_entity(Section, _suite.project_id, subsection_data)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return all Subsections in this Section
|
60
|
+
def subsections
|
61
|
+
return suite.sections.select do |sect|
|
62
|
+
sect.parent_id == data.id
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Return the subsection with the given name
|
67
|
+
def subsection_by_name(subsection_name)
|
68
|
+
subsect = subsections.find do |s|
|
69
|
+
s.name == subsection_name
|
70
|
+
end
|
71
|
+
if subsect.nil?
|
72
|
+
raise RTrail::NotFound.new(
|
73
|
+
"Sub-Section '#{subsection_name}' not found within Section '#{data.name}'")
|
74
|
+
end
|
75
|
+
return subsect
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return the Subsection with the given name or ID
|
79
|
+
def subsection(subsection_name_or_id)
|
80
|
+
if is_id?(subsection_name_or_id)
|
81
|
+
return Section.get(subsection_name_or_id)
|
82
|
+
else
|
83
|
+
return subsection_by_name(subsection_name_or_id)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end # class Section
|
6
87
|
end # module RTrail
|
7
88
|
|
data/lib/rtrail/suite.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
require_relative 'entity'
|
2
2
|
require_relative 'case'
|
3
3
|
require_relative 'section'
|
4
|
+
require_relative 'methods'
|
4
5
|
|
5
6
|
module RTrail
|
6
7
|
class Suite < Entity
|
8
|
+
include Methods::Get
|
9
|
+
include Methods::Update
|
10
|
+
include Methods::Delete
|
11
|
+
|
7
12
|
def sections
|
8
13
|
return get_entities(
|
9
14
|
Section,
|
@@ -12,7 +17,12 @@ module RTrail
|
|
12
17
|
)
|
13
18
|
end
|
14
19
|
|
15
|
-
def cases(
|
20
|
+
def cases(section_name_or_id=nil)
|
21
|
+
if section_name_or_id
|
22
|
+
section_id = section(section_name_or_id).id
|
23
|
+
else
|
24
|
+
section_id = nil
|
25
|
+
end
|
16
26
|
return get_entities(
|
17
27
|
Case,
|
18
28
|
data.project_id,
|
@@ -20,6 +30,35 @@ module RTrail
|
|
20
30
|
:section_id => section_id
|
21
31
|
)
|
22
32
|
end
|
33
|
+
|
34
|
+
# Return the first Section with the given name, or raise RTrail::NotFound
|
35
|
+
def section_by_name(section_name)
|
36
|
+
section = sections.find do |s|
|
37
|
+
s.name == section_name
|
38
|
+
end
|
39
|
+
if section.nil?
|
40
|
+
raise RTrail::NotFound.new(
|
41
|
+
"Section '#{section_name}' not found in Suite '#{data.name}'")
|
42
|
+
end
|
43
|
+
return section
|
44
|
+
end
|
45
|
+
|
46
|
+
def section(section_name_or_id)
|
47
|
+
if is_id?(section_name_or_id)
|
48
|
+
return Section.get(section_name_or_id)
|
49
|
+
else
|
50
|
+
return section_by_name(section_name_or_id)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Add a Section to the Suite.
|
55
|
+
# Requires :name
|
56
|
+
def add_section(fields={})
|
57
|
+
section_data = fields.merge({
|
58
|
+
:suite_id => data.id,
|
59
|
+
})
|
60
|
+
return add_entity(Section, data.project_id, section_data)
|
61
|
+
end
|
23
62
|
end
|
24
63
|
|
25
64
|
end # module RTrail
|
data/lib/rtrail/test.rb
CHANGED
data/mock/app.rb
CHANGED
@@ -28,6 +28,11 @@ class TestApp < Sinatra::Base
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
# Allow shutting down the app with a request
|
32
|
+
get '/shutdown' do
|
33
|
+
Process.kill('KILL', Process.pid)
|
34
|
+
end
|
35
|
+
|
31
36
|
get '/index.php' do
|
32
37
|
# FIXME: Handle query (used for suite_id, section_id etc.)
|
33
38
|
path, query = parse(params)
|
data/rtrail.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rtrail"
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.3"
|
4
4
|
s.summary = "Ruby object wrapper for TestRail API"
|
5
5
|
s.description = <<-EOS
|
6
6
|
RTrail wraps the TestRail API v2.0 in Ruby objects
|
@@ -9,30 +9,34 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = "epierce@automation-excellence.com"
|
10
10
|
s.homepage = "http://github.com/a-e/rtrail"
|
11
11
|
s.platform = Gem::Platform::RUBY
|
12
|
+
s.license = 'MIT'
|
12
13
|
|
13
|
-
s.add_dependency 'hashie'
|
14
|
+
s.add_dependency 'hashie', '~> 3.3'
|
14
15
|
|
15
16
|
# Basic utilities
|
16
|
-
s.add_development_dependency 'rake'
|
17
|
-
s.add_development_dependency 'pry'
|
17
|
+
s.add_development_dependency 'rake', '~> 10.3'
|
18
|
+
s.add_development_dependency 'pry', '~> 0.10'
|
18
19
|
|
19
20
|
# For testing
|
20
|
-
s.add_development_dependency 'rspec'
|
21
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
22
|
+
s.add_development_dependency 'rspec-autotest', '~> 1.0'
|
23
|
+
s.add_development_dependency 'ZenTest', '~> 4.10'
|
21
24
|
|
22
25
|
# Mock webapp to support testing
|
23
|
-
s.add_development_dependency 'sinatra'
|
24
|
-
s.add_development_dependency 'sinatra-contrib'
|
25
|
-
s.add_development_dependency 'thin'
|
26
|
+
s.add_development_dependency 'sinatra', '~> 1.4'
|
27
|
+
s.add_development_dependency 'sinatra-contrib', '~> 1.4'
|
28
|
+
s.add_development_dependency 'thin', '~> 1.6'
|
26
29
|
|
27
30
|
# For test coverage
|
28
|
-
s.add_development_dependency 'simplecov'
|
31
|
+
s.add_development_dependency 'simplecov', '~> 0.9'
|
32
|
+
s.add_development_dependency 'coveralls', '~> 0.7'
|
29
33
|
|
30
34
|
# For documentation and markdown support
|
31
|
-
s.add_development_dependency 'yard'
|
32
|
-
s.add_development_dependency 'rdiscount'
|
35
|
+
s.add_development_dependency 'yard', '~> 0.8'
|
36
|
+
s.add_development_dependency 'rdiscount', '~> 2.1'
|
33
37
|
|
34
38
|
# Others
|
35
|
-
s.add_development_dependency 'yajl-ruby'
|
39
|
+
s.add_development_dependency 'yajl-ruby', '~> 1.2'
|
36
40
|
|
37
41
|
# Files to distribute
|
38
42
|
s.files = `git ls-files`.split("\n")
|
data/spec/project_spec.rb
CHANGED
@@ -6,8 +6,7 @@ module RTrail
|
|
6
6
|
describe "#all" do
|
7
7
|
it "returns all Projects" do
|
8
8
|
projects = Project.all
|
9
|
-
expect(projects).to
|
10
|
-
expect(projects.first).to be_a(Project)
|
9
|
+
expect(projects).to be_a_list_of(Project)
|
11
10
|
end
|
12
11
|
end
|
13
12
|
|
@@ -15,7 +14,6 @@ module RTrail
|
|
15
14
|
it "returns the Project with the given name if it exists" do
|
16
15
|
project = Project.by_name("First Project")
|
17
16
|
expect(project).to be_a(Project)
|
18
|
-
expect(project).to_not be_nil
|
19
17
|
expect(project.name).to eq("First Project")
|
20
18
|
end
|
21
19
|
|
@@ -28,11 +26,12 @@ module RTrail
|
|
28
26
|
end
|
29
27
|
|
30
28
|
context "Instance methods" do
|
31
|
-
let(:project1) { Project.
|
32
|
-
let(:project2) { Project.
|
29
|
+
let(:project1) { Project.get(1) }
|
30
|
+
let(:project2) { Project.get(2) }
|
33
31
|
|
34
32
|
describe "#initialize" do
|
35
33
|
it "gets the Project data" do
|
34
|
+
expect(project1).to be_a(Project)
|
36
35
|
expect(project1.id).to eq(1)
|
37
36
|
expect(project1.name).to eq("First Project")
|
38
37
|
expect(project2.id).to eq(2)
|
@@ -83,9 +82,8 @@ module RTrail
|
|
83
82
|
describe "#plans" do
|
84
83
|
it "returns all Plans in the Project" do
|
85
84
|
plans = project1.plans
|
86
|
-
expect(plans).to
|
85
|
+
expect(plans).to be_a_list_of(Plan)
|
87
86
|
expect(plans.count).to eq(1)
|
88
|
-
expect(plans.first).to be_a(Plan)
|
89
87
|
end
|
90
88
|
end
|
91
89
|
|
data/spec/run_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'simplecov'
|
2
2
|
SimpleCov.start if ENV['COVERAGE']
|
3
|
+
require 'coveralls'
|
4
|
+
Coveralls.wear!
|
3
5
|
|
4
6
|
PROJECT_ROOT = File.expand_path('..', File.dirname(__FILE__))
|
5
7
|
SPEC_DIR = File.join(PROJECT_ROOT, 'spec')
|
@@ -8,6 +10,9 @@ MOCK_APP_URL = "http://localhost:8080/index.php?/api/v2/"
|
|
8
10
|
$LOAD_PATH.unshift(File.join(PROJECT_ROOT, 'lib'))
|
9
11
|
require 'rtrail'
|
10
12
|
|
13
|
+
# Require all .rb files in spec/support
|
14
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
15
|
+
|
11
16
|
module SpecHelpers
|
12
17
|
end
|
13
18
|
|
@@ -17,3 +22,4 @@ RSpec.configure do |config|
|
|
17
22
|
RTrail::Entity.client = RTrail::Client.new(MOCK_APP_URL, 'user', 'password')
|
18
23
|
end
|
19
24
|
end
|
25
|
+
|
data/spec/suite_spec.rb
CHANGED
@@ -6,7 +6,7 @@ module RTrail
|
|
6
6
|
end
|
7
7
|
|
8
8
|
context "Instance methods" do
|
9
|
-
let(:suite) { Suite.
|
9
|
+
let(:suite) { Suite.get(1) }
|
10
10
|
|
11
11
|
describe "#sections" do
|
12
12
|
let(:sections) { suite.sections }
|
@@ -23,6 +23,16 @@ module RTrail
|
|
23
23
|
expect(cases.first).to be_a(Case)
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
describe "#section_by_name" do
|
28
|
+
it "gets the Section with the given name if it exists"
|
29
|
+
it "raises RTrail::NotFound if no section exists with the given name"
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#section" do
|
33
|
+
it "returns a Section by id"
|
34
|
+
it "returns a Section by name"
|
35
|
+
end
|
26
36
|
end
|
27
37
|
end
|
28
38
|
end # module RTrail
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Custom RSpec matchers
|
2
|
+
|
3
|
+
RSpec::Matchers.define :be_a_list_of do |klass|
|
4
|
+
match do |list|
|
5
|
+
expect(list).to be_an(Array)
|
6
|
+
expect(list.first).to be_a(klass)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec::Matchers.define :have_fields do |fields|
|
11
|
+
match do |obj|
|
12
|
+
#expect(hash).to be_a(Hashie::Mash)
|
13
|
+
fields.each do |k, v|
|
14
|
+
expect(obj).to include(k)
|
15
|
+
expect(obj[k]).to eq(v)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
data/spec/test_spec.rb
CHANGED
metadata
CHANGED
@@ -1,169 +1,211 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtrail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Pierce
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '3.3'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '3.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '10.3'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '10.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pry
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
47
|
+
version: '0.10'
|
48
48
|
type: :development
|
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'
|
54
|
+
version: '0.10'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
61
|
+
version: '3.0'
|
62
62
|
type: :development
|
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: '0'
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-autotest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: ZenTest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.10'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '4.10'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: sinatra
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
72
100
|
requirements:
|
73
|
-
- -
|
101
|
+
- - ~>
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
103
|
+
version: '1.4'
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
|
-
- -
|
108
|
+
- - ~>
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
110
|
+
version: '1.4'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: sinatra-contrib
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
|
-
- -
|
115
|
+
- - ~>
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
117
|
+
version: '1.4'
|
90
118
|
type: :development
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
|
-
- -
|
122
|
+
- - ~>
|
95
123
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
124
|
+
version: '1.4'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
126
|
name: thin
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
100
128
|
requirements:
|
101
|
-
- -
|
129
|
+
- - ~>
|
102
130
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
131
|
+
version: '1.6'
|
104
132
|
type: :development
|
105
133
|
prerelease: false
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
107
135
|
requirements:
|
108
|
-
- -
|
136
|
+
- - ~>
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
138
|
+
version: '1.6'
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
140
|
name: simplecov
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
114
142
|
requirements:
|
115
|
-
- -
|
143
|
+
- - ~>
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.9'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ~>
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.9'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: coveralls
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ~>
|
116
158
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
159
|
+
version: '0.7'
|
118
160
|
type: :development
|
119
161
|
prerelease: false
|
120
162
|
version_requirements: !ruby/object:Gem::Requirement
|
121
163
|
requirements:
|
122
|
-
- -
|
164
|
+
- - ~>
|
123
165
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
166
|
+
version: '0.7'
|
125
167
|
- !ruby/object:Gem::Dependency
|
126
168
|
name: yard
|
127
169
|
requirement: !ruby/object:Gem::Requirement
|
128
170
|
requirements:
|
129
|
-
- -
|
171
|
+
- - ~>
|
130
172
|
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
173
|
+
version: '0.8'
|
132
174
|
type: :development
|
133
175
|
prerelease: false
|
134
176
|
version_requirements: !ruby/object:Gem::Requirement
|
135
177
|
requirements:
|
136
|
-
- -
|
178
|
+
- - ~>
|
137
179
|
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
180
|
+
version: '0.8'
|
139
181
|
- !ruby/object:Gem::Dependency
|
140
182
|
name: rdiscount
|
141
183
|
requirement: !ruby/object:Gem::Requirement
|
142
184
|
requirements:
|
143
|
-
- -
|
185
|
+
- - ~>
|
144
186
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
187
|
+
version: '2.1'
|
146
188
|
type: :development
|
147
189
|
prerelease: false
|
148
190
|
version_requirements: !ruby/object:Gem::Requirement
|
149
191
|
requirements:
|
150
|
-
- -
|
192
|
+
- - ~>
|
151
193
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
194
|
+
version: '2.1'
|
153
195
|
- !ruby/object:Gem::Dependency
|
154
196
|
name: yajl-ruby
|
155
197
|
requirement: !ruby/object:Gem::Requirement
|
156
198
|
requirements:
|
157
|
-
- -
|
199
|
+
- - ~>
|
158
200
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
201
|
+
version: '1.2'
|
160
202
|
type: :development
|
161
203
|
prerelease: false
|
162
204
|
version_requirements: !ruby/object:Gem::Requirement
|
163
205
|
requirements:
|
164
|
-
- -
|
206
|
+
- - ~>
|
165
207
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
208
|
+
version: '1.2'
|
167
209
|
description: ! ' RTrail wraps the TestRail API v2.0 in Ruby objects
|
168
210
|
|
169
211
|
'
|
@@ -174,16 +216,20 @@ extra_rdoc_files: []
|
|
174
216
|
files:
|
175
217
|
- .gitignore
|
176
218
|
- .rspec
|
219
|
+
- .travis.yml
|
177
220
|
- Gemfile
|
178
221
|
- LICENSE
|
179
222
|
- README.md
|
223
|
+
- Rakefile
|
180
224
|
- lib/rtrail.rb
|
181
225
|
- lib/rtrail/api.rb
|
182
226
|
- lib/rtrail/case.rb
|
183
227
|
- lib/rtrail/client.rb
|
184
228
|
- lib/rtrail/entity.rb
|
229
|
+
- lib/rtrail/entry.rb
|
185
230
|
- lib/rtrail/exceptions.rb
|
186
231
|
- lib/rtrail/helpers.rb
|
232
|
+
- lib/rtrail/methods.rb
|
187
233
|
- lib/rtrail/plan.rb
|
188
234
|
- lib/rtrail/project.rb
|
189
235
|
- lib/rtrail/result.rb
|
@@ -224,15 +270,18 @@ files:
|
|
224
270
|
- spec/client_spec.rb
|
225
271
|
- spec/entity_spec.rb
|
226
272
|
- spec/helpers_spec.rb
|
273
|
+
- spec/methods_spec.rb
|
227
274
|
- spec/plan_spec.rb
|
228
275
|
- spec/project_spec.rb
|
229
276
|
- spec/result_spec.rb
|
230
277
|
- spec/run_spec.rb
|
231
278
|
- spec/spec_helper.rb
|
232
279
|
- spec/suite_spec.rb
|
280
|
+
- spec/support/matchers.rb
|
233
281
|
- spec/test_spec.rb
|
234
282
|
homepage: http://github.com/a-e/rtrail
|
235
|
-
licenses:
|
283
|
+
licenses:
|
284
|
+
- MIT
|
236
285
|
metadata: {}
|
237
286
|
post_install_message:
|
238
287
|
rdoc_options: []
|
@@ -250,7 +299,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
299
|
version: '0'
|
251
300
|
requirements: []
|
252
301
|
rubyforge_project:
|
253
|
-
rubygems_version: 2.
|
302
|
+
rubygems_version: 2.4.8
|
254
303
|
signing_key:
|
255
304
|
specification_version: 4
|
256
305
|
summary: Ruby object wrapper for TestRail API
|