foca-integrity 0.1.8 → 0.1.9.0

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