codefumes 0.1.10 → 0.2.0
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/Gemfile +19 -0
- data/Gemfile.lock +135 -0
- data/History.txt +12 -0
- data/LICENSE +20 -0
- data/Manifest.txt +40 -19
- data/README.txt +11 -29
- data/Rakefile +15 -10
- data/bin/fumes +214 -0
- data/config/website.yml +2 -0
- data/cucumber.yml +2 -0
- data/features/claiming_a_project.feature +46 -0
- data/features/deleting_a_project.feature +32 -0
- data/features/releasing_a_project.feature +50 -0
- data/features/step_definitions/cli_steps.rb +98 -0
- data/features/step_definitions/common_steps.rb +168 -0
- data/features/step_definitions/filesystem_steps.rb +19 -0
- data/features/storing_user_api_key.feature +41 -0
- data/features/support/common.rb +29 -0
- data/features/support/env.rb +24 -0
- data/features/support/matchers.rb +11 -0
- data/features/synchronizing_repository_with_project.feature +33 -0
- data/lib/codefumes.rb +10 -8
- data/lib/codefumes/api.rb +20 -11
- data/lib/codefumes/api/build.rb +139 -0
- data/lib/codefumes/api/claim.rb +74 -0
- data/lib/codefumes/api/commit.rb +150 -0
- data/lib/codefumes/api/payload.rb +93 -0
- data/lib/codefumes/api/project.rb +158 -0
- data/lib/codefumes/cli_helpers.rb +54 -0
- data/lib/codefumes/config_file.rb +3 -2
- data/lib/codefumes/errors.rb +21 -0
- data/lib/codefumes/exit_codes.rb +10 -0
- data/lib/codefumes/harvester.rb +113 -0
- data/lib/codefumes/quick_build.rb +43 -0
- data/lib/codefumes/quick_metric.rb +20 -0
- data/lib/codefumes/source_control.rb +137 -0
- data/lib/integrity_notifier/codefumes.haml +11 -0
- data/lib/integrity_notifier/codefumes.rb +62 -0
- data/spec/codefumes/{build_spec.rb → api/build_spec.rb} +14 -24
- data/spec/codefumes/{claim_spec.rb → api/claim_spec.rb} +42 -3
- data/spec/codefumes/{commit_spec.rb → api/commit_spec.rb} +34 -24
- data/spec/codefumes/api/payload_spec.rb +148 -0
- data/spec/codefumes/api/project_spec.rb +286 -0
- data/spec/codefumes/api_spec.rb +38 -15
- data/spec/codefumes/config_file_spec.rb +69 -13
- data/spec/codefumes/harvester_spec.rb +118 -0
- data/spec/codefumes/source_control_spec.rb +199 -0
- data/spec/codefumes_service_helpers.rb +23 -19
- data/spec/fixtures/sample_project_dirs/no_scm/description +4 -0
- data/spec/spec_helper.rb +1 -0
- data/tasks/cucumber.rake +11 -0
- metadata +145 -60
- data/bin/cf_claim_project +0 -9
- data/bin/cf_release_project +0 -10
- data/bin/cf_store_credentials +0 -10
- data/lib/cf_claim_project/cli.rb +0 -95
- data/lib/cf_release_project/cli.rb +0 -76
- data/lib/cf_store_credentials/cli.rb +0 -50
- data/lib/codefumes/build.rb +0 -131
- data/lib/codefumes/claim.rb +0 -57
- data/lib/codefumes/commit.rb +0 -144
- data/lib/codefumes/payload.rb +0 -103
- data/lib/codefumes/project.rb +0 -129
- data/spec/cf_claim_project/cli_spec.rb +0 -17
- data/spec/cf_release_project/cli_spec.rb +0 -41
- data/spec/cf_store_credentials/cli_spec.rb +0 -28
- data/spec/codefumes/payload_spec.rb +0 -155
- data/spec/codefumes/project_spec.rb +0 -274
@@ -0,0 +1,43 @@
|
|
1
|
+
module CodeFumes
|
2
|
+
class QuickBuild
|
3
|
+
# Creates a new build for the CodeFumes project linked
|
4
|
+
# at the specified repository path and associates
|
5
|
+
# it with the current local commit identifier
|
6
|
+
#
|
7
|
+
# Returns +true+ if the request succeeded.
|
8
|
+
#
|
9
|
+
# Returns +false+ if the request failed.
|
10
|
+
def self.start(build_name, options = {})
|
11
|
+
repo = SourceControl.new(options[:repository_path] || './')
|
12
|
+
|
13
|
+
commit_identifier = options[:commit_identifier] || repo.local_commit_identifier
|
14
|
+
public_key = options[:public_key] || repo.public_key
|
15
|
+
private_key = options[:private_key] || repo.private_key
|
16
|
+
started_at = options[:started_at] || Time.now
|
17
|
+
|
18
|
+
project = Project.new(public_key, :private_key => private_key)
|
19
|
+
commit = Commit.new(project, commit_identifier)
|
20
|
+
timestamps = {:started_at => started_at, :ended_at => ""}
|
21
|
+
build = Build.new(commit, build_name, :running, timestamps)
|
22
|
+
build.save
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.finish(build_name, success_or_failure, options = {})
|
26
|
+
repo = SourceControl.new(options[:repository_path] || './')
|
27
|
+
|
28
|
+
commit_identifier = options[:commit_identifier] || repo.local_commit_identifier
|
29
|
+
public_key = options[:public_key] || repo.public_key
|
30
|
+
private_key = options[:private_key] || repo.private_key
|
31
|
+
ended_at = options[:ended_at] || Time.now
|
32
|
+
|
33
|
+
project = Project.new(public_key, :private_key => private_key)
|
34
|
+
commit = Commit.new(project, commit_identifier)
|
35
|
+
|
36
|
+
build = Build.find(commit, build_name)
|
37
|
+
return false if build.nil?
|
38
|
+
build.state = success_or_failure.to_s
|
39
|
+
build.ended_at = ended_at
|
40
|
+
build.save
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CodeFumes
|
2
|
+
class QuickMetric
|
3
|
+
# Associates a Hash of +custom_attributes+ with the current commit
|
4
|
+
# identifier of the repository located at +repository_path+.
|
5
|
+
#
|
6
|
+
# Returns +true+ if the request succeeded.
|
7
|
+
#
|
8
|
+
# Returns +false+ if the request failed.
|
9
|
+
def self.save(custom_attributes, repository_path = './')
|
10
|
+
repo = SourceControl.new(repository_path)
|
11
|
+
commit = {:identifier => repo.local_commit_identifier,
|
12
|
+
:custom_attributes => custom_attributes
|
13
|
+
}
|
14
|
+
content = {:content => {:commits => [commit]}}
|
15
|
+
project = Project.new(repo.public_key, :private_key => repo.private_key)
|
16
|
+
payload_set = Payload.prepare(project, content)
|
17
|
+
payload_set.reject {|payload| payload.save}.empty?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module CodeFumes
|
2
|
+
# Defines the contract between CodeFumes and any local source control
|
3
|
+
# management system (SCM).
|
4
|
+
#
|
5
|
+
# *NOTE:* Git is currently the only supported SCM. We look
|
6
|
+
# forward to changing this soon.
|
7
|
+
class SourceControl
|
8
|
+
SUPPORTED_SCMS_AND_DETECTORS = {:git => '.git'} #:nodoc:
|
9
|
+
|
10
|
+
# Sets up a SourceControl object to read content from the repository
|
11
|
+
# located at +path+.
|
12
|
+
def initialize(path)
|
13
|
+
begin
|
14
|
+
@repository = Grit::Repo.new(path)
|
15
|
+
rescue Grit::InvalidGitRepositoryError
|
16
|
+
raise Errors::UnsupportedScmToolError
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a serialized Hash containing a single +:commits+ key
|
21
|
+
# associated with an Array of serialized commit information, ready
|
22
|
+
# to be sent to the CodeFumes service.
|
23
|
+
def payload_between(from = initial_commit_identifier, to = "HEAD")
|
24
|
+
start_commit = from || initial_commit_identifier
|
25
|
+
end_commit = to || "HEAD"
|
26
|
+
new_commits = commits_between(start_commit, end_commit)
|
27
|
+
new_commits.empty? ? {} : {:commits => new_commits}
|
28
|
+
end
|
29
|
+
alias :payload :payload_between
|
30
|
+
|
31
|
+
# Returns the first commit identifier of a repository's history.
|
32
|
+
def initial_commit_identifier
|
33
|
+
initial_commit.sha
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns an array of 'symbolized' executable names for all
|
37
|
+
# supported SCMs.
|
38
|
+
#
|
39
|
+
# The names are returned as symbols.
|
40
|
+
def self.supported_systems
|
41
|
+
SUPPORTED_SCMS_AND_DETECTORS.keys
|
42
|
+
end
|
43
|
+
|
44
|
+
# Accepts command-line executable name of SCM and returns whether it
|
45
|
+
# is a supported SCM or not. +tool_cli_name+ should be the
|
46
|
+
# name of the executable, not the 'full name' of the application
|
47
|
+
# (ex: 'svn' not 'subversion').
|
48
|
+
#
|
49
|
+
# Returns +true+ if the SCM is supported
|
50
|
+
#
|
51
|
+
# Returns +false+ if the SCM is not supported.
|
52
|
+
def self.supported_system?(tool_cli_name)
|
53
|
+
SUPPORTED_SCMS_AND_DETECTORS.keys.include?(tool_cli_name.to_sym)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Stores the public_key of the project associated with the
|
57
|
+
# underlying local repository. This will not be necessary
|
58
|
+
# with all SCMs.
|
59
|
+
#
|
60
|
+
# For example, in a git repository, this method will store a
|
61
|
+
# +codefumes+ key in the +.git/config+ file. This value can be used
|
62
|
+
# as a lookup key for other tools to use in conjunction with the
|
63
|
+
# CodeFumes config file (see +ConfigFile+) to interact with a
|
64
|
+
# CodeFumes project.
|
65
|
+
def store_public_key(public_key)
|
66
|
+
@repository.config["codefumes.public-key"] = public_key
|
67
|
+
end
|
68
|
+
|
69
|
+
# Removes any association to the CodeFumes service which would have
|
70
|
+
# been added using the +store_public_key+ method.
|
71
|
+
#
|
72
|
+
# This method does not remove anything from the user's global
|
73
|
+
# CodeFumes config file.
|
74
|
+
def unlink_from_codefumes!
|
75
|
+
@repository.git.config({}, "--remove-section", "codefumes")
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the public key of the project associated with this
|
79
|
+
# repository.
|
80
|
+
def public_key
|
81
|
+
@repository.config["codefumes.public-key"]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns the private key of the project assciated with this
|
85
|
+
# repository.
|
86
|
+
def private_key
|
87
|
+
ConfigFile.options_for_project(public_key)[:private_key]
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns the current commit identifier of the underlying
|
91
|
+
# repository ('HEAD' of the supplied branch in git parlance).
|
92
|
+
def local_commit_identifier(branch_name = "master")
|
93
|
+
raise ArgumentError, "nil branch name supplied" if branch_name.nil?
|
94
|
+
@repository.get_head(branch_name).commit.sha
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the full path of the underlying repository.
|
98
|
+
def path
|
99
|
+
@repository.path
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
def initial_commit
|
104
|
+
@repository.log.last
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns Array of serialized commit data. Each item in the Array
|
108
|
+
# contains attributes of a single commit.
|
109
|
+
def commits_between(from, to, including_from_commit = false)
|
110
|
+
commit_list = @repository.commits_between(from,to)
|
111
|
+
|
112
|
+
if including_from_commit == true || from == initial_commit_identifier
|
113
|
+
commit_list = [initial_commit] + commit_list
|
114
|
+
end
|
115
|
+
|
116
|
+
commit_list.map do |commit|
|
117
|
+
commit_stats = commit.stats
|
118
|
+
{
|
119
|
+
:identifier => commit.sha,
|
120
|
+
:author_name => commit.author.name,
|
121
|
+
:author_email => commit.author.email,
|
122
|
+
:committer_name => commit.committer.name,
|
123
|
+
:committer_email => commit.committer.email,
|
124
|
+
:authored_at => commit.authored_date,
|
125
|
+
:committed_at => commit.committed_date,
|
126
|
+
:message => commit.message,
|
127
|
+
:short_message => commit.short_message,
|
128
|
+
:parent_identifiers => commit.parents.map(&:sha).join(','),
|
129
|
+
:line_additions => commit_stats.additions,
|
130
|
+
:line_deletions => commit_stats.deletions,
|
131
|
+
:line_total => commit_stats.deletions,
|
132
|
+
:affected_file_count => commit_stats.files.count
|
133
|
+
}
|
134
|
+
end.reverse
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
%p.normal
|
2
|
+
%label{ :for => "cf_build_name" } Build name
|
3
|
+
%input.text#cf_build_name{ :name => "notifiers[CodeFumes][build_name]", :type => "text", :value => config["build_name"] }
|
4
|
+
|
5
|
+
%p.normal
|
6
|
+
%label{ :for => "cf_public_key" } Public key
|
7
|
+
%input.text#cf_public_key{ :name => "notifiers[CodeFumes][public_key]", :type => "text", :value => config["public_key"] }
|
8
|
+
|
9
|
+
%p.normal
|
10
|
+
%label{ :for => "cf_private_key" } Private key
|
11
|
+
%input.text#cf_private_key{ :name => "notifiers[CodeFumes][private_key]", :type => "text", :value => config["private_key"] }
|
@@ -0,0 +1,62 @@
|
|
1
|
+
begin
|
2
|
+
require 'codefumes_harvester'
|
3
|
+
rescue LoadError
|
4
|
+
abort "Install codefumes_harvester to use the CodeFumes notifier"
|
5
|
+
end
|
6
|
+
|
7
|
+
module CodeFumesHarvester
|
8
|
+
class IntegrityNotifier
|
9
|
+
class CodeFumes < ::Integrity::Notifier::Base
|
10
|
+
attr_reader :private_key, :public_key
|
11
|
+
|
12
|
+
def self.to_haml
|
13
|
+
@haml ||= File.read(File.dirname(__FILE__) + "/codefumes.haml")
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(build, config={})
|
17
|
+
@public_key = config["public_key"]
|
18
|
+
@private_key = config["private_key"]
|
19
|
+
@build_name = config["build_name"]
|
20
|
+
@repo_path = Integrity::Repository.new(
|
21
|
+
build.id, build.project.uri, build.project.branch, build.commit.identifier
|
22
|
+
).directory
|
23
|
+
super(build, config)
|
24
|
+
end
|
25
|
+
|
26
|
+
def deliver!
|
27
|
+
Integrity.log "Updating build '#{@build_name}' for '#{@public_key}' (state: #{build_state})"
|
28
|
+
qb_options = {:public_key => @public_key,
|
29
|
+
:private_key => @private_key,
|
30
|
+
:ended_at => @build.completed_at,
|
31
|
+
:repository_path => @repo_path}
|
32
|
+
|
33
|
+
CodeFumesHarvester::QuickBuild.finish(@build_name, build_state, qb_options)
|
34
|
+
end
|
35
|
+
|
36
|
+
def deliver_started_notification!
|
37
|
+
Integrity.log "Adding build '#{@build_name}' for '#{@public_key}' (state: #{build_state})"
|
38
|
+
qb_options = {:public_key => @public_key,
|
39
|
+
:private_key => @private_key,
|
40
|
+
:started_at => @build.started_at,
|
41
|
+
:repository_path => @repo_path}
|
42
|
+
|
43
|
+
CodeFumesHarvester::QuickBuild.start(@build_name, qb_options)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def build_state
|
48
|
+
case @build.status
|
49
|
+
when :success then :successful
|
50
|
+
when :failed then :failed
|
51
|
+
when :building then :running
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module Integrity
|
59
|
+
class Notifier
|
60
|
+
register CodeFumesHarvester::IntegrityNotifier::CodeFumes
|
61
|
+
end
|
62
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require File.dirname(__FILE__) + '
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
2
|
|
3
|
-
describe "Build" do
|
4
|
-
include CodeFumesServiceHelpers::
|
3
|
+
describe "API::Build" do
|
4
|
+
include CodeFumesServiceHelpers::BuildHelpers
|
5
5
|
|
6
6
|
after(:all) do
|
7
7
|
FakeWeb.allow_net_connect = false
|
@@ -11,11 +11,7 @@ describe "Build" do
|
|
11
11
|
before(:each) do
|
12
12
|
setup_fixture_base
|
13
13
|
setup_build_fixtures
|
14
|
-
@
|
15
|
-
:name => @build_name, :commit_identifier => @commit_identifier,
|
16
|
-
:started_at => @started_at, :state => @state}
|
17
|
-
|
18
|
-
@build = Build.new(@build_params)
|
14
|
+
@build = Build.new(@commit, @build_name, @state, {:started_at => @started_at})
|
19
15
|
end
|
20
16
|
|
21
17
|
describe "save" do
|
@@ -23,10 +19,10 @@ describe "Build" do
|
|
23
19
|
@build.stub!(:exists?).and_return(false)
|
24
20
|
register_create_uri(["401", "Unauthorized"], "")
|
25
21
|
|
26
|
-
basic_auth_params = {:username => @
|
22
|
+
basic_auth_params = {:username => @project.public_key, :password => @project.private_key}
|
27
23
|
|
28
24
|
build_query = {:build => {:name => @build_name, :ended_at => nil, :started_at => @started_at, :state => @state}}
|
29
|
-
|
25
|
+
API.should_receive(:post).with("/projects/#{@project.public_key}/commits/#{@commit_identifier}/builds", :query => build_query, :basic_auth => basic_auth_params).and_return(mock("response", :code => 401))
|
30
26
|
@build.save
|
31
27
|
end
|
32
28
|
|
@@ -63,16 +59,13 @@ describe "Build" do
|
|
63
59
|
end
|
64
60
|
|
65
61
|
context "when the build already exists on the server" do
|
66
|
-
before(:each) do
|
67
|
-
register_update_uri(["200", "OK"])
|
68
|
-
@build = Build.new(@build_params.merge(:identifier => @build_identifier))
|
69
|
-
Build.stub!(:find).and_return(@build)
|
70
|
-
end
|
71
|
-
|
72
62
|
it "updates the existing build" do
|
63
|
+
register_update_uri(["200", "OK"])
|
64
|
+
build = Build.new(@commit, @build_name, @state, {:identifier => @build_identifier})
|
65
|
+
Build.stub!(:find).and_return(build)
|
73
66
|
mock_response = mock("Response", :code => 200).as_null_object
|
74
|
-
|
75
|
-
|
67
|
+
build.should_receive(:update).and_return(mock_response)
|
68
|
+
build.save
|
76
69
|
end
|
77
70
|
end
|
78
71
|
end
|
@@ -81,21 +74,18 @@ describe "Build" do
|
|
81
74
|
before(:each) do
|
82
75
|
setup_fixture_base
|
83
76
|
setup_build_fixtures
|
84
|
-
@find_params = {:public_key => @pub_key,
|
85
|
-
:commit_identifier => @commit_identifier,
|
86
|
-
:identifier => @build_identifier}
|
87
77
|
end
|
88
78
|
|
89
79
|
it "returns an instance of Build when found" do
|
90
80
|
register_show_uri(["200", "OK"])
|
91
|
-
returned_object = Build.find(@
|
81
|
+
returned_object = Build.find(@commit, @build_name)
|
92
82
|
returned_object.should be_instance_of(Build)
|
93
83
|
returned_object.state.should_not be_nil
|
94
84
|
end
|
95
85
|
|
96
86
|
it "returns nil when not found" do
|
97
87
|
register_show_uri(["404", "Not found"])
|
98
|
-
Build.find(@
|
88
|
+
Build.find(@commit, @build_name).should be_nil
|
99
89
|
end
|
100
90
|
end
|
101
91
|
|
@@ -103,7 +93,7 @@ describe "Build" do
|
|
103
93
|
before(:each) do
|
104
94
|
setup_fixture_base
|
105
95
|
setup_build_fixtures
|
106
|
-
@build = Build.new(@
|
96
|
+
@build = Build.new(@commit, @build_name, @state)
|
107
97
|
end
|
108
98
|
|
109
99
|
it "returns true when the request returns a status of '200 Ok'" do
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require File.dirname(__FILE__) + '
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
2
|
|
3
|
-
describe Claim do
|
4
|
-
include CodeFumesServiceHelpers::
|
3
|
+
describe "API::Claim" do
|
4
|
+
include CodeFumesServiceHelpers::ClaimHelpers
|
5
5
|
|
6
6
|
after(:all) do
|
7
7
|
FakeWeb.allow_net_connect = false
|
@@ -47,6 +47,32 @@ describe Claim do
|
|
47
47
|
}.should raise_error(ArgumentError)
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
context "a nil value is passed in for the api_key" do
|
52
|
+
it "should not hit the CodeFumes API" do
|
53
|
+
API.should_not_receive(:put)
|
54
|
+
lambda {Claim.create(@project, nil)}
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raises a NoUserApiKeyError" do
|
58
|
+
lambda {
|
59
|
+
Claim.create(@project, nil)
|
60
|
+
}.should raise_error(Errors::NoUserApiKeyError)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "an empty string is passed in for the api_key" do
|
65
|
+
it "should not hit the CodeFumes API" do
|
66
|
+
API.should_not_receive(:put)
|
67
|
+
lambda {Claim.create(@project, '')}
|
68
|
+
end
|
69
|
+
|
70
|
+
it "raises a NoUserApiKeyError" do
|
71
|
+
lambda {
|
72
|
+
Claim.create(@project, '')
|
73
|
+
}.should raise_error(Errors::NoUserApiKeyError)
|
74
|
+
end
|
75
|
+
end
|
50
76
|
end
|
51
77
|
|
52
78
|
describe "destroy" do
|
@@ -63,5 +89,18 @@ describe Claim do
|
|
63
89
|
Claim.destroy(@project, @api_key).should be_false
|
64
90
|
end
|
65
91
|
end
|
92
|
+
|
93
|
+
context "a nil value is passed in for the api_key" do
|
94
|
+
it "should not hit the CodeFumes API" do
|
95
|
+
API.should_not_receive(:delete)
|
96
|
+
lambda {Claim.destroy(@project, nil)}
|
97
|
+
end
|
98
|
+
|
99
|
+
it "raises a NoUserApiKeyError" do
|
100
|
+
lambda {
|
101
|
+
Claim.destroy(@project, nil)
|
102
|
+
}.should raise_error(Errors::NoUserApiKeyError)
|
103
|
+
end
|
104
|
+
end
|
66
105
|
end
|
67
106
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require File.dirname(__FILE__) + '
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
2
|
|
3
|
-
describe "Commit" do
|
4
|
-
include CodeFumesServiceHelpers::
|
3
|
+
describe "API::Commit" do
|
4
|
+
include CodeFumesServiceHelpers::CommitHelpers
|
5
5
|
|
6
6
|
before(:all) do
|
7
7
|
FakeWeb.allow_net_connect = false
|
@@ -11,9 +11,7 @@ describe "Commit" do
|
|
11
11
|
@priv_key = 'private_key_value'
|
12
12
|
@anonymous_base_uri = "http://codefumes.com/api/v1/xml"
|
13
13
|
@authenticated_base_uri = "http://#{@pub_key}:#{@priv_key}@codefumes.com/api/v1/xml/projects"
|
14
|
-
@project = Project.new(:
|
15
|
-
:private_key => @priv_key,
|
16
|
-
:name => @project_name)
|
14
|
+
@project = Project.new(@pub_key, :private_key => @priv_key, :name => @project_name)
|
17
15
|
@authd_project_api_uri = "#{@authenticated_base_uri}/projects/#{@pub_key}"
|
18
16
|
@anon_project_api_uri = "#{@anonymous_base_uri}/projects/#{@pub_key}"
|
19
17
|
@basic_auth_params = {:username => @pub_key, :password => @priv_key}
|
@@ -24,11 +22,23 @@ describe "Commit" do
|
|
24
22
|
FakeWeb.clean_registry
|
25
23
|
end
|
26
24
|
|
27
|
-
describe "
|
25
|
+
describe "#id" do
|
26
|
+
it "returns the value of #identifier" do
|
27
|
+
Commit.new(@project, @identifier).id.should == @identifier
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#sha" do
|
32
|
+
it "returns the value of #identifier" do
|
33
|
+
Commit.new(@project, @identifier).sha.should == @identifier
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#find" do
|
28
38
|
context "with a valid commit identifier" do
|
29
39
|
before(:each) do
|
30
40
|
register_find_uri
|
31
|
-
@commit = Commit.find(@identifier)
|
41
|
+
@commit = Commit.find(@project, @identifier)
|
32
42
|
end
|
33
43
|
|
34
44
|
[:identifier,
|
@@ -60,40 +70,40 @@ describe "Commit" do
|
|
60
70
|
end
|
61
71
|
|
62
72
|
it "returns nil" do
|
63
|
-
Commit.find(@identifier).should == nil
|
73
|
+
Commit.find(@project, @identifier).should == nil
|
64
74
|
end
|
65
75
|
end
|
66
76
|
end
|
67
77
|
|
68
|
-
describe "
|
78
|
+
describe "#latest" do
|
69
79
|
context "with valid parameters" do
|
70
80
|
it "returns a commit object for the latest commit" do
|
71
81
|
register_latest_uri
|
72
|
-
Commit.latest(@
|
82
|
+
Commit.latest(@project).identifier.should == @identifier
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
76
86
|
context "with invalid parameters" do
|
77
87
|
it "returns nil" do
|
78
88
|
register_latest_uri(["404", "Not Found"], "")
|
79
|
-
Commit.latest(@
|
89
|
+
Commit.latest(@project).should == nil
|
80
90
|
end
|
81
91
|
end
|
82
92
|
end
|
83
93
|
|
84
|
-
describe "
|
94
|
+
describe "#latest_identifier" do
|
85
95
|
context "with valid parameters" do
|
86
96
|
context "when the specified project has commits stored" do
|
87
97
|
it "returns the commit identifier of the latest commit" do
|
88
98
|
register_latest_uri
|
89
|
-
Commit.latest_identifier(@
|
99
|
+
Commit.latest_identifier(@project).should == @identifier
|
90
100
|
end
|
91
101
|
end
|
92
102
|
|
93
103
|
context "when the specified project does not have any commits stored" do
|
94
104
|
it "returns nil" do
|
95
105
|
register_latest_uri(["404", "Not Found"], "")
|
96
|
-
Commit.latest_identifier(@
|
106
|
+
Commit.latest_identifier(@project).should == nil
|
97
107
|
end
|
98
108
|
end
|
99
109
|
end
|
@@ -101,23 +111,23 @@ describe "Commit" do
|
|
101
111
|
context "with invalid parameters" do
|
102
112
|
it "returns nil" do
|
103
113
|
register_latest_uri(["404", "Not Found"], "")
|
104
|
-
Commit.latest(@
|
114
|
+
Commit.latest(@project).should == nil
|
105
115
|
end
|
106
116
|
end
|
107
117
|
end
|
108
118
|
|
109
|
-
describe "
|
119
|
+
describe "#all" do
|
110
120
|
context "with valid parameters" do
|
111
121
|
it "returns an array of commits" do
|
112
122
|
register_index_uri
|
113
|
-
Commit.all(@
|
123
|
+
Commit.all(@project).should have(3).items
|
114
124
|
end
|
115
125
|
end
|
116
126
|
|
117
127
|
context "with invalid parameters" do
|
118
128
|
it "returns nil" do
|
119
129
|
register_index_uri(["404", "Not Found"], "")
|
120
|
-
Commit.all(@
|
130
|
+
Commit.all(@project).should == nil
|
121
131
|
end
|
122
132
|
end
|
123
133
|
end
|
@@ -127,17 +137,17 @@ describe "Commit" do
|
|
127
137
|
register_find_uri
|
128
138
|
@email = "jdoe@example.com"
|
129
139
|
@name = "John Doe"
|
130
|
-
@commit = Commit.find(@identifier)
|
140
|
+
@commit = Commit.find(@project, @identifier)
|
131
141
|
end
|
132
142
|
|
133
|
-
describe "author" do
|
143
|
+
describe "#author" do
|
134
144
|
it "returns a concatenated string containing the author's name & email" do
|
135
145
|
@commit.author.should =~ /#{@name}/
|
136
146
|
@commit.author.should =~ /#{@email}/
|
137
147
|
end
|
138
148
|
end
|
139
149
|
|
140
|
-
describe "committer" do
|
150
|
+
describe "#committer" do
|
141
151
|
it "returns a concatenated string containing the author's name & email" do
|
142
152
|
@commit.committer.should =~ /#{@name}/
|
143
153
|
@commit.committer.should =~ /#{@email}/
|
@@ -152,14 +162,14 @@ describe "Commit" do
|
|
152
162
|
end
|
153
163
|
|
154
164
|
it "returns an empty Hash" do
|
155
|
-
Commit.latest(@
|
165
|
+
Commit.latest(@project).custom_attributes.should == {}
|
156
166
|
end
|
157
167
|
end
|
158
168
|
|
159
169
|
context "when the commit has defined custom attributes" do
|
160
170
|
before(:each) do
|
161
171
|
register_latest_uri(["200", "Ok"], fixtures[:commit_with_custom_attrs])
|
162
|
-
@commit = Commit.latest(@
|
172
|
+
@commit = Commit.latest(@project)
|
163
173
|
end
|
164
174
|
|
165
175
|
it "returns a Hash of key-value pairs (attribute_name -> attribute_value)" do
|