foca-integrity 0.1.8 → 0.1.9.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.
Files changed (75) hide show
  1. data/README.markdown +7 -0
  2. data/Rakefile +89 -81
  3. data/config/config.sample.ru +11 -21
  4. data/config/config.sample.yml +15 -12
  5. data/lib/integrity.rb +21 -23
  6. data/lib/integrity/app.rb +138 -0
  7. data/lib/integrity/author.rb +39 -0
  8. data/lib/integrity/build.rb +54 -31
  9. data/lib/integrity/commit.rb +71 -0
  10. data/lib/integrity/helpers.rb +3 -3
  11. data/lib/integrity/helpers/authorization.rb +2 -2
  12. data/lib/integrity/helpers/forms.rb +3 -3
  13. data/lib/integrity/helpers/pretty_output.rb +1 -1
  14. data/lib/integrity/helpers/rendering.rb +6 -1
  15. data/lib/integrity/helpers/resources.rb +9 -3
  16. data/lib/integrity/helpers/urls.rb +15 -13
  17. data/lib/integrity/installer.rb +43 -60
  18. data/lib/integrity/migrations.rb +31 -48
  19. data/lib/integrity/notifier.rb +14 -16
  20. data/lib/integrity/notifier/base.rb +29 -19
  21. data/lib/integrity/notifier/test_helpers.rb +100 -0
  22. data/lib/integrity/project.rb +69 -33
  23. data/lib/integrity/project_builder.rb +23 -14
  24. data/lib/integrity/scm/git.rb +15 -14
  25. data/lib/integrity/scm/git/uri.rb +9 -9
  26. data/test/acceptance/api_test.rb +97 -0
  27. data/test/acceptance/browse_project_builds_test.rb +65 -0
  28. data/test/acceptance/browse_project_test.rb +95 -0
  29. data/test/acceptance/build_notifications_test.rb +42 -0
  30. data/test/acceptance/create_project_test.rb +97 -0
  31. data/test/acceptance/delete_project_test.rb +53 -0
  32. data/test/acceptance/edit_project_test.rb +117 -0
  33. data/test/acceptance/error_page_test.rb +18 -0
  34. data/test/acceptance/helpers.rb +2 -0
  35. data/test/acceptance/installer_test.rb +62 -0
  36. data/test/acceptance/manual_build_project_test.rb +82 -0
  37. data/test/acceptance/notifier_test.rb +109 -0
  38. data/test/acceptance/project_syndication_test.rb +30 -0
  39. data/test/acceptance/stylesheet_test.rb +18 -0
  40. data/test/helpers.rb +59 -27
  41. data/test/helpers/acceptance.rb +19 -64
  42. data/test/helpers/acceptance/email_notifier.rb +55 -0
  43. data/test/helpers/acceptance/git_helper.rb +15 -15
  44. data/test/helpers/acceptance/textfile_notifier.rb +3 -3
  45. data/test/helpers/expectations.rb +0 -1
  46. data/test/helpers/expectations/be_a.rb +4 -4
  47. data/test/helpers/expectations/change.rb +5 -5
  48. data/test/helpers/expectations/have.rb +4 -4
  49. data/test/helpers/expectations/predicates.rb +4 -4
  50. data/test/helpers/fixtures.rb +44 -18
  51. data/test/helpers/initial_migration_fixture.sql +44 -0
  52. data/test/unit/build_test.rb +51 -0
  53. data/test/unit/commit_test.rb +83 -0
  54. data/test/unit/helpers_test.rb +56 -0
  55. data/test/unit/integrity_test.rb +18 -0
  56. data/test/unit/migrations_test.rb +56 -0
  57. data/test/unit/notifier_test.rb +123 -0
  58. data/test/unit/project_builder_test.rb +108 -0
  59. data/test/unit/project_test.rb +282 -0
  60. data/test/unit/scm_test.rb +54 -0
  61. data/views/_commit_info.haml +24 -0
  62. data/views/build.haml +2 -2
  63. data/views/error.haml +4 -3
  64. data/views/home.haml +3 -5
  65. data/views/integrity.sass +19 -6
  66. data/views/new.haml +6 -6
  67. data/views/project.builder +9 -9
  68. data/views/project.haml +14 -12
  69. metadata +98 -116
  70. data/VERSION.yml +0 -4
  71. data/app.rb +0 -137
  72. data/integrity.gemspec +0 -76
  73. data/lib/integrity/core_ext/string.rb +0 -5
  74. data/test/helpers/expectations/have_tag.rb +0 -128
  75. data/views/_build_info.haml +0 -18
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + "/helpers"
2
+
3
+ class ProjectSyndicationTest < Test::Unit::AcceptanceTestCase
4
+ story <<-EOS
5
+ As a user,
6
+ I want to subscribe to a public project's Atom feed
7
+ So I can know the status of my favorite projects while having my morning coffee
8
+ EOS
9
+
10
+ scenario "a public project's page includes an autodiscovery link tag for the feed" do
11
+ Project.gen(:integrity, :public => true)
12
+ visit "/integrity"
13
+
14
+ assert_have_tag("link[@href='/integrity.atom']")
15
+ end
16
+
17
+ scenario "a public project's feed should include the latest builds" do
18
+ commits = 10.of { Commit.gen(:successful) } + 1.of { Commit.gen(:failed) }
19
+ Project.gen(:integrity, :public => true, :commits => commits)
20
+
21
+ visit "/integrity.atom"
22
+
23
+ # TODO: check for content-type
24
+
25
+ assert_have_tag("feed title", :content => "Build history for Integrity")
26
+ assert_have_tag("feed entry", :count => 11)
27
+ assert_have_tag("feed entry:first title", :content => "success")
28
+ assert_have_tag("feed entry:last title", :content => "failed")
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + "/helpers"
2
+
3
+ class IntegrityStylesheetTest < Test::Unit::AcceptanceTestCase
4
+ story <<-EOS
5
+ As a user,
6
+ I want the stylesheet to work (even with Sinatra 0.9.1)
7
+ So that Integrity isn't a PITA to use
8
+ EOS
9
+
10
+ scenario "browsing on some Integrity install" do
11
+ visit "/integrity.css"
12
+
13
+ assert_contain("body {")
14
+ # TODO: better test
15
+ assert_equal %Q{"2465c472aacf302259dde5146a841e45"},
16
+ webrat_session.send(:response).headers["ETag"]
17
+ end
18
+ end
data/test/helpers.rb CHANGED
@@ -1,38 +1,43 @@
1
- require File.dirname(__FILE__) + "/../lib/integrity"
1
+ $:.unshift File.dirname(__FILE__) + "/../lib", File.dirname(__FILE__),
2
+ File.dirname(__FILE__) + "/../vendor/webrat/lib"
3
+
4
+ %w(test/unit
5
+ context
6
+ pending
7
+ matchy
8
+ storyteller
9
+ webrat/sinatra
10
+ rr
11
+ mocha
12
+ test/zentest_assertions
13
+ dm-sweatshop).each { |dependency|
14
+ begin
15
+ require dependency
16
+ rescue LoadError
17
+ puts "You're missing some gems required to run the tests."
18
+ puts "Please run `rake test:install_dependencies`"
19
+ puts "You'll probably need to run that command as root or with sudo."
20
+
21
+ puts "Thanks :)"
22
+ puts
23
+
24
+ exit 1
25
+ end
26
+ }
2
27
 
