ruby_tfs 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.
- data/LICENSE.md +7 -0
- data/README.md +55 -0
- data/Rakefile +8 -0
- data/lib/tfs/builds.rb +29 -0
- data/lib/tfs/changesets.rb +13 -0
- data/lib/tfs/class_helpers.rb +19 -0
- data/lib/tfs/client.rb +53 -0
- data/lib/tfs/configuration.rb +78 -0
- data/lib/tfs/projects.rb +19 -0
- data/lib/tfs/query_engine.rb +103 -0
- data/lib/tfs/queryable.rb +42 -0
- data/lib/tfs/work_items.rb +42 -0
- data/lib/tfs.rb +30 -0
- data/ruby_tfs.gemspec +23 -0
- data/spec/fixtures/cassettes/builds.yml +405 -0
- data/spec/fixtures/cassettes/changeset_queries.yml +374 -0
- data/spec/fixtures/cassettes/changesets.yml +237 -0
- data/spec/fixtures/cassettes/project_workitems_queries.yml +793 -0
- data/spec/fixtures/cassettes/projects.yml +210 -0
- data/spec/fixtures/cassettes/workitems.yml +2037 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/tfs/builds_spec.rb +34 -0
- data/spec/tfs/changesets_spec.rb +34 -0
- data/spec/tfs/client_spec.rb +62 -0
- data/spec/tfs/projects_spec.rb +35 -0
- data/spec/tfs/query_engine_spec.rb +37 -0
- data/spec/tfs/work_items_spec.rb +68 -0
- data/spec/tfs_spec.rb +25 -0
- metadata +123 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'vcr'
|
3
|
+
require 'simplecov'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require_relative "../lib/tfs"
|
7
|
+
|
8
|
+
SimpleCov.start do
|
9
|
+
add_filter "spec/"
|
10
|
+
add_filter ".gems/"
|
11
|
+
end
|
12
|
+
|
13
|
+
VCR.configure do |config|
|
14
|
+
config.cassette_library_dir = 'spec/fixtures/cassettes'
|
15
|
+
config.hook_into :webmock
|
16
|
+
config.default_cassette_options = { :record => :new_episodes }
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.extend VCR::RSpec::Macros
|
21
|
+
config.mock_with :flexmock
|
22
|
+
end
|
23
|
+
|
24
|
+
def load_result_fixture(fixture)
|
25
|
+
path = File.join File.dirname(__FILE__), 'fixtures', fixture
|
26
|
+
File.open(path) {|f| f.read }
|
27
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
@pending
|
4
|
+
describe TFS::Builds do
|
5
|
+
let(:client) { TFS.client }
|
6
|
+
|
7
|
+
before do
|
8
|
+
TFS.configure do |config|
|
9
|
+
config.endpoint = "https://codeplexodata.cloudapp.net/TFS29"
|
10
|
+
config.username ='snd\plukevdh_cp'
|
11
|
+
config.password = 'garbage'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# TODO: Very poor testing against Codeplex
|
16
|
+
# because we have no builds. Eventually
|
17
|
+
# migrating this over to visualstudio.com
|
18
|
+
context "finders" do
|
19
|
+
use_vcr_cassette 'builds'
|
20
|
+
|
21
|
+
it "can get builds from TFS, limits to 50" do
|
22
|
+
results = TFS::Builds.all
|
23
|
+
results.count.should == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can query in the raw" do
|
27
|
+
results = TFS::Builds.odata_query("Status eq 'Succeeded'").limit(5).run
|
28
|
+
results.each do |build|
|
29
|
+
build.Status.should == 'Succeeded'
|
30
|
+
end
|
31
|
+
results.count.should == 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TFS::Changesets do
|
4
|
+
let(:client) { TFS.client }
|
5
|
+
before do
|
6
|
+
TFS.configure do |config|
|
7
|
+
config.endpoint = "https://codeplexodata.cloudapp.net/TFS29"
|
8
|
+
config.username ='snd\plukevdh_cp'
|
9
|
+
config.password = 'garbage'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "finders" do
|
14
|
+
use_vcr_cassette 'changesets'
|
15
|
+
|
16
|
+
it "can get changesets from TFS" do
|
17
|
+
results = TFS::Changesets.all
|
18
|
+
results.count.should == 2
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can get a project by name" do
|
22
|
+
result = TFS::Changesets.find(23460)
|
23
|
+
result.Comment.should =~ /use the repo to persist\/update/
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can query in the raw" do
|
27
|
+
results = TFS::Changesets.odata_query("Committer eq 'plukevdh_cp'").run
|
28
|
+
results.each do |build|
|
29
|
+
build.Committer.should end_with 'plukevdh_cp'
|
30
|
+
end
|
31
|
+
results.count.should == 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TFS::Client do
|
4
|
+
let(:provider) { flexmock(:provider) }
|
5
|
+
let(:client) { TFS::Client.new(provider: provider) }
|
6
|
+
|
7
|
+
it "should be able to connect to tfs with defaults" do
|
8
|
+
client = TFS::Client.new(endpoint: "http://fake.tfs.net/tfs:8080",
|
9
|
+
username: "test", password: "123", provider: provider)
|
10
|
+
|
11
|
+
provider.should_receive(new: true).with("http://fake.tfs.net/tfs:8080",
|
12
|
+
{:username=>"test", :password=>"123",
|
13
|
+
:headers=>{:accept=>"application/json", :user_agent=>"TFS Ruby Gem"},
|
14
|
+
:request=>{:open_timeout=>5, :timeout=>10},
|
15
|
+
:verify_ssl=>false}).once
|
16
|
+
|
17
|
+
client.connect
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with odata" do
|
21
|
+
let(:client) { TFS::Client.new(endpoint: "https://codeplexodata.cloudapp.net/TFS29",
|
22
|
+
username: 'snd\plukevdh_cp', password: 'garbage') }
|
23
|
+
|
24
|
+
context "individual queries" do
|
25
|
+
use_vcr_cassette "changeset_queries"
|
26
|
+
|
27
|
+
before do
|
28
|
+
client.connect
|
29
|
+
end
|
30
|
+
|
31
|
+
it "creates queries for data" do
|
32
|
+
results = client.changesets
|
33
|
+
results.should be_a(TFS::QueryEngine)
|
34
|
+
results.type.should == TFS::Changesets
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can query with a nice api" do
|
38
|
+
project = client.projects("rubytfs").run
|
39
|
+
project.size.should == 1
|
40
|
+
project.first.Name.should == "rubytfs"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "sub queries" do
|
45
|
+
use_vcr_cassette "project_workitems_queries"
|
46
|
+
|
47
|
+
before do
|
48
|
+
client.connect
|
49
|
+
end
|
50
|
+
|
51
|
+
it "can traverse/filter by sub items (children)" do
|
52
|
+
work_items = client.projects('rubytfs').workitems.run
|
53
|
+
work_items.count.should == 19
|
54
|
+
work_items.first.should be_a WorkItem
|
55
|
+
end
|
56
|
+
|
57
|
+
it "can't traverse unrelated items" do
|
58
|
+
expect { client.projects('rubytfs').weed }.to raise_error(NoMethodError)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TFS::Projects do
|
4
|
+
let(:client) { TFS.client }
|
5
|
+
|
6
|
+
before do
|
7
|
+
TFS.configure do |config|
|
8
|
+
config.endpoint = "https://codeplexodata.cloudapp.net/TFS29"
|
9
|
+
config.username ='snd\plukevdh_cp'
|
10
|
+
config.password = 'garbage'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "finders" do
|
15
|
+
use_vcr_cassette 'projects'
|
16
|
+
|
17
|
+
it "can get projects from TFS" do
|
18
|
+
results = TFS::Projects.all
|
19
|
+
results.count.should == 1
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can get a project by name" do
|
23
|
+
result = TFS::Projects.find('rubytfs')
|
24
|
+
result.Name.should == 'rubytfs'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "can query in the raw" do
|
28
|
+
results = TFS::Projects.odata_query("startswith(Name,'rubytfs')").run
|
29
|
+
results.each do |build|
|
30
|
+
build.Name.should start_with 'rubytfs'
|
31
|
+
end
|
32
|
+
results.count.should == 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe TFS::QueryEngine do
|
5
|
+
class TFS::Builds; end
|
6
|
+
let(:native_query) { flexmock(:queryable) }
|
7
|
+
let(:conn) { flexmock(:connection, "Builds" => native_query) }
|
8
|
+
|
9
|
+
it "raises an error if we try to create a query for a bad object" do
|
10
|
+
expect { TFS::QueryEngine.new(String, conn) }.to raise_error(TypeError, /String is not/)
|
11
|
+
expect { TFS::QueryEngine.new(TFS::Builds, conn) }.to_not raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can chain queries" do
|
15
|
+
query = TFS::QueryEngine.new(TFS::Builds, conn)
|
16
|
+
|
17
|
+
native_query.should_receive(:top).with(10).and_return(native_query).once
|
18
|
+
native_query.should_receive(:order_by).with("Reason").and_return(native_query).once
|
19
|
+
|
20
|
+
query.limit(10).order_by("Reason")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can include other results" do
|
24
|
+
query = TFS::QueryEngine.new(TFS::Builds, conn)
|
25
|
+
native_query.should_receive(:expand).with('Changesets').and_return(native_query).once
|
26
|
+
|
27
|
+
query.include(TFS::Changesets)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises error if expand by invalid class" do
|
31
|
+
query = TFS::QueryEngine.new(TFS::Builds, conn)
|
32
|
+
|
33
|
+
expect { query.include('String') }.to raise_error(TypeError)
|
34
|
+
|
35
|
+
native_query.should_not have_received(:expand)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TFS::WorkItems do
|
4
|
+
let(:client) { TFS.client }
|
5
|
+
before do
|
6
|
+
TFS.configure do |config|
|
7
|
+
config.endpoint = "https://codeplexodata.cloudapp.net/TFS29"
|
8
|
+
config.username ='snd\plukevdh_cp'
|
9
|
+
config.password = 'garbage'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "finders" do
|
14
|
+
use_vcr_cassette 'workitems'
|
15
|
+
|
16
|
+
it "can get workitems from TFS" do
|
17
|
+
results = TFS::WorkItems.all
|
18
|
+
results.count.should == 18
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can get a project by name" do
|
22
|
+
result = TFS::WorkItems.find(1234)
|
23
|
+
result.CreatedBy.should == "MCLWEB"
|
24
|
+
result.AssignedTo.should == "plukevdh_cp"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "can query in the raw" do
|
28
|
+
results = TFS::WorkItems.odata_query("AssignedTo eq 'plukevdh_cp'").run
|
29
|
+
results.each do |build|
|
30
|
+
build.AssignedTo.should == 'plukevdh_cp'
|
31
|
+
end
|
32
|
+
results.count.should == 14
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can add a work item" do
|
36
|
+
temp = ::WorkItem.new(client)
|
37
|
+
temp.Title = "A Testing Item."
|
38
|
+
temp.AssignedTo = 'plukevdh_cp'
|
39
|
+
temp.Description = "A Test WorkItem from ruby_tfs wrapper"
|
40
|
+
temp.Type = "Work Item"
|
41
|
+
temp.Project = "rubytfs"
|
42
|
+
|
43
|
+
created = TFS::WorkItems.save(temp)
|
44
|
+
|
45
|
+
item = TFS::WorkItems.where("Title eq '#{created.Title}'").limit(1).run.first
|
46
|
+
item.AssignedTo.should == created.AssignedTo
|
47
|
+
item.Type.should == created.Type
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can update existing work items" do
|
51
|
+
temp = TFS::WorkItems.find(1245)
|
52
|
+
temp.Title = "I'm updated, son!!"
|
53
|
+
|
54
|
+
saved = TFS::WorkItems.update(temp)
|
55
|
+
item = TFS::WorkItems.find(temp.Id)
|
56
|
+
|
57
|
+
saved.should be_true
|
58
|
+
item.Title.should == temp.Title
|
59
|
+
end
|
60
|
+
|
61
|
+
it "throws error if missing param" do
|
62
|
+
temp = ::WorkItem.new(client)
|
63
|
+
temp.Title = "A Testing Item."
|
64
|
+
|
65
|
+
expect { TFS::WorkItems.save(temp) }.to raise_error(TFS::WorkItems::InvalidRecord, /Missing required parameter 'Type'/)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/tfs_spec.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TFS do
|
4
|
+
let(:odata) { flexmock(:odata) }
|
5
|
+
let(:client) { TFS.client }
|
6
|
+
|
7
|
+
before do
|
8
|
+
TFS.configure do |config|
|
9
|
+
config.endpoint = "http://fake.tfs.com:8080/tfs"
|
10
|
+
config.provider = flexmock(:provider, new: odata)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "creates a client" do
|
15
|
+
client.should be_a TFS::Client
|
16
|
+
client.endpoint.should == "http://fake.tfs.com:8080/tfs"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "aliases methods to the client" do
|
20
|
+
flexmock(client, :connect_as)
|
21
|
+
client.should_receive(:connect).once
|
22
|
+
|
23
|
+
TFS.connect
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_tfs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Luke van der Hoeven
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ruby_odata
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.0'
|
46
|
+
description: A Ruby interface to the TFS OData API.
|
47
|
+
email:
|
48
|
+
- hungerandthirst@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- Rakefile
|
54
|
+
- LICENSE.md
|
55
|
+
- README.md
|
56
|
+
- ruby_tfs.gemspec
|
57
|
+
- lib/tfs/builds.rb
|
58
|
+
- lib/tfs/changesets.rb
|
59
|
+
- lib/tfs/class_helpers.rb
|
60
|
+
- lib/tfs/client.rb
|
61
|
+
- lib/tfs/configuration.rb
|
62
|
+
- lib/tfs/projects.rb
|
63
|
+
- lib/tfs/query_engine.rb
|
64
|
+
- lib/tfs/queryable.rb
|
65
|
+
- lib/tfs/work_items.rb
|
66
|
+
- lib/tfs.rb
|
67
|
+
- spec/fixtures/cassettes/builds.yml
|
68
|
+
- spec/fixtures/cassettes/changeset_queries.yml
|
69
|
+
- spec/fixtures/cassettes/changesets.yml
|
70
|
+
- spec/fixtures/cassettes/project_workitems_queries.yml
|
71
|
+
- spec/fixtures/cassettes/projects.yml
|
72
|
+
- spec/fixtures/cassettes/workitems.yml
|
73
|
+
- spec/spec_helper.rb
|
74
|
+
- spec/tfs/builds_spec.rb
|
75
|
+
- spec/tfs/changesets_spec.rb
|
76
|
+
- spec/tfs/client_spec.rb
|
77
|
+
- spec/tfs/projects_spec.rb
|
78
|
+
- spec/tfs/query_engine_spec.rb
|
79
|
+
- spec/tfs/work_items_spec.rb
|
80
|
+
- spec/tfs_spec.rb
|
81
|
+
homepage: https://github.com/BFGCOMMUNICATIONS/ruby_tfs
|
82
|
+
licenses:
|
83
|
+
- APLv2
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
hash: -4292206802571305050
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 1.3.6
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 1.8.23
|
106
|
+
signing_key:
|
107
|
+
specification_version: 3
|
108
|
+
summary: A Ruby interface to the TFS OData API.
|
109
|
+
test_files:
|
110
|
+
- spec/fixtures/cassettes/builds.yml
|
111
|
+
- spec/fixtures/cassettes/changeset_queries.yml
|
112
|
+
- spec/fixtures/cassettes/changesets.yml
|
113
|
+
- spec/fixtures/cassettes/project_workitems_queries.yml
|
114
|
+
- spec/fixtures/cassettes/projects.yml
|
115
|
+
- spec/fixtures/cassettes/workitems.yml
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
- spec/tfs/builds_spec.rb
|
118
|
+
- spec/tfs/changesets_spec.rb
|
119
|
+
- spec/tfs/client_spec.rb
|
120
|
+
- spec/tfs/projects_spec.rb
|
121
|
+
- spec/tfs/query_engine_spec.rb
|
122
|
+
- spec/tfs/work_items_spec.rb
|
123
|
+
- spec/tfs_spec.rb
|