rtrail 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|