3
28
  begin
4
- require "test/unit"
5
- require "redgreen"
6
- require "context"
7
- require "storyteller"
8
- require "pending"
9
- require "matchy"
10
- require "rr"
11
- require "mocha"
12
29
  require "ruby-debug"
30
+ require "redgreen"
13
31
  rescue LoadError
14
- puts "You're missing some gems required to run the tests."
15
- puts "Please run `rake test:install_dependencies`"
16
- puts "You'll probably need to run that command as root or with sudo."
17
- puts
18
- puts "Thanks :)"
19
- puts
20
-
21
- exit 1
22
32
  end
23
33
 
24
- require File.dirname(__FILE__) / "helpers" / "expectations"
25
- require File.dirname(__FILE__) / "helpers" / "fixtures"
26
- require File.dirname(__FILE__) / "helpers" / "acceptance"
34
+ require "integrity"
35
+ require "helpers/expectations"
36
+ require "helpers/fixtures"
27
37
 
28
38
  module TestHelper
29
- def setup_and_reset_database!
30
- DataMapper.setup(:default, "sqlite3::memory:")
31
- DataMapper.auto_migrate!
32
- end
33
-
34
39
  def ignore_logs!
35
- stub(Integrity).log { nil }
40
+ Integrity.config[:log] = "/tmp/integrity.test.log"
36
41
  end
