##// END OF EJS Templates
Use simplecov for code coverage, rcov does not support ruby>=1.9....
Jean-Philippe Lang -
r13309:c3ba302f0de6
parent child
Show More
@@ -0,0 +1,70
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require 'erb'
19 require 'cgi'
20
21 # A simple formatter for SimpleCov
22 module Redmine
23 module Coverage
24 class HtmlFormatter
25 def format(result)
26 File.open(File.join(output_path, "index.html"), "w") do |file|
27 file.puts template('index').result(binding)
28 end
29 result.source_files.each do |source_file|
30 File.open(File.join(output_path, source_file_result(source_file)), "w") do |file|
31 file.puts template('source').result(binding)
32 end
33 end
34 end
35
36 private
37
38 def now
39 @now = Time.now.utc
40 end
41
42 def output_path
43 SimpleCov.coverage_path
44 end
45
46 def shortened_filename(source_file)
47 source_file.filename.gsub(SimpleCov.root, '.').gsub(/^\.\//, '')
48 end
49
50 def link_to_source_file(source_file)
51 %(<a href="#{source_file_result source_file}">#{shortened_filename source_file}</a>)
52 end
53
54 def source_file_result(source_file)
55 shortened_filename(source_file).gsub('/', '__')+'.html'
56 end
57
58 def revision_link
59 if revision = Redmine::VERSION.revision
60 %(<a href="http://www.redmine.org/projects/redmine/repository/revisions/#{revision}">r#{revision}</a>)
61 end
62 end
63
64 # Returns the an erb instance for the template of given name
65 def template(name)
66 ERB.new(File.read(File.join(File.dirname(__FILE__), 'views', "#{name}.erb")))
67 end
68 end
69 end
70 end
@@ -0,0 +1,60
1 <!DOCTYPE html>
2 <head>
3 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
4 <title>Redmine code coverage</title>
5 <style>
6 html {overflow-y:scroll;}
7 body {font-family:"Lucida Grande","Lucida Sans",Verdana,Helvetica,Arial,sans-serif; font-size:80%;}
8 h1 {color:#777; margin-bottom:0.2em;}
9 h2 {color:#aaa;margin-top:1em;font-size:18px;}
10 table {width:100%; border-collapse:collapse;}
11 th, td {border:1px solid #e2e2e2;}
12 td {text-align:right; font-family:"Bitstream Vera Sans Mono","Monaco","Courier New",monospace;}
13 td.filename {text-align:left; font-family:"Lucida Grande","Lucida Sans",Verdana,Helvetica,Arial,sans-serif;}
14 th {background:#e2e2e2;}
15 #generation {color:#777; font-size:90%;}
16 a, a:link, a:visited {color:#169; text-decoration:none;}
17 a:hover, a:active {color:#c61a1a; text-decoration:underline;}
18 div.percent {height:1em; empty-cells:show; padding:0px; border-collapse:collapse; width:100px !important; float:left; margin:0 0.5em 0 0.5em;}
19 div.percent div {float:left; height:1em; padding:0px !important;}
20 div.percent div.covered {background:#8c7;}
21 div.percent div.uncovered {background:#d76;}
22 </style>
23 </head>
24 <body>
25 <h1>Redmine code coverage</h1>
26 <p id='generation'>
27 Generated on <%= now %> (<%= revision_link %>).
28 More information about this environment at <a href='http://www.redmine.org/projects/redmine/wiki/Continuous_integration'>redmine.org</a>.
29 </p>
30
31 <table class="file_list">
32 <thead>
33 <tr>
34 <th>File</th>
35 <th colspan="2">% covered</th>
36 <th>Lines</th>
37 <th>Relevant</th>
38 <th>Covered</th>
39 </tr>
40 </thead>
41 <tbody>
42 <% result.source_files.each do |source_file| %>
43 <tr>
44 <td class="filename"><%= link_to_source_file(source_file) %></td>
45 <td><%= "%.1f" % source_file.covered_percent %> %</td>
46 <td>
47 <div class="percent">
48 <div class="covered" style="width:<%= source_file.covered_percent.to_i %>px"></div>
49 <div class="uncovered" style="width:<%= 100 - source_file.covered_percent.to_i %>px"></div>
50 </div>
51 </td>
52 <td><%= source_file.lines.count %></td>
53 <td><%= source_file.covered_lines.count + source_file.missed_lines.count %></td>
54 <td><%= source_file.covered_lines.count %></td>
55 </tr>
56 <% end %>
57 </tbody>
58 </table>
59 </body>
60 </html>
@@ -0,0 +1,41
1 <!DOCTYPE html>
2 <head>
3 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
4 <title>Redmine code coverage</title>
5 <style>
6 html {overflow-y:scroll;}
7 body {font-family:"Lucida Grande","Lucida Sans",Verdana,Helvetica,Arial,sans-serif; font-size:80%;}
8 h1 {color:#777; margin-bottom:0.2em;}
9 h2 {color:#aaa; margin-top:1em; font-size:18px;}
10 #generation {color:#777; font-size:90%;}
11 a, a:link, a:visited {color:#169; text-decoration:none;}
12 a:hover, a:active {color:#c61a1a; text-decoration:underline;}
13 pre, code {
14 color: #000000;
15 font-family: "Bitstream Vera Sans Mono","Monaco","Courier New",monospace;
16 font-size: 95%;
17 line-height: 1.3em;
18 margin-top: 0;
19 margin-bottom: 0;
20 padding: 0;
21 }
22 div.source {border:1px solid #e2e2e2;}
23 .covered {background:#bed2be;}
24 .missed {background:#fba;}
25 .never {background:#eee;}
26 </style>
27 </head>
28 <body>
29 <h1>Redmine code coverage</h1>
30 <p id='generation'>
31 Generated on <%= now %> (<%= revision_link %>).
32 More information about this environment at <a href='http://www.redmine.org/projects/redmine/wiki/Continuous_integration'>redmine.org</a>.
33 </p>
34 <h2><%= shortened_filename source_file %> (<%= "%.1f" % source_file.covered_percent %> %)</h2>
35
36 <div class="source">
37 <% source_file.lines.each_with_index do |line, i| %>
38 <pre class="<%= line.status %>" data-hits="<%= line.coverage ? line.coverage : '' %>" data-linenumber="<%= line.number %>"
39 ><code class="ruby"><%= i.to_s.rjust 4 %> <%= CGI.escapeHTML(line.src.chomp) %></code></pre>
40 <% end %>
41 </div>
@@ -1,103 +1,104
1 1 source 'https://rubygems.org'
2 2
3 3 gem "rails", "4.1.8"
4 4 gem "jquery-rails", "~> 3.1.1"
5 5 gem "coderay", "~> 1.1.0"
6 6 gem "builder", ">= 3.0.4"
7 7 gem "request_store", "1.0.5"
8 8 gem "mime-types"
9 9 gem "awesome_nested_set", "3.0.0"
10 10 gem "protected_attributes"
11 11 gem "actionpack-action_caching"
12 12
13 13 # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
14 14 gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin, :jruby]
15 15 gem "rbpdf", "~> 1.18.2"
16 16
17 17 # Optional gem for LDAP authentication
18 18 group :ldap do
19 19 gem "net-ldap", "~> 0.3.1"
20 20 end
21 21
22 22 # Optional gem for OpenID authentication
23 23 group :openid do
24 24 gem "ruby-openid", "~> 2.3.0", :require => "openid"
25 25 gem "rack-openid"
26 26 end
27 27
28 28 platforms :mri, :mingw, :x64_mingw do
29 29 # Optional gem for exporting the gantt to a PNG file, not supported with jruby
30 30 group :rmagick do
31 31 gem "rmagick", ">= 2.0.0"
32 32 end
33 33
34 34 # Optional Markdown support, not for JRuby
35 35 group :markdown do
36 36 gem "redcarpet", "~> 3.1.2"
37 37 end
38 38 end
39 39
40 40 platforms :jruby do
41 41 # jruby-openssl is bundled with JRuby 1.7.0
42 42 gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
43 43 gem "activerecord-jdbc-adapter", "~> 1.3.2"
44 44 end
45 45
46 46 # Include database gems for the adapters found in the database
47 47 # configuration file
48 48 require 'erb'
49 49 require 'yaml'
50 50 database_file = File.join(File.dirname(__FILE__), "config/database.yml")
51 51 if File.exist?(database_file)
52 52 database_config = YAML::load(ERB.new(IO.read(database_file)).result)
53 53 adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
54 54 if adapters.any?
55 55 adapters.each do |adapter|
56 56 case adapter
57 57 when 'mysql2'
58 58 gem "mysql2", "~> 0.3.11", :platforms => [:mri, :mingw, :x64_mingw]
59 59 gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
60 60 when 'mysql'
61 61 gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
62 62 when /postgresql/
63 63 gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw, :x64_mingw]
64 64 gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
65 65 when /sqlite3/
66 66 gem "sqlite3", :platforms => [:mri, :mingw, :x64_mingw]
67 67 gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
68 68 when /sqlserver/
69 69 gem "tiny_tds", "~> 0.6.2", :platforms => [:mri, :mingw, :x64_mingw]
70 70 gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw, :x64_mingw]
71 71 else
72 72 warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
73 73 end
74 74 end
75 75 else
76 76 warn("No adapter found in config/database.yml, please configure it first")
77 77 end
78 78 else
79 79 warn("Please configure your config/database.yml first")
80 80 end
81 81
82 82 group :development do
83 83 gem "rdoc", ">= 2.4.2"
84 84 gem "yard"
85 85 end
86 86
87 87 group :test do
88 88 gem "minitest"
89 89 gem "mocha", "~> 1.0.0", :require => 'mocha/api'
90 gem "simplecov", "~> 0.9.1", :require => false
90 91 # For running UI tests
91 92 gem "capybara", "~> 2.1.0"
92 93 gem "selenium-webdriver"
93 94 end
94 95
95 96 local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
96 97 if File.exists?(local_gemfile)
97 98 eval_gemfile local_gemfile
98 99 end
99 100
100 101 # Load plugins' Gemfiles
101 102 Dir.glob File.expand_path("../plugins/*/{Gemfile,PluginGemfile}", __FILE__) do |file|
102 103 eval_gemfile file
103 104 end
@@ -1,114 +1,110
1 ### From http://svn.geekdaily.org/public/rails/plugins/generally_useful/tasks/coverage_via_rcov.rake
2
3 1 namespace :test do
4 2 desc 'Measures test coverage'
5 3 task :coverage do
6 4 rm_f "coverage"
7 rm_f "coverage.data"
8 rcov = "rcov --rails --aggregate coverage.data --text-summary -Ilib --html --exclude gems/"
9 files = %w(unit functional integration).map {|dir| Dir.glob("test/#{dir}/**/*_test.rb")}.flatten.join(" ")
10 system("#{rcov} #{files}")
5 ENV["COVERAGE"] = "1"
6 Rake::Task["test"].invoke
11 7 end
12 8
13 9 desc 'Run unit and functional scm tests'
14 10 task :scm do
15 11 errors = %w(test:scm:units test:scm:functionals).collect do |task|
16 12 begin
17 13 Rake::Task[task].invoke
18 14 nil
19 15 rescue => e
20 16 task
21 17 end
22 18 end.compact
23 19 abort "Errors running #{errors.to_sentence(:locale => :en)}!" if errors.any?
24 20 end
25 21
26 22 namespace :scm do
27 23 namespace :setup do
28 24 desc "Creates directory for test repositories"
29 25 task :create_dir => :environment do
30 26 FileUtils.mkdir_p Rails.root + '/tmp/test'
31 27 end
32 28
33 29 supported_scms = [:subversion, :cvs, :bazaar, :mercurial, :git, :darcs, :filesystem]
34 30
35 31 desc "Creates a test subversion repository"
36 32 task :subversion => :create_dir do
37 33 repo_path = "tmp/test/subversion_repository"
38 34 unless File.exists?(repo_path)
39 35 system "svnadmin create #{repo_path}"
40 36 system "gunzip < test/fixtures/repositories/subversion_repository.dump.gz | svnadmin load #{repo_path}"
41 37 end
42 38 end
43 39
44 40 desc "Creates a test mercurial repository"
45 41 task :mercurial => :create_dir do
46 42 repo_path = "tmp/test/mercurial_repository"
47 43 unless File.exists?(repo_path)
48 44 bundle_path = "test/fixtures/repositories/mercurial_repository.hg"
49 45 system "hg init #{repo_path}"
50 46 system "hg -R #{repo_path} pull #{bundle_path}"
51 47 end
52 48 end
53 49
54 50 def extract_tar_gz(prefix)
55 51 unless File.exists?("tmp/test/#{prefix}_repository")
56 52 # system "gunzip < test/fixtures/repositories/#{prefix}_repository.tar.gz | tar -xv -C tmp/test"
57 53 system "tar -xvz -C tmp/test -f test/fixtures/repositories/#{prefix}_repository.tar.gz"
58 54 end
59 55 end
60 56
61 57 (supported_scms - [:subversion, :mercurial]).each do |scm|
62 58 desc "Creates a test #{scm} repository"
63 59 task scm => :create_dir do
64 60 extract_tar_gz(scm)
65 61 end
66 62 end
67 63
68 64 desc "Creates all test repositories"
69 65 task :all => supported_scms
70 66 end
71 67
72 68 desc "Updates installed test repositories"
73 69 task :update => :environment do
74 70 require 'fileutils'
75 71 Dir.glob("tmp/test/*_repository").each do |dir|
76 72 next unless File.basename(dir) =~ %r{^(.+)_repository$} && File.directory?(dir)
77 73 scm = $1
78 74 next unless fixture = Dir.glob("test/fixtures/repositories/#{scm}_repository.*").first
79 75 next if File.stat(dir).ctime > File.stat(fixture).mtime
80 76
81 77 FileUtils.rm_rf dir
82 78 Rake::Task["test:scm:setup:#{scm}"].execute
83 79 end
84 80 end
85 81
86 82 Rake::TestTask.new(:units => "db:test:prepare") do |t|
87 83 t.libs << "test"
88 84 t.verbose = true
89 85 t.test_files = FileList['test/unit/repository*_test.rb'] + FileList['test/unit/lib/redmine/scm/**/*_test.rb']
90 86 end
91 87 Rake::Task['test:scm:units'].comment = "Run the scm unit tests"
92 88
93 89 Rake::TestTask.new(:functionals => "db:test:prepare") do |t|
94 90 t.libs << "test"
95 91 t.verbose = true
96 92 t.test_files = FileList['test/functional/repositories*_test.rb']
97 93 end
98 94 Rake::Task['test:scm:functionals'].comment = "Run the scm functional tests"
99 95 end
100 96
101 97 Rake::TestTask.new(:routing) do |t|
102 98 t.libs << "test"
103 99 t.verbose = true
104 100 t.test_files = FileList['test/integration/routing/*_test.rb'] + FileList['test/integration/api_test/*_routing_test.rb']
105 101 end
106 102 Rake::Task['test:routing'].comment = "Run the routing tests"
107 103
108 104 Rake::TestTask.new(:ui => "db:test:prepare") do |t|
109 105 t.libs << "test"
110 106 t.verbose = true
111 107 t.test_files = FileList['test/ui/**/*_test.rb']
112 108 end
113 109 Rake::Task['test:ui'].comment = "Run the UI tests with Capybara (PhantomJS listening on port 4444 is required)"
114 110 end
@@ -1,281 +1,288
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 if ENV["COVERAGE"]
19 require 'simplecov'
20 require File.expand_path(File.dirname(__FILE__) + "/coverage/html_formatter")
21 SimpleCov.formatter = Redmine::Coverage::HtmlFormatter
22 SimpleCov.start 'rails'
23 end
24
18 25 ENV["RAILS_ENV"] = "test"
19 26 require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
20 27 require 'rails/test_help'
21 28 require Rails.root.join('test', 'mocks', 'open_id_authentication_mock.rb').to_s
22 29
23 30 require File.expand_path(File.dirname(__FILE__) + '/object_helpers')
24 31 include ObjectHelpers
25 32
26 33 require 'awesome_nested_set/version'
27 34 require 'net/ldap'
28 35
29 36 class ActionView::TestCase
30 37 helper :application
31 38 include ApplicationHelper
32 39 end
33 40
34 41 class ActiveSupport::TestCase
35 42 include ActionDispatch::TestProcess
36 43
37 44 self.use_transactional_fixtures = true
38 45 self.use_instantiated_fixtures = false
39 46
40 47 #ESCAPED_CANT = 'can&#x27;t'
41 48 #ESCAPED_UCANT = 'Can&#x27;t'
42 49 # Rails 4.0.2
43 50 ESCAPED_CANT = 'can&#39;t'
44 51 ESCAPED_UCANT = 'Can&#39;t'
45 52
46 53 def uploaded_test_file(name, mime)
47 54 fixture_file_upload("files/#{name}", mime, true)
48 55 end
49 56
50 57 # Mock out a file
51 58 def self.mock_file
52 59 file = 'a_file.png'
53 60 file.stubs(:size).returns(32)
54 61 file.stubs(:original_filename).returns('a_file.png')
55 62 file.stubs(:content_type).returns('image/png')
56 63 file.stubs(:read).returns(false)
57 64 file
58 65 end
59 66
60 67 def mock_file
61 68 self.class.mock_file
62 69 end
63 70
64 71 def mock_file_with_options(options={})
65 72 file = ''
66 73 file.stubs(:size).returns(32)
67 74 original_filename = options[:original_filename] || nil
68 75 file.stubs(:original_filename).returns(original_filename)
69 76 content_type = options[:content_type] || nil
70 77 file.stubs(:content_type).returns(content_type)
71 78 file.stubs(:read).returns(false)
72 79 file
73 80 end
74 81
75 82 # Use a temporary directory for attachment related tests
76 83 def set_tmp_attachments_directory
77 84 Dir.mkdir "#{Rails.root}/tmp/test" unless File.directory?("#{Rails.root}/tmp/test")
78 85 unless File.directory?("#{Rails.root}/tmp/test/attachments")
79 86 Dir.mkdir "#{Rails.root}/tmp/test/attachments"
80 87 end
81 88 Attachment.storage_path = "#{Rails.root}/tmp/test/attachments"
82 89 end
83 90
84 91 def set_fixtures_attachments_directory
85 92 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
86 93 end
87 94
88 95 def with_settings(options, &block)
89 96 saved_settings = options.keys.inject({}) do |h, k|
90 97 h[k] = case Setting[k]
91 98 when Symbol, false, true, nil
92 99 Setting[k]
93 100 else
94 101 Setting[k].dup
95 102 end
96 103 h
97 104 end
98 105 options.each {|k, v| Setting[k] = v}
99 106 yield
100 107 ensure
101 108 saved_settings.each {|k, v| Setting[k] = v} if saved_settings
102 109 end
103 110
104 111 # Yields the block with user as the current user
105 112 def with_current_user(user, &block)
106 113 saved_user = User.current
107 114 User.current = user
108 115 yield
109 116 ensure
110 117 User.current = saved_user
111 118 end
112 119
113 120 def with_locale(locale, &block)
114 121 saved_localed = ::I18n.locale
115 122 ::I18n.locale = locale
116 123 yield
117 124 ensure
118 125 ::I18n.locale = saved_localed
119 126 end
120 127
121 128 def self.ldap_configured?
122 129 @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
123 130 return @test_ldap.bind
124 131 rescue Exception => e
125 132 # LDAP is not listening
126 133 return nil
127 134 end
128 135
129 136 def self.convert_installed?
130 137 Redmine::Thumbnail.convert_available?
131 138 end
132 139
133 140 # Returns the path to the test +vendor+ repository
134 141 def self.repository_path(vendor)
135 142 path = Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s
136 143 # Unlike ruby, JRuby returns Rails.root with backslashes under Windows
137 144 path.tr("\\", "/")
138 145 end
139 146
140 147 # Returns the url of the subversion test repository
141 148 def self.subversion_repository_url
142 149 path = repository_path('subversion')
143 150 path = '/' + path unless path.starts_with?('/')
144 151 "file://#{path}"
145 152 end
146 153
147 154 # Returns true if the +vendor+ test repository is configured
148 155 def self.repository_configured?(vendor)
149 156 File.directory?(repository_path(vendor))
150 157 end
151 158
152 159 def repository_path_hash(arr)
153 160 hs = {}
154 161 hs[:path] = arr.join("/")
155 162 hs[:param] = arr.join("/")
156 163 hs
157 164 end
158 165
159 166 def assert_save(object)
160 167 saved = object.save
161 168 message = "#{object.class} could not be saved"
162 169 errors = object.errors.full_messages.map {|m| "- #{m}"}
163 170 message << ":\n#{errors.join("\n")}" if errors.any?
164 171 assert_equal true, saved, message
165 172 end
166 173
167 174 def assert_select_error(arg)
168 175 assert_select '#errorExplanation', :text => arg
169 176 end
170 177
171 178 def assert_include(expected, s, message=nil)
172 179 assert s.include?(expected), (message || "\"#{expected}\" not found in \"#{s}\"")
173 180 end
174 181
175 182 def assert_not_include(expected, s, message=nil)
176 183 assert !s.include?(expected), (message || "\"#{expected}\" found in \"#{s}\"")
177 184 end
178 185
179 186 def assert_select_in(text, *args, &block)
180 187 d = HTML::Document.new(CGI::unescapeHTML(String.new(text))).root
181 188 assert_select(d, *args, &block)
182 189 end
183 190
184 191 def assert_mail_body_match(expected, mail, message=nil)
185 192 if expected.is_a?(String)
186 193 assert_include expected, mail_body(mail), message
187 194 else
188 195 assert_match expected, mail_body(mail), message
189 196 end
190 197 end
191 198
192 199 def assert_mail_body_no_match(expected, mail, message=nil)
193 200 if expected.is_a?(String)
194 201 assert_not_include expected, mail_body(mail), message
195 202 else
196 203 assert_no_match expected, mail_body(mail), message
197 204 end
198 205 end
199 206
200 207 def mail_body(mail)
201 208 mail.parts.first.body.encoded
202 209 end
203 210
204 211 # awesome_nested_set new node lft and rgt value changed this refactor revision.
205 212 # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb938e40200cd90714dc69247ef017c61
206 213 # The reason of behavior change is that "self.class.base_class.unscoped" was added to this line.
207 214 # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb9#diff-f61b59a5e6319024e211b0ffdd0e4ef1R273
208 215 # It seems correct behavior because of this line comment.
209 216 # https://github.com/collectiveidea/awesome_nested_set/blame/199fca9bb9/lib/awesome_nested_set/model.rb#L278
210 217 def new_issue_lft
211 218 # ::AwesomeNestedSet::VERSION > "2.1.6" ? Issue.maximum(:rgt) + 1 : 1
212 219 Issue.maximum(:rgt) + 1
213 220 end
214 221 end
215 222
216 223 module Redmine
217 224 class RoutingTest < ActionDispatch::IntegrationTest
218 225 def should_route(arg)
219 226 arg = arg.dup
220 227 request = arg.keys.detect {|key| key.is_a?(String)}
221 228 raise ArgumentError unless request
222 229 options = arg.slice!(request)
223 230
224 231 raise ArgumentError unless request =~ /\A(GET|POST|PUT|PATCH|DELETE)\s+(.+)\z/
225 232 method, path = $1.downcase.to_sym, $2
226 233
227 234 raise ArgumentError unless arg.values.first =~ /\A(.+)#(.+)\z/
228 235 controller, action = $1, $2
229 236
230 237 assert_routing(
231 238 {:method => method, :path => path},
232 239 options.merge(:controller => controller, :action => action)
233 240 )
234 241 end
235 242 end
236 243
237 244 class IntegrationTest < ActionDispatch::IntegrationTest
238 245 def log_user(login, password)
239 246 User.anonymous
240 247 get "/login"
241 248 assert_equal nil, session[:user_id]
242 249 assert_response :success
243 250 assert_template "account/login"
244 251 post "/login", :username => login, :password => password
245 252 assert_equal login, User.find(session[:user_id]).login
246 253 end
247 254
248 255 def credentials(user, password=nil)
249 256 {'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)}
250 257 end
251 258 end
252 259
253 260 module ApiTest
254 261 API_FORMATS = %w(json xml).freeze
255 262
256 263 # Base class for API tests
257 264 class Base < Redmine::IntegrationTest
258 265 def setup
259 266 Setting.rest_api_enabled = '1'
260 267 end
261 268
262 269 def teardown
263 270 Setting.rest_api_enabled = '0'
264 271 end
265 272 end
266 273
267 274 class Routing < Redmine::RoutingTest
268 275 def should_route(arg)
269 276 arg = arg.dup
270 277 request = arg.keys.detect {|key| key.is_a?(String)}
271 278 raise ArgumentError unless request
272 279 options = arg.slice!(request)
273 280
274 281 API_FORMATS.each do |format|
275 282 format_request = request.sub /$/, ".#{format}"
276 283 super options.merge(format_request => arg[request], :format => format)
277 284 end
278 285 end
279 286 end
280 287 end
281 288 end
General Comments 0
You need to be logged in to leave comments. Login now