hoboken 0.0.1.beta2 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
- data/.github/ISSUE_TEMPLATE/code_change.md +11 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +25 -0
- data/.github/dependabot.yml +7 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +41 -0
- data/.ruby-version +1 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +131 -0
- data/CODE_OF_CONDUCT.md +8 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +2 -0
- data/IDEAS.md +57 -0
- data/LICENSE.txt +1 -1
- data/README.md +28 -17
- data/Rakefile +14 -8
- data/bin/hoboken +2 -1
- data/hoboken.gemspec +63 -16
- data/lib/hoboken/actions.rb +11 -6
- data/lib/hoboken/add_ons/active_record.rb +142 -0
- data/lib/hoboken/add_ons/airbrake.rb +64 -0
- data/lib/hoboken/add_ons/github_action.rb +14 -0
- data/lib/hoboken/add_ons/heroku.rb +29 -0
- data/lib/hoboken/add_ons/internationalization.rb +28 -0
- data/lib/hoboken/add_ons/metrics.rb +60 -0
- data/lib/hoboken/add_ons/omniauth.rb +174 -0
- data/lib/hoboken/add_ons/rubocop.rb +46 -0
- data/lib/hoboken/add_ons/sequel.rb +135 -0
- data/lib/hoboken/add_ons/sidekiq.rb +137 -0
- data/lib/hoboken/add_ons/travis.rb +15 -0
- data/lib/hoboken/add_ons/turnip.rb +109 -0
- data/lib/hoboken/add_ons/twbs.rb +50 -0
- data/lib/hoboken/add_ons/vcr.rb +54 -0
- data/lib/hoboken/generate.rb +146 -46
- data/lib/hoboken/templates/Gemfile.erb.tt +43 -8
- data/lib/hoboken/templates/README.md.tt +117 -35
- data/lib/hoboken/templates/Rakefile.tt +20 -16
- data/lib/hoboken/templates/active_record.rake +11 -0
- data/lib/hoboken/templates/airbrake.rb.tt +13 -0
- data/lib/hoboken/templates/classic.rb.tt +25 -11
- data/lib/hoboken/templates/classic_environment.rb.tt +51 -0
- data/lib/hoboken/templates/config.ru.tt +4 -2
- data/lib/hoboken/templates/console +19 -0
- data/lib/hoboken/templates/db.rb.tt +24 -0
- data/lib/hoboken/templates/example_worker.rb.tt +14 -0
- data/lib/hoboken/templates/github_action.tt +28 -0
- data/lib/hoboken/templates/gitignore +8 -0
- data/lib/hoboken/templates/metrics.rake.tt +12 -9
- data/lib/hoboken/templates/modular.rb.tt +28 -15
- data/lib/hoboken/templates/modular_environment.rb.tt +62 -0
- data/lib/hoboken/templates/puma.rb.tt +21 -0
- data/lib/hoboken/templates/rspec.rake.tt +9 -0
- data/lib/hoboken/templates/rubocop.yml.tt +51 -0
- data/lib/hoboken/templates/seeds.rb +12 -0
- data/lib/hoboken/templates/sequel.rake +21 -0
- data/lib/hoboken/templates/server +15 -0
- data/lib/hoboken/templates/setup +28 -0
- data/lib/hoboken/templates/sidekiq.rb.tt +21 -0
- data/lib/hoboken/templates/spec/app_spec.rb.tt +13 -0
- data/lib/hoboken/templates/spec/example_worker_spec.rb.tt +16 -0
- data/lib/hoboken/templates/spec/rack_matchers.rb.tt +58 -0
- data/lib/hoboken/templates/spec/spec_helper.rb.tt +37 -0
- data/lib/hoboken/templates/spec/turnip_helper.rb.tt +10 -0
- data/lib/hoboken/templates/styles.css.tt +1 -1
- data/lib/hoboken/templates/support/rack_helpers.rb.tt +55 -0
- data/lib/hoboken/templates/support/rack_test_assertions.rb.tt +113 -0
- data/lib/hoboken/templates/test/test_helper.rb.tt +47 -0
- data/lib/hoboken/templates/test/unit/app_test.rb.tt +11 -3
- data/lib/hoboken/templates/test/unit/example_worker_test.rb.tt +20 -0
- data/lib/hoboken/templates/test_unit.rake.tt +18 -0
- data/lib/hoboken/templates/vcr_setup.rb.tt +15 -0
- data/lib/hoboken/templates/views/index.erb.tt +11 -4
- data/lib/hoboken/templates/views/layout.erb.tt +7 -4
- data/lib/hoboken/version.rb +3 -1
- data/lib/hoboken.rb +147 -325
- data/test/fixtures/Gemfile +3 -3
- data/test/fixtures/Gemfile.pristine +3 -2
- data/test/integration/active_record_test.rb +66 -0
- data/test/integration/airbrake_test.rb +31 -0
- data/test/integration/generate_classic_test.rb +75 -0
- data/test/integration/generate_modular_test.rb +83 -0
- data/test/integration/github_action_test.rb +13 -0
- data/test/integration/heroku_test.rb +14 -0
- data/test/integration/internationalization_test.rb +26 -0
- data/test/integration/metrics_test.rb +54 -0
- data/test/integration/omniauth_test.rb +143 -0
- data/test/integration/rubocop_test.rb +39 -0
- data/test/integration/sequel_test.rb +64 -0
- data/test/integration/sidekiq_test.rb +105 -0
- data/test/integration/travis_test.rb +13 -0
- data/test/integration/turnip_test.rb +51 -0
- data/test/integration/twitter_bootstrap_test.rb +39 -0
- data/test/integration/vcr_test.rb +54 -0
- data/test/test_helper.rb +109 -0
- data/test/unit/hoboken_actions_test.rb +82 -53
- data/www/Gemfile +4 -0
- data/www/README.md +2 -0
- data/www/config.rb +11 -0
- data/www/source/documentation.html.erb +274 -0
- data/www/source/images/hoboken-running.png +0 -0
- data/www/source/images/hoboken.png +0 -0
- data/www/source/images/sinatra.png +0 -0
- data/www/source/index.html.erb +44 -0
- data/www/source/javascripts/all.js +1 -0
- data/www/source/layouts/layout.erb +38 -0
- data/www/source/stylesheets/all.css.scss +116 -0
- data/www/source/stylesheets/normalize.css +375 -0
- metadata +655 -29
- data/lib/hoboken/templates/sprockets.rake +0 -33
- data/lib/hoboken/templates/sprockets_chain.rb +0 -26
- data/lib/hoboken/templates/sprockets_helper.rb +0 -13
- data/lib/hoboken/templates/test/support/rack_test_assertions.rb.tt +0 -79
- data/lib/hoboken/templates/test/unit/test_helper.rb.tt +0 -36
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
workers_count = Integer(ENV['WEB_CONCURRENCY'] || 1)
|
4
|
+
threads_count = Integer(ENV['MAX_THREADS'] || 5)
|
5
|
+
threads threads_count, threads_count
|
6
|
+
|
7
|
+
port ENV['PORT'] || 9292
|
8
|
+
environment ENV['RACK_ENV'] || 'production'
|
9
|
+
|
10
|
+
if workers_count > 1
|
11
|
+
preload_app!
|
12
|
+
workers workers_count
|
13
|
+
|
14
|
+
# rubocop:disable Lint/EmptyBlock
|
15
|
+
before_fork do
|
16
|
+
end
|
17
|
+
|
18
|
+
on_worker_boot do
|
19
|
+
end
|
20
|
+
# rubocop:enable Lint/EmptyBlock
|
21
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-performance
|
3
|
+
- rubocop-rake
|
4
|
+
<% if rspec? -%>
|
5
|
+
- rubocop-rspec
|
6
|
+
<% end -%>
|
7
|
+
<% if sequel? -%>
|
8
|
+
- rubocop-sequel
|
9
|
+
<% end -%>
|
10
|
+
|
11
|
+
AllCops:
|
12
|
+
Exclude:
|
13
|
+
- 'tmp/*'
|
14
|
+
- 'vendor/bundle/**/*'
|
15
|
+
NewCops: enable
|
16
|
+
TargetRubyVersion: <%= RUBY_VERSION %>
|
17
|
+
|
18
|
+
Layout/LineLength:
|
19
|
+
Max: 90
|
20
|
+
|
21
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
22
|
+
EnforcedStyle: no_space
|
23
|
+
<% if rspec? -%>
|
24
|
+
|
25
|
+
Metrics/BlockLength:
|
26
|
+
IgnoredMethods:
|
27
|
+
- describe
|
28
|
+
- context
|
29
|
+
- it
|
30
|
+
- RSpec.configure
|
31
|
+
<% end -%>
|
32
|
+
|
33
|
+
Metrics/ClassLength:
|
34
|
+
Max: 150
|
35
|
+
|
36
|
+
Metrics/MethodLength:
|
37
|
+
Max: 15
|
38
|
+
<% if rspec? -%>
|
39
|
+
|
40
|
+
RSpec/DescribeClass:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
RSpec/MultipleDescribes:
|
44
|
+
Enabled: false
|
45
|
+
<% end -%>
|
46
|
+
|
47
|
+
Style/BlockDelimiters:
|
48
|
+
EnforcedStyle: braces_for_chaining
|
49
|
+
|
50
|
+
Style/YodaCondition:
|
51
|
+
EnforcedStyle: require_for_equality_operators_only
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file should contain all the record creation needed to seed the database
|
4
|
+
# with its default values.
|
5
|
+
#
|
6
|
+
# The data can then be loaded with the bin/rails db:seed command (or created
|
7
|
+
# alongside the database with db:setup).
|
8
|
+
#
|
9
|
+
# Examples:
|
10
|
+
#
|
11
|
+
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
|
12
|
+
# Character.create(name: 'Luke', movie: movies.first)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
Sequel.extension :migration
|
7
|
+
db = Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://db/development.db')
|
8
|
+
|
9
|
+
desc 'Migrate the database to latest version'
|
10
|
+
task :migrate do
|
11
|
+
Sequel::Migrator.run(db, 'db/migrate')
|
12
|
+
puts '<= db:migrate executed'
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Perform migration reset (full erase and migration up)'
|
16
|
+
task :reset do
|
17
|
+
Sequel::Migrator.run(db, 'db/migrate', target: 0)
|
18
|
+
Sequel::Migrator.run(db, 'db/migrate')
|
19
|
+
puts '<= db:reset executed'
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
APP_ROOT = File.expand_path('..', __dir__)
|
7
|
+
|
8
|
+
def system!(*args)
|
9
|
+
system(*args) || abort("\n== Command #{args} failed ==")
|
10
|
+
end
|
11
|
+
|
12
|
+
FileUtils.chdir APP_ROOT do
|
13
|
+
puts '== Starting development server =='
|
14
|
+
system! 'rerun --background foreman start'
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
APP_ROOT = File.expand_path('..', __dir__)
|
7
|
+
|
8
|
+
def system!(*args)
|
9
|
+
system(*args) || abort("\n== Command #{args} failed ==")
|
10
|
+
end
|
11
|
+
|
12
|
+
FileUtils.chdir APP_ROOT do
|
13
|
+
# This script is a way to set up or update your development environment
|
14
|
+
# automatically. This script is idempotent, so that you can run it at
|
15
|
+
# anytime and get an expectable outcome. Add necessary setup steps to
|
16
|
+
# this file.
|
17
|
+
|
18
|
+
puts '== Installing dependencies =='
|
19
|
+
system! 'gem install bundler --conservative'
|
20
|
+
system! 'bundle config --local cache_all true'
|
21
|
+
system! 'bundle config --local cache_all_platforms true'
|
22
|
+
system! 'bundle config --local ignore_messages.rpush true'
|
23
|
+
system('bundle check') || system!('bundle install')
|
24
|
+
|
25
|
+
system! 'gem list "^foreman$" -v 0.87.2 -i --silent || gem install foreman'
|
26
|
+
system! 'gem list "^rerun$" -v 0.13.1 -i --silent || gem install rerun'
|
27
|
+
system! 'gem list "^rb-fsevent$" -v 0.11.0 -i --silent || gem install rb-fsevent'
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sidekiq'
|
4
|
+
|
5
|
+
Sidekiq.configure_client do |config|
|
6
|
+
config.redis = { size: 1 }
|
7
|
+
end
|
8
|
+
|
9
|
+
Sidekiq.configure_server do |config|
|
10
|
+
# TODO: Setup an error handling service (i.e. Airbrake, Sentry, etc.)
|
11
|
+
# https://github.com/mperham/sidekiq/wiki/Error-Handling#best-practices
|
12
|
+
# config.error_handlers << ->(ex, ctx_hash) { MyErrorService.notify(ex, ctx_hash) }
|
13
|
+
|
14
|
+
config.death_handlers << lambda do |job, ex|
|
15
|
+
puts "#{job['class']} job #{job['jid']} just died (#{ex.message})"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Dir.glob(File.join('workers', '**', '*.rb')).each do |worker|
|
20
|
+
require_relative "../#{worker}"
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe 'GET /', rack: true do
|
4
|
+
before { get '/' }
|
5
|
+
|
6
|
+
it { expect(last_response).to have_http_status(:ok) }
|
7
|
+
<% if options[:api_only] -%>
|
8
|
+
it { expect(last_response).to have_content_type(:json) }
|
9
|
+
<% else -%>
|
10
|
+
it { expect(last_response).to have_content_type(:html) }
|
11
|
+
<% end -%>
|
12
|
+
it { expect(last_response.body).to include('Smoke test successful!') }
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Refer to the Sidekiq documentation[1] for more information about testing
|
4
|
+
# workers.
|
5
|
+
#
|
6
|
+
# [1]: https://github.com/mperham/sidekiq/wiki/Testing
|
7
|
+
#
|
8
|
+
RSpec.describe ExampleWorker, sidekiq: true do
|
9
|
+
subject(:worker) { described_class }
|
10
|
+
|
11
|
+
it 'performs work' do
|
12
|
+
expect {
|
13
|
+
worker.perform_async
|
14
|
+
}.to change(worker.jobs, :size).by(1)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec::Matchers.define :have_http_status do |expected|
|
4
|
+
match do |response|
|
5
|
+
response.status == response_codes[expected]
|
6
|
+
end
|
7
|
+
|
8
|
+
failure_message do |response|
|
9
|
+
'expected last response status to be ' \
|
10
|
+
"#{response_codes.fetch(expected, 'unknown')}, " \
|
11
|
+
"but was #{response.status}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def response_codes
|
15
|
+
{
|
16
|
+
ok: 200,
|
17
|
+
no_content: 204,
|
18
|
+
not_authorized: 401,
|
19
|
+
not_found: 404,
|
20
|
+
redirect: 302,
|
21
|
+
server_error: 500
|
22
|
+
}.freeze
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec::Matchers.define :have_content_type do |expected|
|
27
|
+
match do |response|
|
28
|
+
response.content_type == content_types[expected]
|
29
|
+
end
|
30
|
+
|
31
|
+
failure_message do |response|
|
32
|
+
'expected last response to have content type ' \
|
33
|
+
"'#{content_types.fetch(expected, 'unknown')}', " \
|
34
|
+
"but was '#{response.content_type}'"
|
35
|
+
end
|
36
|
+
|
37
|
+
def content_types
|
38
|
+
{
|
39
|
+
html: 'text/html;charset=utf-8',
|
40
|
+
json: 'application/json'
|
41
|
+
}.freeze
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
RSpec::Matchers.define :redirect_to do |expected|
|
46
|
+
match do |response|
|
47
|
+
path(response) == expected
|
48
|
+
end
|
49
|
+
|
50
|
+
failure_message do |response|
|
51
|
+
"expected last response to redirect to '#{expected}', " \
|
52
|
+
"but it redirected to '#{path(response)}'"
|
53
|
+
end
|
54
|
+
|
55
|
+
def path(response)
|
56
|
+
URI(response.location).path
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ENV['RACK_ENV'] = 'test'
|
4
|
+
|
5
|
+
require_relative '../config/environment'
|
6
|
+
|
7
|
+
require 'warning'
|
8
|
+
|
9
|
+
# Ignore all warnings in Gem dependencies
|
10
|
+
Gem.path.each { |path| Warning.ignore(//, path) }
|
11
|
+
|
12
|
+
require 'pry-byebug'
|
13
|
+
require 'rack/test'
|
14
|
+
require 'support/rack_helpers'
|
15
|
+
|
16
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.include RackHelpers, rack: true
|
19
|
+
|
20
|
+
config.expect_with :rspec do |expectations|
|
21
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
22
|
+
end
|
23
|
+
|
24
|
+
config.mock_with :rspec do |mocks|
|
25
|
+
mocks.verify_partial_doubles = true
|
26
|
+
end
|
27
|
+
|
28
|
+
config.default_formatter = 'doc' if config.files_to_run.one?
|
29
|
+
config.disable_monkey_patching!
|
30
|
+
config.example_status_persistence_file_path = 'spec/examples.txt'
|
31
|
+
config.filter_run_when_matching :focus
|
32
|
+
config.order = :random
|
33
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
34
|
+
config.warnings = true
|
35
|
+
|
36
|
+
Kernel.srand config.seed
|
37
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'spec_helper'
|
4
|
+
|
5
|
+
Dir.glob('spec/support/steps/**/*_steps.rb') { |f| load f, true }
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.raise_error_for_unimplemented_steps = true
|
9
|
+
config.include RackHelpers, feature: true
|
10
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
<% if 'test-unit' == options[:test_framework] -%>
|
4
|
+
require_relative 'rack_test_assertions'
|
5
|
+
<% end -%>
|
6
|
+
<% if 'rspec' == options[:test_framework] -%>
|
7
|
+
require_relative 'rack_matchers'
|
8
|
+
<% end -%>
|
9
|
+
|
10
|
+
# Helpers for running Rack-based tests or specs. Decorates normal Rack methods
|
11
|
+
# with an optional `:as` parameter. If present, the `rack.session` will
|
12
|
+
# include the value of the given user's ID, effectively signing them in for
|
13
|
+
# the request.
|
14
|
+
#
|
15
|
+
# Example
|
16
|
+
# ```
|
17
|
+
# # Find or create a user. You can name the class anything you'd like, the
|
18
|
+
# # only requirement is that it responds to a `id` method.
|
19
|
+
# user = User.new(id: 1) # or User.find, etc.
|
20
|
+
# get '/', as: user
|
21
|
+
# ```
|
22
|
+
#
|
23
|
+
# The above will add a `current_user` to the `rack.session` with a value of
|
24
|
+
# the user's ID.
|
25
|
+
#
|
26
|
+
module RackHelpers
|
27
|
+
include Rack::Test::Methods
|
28
|
+
<% if 'test-unit' == options[:test_framework] -%>
|
29
|
+
include Rack::Test::Assertions
|
30
|
+
<% end -%>
|
31
|
+
|
32
|
+
%w[get post put patch delete options].each do |type|
|
33
|
+
define_method(type) do |uri, params={}, env={}, &block|
|
34
|
+
extract_user!(params, env)
|
35
|
+
super uri, params, env, &block
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def extract_user!(params, env)
|
42
|
+
user = params.delete(:as)
|
43
|
+
return unless user
|
44
|
+
|
45
|
+
if env.key?('rack.session')
|
46
|
+
env['rack.session'].merge!(current_user: user.id)
|
47
|
+
else
|
48
|
+
env.merge!({ 'rack.session' => { current_user: user.id } })
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def app
|
53
|
+
Sinatra::Application
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module Test
|
5
|
+
module Assertions
|
6
|
+
RESPONSE_CODES = {
|
7
|
+
ok: 200,
|
8
|
+
no_content: 204,
|
9
|
+
not_authorized: 401,
|
10
|
+
not_found: 404,
|
11
|
+
redirect: 302,
|
12
|
+
server_error: 500
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
CONTENT_TYPES = {
|
16
|
+
json: 'application/json',
|
17
|
+
html: 'text/html;charset=utf-8'
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
def assert_body_contains(expected, message=nil)
|
21
|
+
msg = build_message(
|
22
|
+
message,
|
23
|
+
"expected body to contain <?>\n#{last_response.body}",
|
24
|
+
expected
|
25
|
+
)
|
26
|
+
|
27
|
+
assert_block(msg) { last_response.body.include?(expected) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def assert_content_type(content_type)
|
31
|
+
unless CONTENT_TYPES.key?(content_type)
|
32
|
+
raise ArgumentError, "unrecognized content_type (#{content_type})"
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_equal CONTENT_TYPES[content_type], last_response.content_type
|
36
|
+
end
|
37
|
+
|
38
|
+
def assert_flash(type=:notice, message=nil)
|
39
|
+
msg = build_message(
|
40
|
+
message,
|
41
|
+
'expected <?> flash to exist, but was nil',
|
42
|
+
type.to_s
|
43
|
+
)
|
44
|
+
|
45
|
+
assert_block(msg) { last_request.env['rack.session']['flash'] }
|
46
|
+
end
|
47
|
+
|
48
|
+
def assert_flash_message(expected, type=:notice, message=nil)
|
49
|
+
assert_flash(type, message)
|
50
|
+
flash = last_request.env['rack.session']['flash'][type.to_s]
|
51
|
+
|
52
|
+
msg = build_message(
|
53
|
+
message,
|
54
|
+
'expected flash to be <?> but was <?>',
|
55
|
+
expected,
|
56
|
+
flash
|
57
|
+
)
|
58
|
+
|
59
|
+
assert_block(msg) { expected == flash }
|
60
|
+
end
|
61
|
+
|
62
|
+
def assert_has_session(message=nil)
|
63
|
+
msg = build_message(message, 'expected a valid session')
|
64
|
+
assert_block(msg) { last_request.env['rack.session'] }
|
65
|
+
end
|
66
|
+
|
67
|
+
def assert_session_has_key(key, message=nil)
|
68
|
+
assert_has_session
|
69
|
+
msg = build_message(message, 'expected session to have key named <?>', key)
|
70
|
+
assert_block(msg) { last_request.env['rack.session'].key?(key.to_s) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def assert_session(key, expected, message=nil)
|
74
|
+
assert_session_has_key(key)
|
75
|
+
actual = last_request.env['rack.session'][key.to_s]
|
76
|
+
msg = build_message(
|
77
|
+
message,
|
78
|
+
'expected session key <?> to be <?>, but was <?>',
|
79
|
+
key,
|
80
|
+
expected,
|
81
|
+
actual
|
82
|
+
)
|
83
|
+
|
84
|
+
assert_block(msg) { expected == actual }
|
85
|
+
end
|
86
|
+
|
87
|
+
def assert_response(expected, message=nil)
|
88
|
+
status = last_response.status
|
89
|
+
msg = build_message(
|
90
|
+
message,
|
91
|
+
'expected last response to be <?> but was <?>',
|
92
|
+
"#{RESPONSE_CODES[expected]}:#{expected}",
|
93
|
+
"#{status}:#{RESPONSE_CODES.key(status)}"
|
94
|
+
)
|
95
|
+
|
96
|
+
assert_block(msg) { status == RESPONSE_CODES[expected] }
|
97
|
+
end
|
98
|
+
|
99
|
+
def assert_redirected_to(expected, message=nil)
|
100
|
+
assert_response(:redirect)
|
101
|
+
actual = URI(last_response.location).path
|
102
|
+
msg = build_message(
|
103
|
+
message,
|
104
|
+
'expected to be redirected to <?> but was <?>',
|
105
|
+
expected,
|
106
|
+
actual
|
107
|
+
)
|
108
|
+
|
109
|
+
assert_block(msg) { expected == actual }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ENV['RACK_ENV'] = 'test'
|
4
|
+
|
5
|
+
require_relative '../config/environment'
|
6
|
+
|
7
|
+
require 'warning'
|
8
|
+
|
9
|
+
# Ignore all warnings in Gem dependencies
|
10
|
+
Gem.path.each { |path| Warning.ignore(//, path) }
|
11
|
+
|
12
|
+
require 'test/unit'
|
13
|
+
require 'contest'
|
14
|
+
require 'pry-byebug'
|
15
|
+
require 'rack/test'
|
16
|
+
|
17
|
+
require_relative 'support/rack_helpers'
|
18
|
+
|
19
|
+
module Test
|
20
|
+
module Unit
|
21
|
+
class TestCase
|
22
|
+
# Syntactic sugar for defining a memoized helper method.
|
23
|
+
#
|
24
|
+
def self.let(name, &block)
|
25
|
+
ivar = "@#{name}"
|
26
|
+
class_eval do
|
27
|
+
define_method(name) do
|
28
|
+
if instance_variable_defined?(ivar)
|
29
|
+
instance_variable_get(ivar)
|
30
|
+
else
|
31
|
+
value = instance_eval(&block)
|
32
|
+
instance_variable_set(ivar, value)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module Rack
|
42
|
+
module Test
|
43
|
+
class TestCase < ::Test::Unit::TestCase
|
44
|
+
include RackHelpers
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,8 +1,16 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../test_helper'
|
2
4
|
|
3
5
|
class AppTest < Rack::Test::TestCase
|
4
|
-
test
|
5
|
-
get
|
6
|
+
test 'GET /' do
|
7
|
+
get '/'
|
6
8
|
assert_response :ok
|
9
|
+
<% if options[:api_only] -%>
|
10
|
+
assert_content_type(:json)
|
11
|
+
<% else -%>
|
12
|
+
assert_content_type(:html)
|
13
|
+
<% end -%>
|
14
|
+
assert_body_contains('Smoke test successful!')
|
7
15
|
end
|
8
16
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../test_helper'
|
4
|
+
|
5
|
+
# Refer to the Sidekiq documentation[1] for more information about testing
|
6
|
+
# workers.
|
7
|
+
#
|
8
|
+
# [1]: https://github.com/mperham/sidekiq/wiki/Testing
|
9
|
+
#
|
10
|
+
class ExampleWorkerTest < Test::Unit::TestCase
|
11
|
+
setup do
|
12
|
+
Sidekiq::Worker.clear_all
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'performs work' do
|
16
|
+
assert_equal 0, ExampleWorker.jobs.size
|
17
|
+
ExampleWorker.perform_async
|
18
|
+
assert_equal 1, ExampleWorker.jobs.size
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
namespace :test do
|
6
|
+
Rake::TestTask.new(:unit) do |t|
|
7
|
+
t.libs << 'test/unit'
|
8
|
+
t.test_files = Dir['test/unit/**/*_test.rb']
|
9
|
+
end
|
10
|
+
|
11
|
+
Rake::TestTask.new(:integration) do |t|
|
12
|
+
t.libs << 'test/unit'
|
13
|
+
t.test_files = Dir['test/integration/**/*_test.rb']
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Run all tests'
|
17
|
+
task all: %w[test:unit test:integration]
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vcr'
|
4
|
+
|
5
|
+
VCR.configure do |c|
|
6
|
+
<% if rspec? -%>
|
7
|
+
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
|
8
|
+
<% else -%>
|
9
|
+
c.cassette_library_dir = 'test/fixtures/vcr_cassettes'
|
10
|
+
<% end -%>
|
11
|
+
c.hook_into :webmock
|
12
|
+
<% if rspec? -%>
|
13
|
+
c.configure_rspec_metadata!
|
14
|
+
<% end -%>
|
15
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="wrapper">
|
2
2
|
<h1>Hoboken</h1>
|
3
|
-
<img src="
|
3
|
+
<img src="<%%= image_path('images/hoboken.png') %>" />
|
4
4
|
<div class="main">
|
5
5
|
<h2>Getting Started</h2>
|
6
6
|
<p>Smoke test successful!</p>
|
@@ -51,9 +51,10 @@
|
|
51
51
|
<p>The following Rake tasks are available:</p>
|
52
52
|
<table>
|
53
53
|
<tr>
|
54
|
-
<td>rake
|
55
|
-
<th>
|
54
|
+
<td>rake ci</td>
|
55
|
+
<th>Run CI checks</th>
|
56
56
|
</tr>
|
57
|
+
<% if 'test-unit' == options[:test_framework] -%>
|
57
58
|
<tr>
|
58
59
|
<td>rake test:all</td>
|
59
60
|
<th>Run all tests</th>
|
@@ -62,6 +63,12 @@
|
|
62
63
|
<td>rake test:unit</td>
|
63
64
|
<th>Run unit tests</th>
|
64
65
|
</tr>
|
66
|
+
<% else -%>
|
67
|
+
<tr>
|
68
|
+
<td>rake spec</td>
|
69
|
+
<th>Run RSpec</th>
|
70
|
+
</tr>
|
71
|
+
<% end -%>
|
65
72
|
</table>
|
66
73
|
|
67
74
|
<h3>Add Ons</h3>
|
@@ -70,7 +77,7 @@
|
|
70
77
|
|
71
78
|
<h3>Links</h3>
|
72
79
|
<ul>
|
73
|
-
<li><a href="
|
80
|
+
<li><a href="http://bobnadler.com/hoboken">Documentation</a></li>
|
74
81
|
<li><a href="https://github.com/bnadlerjr/hoboken">Source Code</a></li>
|
75
82
|
</ul>
|
76
83
|
|