37
42
  end
38
43
 
@@ -44,5 +49,32 @@ class Test::Unit::TestCase
44
49
  include RR::Adapters::TestUnit
45
50
  include Integrity
46
51
  include TestHelper
47
- end
48
52
 
53
+ before(:all) do
54
+ DataMapper.setup(:default, "sqlite3::memory:")
55
+ end
56
+
57
+ before(:each) do
58
+ RR.reset
59
+ DataMapper.auto_migrate!
60
+ Integrity.instance_variable_set(:@config, nil)
61
+ Notifier.available.each { |n|
62
+ Notifier.send(:remove_const, n.to_s.split(":").last.to_sym)
63
+ }
64
+
65
+ repository(:default) do
66
+ transaction = DataMapper::Transaction.new(repository)
67
+ transaction.begin
68
+ repository.adapter.push_transaction(transaction)
69
+ end
70
+ end
71
+
72
+ after(:each) do
73
+ repository(:default) do
74
+ while repository.adapter.current_transaction
75
+ repository.adapter.current_transaction.rollback
76
+ repository.adapter.pop_transaction
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,66 +1,10 @@
1
- require 'webrat/rack'
2
- require 'sinatra'
3
- require 'sinatra/test'
4
-
5
- disable :run
6
- disable :reload
7
-
8
- Webrat.configuration.instance_variable_set("@mode", :sinatra)
9
-
10
- module Webrat
11
- class SinatraSession < Session
12
- DEFAULT_DOMAIN = "integrity.example.org"
13
-
14
- def initialize(context = nil)
15
- super(context)
16
- @sinatra_test = Sinatra::TestHarness.new
17
- end
18
-
19
- %w(get head post put delete).each do |verb|
20
- class_eval <<-METHOD
21
- def #{verb}(path, data, headers = {})
22
- params = data.inject({}) do |data, (key,value)|
23
- data[key] = Rack::Utils.unescape(value)
24
- data
25
- end
26
- headers['HTTP_HOST'] = DEFAULT_DOMAIN
27
- @sinatra_test.#{verb}(path, params, headers)
28
- end
29
- METHOD
30
- end
31
-
32
- def response_body
33
- @sinatra_test.body
34
- end
35
-
36
- def response_code
37
- @sinatra_test.status
38
- end
39
-
40
- private
41
-
42
- def response
43
- @sinatra_test.response
44
- end
45
-
46
- def current_host
47
- URI.parse(current_url).host || DEFAULT_DOMAIN
48
- end
49
-
50
- def response_location_host
51
- URI.parse(response_location).host || DEFAULT_DOMAIN
52
- end
53
- end
54
- end
55
-
56
- require Integrity.root / "app"
57
- require File.dirname(__FILE__) / "acceptance/git_helper"
1
+ require "helpers/acceptance/git_helper"
58
2
 
59
3
  module AcceptanceHelper
60
4
  include FileUtils
61
5
 
62
6
  def export_directory
63
- Integrity.root / "exports"
7
+ File.dirname(__FILE__) + "/../../exports"
64
8
  end
65
9
 
66
10
  def enable_auth!
@@ -74,7 +18,7 @@ module AcceptanceHelper
74
18
  def AcceptanceHelper.logged_in; true; end
75
19
  basic_auth user, password
76
20
  visit "/login"
77
- Sinatra::Application.before { login_required if AcceptanceHelper.logged_in }
21
+ Integrity::App.before { login_required if AcceptanceHelper.logged_in }
78
22
  end
