rtrail 0.0.1
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 +15 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +96 -0
- data/lib/rtrail.rb +19 -0
- data/lib/rtrail/api.rb +42 -0
- data/lib/rtrail/case.rb +8 -0
- data/lib/rtrail/client.rb +113 -0
- data/lib/rtrail/entity.rb +65 -0
- data/lib/rtrail/exceptions.rb +4 -0
- data/lib/rtrail/helpers.rb +32 -0
- data/lib/rtrail/plan.rb +7 -0
- data/lib/rtrail/project.rb +83 -0
- data/lib/rtrail/result.rb +9 -0
- data/lib/rtrail/run.rb +39 -0
- data/lib/rtrail/section.rb +7 -0
- data/lib/rtrail/suite.rb +26 -0
- data/lib/rtrail/test.rb +22 -0
- data/mock/app.rb +55 -0
- data/mock/views/add_result/1.yajl +4 -0
- data/mock/views/add_run/1.yajl +7 -0
- data/mock/views/error.yajl +3 -0
- data/mock/views/get_case/1.yajl +4 -0
- data/mock/views/get_cases/1.yajl +3 -0
- data/mock/views/get_plan/1.yajl +4 -0
- data/mock/views/get_plans/1.yajl +3 -0
- data/mock/views/get_project/1.yajl +4 -0
- data/mock/views/get_project/2.yajl +4 -0
- data/mock/views/get_projects.yajl +4 -0
- data/mock/views/get_result/1.yajl +4 -0
- data/mock/views/get_results/1.yajl +3 -0
- data/mock/views/get_run/1.yajl +7 -0
- data/mock/views/get_run/2.yajl +7 -0
- data/mock/views/get_runs/1.yajl +4 -0
- data/mock/views/get_section/1.yajl +9 -0
- data/mock/views/get_section/2.yajl +9 -0
- data/mock/views/get_sections/1.yajl +4 -0
- data/mock/views/get_suite/1.yajl +6 -0
- data/mock/views/get_suite/2.yajl +5 -0
- data/mock/views/get_suite/3.yajl +6 -0
- data/mock/views/get_suites/1.yajl +4 -0
- data/mock/views/get_suites/2.yajl +4 -0
- data/mock/views/get_test/1.yajl +4 -0
- data/mock/views/get_test/2.yajl +4 -0
- data/mock/views/get_tests/1.yajl +5 -0
- data/rtrail.gemspec +41 -0
- data/spec/api_spec.rb +46 -0
- data/spec/case_spec.rb +12 -0
- data/spec/client_spec.rb +43 -0
- data/spec/entity_spec.rb +12 -0
- data/spec/helpers_spec.rb +52 -0
- data/spec/plan_spec.rb +12 -0
- data/spec/project_spec.rb +132 -0
- data/spec/result_spec.rb +12 -0
- data/spec/run_spec.rb +61 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/suite_spec.rb +29 -0
- data/spec/test_spec.rb +34 -0
- metadata +258 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
require_relative 'entity'
|
2
|
+
require_relative 'suite'
|
3
|
+
require_relative 'run'
|
4
|
+
require_relative 'plan'
|
5
|
+
|
6
|
+
module RTrail
|
7
|
+
class Project < Entity
|
8
|
+
def self.all
|
9
|
+
return client.get("get_projects").map do |project|
|
10
|
+
self.new(project)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.by_name(project_name)
|
15
|
+
result = Project.all.find do |project|
|
16
|
+
project.name == project_name
|
17
|
+
end
|
18
|
+
|
19
|
+
if result.nil?
|
20
|
+
raise RTrail::NotFound.new("Project '#{project_name}' not found in TestRail")
|
21
|
+
else
|
22
|
+
return self.new(result)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Return a suite with the given name in the current project.
|
27
|
+
def suite_by_name(suite_name)
|
28
|
+
suite = self.suites.find do |s|
|
29
|
+
s.name == suite_name
|
30
|
+
end
|
31
|
+
if suite.nil?
|
32
|
+
raise RTrail::NotFound.new(
|
33
|
+
"Suite '#{suite_name}' not found in project '#{self.data.name}'")
|
34
|
+
end
|
35
|
+
return suite
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return a suite with the given name or id in the current project.
|
39
|
+
def suite(suite_name_or_id)
|
40
|
+
if is_id?(suite_name_or_id)
|
41
|
+
return Suite.new(suite_name_or_id)
|
42
|
+
else
|
43
|
+
return suite_by_name(suite_name_or_id)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def suite_id(suite_name_or_id)
|
48
|
+
return self.suite(suite_name_or_id).id
|
49
|
+
end
|
50
|
+
|
51
|
+
def plans
|
52
|
+
return get_entities(Plan, data.id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def runs
|
56
|
+
return get_entities(Run, data.id)
|
57
|
+
end
|
58
|
+
|
59
|
+
def suites
|
60
|
+
return get_entities(Suite, data.id)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Return an existing run with the given name, or create and
|
64
|
+
# return a new run.
|
65
|
+
def run(suite_name_or_id, run_name)
|
66
|
+
existing = runs.find {|r| r.name == run_name}
|
67
|
+
if existing
|
68
|
+
return existing
|
69
|
+
else
|
70
|
+
return add_run(suite_name_or_id, :name => run_name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Create a new Run in the given Suite in this project.
|
75
|
+
def add_run(suite_name_or_id, fields={})
|
76
|
+
run_data = fields.merge({
|
77
|
+
:suite_id => suite_id(suite_name_or_id),
|
78
|
+
})
|
79
|
+
return add_entity(Run, data.id, run_data)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end # module RTrail
|
83
|
+
|
data/lib/rtrail/run.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'entity'
|
2
|
+
require_relative 'test'
|
3
|
+
require_relative 'helpers'
|
4
|
+
|
5
|
+
module RTrail
|
6
|
+
class Run < Entity
|
7
|
+
include HasCreateTime
|
8
|
+
|
9
|
+
# Return a one-line summary of this Run
|
10
|
+
def summary
|
11
|
+
# TODO: Include these?
|
12
|
+
# self.untested_count
|
13
|
+
# self.blocked_count
|
14
|
+
# self.passed_count
|
15
|
+
# self.failed_count
|
16
|
+
result = "#{self.id}: #{self.name}"
|
17
|
+
if self.completed?
|
18
|
+
result += " [completed #{self.complete_time}]"
|
19
|
+
else
|
20
|
+
result += " [not completed]"
|
21
|
+
end
|
22
|
+
return result
|
23
|
+
end
|
24
|
+
|
25
|
+
def tests
|
26
|
+
return get_entities(Test, data.id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def complete_time
|
30
|
+
return nil if !completed?
|
31
|
+
return Time.at(self[:completed_on].to_i).utc
|
32
|
+
end
|
33
|
+
|
34
|
+
def completed?
|
35
|
+
return !self[:completed_on].nil?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end # module RTrail
|
39
|
+
|
data/lib/rtrail/suite.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'entity'
|
2
|
+
require_relative 'case'
|
3
|
+
require_relative 'section'
|
4
|
+
|
5
|
+
module RTrail
|
6
|
+
class Suite < Entity
|
7
|
+
def sections
|
8
|
+
return get_entities(
|
9
|
+
Section,
|
10
|
+
data.project_id,
|
11
|
+
:suite_id => data.id
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def cases(section_id=nil)
|
16
|
+
return get_entities(
|
17
|
+
Case,
|
18
|
+
data.project_id,
|
19
|
+
:suite_id => data.id,
|
20
|
+
:section_id => section_id
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end # module RTrail
|
26
|
+
|
data/lib/rtrail/test.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'entity'
|
2
|
+
require_relative 'result'
|
3
|
+
|
4
|
+
module RTrail
|
5
|
+
class Test < Entity
|
6
|
+
# Return all Results for this Test.
|
7
|
+
def results
|
8
|
+
return get_entities(Result, data.id)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Return the most recently created Result for this Test.
|
12
|
+
def latest_result
|
13
|
+
return get_entities(Result, data.id, :limit => 1).first
|
14
|
+
end
|
15
|
+
|
16
|
+
# Add a new Result to this test.
|
17
|
+
def add_result(fields)
|
18
|
+
return add_entity(Result, data.id, fields)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end # module RTrail
|
22
|
+
|
data/mock/app.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'sinatra/base'
|
5
|
+
require 'sinatra/reloader'
|
6
|
+
require 'yajl'
|
7
|
+
|
8
|
+
# Mock TestRail web application
|
9
|
+
class TestApp < Sinatra::Base
|
10
|
+
set :root, File.dirname(__FILE__)
|
11
|
+
|
12
|
+
configure do
|
13
|
+
register Sinatra::Reloader
|
14
|
+
end
|
15
|
+
|
16
|
+
helpers do
|
17
|
+
def parse(params)
|
18
|
+
path = ''
|
19
|
+
query = {}
|
20
|
+
params.each do |key, value|
|
21
|
+
if key.start_with?("/api/v2")
|
22
|
+
path = key.gsub('/api/v2/', '')
|
23
|
+
else
|
24
|
+
query[key] = value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
return path, query
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
get '/index.php' do
|
32
|
+
# FIXME: Handle query (used for suite_id, section_id etc.)
|
33
|
+
path, query = parse(params)
|
34
|
+
begin
|
35
|
+
yajl(path.to_sym)
|
36
|
+
rescue => ex
|
37
|
+
halt 400, yajl(:error, :locals => {:error => ex.message})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
post '/index.php' do
|
42
|
+
path, query = parse(params)
|
43
|
+
data = Yajl::Parser.parse(request.body.read)
|
44
|
+
begin
|
45
|
+
yajl(path.to_sym, :locals => data)
|
46
|
+
rescue => ex
|
47
|
+
halt 400, yajl(:error, :locals => {:error => ex.message})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if __FILE__ == $0
|
53
|
+
TestApp.run! :port => 8080
|
54
|
+
end
|
55
|
+
|
data/rtrail.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "rtrail"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "Ruby object wrapper for TestRail API"
|
5
|
+
s.description = <<-EOS
|
6
|
+
RTrail wraps the TestRail API v2.0 in Ruby objects
|
7
|
+
EOS
|
8
|
+
s.authors = ["Eric Pierce"]
|
9
|
+
s.email = "epierce@automation-excellence.com"
|
10
|
+
s.homepage = "http://github.com/a-e/rtrail"
|
11
|
+
s.platform = Gem::Platform::RUBY
|
12
|
+
|
13
|
+
s.add_dependency 'hashie'
|
14
|
+
|
15
|
+
# Basic utilities
|
16
|
+
s.add_development_dependency 'rake'
|
17
|
+
s.add_development_dependency 'pry'
|
18
|
+
|
19
|
+
# For testing
|
20
|
+
s.add_development_dependency 'rspec'
|
21
|
+
|
22
|
+
# 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
|
+
|
27
|
+
# For test coverage
|
28
|
+
s.add_development_dependency 'simplecov'
|
29
|
+
|
30
|
+
# For documentation and markdown support
|
31
|
+
s.add_development_dependency 'yard'
|
32
|
+
s.add_development_dependency 'rdiscount'
|
33
|
+
|
34
|
+
# Others
|
35
|
+
s.add_development_dependency 'yajl-ruby'
|
36
|
+
|
37
|
+
# Files to distribute
|
38
|
+
s.files = `git ls-files`.split("\n")
|
39
|
+
|
40
|
+
s.require_path = 'lib'
|
41
|
+
end
|