79
23
 
80
24
  def log_out
@@ -93,9 +37,9 @@ module AcceptanceHelper
93
37
  end
94
38
 
95
39
  def setup_log!
96
- pathname = Integrity.root / "integrity.log"
97
- FileUtils.rm pathname if File.exists?(pathname)
98
- Integrity.config[:log] = pathname
40
+ log_file = Pathname(File.dirname(__FILE__) + "/../../integrity.log")
41
+ log_file.delete if log_file.exist?
42
+ Integrity.config[:log] = log_file
99
43
  end
100
44
  end
101
45
 
@@ -104,15 +48,25 @@ class Test::Unit::AcceptanceTestCase < Test::Unit::TestCase
104
48
  include Test::Storyteller
105
49
  include GitHelper
106
50
  include Webrat::Methods
51
+ include Webrat::Matchers
52
+ include Webrat::HaveTagMatcher
53
+
54
+ # TODO: does this belongs in Webrat::SinatraSession?
107
55
  Webrat::Methods.delegate_to_session :response_code
108
56
 
57
+ def app
58
+ Integrity::App.tap { |app|
59
+ app.set :environment, :test
60
+ app.disable :raise_errors, :run, :reload
61
+ }
62
+ end
63
+
109
64
  before(:all) do
110
- Integrity.config[:base_uri] = "http://#{Webrat::SinatraSession::DEFAULT_DOMAIN}"
65
+ Integrity.config[:base_uri] = "http://www.example.com"
111
66
  end
112
67
 
113
68
  before(:each) do
114
69
  # ensure each scenario is run in a clean sandbox
115
- setup_and_reset_database!
116
70
  enable_auth!
117
71
  setup_log!
118
72
  set_and_create_export_directory!
@@ -123,4 +77,5 @@ class Test::Unit::AcceptanceTestCase < Test::Unit::TestCase
123
77
  destroy_all_git_repos
124
78
  rm_r export_directory if File.directory?(export_directory)
125
79
  end
80
+
126
81
  end
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'integrity'
3
+
4
+ module Integrity
5
+ class Notifier
6
+ class Email < Notifier::Base
7
+ attr_reader :to, :from
8
+
9
+ def self.to_haml
10
+ <<-EOF
11
+ %p.normal
12
+ %label{ :for => "email_notifier_to" } Send to
13
+ %input.text#email_notifier_to{ :name => "notifiers[Email][to]", :type => "text", :value => config["to"] }
14
+
15
+ %p.normal
16
+ %label{ :for => "email_notifier_from" } Send from
17
+ %input.text#email_notifier_from{ :name => "notifiers[Email][from]", :type => "text", :value => config["from"] }
18
+
19
+ %h3 SMTP Server Configuration
20
+
21
+ %p.normal
22
+ %label{ :for => "email_notifier_host" } Host : Port
23
+ = succeed " : " do
24
+ %input.text#email_notifier_host{ :name => "notifiers[Email][host]", :value => config["host"], :style => "width: 24.5em;", :type => "text" }
25
+ %input.text#email_notifier_port{ :name => "notifiers[Email][port]", :value => config["port"], :style => "width: 3.5em;", :type => "text" }
26
+
27
+ %p.normal
28
+ %label{ :for => "email_notifier_user" } User
29
+ %input.text#email_notifier_user{ :name => "notifiers[Email][user]", :value => config["user"], :type => "text" }
30
+
31
+ %p.normal
32
+ %label{ :for => "email_notifier_pass" } Password
33
+ %input.text#email_notifier_pass{ :name => "notifiers[Email][pass]", :value => config["pass"], :type => "text" }
34
+
35
+ %p.normal
36
+ %label{ :for => "email_notifier_auth" } Auth type
37
+ %input.text#email_notifier_auth{ :name => "notifiers[Email][auth]", :value => (config["auth"] || "plain"), :type => "text" }
38
+
39
+ %p.normal
40
+ %label{ :for => "email_notifier_domain" } Domain
41
+ %input.text#email_notifier_domain{ :name => "notifiers[Email][domain]", :value => config["domain"], :type => "text" }
42
+ EOF
43
+ end
44
+
45
+ def initialize(build, config={})
46
+ @to = config.delete("to")
47
+ @from = config.delete("from")
48
+ super
49
+ end
50
+
51
+ def deliver!
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,32 +1,32 @@
1
1
  module GitHelper
2
2
  @@_git_repositories = Hash.new {|h,k| h[k] = Repo.new(k) }
3
-
3
+
4
4
  def git_repo(name)
5
5
  @@_git_repositories[name]
6
6
  end
7
-
7
+
8
8
  def destroy_all_git_repos
9
9
  @@_git_repositories.each {|n,r| r.destroy }
10
10
  @@_git_repositories.clear
11
11
  end
12
-
12
+
13
13
  class Repo
14
14
  attr_reader :path
15
-
15
+
16
16
  def initialize(name)
17
17
  @name = name
18
18
  @path = "/tmp" / @name.to_s
19
19
  create
20
20
  end
21
-
21
+
22
22
  def path
23
23
  @path / ".git"
24
24
  end
25
-
25
+
26
26
  def create
27
27
  destroy
28
28
  FileUtils.mkdir_p @path
29
-
29
+
30
30
  Dir.chdir(@path) do
31
31
  system 'git init &>/dev/null'
32
32
  system 'git config user.name "John Doe"'
@@ -35,7 +35,7 @@ module GitHelper
35
35
  system 'git add README &>/dev/null'
36
36
  system 'git commit -m "First commit" &>/dev/null'
37
37
  end
38
-
38
+
39
39
  add_successful_commit
40
40
  end
41
41
 
@@ -43,7 +43,7 @@ module GitHelper
43
43
  Dir.chdir(@path) do
44
44
  commits = `git log --pretty=oneline`.collect { |line| line.split(" ").first }
45
45
  commits.inject([]) do |commits, sha1|
46
- format = %Q(---%n:message: >-%n %s%n:timestamp: %ci%n:id: #{sha1})
46
+ format = %Q(---%n:message: >-%n %s%n:timestamp: %ci%n:id: %H%n:author: %n :name: %an%n :email: %ae%n)
47
47
  commits << YAML.load(`git show -s --pretty=format:"#{format}" #{sha1}`)
48
48
  end
49
49
  end
@@ -55,7 +55,7 @@ module GitHelper
55
55
  system %Q(git commit -m "#{message}" &>/dev/null)
56
56
  end
57
57
  end
58
-
58
+
59
59
  def add_failing_commit
60
60
  add_commit "This commit will fail" do
61
61
  system %Q(echo '#{build_script(false)}' > test)
@@ -71,23 +71,23 @@ module GitHelper
71
71
  system %Q(git add test &>/dev/null)
72
72
  end
73
73
  end
74
-
74
+
75
75
  def head
76
76
  Dir.chdir(@path) do
77
77
  `git log --pretty=format:%H | head -1`.chomp
78
78
  end
79
79
  end
80
-
80
+
81
81
  def short_head
82
82
  head[0..6]
83
83
  end
84
-
84
+
85
85
  def destroy
86
86
  FileUtils.rm_rf @path if File.directory?(@path)
87
87
  end
88
-
88
+
89
89
  protected
90
-
90
+
91
91
  def build_script(successful=true)
92
92
  <<-script
93
93
  #!/bin/sh
@@ -8,12 +8,12 @@ module Integrity
8
8
  %input.text#textfile_notifier_file{ :name => "notifiers[Textfile][file]", :type => "text", :value => config["file"] }
9
9
  haml
10
10
  end
11
-
11
+
12
12
  def initialize(build, config={})
13
13
  super
14
14
  @file = @config["file"]
15
15
  end
16
-
16
+
17
17
  def deliver!
18
18
  File.open(@file, "a") do |f|
19
19
  f.puts "=== #{short_message} ==="
@@ -23,4 +23,4 @@ module Integrity
23
23
  end
24
24
  end
25
25
  end
26
- end
26
+ end