diff --git a/Rakefile b/Rakefile index 395223ed..f66cfdb7 100644 --- a/Rakefile +++ b/Rakefile @@ -8,7 +8,7 @@ require "hanami/devtools/rake_tasks" namespace :spec do RSpec::Core::RakeTask.new(:unit) do |task| file_list = FileList["spec/**/*_spec.rb"] - file_list = file_list.exclude("spec/{integration,isolation}/**/*_spec.rb") + file_list = file_list.exclude("spec/{isolation}/**/*_spec.rb") task.pattern = file_list end diff --git a/spec/new_integration/action/cookies_spec.rb b/spec/integration/action/cookies_spec.rb similarity index 100% rename from spec/new_integration/action/cookies_spec.rb rename to spec/integration/action/cookies_spec.rb diff --git a/spec/new_integration/action/csrf_protection_spec.rb b/spec/integration/action/csrf_protection_spec.rb similarity index 100% rename from spec/new_integration/action/csrf_protection_spec.rb rename to spec/integration/action/csrf_protection_spec.rb diff --git a/spec/new_integration/action/routes_spec.rb b/spec/integration/action/routes_spec.rb similarity index 100% rename from spec/new_integration/action/routes_spec.rb rename to spec/integration/action/routes_spec.rb diff --git a/spec/new_integration/action/sessions_spec.rb b/spec/integration/action/sessions_spec.rb similarity index 100% rename from spec/new_integration/action/sessions_spec.rb rename to spec/integration/action/sessions_spec.rb diff --git a/spec/new_integration/action/slice_configuration_spec.rb b/spec/integration/action/slice_configuration_spec.rb similarity index 100% rename from spec/new_integration/action/slice_configuration_spec.rb rename to spec/integration/action/slice_configuration_spec.rb diff --git a/spec/new_integration/action/view_integration_spec.rb b/spec/integration/action/view_integration_spec.rb similarity index 100% rename from spec/new_integration/action/view_integration_spec.rb rename to spec/integration/action/view_integration_spec.rb diff --git a/spec/new_integration/action/view_rendering/automatic_rendering_spec.rb b/spec/integration/action/view_rendering/automatic_rendering_spec.rb similarity index 100% rename from spec/new_integration/action/view_rendering/automatic_rendering_spec.rb rename to spec/integration/action/view_rendering/automatic_rendering_spec.rb diff --git a/spec/new_integration/action/view_rendering/paired_view_inference_spec.rb b/spec/integration/action/view_rendering/paired_view_inference_spec.rb similarity index 100% rename from spec/new_integration/action/view_rendering/paired_view_inference_spec.rb rename to spec/integration/action/view_rendering/paired_view_inference_spec.rb diff --git a/spec/new_integration/action/view_rendering_spec.rb b/spec/integration/action/view_rendering_spec.rb similarity index 100% rename from spec/new_integration/action/view_rendering_spec.rb rename to spec/integration/action/view_rendering_spec.rb diff --git a/spec/integration/application_middleware_stack_spec.rb b/spec/integration/application_middleware_stack_spec.rb deleted file mode 100644 index 4f158415..00000000 --- a/spec/integration/application_middleware_stack_spec.rb +++ /dev/null @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "App middleware stack", type: :integration do - it "mounts Rack middleware" do - with_project do - generate "action web home#index --url=/" - generate_middleware - - # Add apps/web/middleware to the load paths - replace "apps/web/app.rb", "load_paths << [", "load_paths << ['middleware'," - - # Require Rack::ETag - unshift "apps/web/app.rb", "require 'rack/etag'" - - # Mount middleware - replace "apps/web/app.rb", "# middleware.use", "middleware.use 'Web::Middleware::Runtime'\nmiddleware.use 'Web::Middleware::Custom', 'OK'\nmiddleware.use Rack::ETag" - - rewrite "apps/web/controllers/home/index.rb", <<~EOF - module Web::Controllers::Home - class Index - include Web::Action - - def call(params) - self.body = "OK" - end - end - end - EOF - - server do - get "/" - - expect(last_response.status).to eq(200) - - expect(last_response.headers["X-Runtime"]).to eq("1ms") - expect(last_response.headers["X-Custom"]).to eq("OK") - expect(last_response.headers["ETag"]).to_not be_nil - end - end - end - - private - - def generate_middleware # rubocop:disable Metrics/MethodLength - write "apps/web/middleware/runtime.rb", <<~EOF - module Web - module Middleware - class Runtime - def initialize(app) - @app = app - end - - def call(env) - status, headers, body = @app.call(env) - headers["X-Runtime"] = "1ms" - - [status, headers, body] - end - end - end - end - EOF - - write "apps/web/middleware/custom.rb", <<~EOF - module Web - module Middleware - class Custom - def initialize(app, value) - @app = app - @value = value - end - - def call(env) - status, headers, body = @app.call(env) - headers["X-Custom"] = @value - - [status, headers, body] - end - end - end - end - EOF - end -end diff --git a/spec/integration/assets/cdn_spec.rb b/spec/integration/assets/cdn_spec.rb deleted file mode 100644 index 5886d10d..00000000 --- a/spec/integration/assets/cdn_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "assets", type: :integration do - describe "CDN mode" do - it "servers assets with CDN url" do - with_project do - generate "action web home#index --url=/" - - write "apps/web/assets/javascripts/app.css", <<~EOF - body { color: #333 }; - EOF - rewrite "apps/web/templates/app.html.erb", <<~EOF - - - - Web - <%= favicon %> - <%= stylesheet 'app' %> - - - <%= yield %> - - - EOF - - replace_last "apps/web/app.rb", "# scheme 'https'", "scheme 'https'" - replace "apps/web/app.rb", "# host 'cdn.example.org'", "host 'cdn.example.org'" - replace_last "apps/web/app.rb", "# port 443", "port 443" - - # - # Precompile - # - RSpec::Support::Env["HANAMI_ENV"] = "production" - RSpec::Support::Env["DATABASE_URL"] = "sqlite://#{Pathname.new('db').join('bookshelf.sqlite')}" - RSpec::Support::Env["SMTP_HOST"] = "localhost" - RSpec::Support::Env["SMTP_PORT"] = "25" - - hanami "assets precompile" - - server do - visit "/" - - expect(page.body).to include(%()) - end - end - end - end -end diff --git a/spec/integration/assets/fingerprint_spec.rb b/spec/integration/assets/fingerprint_spec.rb deleted file mode 100644 index 8ca35a75..00000000 --- a/spec/integration/assets/fingerprint_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "assets", type: :integration do - describe "fingerprint mode" do - it "servers assets with fingerprint url" do - with_project do - generate "action web home#index --url=/" - - write "apps/web/assets/javascripts/app.css", <<~EOF - body { color: #333 }; - EOF - rewrite "apps/web/templates/app.html.erb", <<~EOF - - - - Web - <%= favicon %> - <%= stylesheet 'app' %> - - - <%= yield %> - - - EOF - # - # Precompile - # - RSpec::Support::Env["HANAMI_ENV"] = "production" - RSpec::Support::Env["DATABASE_URL"] = "sqlite://#{Pathname.new('db').join('bookshelf.sqlite')}" - RSpec::Support::Env["SMTP_HOST"] = "localhost" - RSpec::Support::Env["SMTP_PORT"] = "25" - hanami "assets precompile" - - server do - visit "/" - - expect(page.body).to include(%()) - end - end - end - end -end diff --git a/spec/integration/assets/helpers_spec.rb b/spec/integration/assets/helpers_spec.rb deleted file mode 100644 index f06a46ff..00000000 --- a/spec/integration/assets/helpers_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "assets", type: :integration do - describe "helpers" do - it "renders assets tags" do - with_project do - generate "action web home#index --url=/" - - rewrite "apps/web/templates/app.html.erb", <<~EOF - - - - Web - <%= favicon %> - <%= stylesheet 'app' %> - - - <%= yield %> - <%= javascript 'app' %> - - - EOF - - rewrite "apps/web/templates/home/index.html.erb", <<~EOF - <%= image('app.jpg') %> - <%= video('movie.mp4') %> - <%= - video do - text "Your browser does not support the video tag" - source src: view.asset_path('movie.mp4'), type: 'video/mp4' - source src: view.asset_path('movie.ogg'), type: 'video/ogg' - end - %> - EOF - - server do - visit "/" - - expect(page.body).to include(%()) - expect(page.body).to include(%()) - expect(page.body).to include(%()) - - expect(page.body).to include(%(App)) - expect(page.body).to include(%()) - expect(page.body).to include(%()) - end - end - end - end -end diff --git a/spec/integration/assets/serve_spec.rb b/spec/integration/assets/serve_spec.rb deleted file mode 100644 index aaf6360f..00000000 --- a/spec/integration/assets/serve_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "assets", type: :integration do - describe "serve" do - it "compiles and serves assets in development mode" do - project = "bookshelf_serve_assets" - - with_project(project, gems: ['sassc']) do - generate "action web home#index --url=/" - - write "apps/web/assets/javascripts/app.css.sass", <<~EOF - $font-family: Helvetica, sans-serif - - body - font: 100% $font-family - EOF - rewrite "apps/web/templates/app.html.erb", <<~EOF - - - - Web - <%= favicon %> - <%= stylesheet 'app' %> - - - <%= yield %> - - - EOF - - server do - visit "/" - expect(page.body).to include(%()) - - visit "/assets/app.css" - expect(page.body).to include(%(body {\n font: 100% Helvetica, sans-serif; }\n)) - end - end - end - - it "serve assets with prefixes" do - with_project do - generate "action web home#index --url=/" - - replace( - "apps/web/app.rb", - "# Specify sources for assets", - "prefix '/library/assets'\n# Specify sources for assets" - ) - - replace( - "apps/web/config/routes.rb", - "/", - "namespace :library { get '/', to: 'home#index' }" - ) - - write "apps/web/assets/javascripts/app.js", <<~EOF - console.log('test'); - EOF - - hanami "assets precompile" - - server do - visit "/library/assets/app.js" - expect(page).to have_content("console.log('test');") - end - end - end - end -end diff --git a/spec/integration/assets/subresource_integrity_spec.rb b/spec/integration/assets/subresource_integrity_spec.rb deleted file mode 100644 index f52c3d2f..00000000 --- a/spec/integration/assets/subresource_integrity_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -require "json" - -RSpec.describe "assets", type: :integration do - describe "subresource integrity" do - it "precompiles assets with checksums calculated with given algorithms" do - with_project do - generate "action web home#index --url=/" - - write "apps/web/assets/javascripts/app.css", <<~EOF - body { font: Helvetica; } - EOF - rewrite "apps/web/templates/app.html.erb", <<~EOF - - - - Web - <%= favicon %> - <%= stylesheet 'app' %> - - - <%= yield %> - - - EOF - - replace "apps/web/app.rb", "subresource_integrity :sha256", "subresource_integrity :sha256, :sha512" - - # - # Precompile - # - RSpec::Support::Env["HANAMI_ENV"] = "production" - # FIXME: database connection shouldn't be required for `assets precompile` - RSpec::Support::Env["DATABASE_URL"] = "sqlite://#{Pathname.new('db').join('bookshelf.sqlite')}" - RSpec::Support::Env["SMTP_HOST"] = "localhost" - RSpec::Support::Env["SMTP_PORT"] = "25" - - hanami "assets precompile" - - manifest = File.read("public/assets.json") - expect(JSON.parse(manifest)).to be_kind_of(Hash) # assert it's a well-formed JSON - - expect(manifest).to include(%("/assets/app.css":{"target":"/assets/app-068e7d97b3671a14824bc20437ac5d06.css","sri":["sha256-cHgODQTP2nNk9ER+ViDGp+lC+ddHRmuLgJk05glJ4+w=","sha512-TDyxo1Ow7UjBib6ykALJh7J1OHEcE0yX4X21s1714ZBAhwdOz7k9t8+QQDAwWAmeH97bNaZGY7oTfVrwyTQ3cw=="]})) - expect(manifest).to include(%("/assets/favicon.ico":{"target":"/assets/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico","sri":["sha256-PLEDhpDsTBpxl1KtXjzBjg+PUG67zpf05B1z2db4iJU=","sha512-9NvaW7aVAywbLPPi3fw5s4wtWwd37i8VpzgfEo9uCOyr/mDT2dbYJtGNjfTJa4R8TOw69yHr4NhazPQsLt1WHw=="]})) - - server do - visit "/" - expect(page.body).to include(%()) - end - end - end - end -end diff --git a/spec/integration/body_parsers_spec.rb b/spec/integration/body_parsers_spec.rb deleted file mode 100644 index f2ccd808..00000000 --- a/spec/integration/body_parsers_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "body parsers", type: :integration do - it "parses JSON payload for non-GET requests" do - with_project do - generate_action - enable_json_body_parser - - server do - post "/books", %({"book": {"title": "CLI apps with Ruby"}}), "CONTENT_TYPE" => "app/json", "HTTP_ACCEPT" => "app/json" - expect(last_response.body).to eq(%({"book":{"title":"CLI apps with Ruby"}})) - end - end - end - - it "doesn't eval untrusted JSON" do - with_project do - generate_action - enable_json_body_parser - - server do - post "/books", %({"json_class": "Foo"}), "CONTENT_TYPE" => "app/json", "HTTP_ACCEPT" => "app/json" - expect(last_response.body).to eq(%({"json_class":"Foo"})) - end - end - end - - private - - def generate_action - generate "action web books#create --url=/books --method=POST" - - rewrite "apps/web/controllers/books/create.rb", <<~EOF - require 'hanami/utils/json' - module Web::Controllers::Books - class Create - include Web::Action - - def call(params) - self.body = Hanami::Utils::Json.generate(params.to_hash) - end - end - end - EOF - end - - def enable_json_body_parser - inject_line_after "apps/web/app.rb", "configure do", "body_parsers :json" - end -end diff --git a/spec/integration/cli/assets/precompile_spec.rb b/spec/integration/cli/assets/precompile_spec.rb deleted file mode 100644 index cff3bec0..00000000 --- a/spec/integration/cli/assets/precompile_spec.rb +++ /dev/null @@ -1,147 +0,0 @@ -# frozen_string_literal: true - -require "json" - -RSpec.describe "hanami assets", type: :integration do - describe "precompile" do - it "precompiles assets" do - gems = %w[sassc coffee-script] - - Platform.match do - os(:linux).engine(:ruby) { gems.push("therubyracer") } - os(:linux).engine(:jruby) { gems.push("therubyrhino") } - end - - with_project("bookshelf_assets_precompile", gems: gems) do - # - # Web assets - # - write "apps/web/assets/javascripts/app.js.coffee", <<~EOF - class App - constructor: () -> - @init = true - EOF - write "apps/web/assets/stylesheets/_colors.scss", <<~EOF - $background-color: #f5f5f5; - EOF - - write "apps/web/assets/stylesheets/app.css.scss", <<~EOF - @import 'colors'; - - body { - background-color: $background-color; - } - EOF - # - # Admin assets - # - generate "app admin" - write "apps/admin/assets/javascripts/dashboard.js.coffee", <<~EOF - class Dashboard - constructor: (@data) -> - EOF - - # - # Precompile - # - RSpec::Support::Env["HANAMI_ENV"] = "production" - hanami "assets precompile" - - # rubocop:disable Lint/ImplicitStringConcatenation - - # - # Verify manifest - # - manifest = retry_exec(Errno::ENOENT) do - File.read("public/assets.json") - end - - expect(JSON.parse(manifest)).to be_kind_of(Hash) # assert it's a well-formed JSON - - expect(manifest).to include(%("/assets/admin/dashboard.js":{"target":"/assets/admin/dashboard-39744f9626a70683b6c2d46305798883.js","sri":["sha256-1myPVWoqrq+uAVP2DSkmAown+5dm0x61+E3AjlGOKEc="]})) - expect(manifest).to include(%("/assets/admin/favicon.ico":{"target":"/assets/admin/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico","sri":["sha256-PLEDhpDsTBpxl1KtXjzBjg+PUG67zpf05B1z2db4iJU="]})) - expect(manifest).to include(%("/assets/app.css":{"target":"/assets/app-adb4104884aadde9abfef0bd98ac461e.css","sri":["sha256-S6V565W2In9pWE0uzMASpp58xCg32TN3at3Fv4g9aRA="]})) - expect(manifest).to include(%("/assets/app.js":{"target":"/assets/app-bb8f10498d83d401db238549409dc4c5.js","sri":["sha256-9m4OTbWigbDPp4oCe1LZz9isqidvW1c3jNL6mXMj2xs="]})) - expect(manifest).to include(%("/assets/favicon.ico":{"target":"/assets/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico","sri":["sha256-PLEDhpDsTBpxl1KtXjzBjg+PUG67zpf05B1z2db4iJU="]})) - - # - # Verify web assets (w/ checksum) - # - expect("public/assets/app-adb4104884aadde9abfef0bd98ac461e.css").to have_file_content <<~EOF - body {background-color: #f5f5f5} - EOF - - expect("public/assets/app-bb8f10498d83d401db238549409dc4c5.js").to have_file_content \ - """ -(function(){var App;App=(function(){function App(){this.init=true;} -return App;})();}).call(this); -""" - - expect("public/assets/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico").to be_an_existing_file - - # - # Verify web assets (w/o checksum) - # - expect("public/assets/app.css").to have_file_content <<~EOF - body {background-color: #f5f5f5} - EOF - - expect("public/assets/app.js").to have_file_content \ - """ -(function(){var App;App=(function(){function App(){this.init=true;} -return App;})();}).call(this); -""" - - expect("public/assets/favicon.ico").to be_an_existing_file - - # - # Verify admin assets (w/ checksum) - # - expect("public/assets/admin/dashboard-39744f9626a70683b6c2d46305798883.js").to have_file_content \ - """ -(function(){var Dashboard;Dashboard=(function(){function Dashboard(data){this.data=data;} -return Dashboard;})();}).call(this); -""" - - expect("public/assets/admin/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico").to be_an_existing_file - - # - # Verify admin assets (w/o checksum) - # - expect("public/assets/admin/dashboard.js").to have_file_content \ - """ -(function(){var Dashboard;Dashboard=(function(){function Dashboard(data){this.data=data;} -return Dashboard;})();}).call(this); -""" - - expect("public/assets/admin/favicon.ico").to be_an_existing_file - - # rubocop:enable Lint/ImplicitStringConcatenation - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami assets precompile - -Usage: - hanami assets precompile - -Description: - Precompile assets for deployment - -Options: - --help, -h # Print this help - -Examples: - hanami assets precompile # Basic usage - hanami assets precompile HANAMI_ENV=production # Precompile assets for production environment -OUT - - run_cmd "hanami assets precompile --help", output - end - end - end -end diff --git a/spec/integration/cli/assets_spec.rb b/spec/integration/cli/assets_spec.rb deleted file mode 100644 index 44c58b92..00000000 --- a/spec/integration/cli/assets_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami assets", type: :integration do - it "prints subcommands" do - with_project do - output = <<~OUT - Commands: - hanami assets precompile # Precompile assets for deployment - OUT - - run_cmd "hanami assets", output, exit_status: 1 - end - end -end diff --git a/spec/integration/cli/console_spec.rb b/spec/integration/cli/console_spec.rb deleted file mode 100644 index 73acd4d8..00000000 --- a/spec/integration/cli/console_spec.rb +++ /dev/null @@ -1,105 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami console", type: :integration do - context "irb" do - it "starts console" do - project_name = "bookshelf_console_irb" - with_project(project_name, console: :irb) do - setup_model - - console do |input, _, _| - input.puts("Hanami::VERSION") - input.puts("Web::App") - input.puts("Web.routes") - input.puts("BookRepository.new.all.to_a") - input.puts("exit") - end - - expect(out).to include(Hanami::VERSION) - expect(out).to include("Web::App") - expect(out).to include("#') - end - end - end # irb - - xit "returns error when known engine isn't bundled" do - with_project("bookshelf_console_irb", console: :irb) do - output = "Missing gem for `pry' console engine. Please make sure to add it to `Gemfile'." - run_cmd "hanami console --engine=pry", output, exit_status: 1 - end - end - - it "returns error when unknown engine is requested" do - with_project("bookshelf_console_irb", console: :irb) do - output = "Unknown console engine: `foo'." - run_cmd "hanami console --engine=foo", output, exit_status: 1 - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami console - -Usage: - hanami console - -Description: - Starts Hanami console - -Options: - --engine=VALUE # Force a specific console engine: (pry/ripl/irb) - --help, -h # Print this help - -Examples: - hanami console # Uses the bundled engine - hanami console --engine=pry # Force to use Pry -OUT - - run_cmd "hanami console --help", output - end - end - - # TODO: test with pry - # TODO: test with ripl -end diff --git a/spec/integration/cli/db/apply_spec.rb b/spec/integration/cli/db/apply_spec.rb deleted file mode 100644 index 9bb75279..00000000 --- a/spec/integration/cli/db/apply_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - describe "apply" do - it "migrates, dumps structure, deletes migrations", if: RUBY_VERSION < '2.4' do - with_project do - versions = generate_migrations - - hanami "db apply" - - hanami "db version" - expect(out).to include(versions.last.to_s) - - db = Pathname.new("db") - schema = db.join("schema.sql").to_s - migrations = db.join("migrations") - - expect(schema).to have_file_content <<~SQL - CREATE TABLE `schema_migrations` (`filename` varchar(255) NOT NULL PRIMARY KEY); - CREATE TABLE `users` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, `name` varchar(255), `age` integer); - INSERT INTO "schema_migrations" VALUES('#{versions.first}_create_users.rb'); - INSERT INTO "schema_migrations" VALUES('#{versions.last}_add_age_to_users.rb'); - SQL - - expect(migrations.children).to be_empty - end - end - - it "migrates, dumps structure, deletes migrations", if: RUBY_VERSION >= '2.4' do - with_project do - versions = generate_migrations - - hanami "db apply" - - hanami "db version" - expect(out).to include(versions.last.to_s) - - db = Pathname.new('db') - schema = db.join('schema.sql').to_s - migrations = db.join('migrations') - - expect(schema).to have_file_content <<-SQL -CREATE TABLE `schema_migrations` (`filename` varchar(255) NOT NULL PRIMARY KEY); -CREATE TABLE `users` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, `name` varchar(255), `age` integer); -CREATE TABLE sqlite_sequence(name,seq); -INSERT INTO schema_migrations VALUES('#{versions.first}_create_users.rb'); -INSERT INTO schema_migrations VALUES('#{versions.last}_add_age_to_users.rb'); -SQL - - expect(migrations.children).to be_empty - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami db apply - -Usage: - hanami db apply - -Description: - Migrate, dump the SQL schema, and delete the migrations (experimental) - -Options: - --help, -h # Print this help -OUT - - run_cmd "hanami db apply --help", output - end - end - end -end diff --git a/spec/integration/cli/db/console_spec.rb b/spec/integration/cli/db/console_spec.rb deleted file mode 100644 index b5e86199..00000000 --- a/spec/integration/cli/db/console_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - describe "console" do - it "starts database console" do - with_project do - generate_migrations - hanami "db prepare" - - db_console do |input, _, _| - input.puts('INSERT INTO users (id, name, age) VALUES(1, "Luca", 34);') - input.puts("SELECT * FROM users;") - input.puts(".quit") - end - - expect(out).to include("1|Luca|34") - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami db console - -Usage: - hanami db console - -Description: - Starts a database console - -Options: - --help, -h # Print this help -OUT - - run_cmd "hanami db console --help", output - end - end - end -end diff --git a/spec/integration/cli/db/create_spec.rb b/spec/integration/cli/db/create_spec.rb deleted file mode 100644 index b01feb8e..00000000 --- a/spec/integration/cli/db/create_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - describe "create" do - it "creates database" do - project = "bookshelf_db_create" - - with_project(project) do - hanami "db create" - - db = Pathname.new("db").join("#{project}_development.sqlite").to_s - expect(db).to be_an_existing_file - end - end - - it "doesn't create in production" do - project = "bookshelf_db_create_production" - - with_project(project) do - RSpec::Support::Env["HANAMI_ENV"] = "production" - hanami "db create" - - expect(exitstatus).to eq(1) - - db = Pathname.new("db").join("#{project}.sqlite").to_s - expect(db).to_not be_an_existing_file - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami db create - -Usage: - hanami db create - -Description: - Create the database (only for development/test) - -Options: - --help, -h # Print this help -OUT - - run_cmd 'hanami db create --help', output - end - end - end -end diff --git a/spec/integration/cli/db/drop_spec.rb b/spec/integration/cli/db/drop_spec.rb deleted file mode 100644 index cfbe8a30..00000000 --- a/spec/integration/cli/db/drop_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - describe "drop" do - it "drops database" do - project = "bookshelf_db_drop" - - with_project(project) do - db = Pathname.new("db").join("#{project}_development.sqlite").to_s - - hanami "db create" - expect(db).to be_an_existing_file - - hanami "db drop" - expect(db).to_not be_an_existing_file - end - end - - it "doesn't drop in production" do - project = "bookshelf_db_drop_production" - - with_project(project) do - RSpec::Support::Env["HANAMI_ENV"] = "production" - db = Pathname.new("db").join("#{project}.sqlite").to_s - FileUtils.touch(db) # simulate existing database - - hanami "db drop" - - expect(exitstatus).to eq(1) - expect(db).to be_an_existing_file - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami db drop - -Usage: - hanami db drop - -Description: - Drop the database (only for development/test) - -Options: - --help, -h # Print this help -OUT - - run_cmd 'hanami db drop --help', output - end - end - end -end diff --git a/spec/integration/cli/db/migrate_spec.rb b/spec/integration/cli/db/migrate_spec.rb deleted file mode 100644 index 53ec36a3..00000000 --- a/spec/integration/cli/db/migrate_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - describe "migrate" do - it "migrates database" do - project = "bookshelf_db_migrate" - - with_project(project) do - generate_migrations - - hanami "db create" - hanami "db migrate" - - db = Pathname.new("db").join("#{project}_development.sqlite") - - users = `sqlite3 #{db} ".schema users"` - expect(users).to include("CREATE TABLE `users` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, `name` varchar(255), `age` integer);") - - version = `sqlite3 #{db} "SELECT filename FROM schema_migrations ORDER BY filename DESC LIMIT 1"` - expect(version).to include("add_age_to_users") - end - end - - it "migrates database up to a version" do - project = "bookshelf_db_migrate_up_to_version" - - with_project(project) do - versions = generate_migrations - - hanami "db create" - hanami "db migrate #{versions.first}" - - db = Pathname.new("db").join("#{project}_development.sqlite") - - users = `sqlite3 #{db} ".schema users"` - expect(users).to include("CREATE TABLE `users` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, `name` varchar(255));") - - version = `sqlite3 #{db} "SELECT filename FROM schema_migrations ORDER BY filename DESC LIMIT 1"` - expect(version).to include("create_users") - end - end - - it "migrates database down to a version" do - project = "bookshelf_db_migrate_down_to_version" - - with_project(project) do - versions = generate_migrations - - hanami "db create" - hanami "db migrate" # up to latest version - hanami "db migrate #{versions.first}" - - db = Pathname.new("db").join("#{project}_development.sqlite") - - users = `sqlite3 #{db} ".schema users"` - expect(users).to include("CREATE TABLE `users`(`id` integer DEFAULT (NULL) NOT NULL PRIMARY KEY AUTOINCREMENT, `name` varchar(255) DEFAULT (NULL) NULL);") - - version = `sqlite3 #{db} "SELECT filename FROM schema_migrations ORDER BY filename DESC LIMIT 1"` - expect(version).to include("create_users") - end - end - - it "migrates database down to 0" do - project = "bookshelf_db_migrate_down_to_zero" - - with_project(project) do - generate_migrations - - hanami "db create" - hanami "db migrate" # up to latest version - hanami "db migrate 0" - - db = Pathname.new("db").join("#{project}_development.sqlite") - - users = `sqlite3 #{db} ".schema users"` - expect(users).to eq("") - - version = `sqlite3 #{db} "SELECT filename FROM schema_migrations ORDER BY filename DESC LIMIT 1"` - expect(version).to eq("") - end - end - - it "prints help message" do - with_project do - banner = <<~OUT -Command: - hanami db drop - -Usage: - hanami db drop - -Description: - Drop the database (only for development/test) - -Options: - --help, -h # Print this help -OUT - - output = [ - banner, - # %r{ hanami db migrate [\d]{14} # Migrate to a specific version} - ] - - run_cmd 'hanami db drop --help', output - end - end - end -end diff --git a/spec/integration/cli/db/prepare_spec.rb b/spec/integration/cli/db/prepare_spec.rb deleted file mode 100644 index 7ef84c29..00000000 --- a/spec/integration/cli/db/prepare_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - describe "prepare" do - it "prepares database" do - with_project do - versions = generate_migrations - - hanami "db prepare" - hanami "db version" - - expect(out).to include(versions.last.to_s) - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami db prepare - -Usage: - hanami db prepare - -Description: - Drop, create, and migrate the database (only for development/test) - -Options: - --help, -h # Print this help -OUT - - run_cmd 'hanami db prepare --help', output - end - end - end -end diff --git a/spec/integration/cli/db/rollback_spec.rb b/spec/integration/cli/db/rollback_spec.rb deleted file mode 100644 index 57663adf..00000000 --- a/spec/integration/cli/db/rollback_spec.rb +++ /dev/null @@ -1,96 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - describe "rollback" do - it "rollbacks database" do - project = "bookshelf_db_rollback" - - with_project(project) do - generate_migrations - - hanami "db create" - hanami "db migrate" - hanami "db rollback" - - db = Pathname.new("db").join("#{project}_development.sqlite") - - users = `sqlite3 #{db} ".schema users"` - expect(users).to include("CREATE TABLE `users`(`id` integer DEFAULT (NULL) NOT NULL PRIMARY KEY AUTOINCREMENT, `name` varchar(255) DEFAULT (NULL) NULL);") - - version = `sqlite3 #{db} "SELECT filename FROM schema_migrations ORDER BY filename DESC LIMIT 1"` - expect(version).to_not include("add_age_to_users") - end - end - - it "rollbacks database using custom steps" do - project = "bookshelf_db_migrate_custom_steps" - - with_project(project) do - generate_migrations - - hanami "db create" - hanami "db migrate" - hanami "db rollback 2" - - db = Pathname.new("db").join("#{project}_development.sqlite") - - users = `sqlite3 #{db} ".schema users"` - expect(users).to_not include("CREATE TABLE `users`(`id` integer DEFAULT (NULL) NOT NULL PRIMARY KEY AUTOINCREMENT, `name` varchar(255) DEFAULT (NULL) NULL);") - - version = `sqlite3 #{db} "SELECT filename FROM schema_migrations ORDER BY filename DESC LIMIT 1"` - expect(version).to_not include("create_users") - end - end - - it "returns an error when steps isn't an integer" do - with_project do - generate_migrations - - hanami "db create" - hanami "db migrate" - - output = "the number of steps must be a positive integer (you entered `quindici')." - run_cmd "hanami db rollback quindici", output, exit_status: 1 - end - end - - it "returns an error when steps is 0" do - with_project do - generate_migrations - - hanami "db create" - hanami "db migrate" - - output = "the number of steps must be a positive integer (you entered `0')." - run_cmd "hanami db rollback 0", output, exit_status: 1 - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami db rollback - -Usage: - hanami db rollback [STEPS] - -Description: - Rollback migrations - -Arguments: - STEPS # Number of steps to rollback the database - -Options: - --help, -h # Print this help - -Examples: - hanami db rollback # Rollbacks latest migration - hanami db rollback 2 # Rollbacks last two migration -OUT - - run_cmd 'hanami db rollback --help', output - end - end - end -end diff --git a/spec/integration/cli/db/version_spec.rb b/spec/integration/cli/db/version_spec.rb deleted file mode 100644 index 1040fb7e..00000000 --- a/spec/integration/cli/db/version_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - describe "version" do - it "prints database version" do - with_project do - versions = generate_migrations - - hanami "db create" - hanami "db migrate" - hanami "db version" - - expect(out).to include(versions.last.to_s) - expect(out).to_not include("SELECT * FROM") - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami db version - -Usage: - hanami db version - -Description: - Print the current migrated version - -Options: - --help, -h # Print this help -OUT - - run_cmd 'hanami db version --help', output - end - end - end -end diff --git a/spec/integration/cli/db_spec.rb b/spec/integration/cli/db_spec.rb deleted file mode 100644 index 1e8af138..00000000 --- a/spec/integration/cli/db_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami db", type: :integration do - it "prints subcommands" do - with_project do - output = <<~OUT - Commands: - hanami db apply # Migrate, dump the SQL schema, and delete the migrations (experimental) - hanami db console # Starts a database console - hanami db create # Create the database (only for development/test) - hanami db drop # Drop the database (only for development/test) - hanami db migrate [VERSION] # Migrate the database - hanami db prepare # Drop, create, and migrate the database (only for development/test) - hanami db rollback [STEPS] # Rollback migrations - hanami db version # Print the current migrated version - OUT - - run_cmd "hanami db", output, exit_status: 1 - end - end -end diff --git a/spec/integration/cli/destroy/action_spec.rb b/spec/integration/cli/destroy/action_spec.rb deleted file mode 100644 index ec4e6f20..00000000 --- a/spec/integration/cli/destroy/action_spec.rb +++ /dev/null @@ -1,143 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami destroy", type: :integration do - describe "action" do - it "destroys action" do - with_project do - generate "action web books#index" - output = [ - "subtract apps/web/config/routes.rb", - "remove spec/web/views/books/index_spec.rb", - "remove apps/web/templates/books/index.html.erb", - "remove apps/web/views/books/index.rb", - "remove apps/web/controllers/books/index.rb", - "remove spec/web/controllers/books/index_spec.rb" - ] - - run_cmd "hanami destroy action web books#index", output - - expect("spec/web/controllers/books/index_spec.rb").to_not be_an_existing_file - expect("apps/web/controllers/books/index.rb").to_not be_an_existing_file - expect("apps/web/views/books/index.rb").to_not be_an_existing_file - expect("apps/web/templates/books/index.html.erb").to_not be_an_existing_file - expect("spec/web/views/books/index_spec.rb").to_not be_an_existing_file - - expect("apps/web/config/routes.rb").to_not have_file_content(%r{get '/books', to: 'books#index'}) - end - end - - it "destroys namespaced action" do - with_project do - generate "action web api/books#index" - output = [ - "subtract apps/web/config/routes.rb", - "remove spec/web/views/api/books/index_spec.rb", - "remove apps/web/templates/api/books/index.html.erb", - "remove apps/web/views/api/books/index.rb", - "remove apps/web/controllers/api/books/index.rb", - "remove spec/web/controllers/api/books/index_spec.rb" - ] - - run_cmd "hanami destroy action web api/books#index", output - - expect("spec/web/controllers/api/books/index_spec.rb").to_not be_an_existing_file - expect("apps/web/controllers/api/books/index.rb").to_not be_an_existing_file - expect("apps/web/views/api/books/index.rb").to_not be_an_existing_file - expect("apps/web/templates/api/books/index.html.erb").to_not be_an_existing_file - expect("spec/web/views/api/books/index_spec.rb").to_not be_an_existing_file - - expect("apps/web/config/routes.rb").to_not have_file_content(%r{get '/api/books', to: 'api/books#index'}) - end - end - - it "destroys action without view" do - with_project do - generate "action web home#ping --skip-view --url=/ping" - output = [ - "subtract apps/web/config/routes.rb", - "remove apps/web/controllers/home/ping.rb", - "remove spec/web/controllers/home/ping_spec.rb" - ] - - run_cmd "hanami destroy action web home#ping", output - - expect("spec/web/controllers/home/ping_spec.rb").to_not be_an_existing_file - expect("apps/web/controllers/home/ping.rb").to_not be_an_existing_file - expect("apps/web/views/home/ping.rb").to_not be_an_existing_file - expect("apps/web/templates/home/ping.html.erb").to_not be_an_existing_file - expect("spec/web/views/home/ping_spec.rb").to_not be_an_existing_file - - expect("apps/web/config/routes.rb").to_not have_file_content(%r{get '/ping', to: 'home#ping'}) - end - end - - it "fails with missing arguments" do - with_project do - output = <<~OUT - ERROR: "hanami destroy action" was called with no arguments - Usage: "hanami destroy action APP ACTION" - OUT - - run_cmd "hanami destroy action", output, exit_status: 1 - end - end - - it "fails with missing app" do - with_project("bookshelf_generate_action_without_app") do - output = <<~OUT - ERROR: "hanami destroy action" was called with arguments ["home#index"] - Usage: "hanami destroy action APP ACTION" - OUT - - run_cmd "hanami destroy action home#index", output, exit_status: 1 - end - end - - it "fails with unknown app" do - with_project("bookshelf_generate_action_with_unknown_app") do - output = "`foo' is not a valid APP. Please specify one of: `web'" - - run_cmd "hanami destroy action foo home#index", output, exit_status: 1 - end - end - - it "fails with unknown action" do - with_project("bookshelf_generate_action_with_unknown_action") do - output = <<~OUT - cannot find `home#index' in `web' app. - please run `hanami routes' to know the existing actions. - OUT - - run_cmd "hanami destroy action web home#index", output, exit_status: 1 - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami destroy action - -Usage: - hanami destroy action APP ACTION - -Description: - Destroy an action from app - -Arguments: - APP # REQUIRED The app name (eg. `web`) - ACTION # REQUIRED The action name (eg. `home#index`) - -Options: - --help, -h # Print this help - -Examples: - hanami destroy action web home#index # Basic usage - hanami destroy action admin users#index # Destroy from `admin` app -OUT - - run_cmd 'hanami destroy action --help', output - end - end - end # action -end diff --git a/spec/integration/cli/destroy/app_spec.rb b/spec/integration/cli/destroy/app_spec.rb deleted file mode 100644 index 83297049..00000000 --- a/spec/integration/cli/destroy/app_spec.rb +++ /dev/null @@ -1,118 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami destroy", type: :integration do - describe "app" do - it "destroys app" do - with_project do - generate "app admin" - - output = [ - "subtract .env.test", - "subtract .env.development", - "subtract config/environment.rb", - "subtract config/environment.rb", - "remove spec/admin", - "remove apps/admin" - ] - - run_cmd "hanami destroy app admin", output - - expect(".env.test").to_not have_file_content(%r{ADMIN_SESSIONS_SECRET}) - expect(".env.development").to_not have_file_content(%r{ADMIN_SESSIONS_SECRET}) - - expect("config/environment.rb").to_not have_file_content(%r{mount Admin::App}) - expect("config/environment.rb").to_not have_file_content("require_relative '../apps/admin/app'") - - expect("public/assets/admin").to_not be_an_existing_path - expect("public/assets.json").to_not be_an_existing_path - - expect("spec/admin").to_not be_an_existing_path - expect("apps/admin").to_not be_an_existing_path - end - end - - it "destroys app with actions and assets" do - with_project do - generate "app api --app-base-url=/api/v1" - generate "action api home#index" - - asset = File.join("apps", "api", "assets", "javascripts", "app.js") - touch asset - - hanami "assets precompile" - - output = [ - "subtract .env.test", - "subtract .env.development", - "subtract config/environment.rb", - "subtract config/environment.rb", - "remove public/assets/api/v1", - "remove public/assets.json", - "remove spec/api", - "remove apps/api" - ] - - run_cmd "hanami destroy app api", output - - expect(".env.test").to_not have_file_content(%r{API_SESSIONS_SECRET}) - expect(".env.development").to_not have_file_content(%r{API_SESSIONS_SECRET}) - - expect("config/environment.rb").to_not have_file_content(%r{mount Api::App}) - expect("config/environment.rb").to_not have_file_content("require_relative '../apps/api/app'") - - expect("public/assets/api/v1").to_not be_an_existing_path - expect("public/assets.json").to_not be_an_existing_path - - expect("spec/api").to_not be_an_existing_path - expect("apps/api").to_not be_an_existing_path - end - end - - it "fails with missing argument" do - with_project do - output = <<-OUT -ERROR: "hanami destroy app" was called with no arguments -Usage: "hanami destroy app APP" -OUT - - run_cmd "hanami destroy app", output, exit_status: 1 - end - end - - it "fails with unknown app" do - with_project do - output = <<-OUT -`unknown' is not a valid APP. Please specify one of: `web' -OUT - - run_cmd "hanami destroy app unknown", output, exit_status: 1 - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami destroy app - -Usage: - hanami destroy app APP - -Description: - Destroy an app - -Arguments: - APP # REQUIRED The app name (eg. `web`) - -Options: - --help, -h # Print this help - -Examples: - hanami destroy app admin # Destroy `admin` app -OUT - - run_cmd 'hanami destroy app --help', output - end - end - end # app -end diff --git a/spec/integration/cli/destroy/mailer_spec.rb b/spec/integration/cli/destroy/mailer_spec.rb deleted file mode 100644 index 9290106b..00000000 --- a/spec/integration/cli/destroy/mailer_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami destroy", type: :integration do - describe "mailer" do - context "destroy a mailer" do - let(:output) do - ["remove spec/bookshelf_generate_mailer/mailers/welcome_spec.rb", - "remove lib/bookshelf_generate_mailer/mailers/templates/welcome.html.erb", - "remove lib/bookshelf_generate_mailer/mailers/templates/welcome.txt.erb", - "remove lib/bookshelf_generate_mailer/mailers/welcome.rb"] - end - - it "generate the mailer files" do - with_project("bookshelf_generate_mailer", test: "rspec") do - generate "mailer welcome" - - run_cmd "hanami destroy mailer welcome", output - - expect("spec/bookshelf_generate_mailer/mailers/welcome_spec.rb").to_not be_an_existing_file - expect("lib/bookshelf_generate_mailer/mailers/templates/welcome.html.erb").to_not be_an_existing_file - expect("lib/bookshelf_generate_mailer/mailers/templates/welcome.txt.erb").to_not be_an_existing_file - expect("lib/bookshelf_generate_mailer/mailers/welcome.rb").to_not be_an_existing_file - end - end - end - - it "fails with missing arguments" do - with_project("bookshelf_generate_mailer_without_args") do - output = <<~OUT - ERROR: "hanami generate mailer" was called with no arguments - Usage: "hanami generate mailer MAILER" - OUT - - run_cmd "hanami generate mailer", output, exit_status: 1 - end - end - - it "fails with unknown mailer" do - with_project do - output = <<~OUT - cannot find `unknown' mailer. Please have a look at `lib/bookshelf/mailers' directory to find an existing mailer. - OUT - - run_cmd "hanami destroy mailer unknown", output, exit_status: 1 - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami destroy mailer - -Usage: - hanami destroy mailer MAILER - -Description: - Destroy a mailer - -Arguments: - MAILER # REQUIRED The mailer name (eg. `welcome`) - -Options: - --help, -h # Print this help - -Examples: - hanami destroy mailer welcome # Destroy `WelcomeMailer` mailer -OUT - - run_cmd 'hanami destroy mailer --help', output - end - end - end -end diff --git a/spec/integration/cli/destroy/migration_spec.rb b/spec/integration/cli/destroy/migration_spec.rb deleted file mode 100644 index 24bd35be..00000000 --- a/spec/integration/cli/destroy/migration_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -require "pathname" - -RSpec.describe "hanami destroy", type: :integration do - describe "migration" do - it "destroys migration" do - with_project do - migration = Pathname.new("db").join("migrations", "20170127165331_create_users.rb").to_s - File.open(migration, "wb+") { |f| f.write("migration") } - - output = [ - "remove #{migration}" - ] - - run_cmd "hanami destroy migration create_users", output - - expect(migration).to_not be_an_existing_file - end - end - - it "fails with missing argument" do - with_project do - output = <<~OUT - ERROR: "hanami destroy migration" was called with no arguments - Usage: "hanami destroy migration MIGRATION" - OUT - run_command "hanami destroy migration", output, exit_status: 1 - end - end - - it "fails with unknown migration" do - with_project do - output = <<~OUT - cannot find `create_unknowns'. Please have a look at `db/migrations' directory to find an existing migration - OUT - run_command "hanami destroy migration create_unknowns", output, exit_status: 1 - end - end - - it "prints help message" do - with_project do - banner = <<~OUT -Command: - hanami destroy migration - -Usage: - hanami destroy migration MIGRATION - -Description: - Destroy a migration - -Arguments: - MIGRATION # REQUIRED The migration name (eg. `create_users`) - -Options: - --help, -h # Print this help - -Examples: -OUT - output = [ - banner, - %r{ hanami destroy migration create_users # Destroy `db/migrations/[\d]{14}_create_users.rb`} - ] - - run_command "hanami destroy migration --help", output - end - end - end # migration -end diff --git a/spec/integration/cli/destroy/model_spec.rb b/spec/integration/cli/destroy/model_spec.rb deleted file mode 100644 index 950ffe0f..00000000 --- a/spec/integration/cli/destroy/model_spec.rb +++ /dev/null @@ -1,113 +0,0 @@ -# frozen_string_literal: true - -require "pathname" - -RSpec.describe "hanami destroy", type: :integration do - describe "model" do - it "destroys model" do - with_project do - generate "model user" - migration = Dir.glob(Pathname.new("db").join("migrations", "*_create_users.rb")).first.to_s - - output = [ - "remove spec/bookshelf/repositories/user_repository_spec.rb", - "remove spec/bookshelf/entities/user_spec.rb", - "remove lib/bookshelf/repositories/user_repository.rb", - "remove lib/bookshelf/entities/user.rb" - ] - - run_cmd "hanami destroy model user", output - - expect(migration).to be_an_existing_file - - expect("lib/bookshelf/entities/user.rb").to_not be_an_existing_file - expect("lib/bookshelf/repositories/user_repository.rb").to_not be_an_existing_file - expect("spec/bookshelf/entities/user_spec.rb").to_not be_an_existing_file - expect("spec/bookshelf/repositories/user_repository_spec.rb").to_not be_an_existing_file - end - end - - it "destroys model even if migration was deleted manually" do - with_project do - generate "model user" - migration = Dir.glob(Pathname.new("db").join("migrations", "*_create_users.rb")).first.to_s - - run_simple "rm #{migration}" - - expect(migration).to_not be_an_existing_file - - output = [ - "remove spec/bookshelf/repositories/user_repository_spec.rb", - "remove spec/bookshelf/entities/user_spec.rb", - "remove lib/bookshelf/repositories/user_repository.rb", - "remove lib/bookshelf/entities/user.rb" - ] - - run_cmd "hanami destroy model user", output - end - end - - it "fails with missing argument" do - with_project do - output = <<~OUT - ERROR: "hanami destroy model" was called with no arguments - Usage: "hanami destroy model MODEL" - OUT - - run_cmd "hanami destroy model", output, exit_status: 1 - end - end - - xit "prints help message" do - with_project do - output = <<~OUT - Usage: - hanami destroy model NAME - - Description: - `hanami destroy model` will destroy an entity along with repository and \n corresponding tests - - > $ hanami destroy model car - OUT - - run_cmd 'hanami destroy model --help', output - end - end - - it "fails with unknown model" do - with_project do - output = <<~OUT - cannot find `unknown' model. Please have a look at `lib/bookshelf/entities' directory to find an existing model. - OUT - - run_cmd "hanami destroy model unknown", output, exit_status: 1 - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami destroy model - -Usage: - hanami destroy model MODEL - -Description: - Destroy a model - -Arguments: - MODEL # REQUIRED The model name (eg. `user`) - -Options: - --help, -h # Print this help - -Examples: - hanami destroy model user # Destroy `User` entity and `UserRepository` repository -OUT - - run_cmd 'hanami destroy model --help', output - end - end - end # model -end diff --git a/spec/integration/cli/destroy_spec.rb b/spec/integration/cli/destroy_spec.rb deleted file mode 100644 index 08551935..00000000 --- a/spec/integration/cli/destroy_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami destroy", type: :integration do - it "prints subcommands" do - with_project do - output = <<~OUT - Commands: - hanami destroy action APP ACTION # Destroy an action from app - hanami destroy app APP # Destroy an app - hanami destroy mailer MAILER # Destroy a mailer - hanami destroy migration MIGRATION # Destroy a migration - hanami destroy model MODEL # Destroy a model - OUT - - run_cmd "hanami destroy", output, exit_status: 1 - end - end -end diff --git a/spec/integration/cli/generate/action_spec.rb b/spec/integration/cli/generate/action_spec.rb deleted file mode 100644 index aa867ba4..00000000 --- a/spec/integration/cli/generate/action_spec.rb +++ /dev/null @@ -1,469 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami generate", type: :integration do - describe "action" do - it "generates action" do - with_project("bookshelf_generate_action") do - output = [ - "create spec/web/controllers/authors/index_spec.rb", - "create apps/web/controllers/authors/index.rb", - "create apps/web/views/authors/index.rb", - "create apps/web/templates/authors/index.html.erb", - "create spec/web/views/authors/index_spec.rb", - "insert apps/web/config/routes.rb" - ] - - run_cmd "hanami generate action web authors#index", output - - # - # apps/web/controllers/authors/index.rb - # - expect("apps/web/controllers/authors/index.rb").to have_file_content <<~END - module Web - module Controllers - module Authors - class Index - include Web::Action - - def call(params) - end - end - end - end - end - END - - # - # apps/web/views/authors/index.rb - # - expect("apps/web/views/authors/index.rb").to have_file_content <<~END - module Web - module Views - module Authors - class Index - include Web::View - end - end - end - end - END - - # - # apps/web/config/routes.rb - # - expect("apps/web/config/routes.rb").to have_file_content(%r{get '/authors', to: 'authors#index'}) - end - end - - it "generates namespaced action" do - with_project("bookshelf_generate_action") do - output = [ - "create spec/web/controllers/api/authors/index_spec.rb", - "create apps/web/controllers/api/authors/index.rb", - "create apps/web/views/api/authors/index.rb", - "create apps/web/templates/api/authors/index.html.erb", - "create spec/web/views/api/authors/index_spec.rb", - "insert apps/web/config/routes.rb" - ] - - run_cmd "hanami generate action web api/authors#index", output - - # - # apps/web/controllers/api/authors/index.rb - # - expect("apps/web/controllers/api/authors/index.rb").to have_file_content <<~END - module Web - module Controllers - module Api - module Authors - class Index - include Web::Action - - def call(params) - end - end - end - end - end - end - END - - # - # apps/web/views/api/authors/index.rb - # - expect("apps/web/views/api/authors/index.rb").to have_file_content <<~END - module Web - module Views - module Api - module Authors - class Index - include Web::View - end - end - end - end - end - END - - # - # apps/web/config/routes.rb - # - expect("apps/web/config/routes.rb").to have_file_content(%r{get '/api/authors', to: 'api/authors#index'}) - end - end - - it "generates non-RESTful actions" do - with_project do - run_cmd "hanami generate action web sessions#sign_out" - - # - # apps/web/config/routes.rb - # - expect("apps/web/config/routes.rb").to have_file_content(%r{get '/sessions/sign_out', to: 'sessions#sign_out'}) - end - end - - it "fails with missing arguments" do - with_project("bookshelf_generate_action_without_args") do - output = <<~OUT - ERROR: "hanami generate action" was called with no arguments - Usage: "hanami generate action APP ACTION" - OUT - run_cmd "hanami generate action", output, exit_status: 1 - end - end - - it "fails with missing app" do - with_project("bookshelf_generate_action_without_app") do - output = <<~OUT - ERROR: "hanami generate action" was called with arguments ["home#index"] - Usage: "hanami generate action APP ACTION" - OUT - - run_cmd "hanami generate action home#index", output, exit_status: 1 - end - end - - it "fails with unknown app" do - with_project("bookshelf_generate_action_with_unknown_app") do - output = "`foo' is not a valid APP. Please specify one of: `web'" - - run_cmd "hanami generate action foo home#index", output, exit_status: 1 - end - end - - context "--url" do - it "generates action" do - with_project("bookshelf_generate_action_url") do - output = [ - "insert apps/web/config/routes.rb" - ] - - run_cmd "hanami generate action web home#index --url=/", output - - # - # apps/web/config/routes.rb - # - expect("apps/web/config/routes.rb").to have_file_content(%r{get '/', to: 'home#index'}) - end - end - - it "fails with missing argument" do - with_project("bookshelf_generate_action_missing_url") do - output = "`' is not a valid URL" - run_cmd "hanami generate action web books#create --url=", output, exit_status: 1 - end - end - end - - context "--skip-view" do - it "generates action" do - with_project("bookshelf_generate_action_skip_view") do - output = [ - "create apps/web/controllers/status/check.rb", - "create spec/web/controllers/status/check_spec.rb", - "insert apps/web/config/routes.rb" - ] - run_cmd "hanami generate action web status#check --skip-view", output - - # - # apps/web/controllers/status/check.rb - # - expect("apps/web/controllers/status/check.rb").to have_file_content <<~END - module Web - module Controllers - module Status - class Check - include Web::Action - - def call(params) - self.body = 'OK' - end - end - end - end - end - END - end - end - - it "generates namespaced action" do - with_project("bookshelf_generate_action_skip_view") do - output = [ - "create apps/web/controllers/api/authors/index.rb", - "create spec/web/controllers/api/authors/index_spec.rb", - "insert apps/web/config/routes.rb" - ] - run_cmd "hanami generate action web api/authors#index --skip-view", output - - # - # apps/web/controllers/status/check.rb - # - expect("apps/web/controllers/api/authors/index.rb").to have_file_content <<~END - module Web - module Controllers - module Api - module Authors - class Index - include Web::Action - - def call(params) - self.body = 'OK' - end - end - end - end - end - end - END - end - end - end - - context "--method" do - it "generates action" do - with_project("bookshelf_generate_action_method") do - output = [ - "insert apps/web/config/routes.rb" - ] - - run_cmd "hanami generate action web books#create --method=POST", output - - # - # apps/web/config/routes.rb - # - expect("apps/web/config/routes.rb").to have_file_content(%r{post '/books', to: 'books#create'}) - end - end - - it "fails with missing argument" do - with_project("bookshelf_generate_action_missing_method") do - output = "`' is not a valid HTTP method. Please use one of: `GET' `POST' `PUT' `DELETE' `HEAD' `OPTIONS' `TRACE' `PATCH' `OPTIONS' `LINK' `UNLINK'" - run_cmd "hanami generate action web books#create --method=", output, exit_status: 1 - end - end - - it "fails with unknown argument" do - with_project('bookshelf_generate_action_unknown_method') do - output = "`FOO' is not a valid HTTP method. Please use one of: `GET' `POST' `PUT' `DELETE' `HEAD' `OPTIONS' `TRACE' `PATCH' `OPTIONS' `LINK' `UNLINK'" - run_cmd "hanami generate action web books#create --method=FOO", output, exit_status: 1 - end - end - end - - context "erb" do - it "generates action" do - with_project("bookshelf_generate_action_erb", template: "erb") do - output = [ - "create apps/web/templates/books/index.html.erb" - ] - - run_cmd "hanami generate action web books#index", output - - # - # apps/web/templates/books/index.html.erb - # - expect("apps/web/templates/books/index.html.erb").to have_file_content <<~END - END - - # - # spec/web/views/books/index_spec.rb - # - expect("spec/web/views/books/index_spec.rb").to have_file_content %r{'apps/web/templates/books/index.html.erb'} - end - end - end # erb - - context "haml" do - it "generates action" do - with_project("bookshelf_generate_action_haml", template: "haml") do - output = [ - "create apps/web/templates/books/index.html.haml" - ] - - run_cmd "hanami generate action web books#index", output - - # - # apps/web/templates/books/index.html.haml - # - expect("apps/web/templates/books/index.html.haml").to have_file_content <<~END - END - - # - # spec/web/views/books/index_spec.rb - # - expect("spec/web/views/books/index_spec.rb").to have_file_content(%r{'apps/web/templates/books/index.html.haml'}) - end - end - end # haml - - context "slim" do - it "generates action" do - with_project("bookshelf_generate_action_slim", template: "slim") do - output = [ - "create apps/web/templates/books/index.html.slim" - ] - - run_cmd "hanami generate action web books#index", output - - # - # apps/web/templates/books/index.html.slim - # - expect("apps/web/templates/books/index.html.slim").to have_file_content <<~END - END - - # - # spec/web/views/books/index_spec.rb - # - expect("spec/web/views/books/index_spec.rb").to have_file_content %r{'apps/web/templates/books/index.html.slim'} - end - end - end # slim - - context "minitest" do - it "generates action" do - with_project("bookshelf_generate_action_minitest", test: "minitest") do - output = [ - "create spec/web/controllers/books/index_spec.rb", - "create spec/web/views/books/index_spec.rb" - ] - - run_cmd "hanami generate action web books#index", output - - # - # spec/web/controllers/books/index_spec.rb - # - expect("spec/web/controllers/books/index_spec.rb").to have_file_content <<~END - require_relative '../../../spec_helper' - - describe Web::Controllers::Books::Index do - let(:action) { Web::Controllers::Books::Index.new } - let(:params) { Hash[] } - - it 'is successful' do - response = action.call(params) - _(response[0]).must_equal 200 - end - end - END - - # - # spec/web/views/books/index_spec.rb - # - expect("spec/web/views/books/index_spec.rb").to have_file_content <<~END - require_relative '../../../spec_helper' - - describe Web::Views::Books::Index do - let(:exposures) { Hash[format: :html] } - let(:template) { Hanami::View::Template.new('apps/web/templates/books/index.html.erb') } - let(:view) { Web::Views::Books::Index.new(template, exposures) } - let(:rendered) { view.render } - - it 'exposes #format' do - _(view.format).must_equal exposures.fetch(:format) - end - end - END - end - end - end # minitest - - context "rspec" do - it "generates action" do - with_project("bookshelf_generate_action_rspec", test: "rspec") do - output = [ - "create spec/web/controllers/books/index_spec.rb", - "create spec/web/views/books/index_spec.rb" - ] - - run_cmd "hanami generate action web books#index", output - - # - # spec/web/controllers/books/index_spec.rb - # - expect("spec/web/controllers/books/index_spec.rb").to have_file_content <<~END - RSpec.describe Web::Controllers::Books::Index, type: :action do - let(:action) { described_class.new } - let(:params) { Hash[] } - - it 'is successful' do - response = action.call(params) - expect(response[0]).to eq 200 - end - end - END - - # - # spec/web/views/books/index_spec.rb - # - expect("spec/web/views/books/index_spec.rb").to have_file_content <<~END - RSpec.describe Web::Views::Books::Index, type: :view do - let(:exposures) { Hash[format: :html] } - let(:template) { Hanami::View::Template.new('apps/web/templates/books/index.html.erb') } - let(:view) { described_class.new(template, exposures) } - let(:rendered) { view.render } - - it 'exposes #format' do - expect(view.format).to eq exposures.fetch(:format) - end - end - END - end - end - end # rspec - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami generate action - -Usage: - hanami generate action APP ACTION - -Description: - Generate an action for app - -Arguments: - APP # REQUIRED The app name (eg. `web`) - ACTION # REQUIRED The action name (eg. `home#index`) - -Options: - --url=VALUE # The action URL - --method=VALUE # The action HTTP method - --[no-]skip-view # Skip view and template, default: false - --help, -h # Print this help - -Examples: - hanami generate action web home#index # Basic usage - hanami generate action admin home#index # Generate for `admin` app - hanami generate action web home#index --url=/ # Specify URL - hanami generate action web sessions#destroy --method=GET # Specify HTTP method - hanami generate action web books#create --skip-view # Skip view and template - OUT - - run_cmd 'hanami generate action --help', output - end - end - end # action -end diff --git a/spec/integration/cli/generate/app_spec.rb b/spec/integration/cli/generate/app_spec.rb deleted file mode 100644 index 427d1c5d..00000000 --- a/spec/integration/cli/generate/app_spec.rb +++ /dev/null @@ -1,215 +0,0 @@ -# frozen_string_literal: true - -require "hanami/utils/string" - -RSpec.describe "hanami generate", type: :integration do - describe "app" do - context "with app name" do - it_behaves_like "a new app" do - let(:input) { "admin" } - end - end - - context "with underscored app name" do - it_behaves_like "a new app" do - let(:input) { "cool_app" } - end - end - - context "with dashed app name" do - it_behaves_like "a new app" do - let(:input) { "awesome-app" } - end - end - - context "with camel case app name" do - it_behaves_like "a new app" do - let(:input) { "CaMElAPp" } - end - end - - context "without require_relative" do - it "generates app" do - with_project("bookshelf_generate_app_without_require_relative") do - app = "no_req_relative" - app_name = Hanami::Utils::String.new(app).classify - output = [ - "insert config/environment.rb" - ] - - File.write( - "config/environment.rb", - File - .read("config/environment.rb") - .lines - .reject { |l| l[/^require_relative '.*'\n$/] } - .reject { |l| l[/^ mount Web::App, at: '\/'\n$/] } - .join("") - ) - - run_cmd "hanami generate app #{app}", output - - # - # config/environment.rb - # - expect("config/environment.rb").to have_file_content(%r{require_relative '../apps/#{app}/app'}) - expect("config/environment.rb").to have_file_content(%r{mount #{app_name}::App, at: '/no_req_relative'}) - end - end - end - - context "--app-base-url" do - it "generates app" do - with_project("bookshelf_generate_app_app_base_url") do - app = "api" - app_name = Hanami::Utils::String.new(app).classify - output = [ - "insert config/environment.rb" - ] - - run_cmd "hanami generate app #{app} --app-base-url=/api/v1", output - - # - # config/environment.rb - # - expect("config/environment.rb").to have_file_content(%r{require_relative '../apps/#{app}/app'}) - expect("config/environment.rb").to have_file_content(%r{mount #{app_name}::App, at: '/api/v1'}) - end - end - - it "fails with missing argument" do - with_project("bookshelf_generate_app_missing_app_base_url") do - output = "`' is not a valid URL" - run_cmd "hanami generate app foo --app-base-url=", output, exit_status: 1 - end - end - end - - context "erb" do - it "generates app" do - with_project("bookshelf_generate_app_erb", template: :erb) do - app = "admin" - app_name = Hanami::Utils::String.new(app).classify - output = [ - "create apps/#{app}/templates/app.html.erb" - ] - - run_cmd "hanami generate app #{app}", output - - # - # apps/admin/templates/app.html.erb - # - expect("apps/admin/templates/app.html.erb").to have_file_content <<~END - - - - #{app_name} - <%= favicon %> - - - <%= yield %> - - - END - # - # spec/admin/views/app_layout_spec.rb - # - expect("spec/admin/views/app_layout_spec.rb").to have_file_content(%r{Admin::Views::AppLayout}) - end - end - end # erb - - context "haml" do - it "generates app" do - with_project("bookshelf_generate_app_haml", template: :haml) do - app = "admin" - app_name = Hanami::Utils::String.new(app).classify - output = [ - "create apps/#{app}/templates/app.html.haml" - ] - - run_cmd "hanami generate app #{app}", output - - # - # apps/admin/templates/app.html.haml - # - expect("apps/admin/templates/app.html.haml").to have_file_content <<~END - !!! - %html - %head - %title #{app_name} - = favicon - %body - = yield - END - - # - # spec/admin/views/app_layout_spec.rb - # - expect("spec/admin/views/app_layout_spec.rb").to have_file_content(%r{Admin::Views::AppLayout}) - end - end - end # haml - - context "slim" do - it "generates app" do - with_project("bookshelf_generate_app_slim", template: :slim) do - app = "admin" - app_name = Hanami::Utils::String.new(app).classify - output = [ - "create apps/#{app}/templates/app.html.slim" - ] - - run_cmd "hanami generate app #{app}", output - - # - # apps/admin/templates/app.html.slim - # - expect("apps/admin/templates/app.html.slim").to have_file_content <<~END - doctype html - html - head - title - | #{app_name} - = favicon - body - = yield - END - - # - # spec/admin/views/app_layout_spec.rb - # - expect("spec/admin/views/app_layout_spec.rb").to have_file_content(%r{Admin::Views::AppLayout}) - end - end - end # slim - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami generate app - -Usage: - hanami generate app APP - -Description: - Generate an app - -Arguments: - APP # REQUIRED The app name (eg. `web`) - -Options: - --app-base-url=VALUE # The app base URL (eg. `/api/v1`) - --help, -h # Print this help - -Examples: - hanami generate app admin # Generate `admin` app - hanami generate app api --app-base-url=/api/v1 # Generate `api` app and mount at `/api/v1` -OUT - - run_cmd 'hanami generate app --help', output - end - end - end # app -end diff --git a/spec/integration/cli/generate/mailer_spec.rb b/spec/integration/cli/generate/mailer_spec.rb deleted file mode 100644 index 27875ce1..00000000 --- a/spec/integration/cli/generate/mailer_spec.rb +++ /dev/null @@ -1,189 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami generate", type: :integration do - describe "mailer" do - context "generates a new mailer" do - let(:output) do - ["create lib/bookshelf_generate_mailer/mailers/welcome.rb", - "create spec/bookshelf_generate_mailer/mailers/welcome_spec.rb", - "create lib/bookshelf_generate_mailer/mailers/templates/welcome.txt.erb", - "create lib/bookshelf_generate_mailer/mailers/templates/welcome.html.erb"] - end - - it 'generate the mailer files' do - with_project('bookshelf_generate_mailer', test: 'rspec') do - run_cmd "hanami generate mailer welcome", output - # - # lib/bookshelf_generate_mailer/mailers/welcome.rb - # - expect("lib/bookshelf_generate_mailer/mailers/welcome.rb").to have_file_content <<~END - module Mailers - class Welcome - include Hanami::Mailer - - from '' - to '' - subject 'Hello' - end - end - END - - expect("lib/bookshelf_generate_mailer/mailers/templates/welcome.txt.erb").to have_file_content "" - expect("lib/bookshelf_generate_mailer/mailers/templates/welcome.html.erb").to have_file_content "" - end - end - - it 'generates a proper minitest file' do - with_project('bookshelf_generate_mailer', test: 'minitest') do - run_cmd "hanami generate mailer welcome", output - # - # spec/bookshelf_generate_mailer/mailers/welcome_spec.rb - # - expect("spec/bookshelf_generate_mailer/mailers/welcome_spec.rb").to have_file_content <<~END - require_relative '../../spec_helper' - - describe Mailers::Welcome do - it 'delivers email' do - mail = Mailers::Welcome.deliver - end - end - END - end - end - - it 'generates a proper RSpec file' do - with_project('bookshelf_generate_mailer', test: 'rspec') do - run_cmd "hanami generate mailer welcome", output - # - # spec/bookshelf_generate_mailer/mailers/welcome_spec.rb - # - expect("spec/bookshelf_generate_mailer/mailers/welcome_spec.rb").to have_file_content <<~END - RSpec.describe Mailers::Welcome, type: :mailer do - it 'delivers email' do - mail = Mailers::Welcome.deliver - end - end - END - end - end - end - - it "generates mailer with options from, to and subject with single quotes" do - with_project("bookshelf_generate_mailer_with_options") do - output = [ - "create spec/bookshelf_generate_mailer_with_options/mailers/welcome_spec.rb", - "create lib/bookshelf_generate_mailer_with_options/mailers/welcome.rb", - "create lib/bookshelf_generate_mailer_with_options/mailers/templates/welcome.txt.erb", - "create lib/bookshelf_generate_mailer_with_options/mailers/templates/welcome.html.erb" - ] - - run_cmd "hanami generate mailer welcome --from=\"'mail@example.com'\" --to=\"'user@example.com'\" --subject=\"'Let\'s start'\"", output - - expect("lib/bookshelf_generate_mailer_with_options/mailers/welcome.rb").to have_file_content <<~END - module Mailers - class Welcome - include Hanami::Mailer - - from 'mail@example.com' - to 'user@example.com' - subject 'Let\'s start' - end - end - END - end - end - - it "generates mailer with options from, to and subject with double quotes" do - with_project("bookshelf_generate_mailer_with_options") do - output = [ - "create spec/bookshelf_generate_mailer_with_options/mailers/welcome_spec.rb", - "create lib/bookshelf_generate_mailer_with_options/mailers/welcome.rb", - "create lib/bookshelf_generate_mailer_with_options/mailers/templates/welcome.txt.erb", - "create lib/bookshelf_generate_mailer_with_options/mailers/templates/welcome.html.erb" - ] - - run_cmd "hanami generate mailer welcome --from='\"mail@example.com\"' --to='\"user@example.com\"' --subject='\"Come on \"Folks\"\"'", output - - expect("lib/bookshelf_generate_mailer_with_options/mailers/welcome.rb").to have_file_content <<~END - module Mailers - class Welcome - include Hanami::Mailer - - from 'mail@example.com' - to 'user@example.com' - subject 'Come on "Folks"' - end - end - END - end - end - - it "generates mailer with options from, to and subject without quotes" do - with_project("bookshelf_generate_mailer_with_options") do - output = [ - "create spec/bookshelf_generate_mailer_with_options/mailers/welcome_spec.rb", - "create lib/bookshelf_generate_mailer_with_options/mailers/welcome.rb", - "create lib/bookshelf_generate_mailer_with_options/mailers/templates/welcome.txt.erb", - "create lib/bookshelf_generate_mailer_with_options/mailers/templates/welcome.html.erb" - ] - - run_cmd "hanami generate mailer welcome --from=mail@example.com --to=user@example.com --subject=Welcome", output - - expect("lib/bookshelf_generate_mailer_with_options/mailers/welcome.rb").to have_file_content <<~END - module Mailers - class Welcome - include Hanami::Mailer - - from 'mail@example.com' - to 'user@example.com' - subject 'Welcome' - end - end - END - end - end - - it "fails with missing arguments" do - with_project("bookshelf_generate_mailer_without_args") do - output = <<~OUT - ERROR: "hanami generate mailer" was called with no arguments - Usage: "hanami generate mailer MAILER" - OUT - - run_cmd "hanami generate mailer", output, exit_status: 1 - end - end - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami generate mailer - -Usage: - hanami generate mailer MAILER - -Description: - Generate a mailer - -Arguments: - MAILER # REQUIRED The mailer name (eg. `welcome`) - -Options: - --from=VALUE # The default `from` field of the mail - --to=VALUE # The default `to` field of the mail - --subject=VALUE # The mail subject - --help, -h # Print this help - -Examples: - hanami generate mailer welcome # Basic usage - hanami generate mailer welcome --from="noreply@example.com" # Generate with default `from` value - hanami generate mailer announcement --to="users@example.com" # Generate with default `to` value - hanami generate mailer forgot_password --subject="Your password reset" # Generate with default `subject` - OUT - - run_cmd 'hanami generate mailer --help', output - end - end - end -end diff --git a/spec/integration/cli/generate/migration_spec.rb b/spec/integration/cli/generate/migration_spec.rb deleted file mode 100644 index 8397114f..00000000 --- a/spec/integration/cli/generate/migration_spec.rb +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami generate", type: :integration do - describe "migration" do - context "with migration name" do - it_behaves_like "a new migration" do - let(:input) { "users" } - end - end - - context "with underscored name" do - it_behaves_like "a new migration" do - let(:input) { "create_users" } - end - end - - context "with dashed name" do - it_behaves_like "a new migration" do - let(:input) { "add-verified-at-to-users" } - end - end - - context "with camel case app name" do - it_behaves_like "a new migration" do - let(:input) { "AddUniqueIndexUsersEmail" } - end - end - - context "with missing argument" do - it "fails" do - with_project('bookshelf_generate_migration_missing_arguments') do - output = <<-END -ERROR: "hanami generate migration" was called with no arguments -Usage: "hanami generate migration MIGRATION" -END - - run_cmd "hanami generate migration", output, exit_status: 1 - end - end - end - - it "prints help message" do - with_project do - banner = <<~OUT -Command: - hanami generate migration - -Usage: - hanami generate migration MIGRATION - -Description: - Generate a migration - -Arguments: - MIGRATION # REQUIRED The migration name (eg. `create_users`) - -Options: - --help, -h # Print this help - -Examples: -OUT - - output = [ - banner, - %r{ hanami generate migration create_users # Generate `db/migrations/[\d]{14}_create_users.rb`}, - ] - - run_cmd 'hanami generate migration --help', output - end - end - end # migration -end diff --git a/spec/integration/cli/generate/model_spec.rb b/spec/integration/cli/generate/model_spec.rb deleted file mode 100644 index abeec22c..00000000 --- a/spec/integration/cli/generate/model_spec.rb +++ /dev/null @@ -1,290 +0,0 @@ -# frozen_string_literal: true - -require "hanami/utils/string" - -RSpec.describe "hanami generate", type: :integration do - describe "model" do - context "with model name" do - it_behaves_like "a new model" do - let(:input) { "user" } - end - end - - context "with underscored name" do - it_behaves_like "a new model" do - let(:input) { "discounted_book" } - end - end - - context "with dashed name" do - it_behaves_like "a new model" do - let(:input) { "user-event" } - end - end - - context "with camel case name" do - it_behaves_like "a new model" do - let(:input) { "VerifiedUser" } - end - end - - context "with missing argument" do - it "fails" do - with_project('bookshelf_generate_model_missing_arguments') do - output = <<-END -ERROR: "hanami generate model" was called with no arguments -Usage: "hanami generate model MODEL" -END - - run_cmd "hanami generate model", output, exit_status: 1 - end - end - end - - context "with missing migrations directory" do - it "will create directory and migration" do - with_project do - model_name = "book" - directory = Pathname.new("db").join("migrations") - FileUtils.rm_rf(directory) - - run_cmd "hanami generate model #{model_name}" - expect(directory).to be_directory - - migration = directory.children.find do |m| - m.to_s.include?(model_name) - end - - expect(migration).to_not be(nil) - end - end - end - - context "with skip-migration" do - it "doesn't create a migration file" do - model_name = "user" - table_name = "users" - project = "bookshelf_generate_model_skip_migration" - with_project(project) do - run_cmd "hanami generate model #{model_name} --skip-migration" - # - # db/migrations/_create_.rb - # - migrations = Pathname.new("db").join("migrations").children - file = migrations.find do |child| - child.to_s.include?("create_#{table_name}") - end - - expect(file).to be_nil, "Expected to not find a migration matching: create_#{table_name}. Found #{file&.to_s}" - end - end - - it "doesn't create a migration file when --relation is used" do - model_name = "user" - table_name = "accounts" - project = "bookshelf_generate_model_skip_migration" - with_project(project) do - run_cmd "hanami generate model #{model_name} --skip-migration --relation=#{table_name}" - # - # db/migrations/_create_.rb - # - migrations = Pathname.new("db").join("migrations").children - file = migrations.find do |child| - child.to_s.include?("create_#{table_name}") - end - - expect(file).to be_nil, "Expected to not find a migration matching: create_#{table_name}. Found #{file&.to_s}" - end - end - end - - context "with relation option" do - let(:project) { "generate_model_with_relation_name" } - let(:model_name) { "stimulus" } - let(:class_name) { "Stimulus" } - let(:relation_name) { "stimuli" } - - it "creates correct entity, repository, and migration" do - with_project(project) do - output = [ - "create lib/#{project}/entities/#{model_name}.rb", - "create lib/#{project}/repositories/#{model_name}_repository.rb", - /create db\/migrations\/(\d+)_create_#{relation_name}.rb/ - ] - - run_cmd "hanami generate model #{model_name} --relation=#{relation_name}", output - - expect("lib/#{project}/repositories/#{model_name}_repository.rb").to have_file_content <<~END - class #{class_name}Repository < Hanami::Repository - self.relation = :#{relation_name} - end - END - - migration = Pathname.new("db").join("migrations").children.find do |child| - child.to_s.include?("create_#{relation_name}") - end - - expect(migration.to_s).to have_file_content <<~END - Hanami::Model.migration do - change do - create_table :#{relation_name} do - primary_key :id - - column :created_at, DateTime, null: false - column :updated_at, DateTime, null: false - end - end - end - END - end - end - - it "handles CamelCase arguments" do - with_project(project) do - model = "sheep" - relation_name = "black_sheeps" - output = [ - "create lib/#{project}/entities/#{model}.rb", - "create lib/#{project}/repositories/#{model}_repository.rb", - /create db\/migrations\/(\d+)_create_#{relation_name}.rb/ - ] - - run_cmd "hanami generate model #{model} --relation=BlackSheeps", output - - expect("lib/#{project}/repositories/sheep_repository.rb").to have_file_content <<~END - class SheepRepository < Hanami::Repository - self.relation = :#{relation_name} - end - END - - migration = Pathname.new("db").join("migrations").children.find do |child| - child.to_s.include?("create_#{relation_name}") - end - - expect(migration.to_s).to have_file_content <<~END - Hanami::Model.migration do - change do - create_table :#{relation_name} do - primary_key :id - - column :created_at, DateTime, null: false - column :updated_at, DateTime, null: false - end - end - end - END - end - end - - it "returns error for blank option" do - with_project(project) do - run_cmd "hanami generate model #{model_name} --relation=", "`' is not a valid relation name", exit_status: 1 - end - end - end - - context "minitest" do - it "generates model" do - project = "bookshelf_generate_model_minitest" - - with_project(project, test: :minitest) do - model = "book" - class_name = Hanami::Utils::String.new(model).classify - output = [ - "create spec/#{project}/entities/#{model}_spec.rb", - "create spec/#{project}/repositories/#{model}_repository_spec.rb" - ] - - run_cmd "hanami generate model #{model}", output - - # - # spec//entities/_spec.rb - # - expect("spec/#{project}/entities/#{model}_spec.rb").to have_file_content <<~END - require_relative '../../spec_helper' - - describe #{class_name} do - # place your tests here - end - END - - # - # spec//repositories/_repository_spec.rb - # - expect("spec/#{project}/repositories/#{model}_repository_spec.rb").to have_file_content <<~END - require_relative '../../spec_helper' - - describe #{class_name}Repository do - # place your tests here - end - END - end - end - end # minitest - - context "rspec" do - it "generates model" do - project = "bookshelf_generate_model_rspec" - - with_project(project, test: :rspec) do - model = "book" - class_name = Hanami::Utils::String.new(model).classify - output = [ - "create spec/#{project}/entities/#{model}_spec.rb", - "create spec/#{project}/repositories/#{model}_repository_spec.rb" - ] - - run_cmd "hanami generate model #{model}", output - - # - # spec//entities/_spec.rb - # - expect("spec/#{project}/entities/#{model}_spec.rb").to have_file_content <<~END - RSpec.describe #{class_name}, type: :entity do - # place your tests here - end - END - - # - # spec//repositories/_repository_spec.rb - # - expect("spec/#{project}/repositories/#{model}_repository_spec.rb").to have_file_content <<~END - RSpec.describe BookRepository, type: :repository do - # place your tests here - end - END - end - end - end # rspec - - it "prints help message" do - with_project do - output = <<~OUT -Command: - hanami generate model - -Usage: - hanami generate model MODEL - -Description: - Generate a model - -Arguments: - MODEL # REQUIRED Model name (eg. `user`) - -Options: - --[no-]skip-migration # Skip migration, default: false - --relation=VALUE # Name of the database relation, default: pluralized model name - --help, -h # Print this help - -Examples: - hanami generate model user # Generate `User` entity, `UserRepository` repository, and the migration - hanami generate model user --skip-migration # Generate `User` entity and `UserRepository` repository - hanami generate model user --relation=accounts # Generate `User` entity, `UserRepository` and migration to create `accounts` table -OUT - - run_cmd 'hanami generate model --help', output - end - end - end # model -end diff --git a/spec/integration/cli/generate/secret_spec.rb b/spec/integration/cli/generate/secret_spec.rb deleted file mode 100644 index 60fbc494..00000000 --- a/spec/integration/cli/generate/secret_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami generate", type: :integration do - describe "secret" do - context "without app name" do - it "prints secret" do - with_project do - generate "secret" - - expect(out).to match(/[\w]{64}/) - end - end - end - - context "with app name" do - it "prints secret" do - with_project do - generate "secret web" - - expect(out).to match(%r{WEB_SESSIONS_SECRET="[\w]{64}"}) - end - end - end - - it 'prints help message' do - with_project do - banner = <<~OUT -Command: - hanami generate secret - -Usage: - hanami generate secret [APP] - -Description: - Generate session secret - -Arguments: - APP # The app name (eg. `web`) - -Options: - --help, -h # Print this help - -Examples: -OUT - - output = [ - banner, - # %r{ hanami generate secret # Prints secret (eg. `[\w]{64}`)}, - # %r{ hanami generate secret web # Prints session secret (eg. `WEB_SESSIONS_SECRET=[\w]{64}`)} - ] - - run_cmd 'hanami generate secret --help', output - end - end - end # secret -end diff --git a/spec/integration/cli/generate_spec.rb b/spec/integration/cli/generate_spec.rb deleted file mode 100644 index da4acbac..00000000 --- a/spec/integration/cli/generate_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami generate", type: :integration do - it "prints subcommands" do - with_project do - output = <<~OUT - Commands: - hanami generate action APP ACTION # Generate an action for app - hanami generate app APP # Generate an app - hanami generate mailer MAILER # Generate a mailer - hanami generate migration MIGRATION # Generate a migration - hanami generate model MODEL # Generate a model - hanami generate secret [APP] # Generate session secret - OUT - - run_cmd "hanami generate", output, exit_status: 1 - end - end -end diff --git a/spec/integration/cli/new/database_spec.rb b/spec/integration/cli/new/database_spec.rb deleted file mode 100644 index 08a89ca1..00000000 --- a/spec/integration/cli/new/database_spec.rb +++ /dev/null @@ -1,235 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami new", type: :integration do - describe "--database" do - context "postgres" do - it "generates project" do - project = "bookshelf_postgresql" - output = [ - "create db/migrations/.gitkeep", - "create db/schema.sql" - ] - - run_cmd "hanami new #{project} --database=postgres", output - - within_project_directory(project) do - # - # .env.development - # - development_url = Platform.match do - engine(:ruby) { "postgresql://localhost/#{project}_development" } - engine(:jruby) { "jdbc:postgresql://localhost/#{project}_development" } - end - - expect(".env.development").to have_file_content(%r{DATABASE_URL="#{development_url}"}) - - # - # .env.test - # - test_url = Platform.match do - engine(:ruby) { "postgresql://localhost/#{project}_test" } - engine(:jruby) { "jdbc:postgresql://localhost/#{project}_test" } - end - - expect(".env.test").to have_file_content(%r{DATABASE_URL="#{test_url}"}) - - # - # Gemfile - # - gem_name = Platform.match do - engine(:ruby) { "pg" } - engine(:jruby) { "jdbc-postgres" } - end - - expect("Gemfile").to have_file_content(%r{gem '#{gem_name}'}) - - # - # config/environment.rb - # - expect("config/environment.rb").to have_file_content(%r{ adapter :sql, ENV.fetch\('DATABASE_URL'\)}) - expect("config/environment.rb").to have_file_content(%r{ migrations 'db/migrations'}) - expect("config/environment.rb").to have_file_content(%r{ schema 'db/schema.sql'}) - - # - # db/migrations/.gitkeep - # - expect("db/migrations/.gitkeep").to be_an_existing_file - - # - # db/schema.sql - # - expect("db/schema.sql").to be_an_existing_file - - # - # .gitignore - # - expect(".gitignore").to have_file_content <<-END -/public/assets* -/tmp -.env.local -.env.*.local - END - end - end - end # postgres - - describe "sqlite" do - it "generates project" do - project = "bookshelf_sqlite" - output = [ - "create db/migrations/.gitkeep", - "create db/schema.sql" - ] - - run_cmd "hanami new #{project} --database=sqlite", output - - within_project_directory(project) do - # - # .env.development - # - development_url = Platform.match do - engine(:ruby) { "sqlite://db/#{project}_development.sqlite" } - engine(:jruby) { "jdbc:sqlite://db/#{project}_development.sqlite" } - end - - expect(".env.development").to have_file_content(%r{DATABASE_URL="#{development_url}"}) - - # - # .env.test - # - test_url = Platform.match do - engine(:ruby) { "sqlite://db/#{project}_test.sqlite" } - engine(:jruby) { "jdbc:sqlite://db/#{project}_test.sqlite" } - end - - expect(".env.test").to have_file_content(%r{DATABASE_URL="#{test_url}"}) - - # - # Gemfile - # - gem_name = Platform.match do - engine(:ruby) { "sqlite3" } - engine(:jruby) { "jdbc-sqlite3" } - end - - expect("Gemfile").to have_file_content(%r{gem '#{gem_name}'}) - - # - # config/environment.rb - # - expect("config/environment.rb").to have_file_content(%r{ adapter :sql, ENV.fetch\('DATABASE_URL'\)}) - expect("config/environment.rb").to have_file_content(%r{ migrations 'db/migrations'}) - expect("config/environment.rb").to have_file_content(%r{ schema 'db/schema.sql'}) - - # - # db/migrations/.gitkeep - # - expect("db/migrations/.gitkeep").to be_an_existing_file - - # - # db/schema.sql - # - expect("db/schema.sql").to be_an_existing_file - - # - # .gitignore - # - expect(".gitignore").to have_file_content <<-END -/db/*.sqlite -/public/assets* -/tmp -.env.local -.env.*.local - END - end - end - end # sqlite - - context "mysql" do - it "generates project" do - project = "bookshelf_mysql" - output = [ - "create db/migrations/.gitkeep", - "create db/schema.sql" - ] - - run_cmd "hanami new #{project} --database=mysql", output - - within_project_directory(project) do - # - # .env.development - # - development_url = Platform.match do - engine(:ruby) { "mysql2://localhost/#{project}_development" } - engine(:jruby) { "jdbc:mysql://localhost/#{project}_development" } - end - - expect(".env.development").to have_file_content(%r{DATABASE_URL="#{development_url}"}) - - # - # .env.test - # - test_url = Platform.match do - engine(:ruby) { "mysql2://localhost/#{project}_test" } - engine(:jruby) { "jdbc:mysql://localhost/#{project}_test" } - end - - expect(".env.test").to have_file_content(%r{DATABASE_URL="#{test_url}"}) - - # - # Gemfile - # - gem_name = Platform.match do - engine(:ruby) { "mysql2" } - engine(:jruby) { "jdbc-mysql" } - end - - expect("Gemfile").to have_file_content(%r{gem '#{gem_name}'}) - - # - # config/environment.rb - # - expect("config/environment.rb").to have_file_content(%r{ adapter :sql, ENV.fetch\('DATABASE_URL'\)}) - expect("config/environment.rb").to have_file_content(%r{ migrations 'db/migrations'}) - expect("config/environment.rb").to have_file_content(%r{ schema 'db/schema.sql'}) - - # - # db/migrations/.gitkeep - # - expect("db/migrations/.gitkeep").to be_an_existing_file - - # - # db/schema.sql - # - expect("db/schema.sql").to be_an_existing_file - - # - # .gitignore - # - expect(".gitignore").to have_file_content <<-END -/public/assets* -/tmp -.env.local -.env.*.local - END - end - end - end # mysql - - context "missing" do - it "returns error" do - output = "`' is not a valid database engine" - - run_cmd "hanami new bookshelf --database=", output, exit_status: 1 - end - end # missing - - context "unknown" do - it "returns error" do - output = "`foo' is not a valid database engine" - - run_cmd "hanami new bookshelf --database=foo", output, exit_status: 1 - end - end # unknown - end # database -end diff --git a/spec/integration/cli/new/hanami_head_spec.rb b/spec/integration/cli/new/hanami_head_spec.rb deleted file mode 100644 index e4e8b14b..00000000 --- a/spec/integration/cli/new/hanami_head_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami new", type: :integration do - describe "--hanami-head" do - it "generates project" do - project = "bookshelf_hanami_head" - - run_cmd "hanami new #{project} --hanami-head" - - within_project_directory(project) do - # - # Gemfile - # - expect('Gemfile').to have_file_content(%r{gem 'hanami-utils', require: false, git: 'https://github.com/hanami/utils.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami-validations', require: false, git: 'https://github.com/hanami/validations.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami-router', require: false, git: 'https://github.com/hanami/router.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami-controller', require: false, git: 'https://github.com/hanami/controller.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami-view', require: false, git: 'https://github.com/hanami/view.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami-helpers', require: false, git: 'https://github.com/hanami/helpers.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami-mailer', require: false, git: 'https://github.com/hanami/mailer.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami-assets', require: false, git: 'https://github.com/hanami/assets.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami-model', require: false, git: 'https://github.com/hanami/model.git', branch: 'develop'}) - expect('Gemfile').to have_file_content(%r{gem 'hanami', git: 'https://github.com/hanami/hanami.git', branch: 'develop'}) - end - end - end # hanami-head -end diff --git a/spec/integration/cli/new/template_spec.rb b/spec/integration/cli/new/template_spec.rb deleted file mode 100644 index 21d5f3a7..00000000 --- a/spec/integration/cli/new/template_spec.rb +++ /dev/null @@ -1,118 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami new", type: :integration do - describe "--template" do - context "erb" do - it "generates project" do - project = "bookshelf_erb" - output = [ - "create apps/web/templates/app.html.erb" - ] - - run_cmd "hanami new #{project} --template=erb", output - - within_project_directory(project) do - # - # .hanamirc - # - expect(".hanamirc").to have_file_content(%r{template=erb}) - - # - # apps/web/templates/app.html.erb - # - expect("apps/web/templates/app.html.erb").to have_file_content <<~END - - - - Web - <%= favicon %> - - - <%= yield %> - - - END - end - end - end # erb - - context "haml" do - it "generates project" do - project = "bookshelf_erb" - output = [ - "create apps/web/templates/app.html.haml" - ] - - run_cmd "hanami new #{project} --template=haml", output - - within_project_directory(project) do - # - # .hanamirc - # - expect(".hanamirc").to have_file_content(%r{template=haml}) - - # - # apps/web/templates/app.html.haml - # - expect("apps/web/templates/app.html.haml").to have_file_content <<~END - !!! - %html - %head - %title Web - = favicon - %body - = yield - END - end - end - end # haml - - context "slim" do - it "generates project" do - project = "bookshelf_erb" - output = [ - "create apps/web/templates/app.html.slim" - ] - - run_cmd "hanami new #{project} --template=slim", output - - within_project_directory(project) do - # - # .hanamirc - # - expect(".hanamirc").to have_file_content(%r{template=slim}) - - # - # apps/web/templates/app.html.slim - # - expect("apps/web/templates/app.html.slim").to have_file_content <<~END - doctype html - html - head - title - | Web - = favicon - body - = yield - END - end - end - end # slim - - context "missing" do - it "returns error" do - output = "`' is not a valid template engine. Please use one of: `erb', `haml', `slim'" - - run_cmd "hanami new bookshelf --template=", output, exit_status: 1 - end - end # missing - - context "unknown" do - it "returns error" do - output = "`foo' is not a valid template engine. Please use one of: `erb', `haml', `slim'" - - run_cmd "hanami new bookshelf --template=foo", output, exit_status: 1 - end - end # unknown - end # template -end diff --git a/spec/integration/cli/new/test_spec.rb b/spec/integration/cli/new/test_spec.rb deleted file mode 100644 index ef553a34..00000000 --- a/spec/integration/cli/new/test_spec.rb +++ /dev/null @@ -1,274 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami new", type: :integration do - describe "--test" do - context "minitest" do - it "generates project" do - project = "bookshelf_minitest" - output = [ - "create spec/spec_helper.rb", - "create spec/features_helper.rb", - "create spec/web/views/app_layout_spec.rb" - ] - - run_cmd "hanami new #{project} --test=minitest", output - - within_project_directory(project) do - # - # .hanamirc - # - expect(".hanamirc").to have_file_content(%r{test=minitest}) - - # - # spec/spec_helper.rb - # - expect("spec/spec_helper.rb").to have_file_content <<~END - # Require this file for unit tests - ENV['HANAMI_ENV'] ||= 'test' - - require_relative '../config/environment' - require 'minitest/autorun' - - Hanami.boot - END - - # - # spec/features_helper.rb - # - expect("spec/features_helper.rb").to have_file_content <<~END - # Require this file for feature tests - require_relative './spec_helper' - - require 'capybara' - require 'capybara/dsl' - - Capybara.app = Hanami.app - - class MiniTest::Spec - include Capybara::DSL - end - END - - # - # spec//views/app_layout_spec.rb - # - expect("spec/web/views/app_layout_spec.rb").to have_file_content <<-END - require "spec_helper" - - describe Web::Views::AppLayout do - let(:layout) { Web::Views::AppLayout.new({ format: :html }, "contents") } - let(:rendered) { layout.render } - - it 'contains app name' do - _(rendered).must_include('Web') - end - end - END - end - end - end # minitest - - describe "rspec" do - it "generates project" do - project = "bookshelf_rspec" - output = [ - "create .rspec", - "create spec/spec_helper.rb", - "create spec/features_helper.rb", - "create spec/support/capybara.rb", - "create spec/web/views/app_layout_spec.rb" - ] - - run_cmd "hanami new #{project} --test=rspec", output - - within_project_directory(project) do - # - # .hanamirc - # - expect(".hanamirc").to have_file_content(%r{test=rspec}) - - # - # .rspec - # - expect(".rspec").to have_file_content <<~END - --color - --require spec_helper - END - - # - # spec/spec_helper.rb - # - expect("spec/spec_helper.rb").to have_file_content <<~END - # Require this file for unit tests - ENV['HANAMI_ENV'] ||= 'test' - - require_relative '../config/environment' - Hanami.boot - Hanami::Utils.require!("\#{__dir__}/support") - - # This file was generated by the `rspec --init` command. Conventionally, all - # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. - # The generated `.rspec` file contains `--require spec_helper` which will cause - # this file to always be loaded, without a need to explicitly require it in any - # files. - # - # Given that it is always loaded, you are encouraged to keep this file as - # light-weight as possible. Requiring heavyweight dependencies from this file - # will add to the boot time of your test suite on EVERY test run, even for an - # individual file that may not need all of that loaded. Instead, consider making - # a separate helper file that requires the additional dependencies and performs - # the additional setup, and require it from the spec files that actually need - # it. - # - # The `.rspec` file also contains a few flags that are not defaults but that - # users commonly want. - # - # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration - RSpec.configure do |config| - # rspec-expectations config goes here. You can use an alternate - # assertion/expectation library such as wrong or the stdlib/minitest - # assertions if you prefer. - config.expect_with :rspec do |expectations| - # This option will default to `true` in RSpec 4. It makes the `description` - # and `failure_message` of custom matchers include text for helper methods - # defined using `chain`, e.g.: - # be_bigger_than(2).and_smaller_than(4).description - # # => "be bigger than 2 and smaller than 4" - # ...rather than: - # # => "be bigger than 2" - expectations.include_chain_clauses_in_custom_matcher_descriptions = true - end - - # rspec-mocks config goes here. You can use an alternate test double - # library (such as bogus or mocha) by changing the `mock_with` option here. - config.mock_with :rspec do |mocks| - # Prevents you from mocking or stubbing a method that does not exist on - # a real object. This is generally recommended, and will default to - # `true` in RSpec 4. - mocks.verify_partial_doubles = true - end - - # The settings below are suggested to provide a good initial experience - # with RSpec, but feel free to customize to your heart's content. - =begin - # These two settings work together to allow you to limit a spec run - # to individual examples or groups you care about by tagging them with - # `:focus` metadata. When nothing is tagged with `:focus`, all examples - # get run. - config.filter_run :focus - config.run_all_when_everything_filtered = true - - # Allows RSpec to persist some state between runs in order to support - # the `--only-failures` and `--next-failure` CLI options. We recommend - # you configure your source control system to ignore this file. - config.example_status_persistence_file_path = "spec/examples.txt" - - # Limits the available syntax to the non-monkey patched syntax that is - # recommended. For more details, see: - # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax - # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ - # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching - config.disable_monkey_patching! - - # This setting enables warnings. It's recommended, but in many cases may - # be too noisy due to issues in dependencies. - config.warnings = false - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = 'doc' - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed - =end - end - END - - # - # spec/features_helper.rb - # - expect("spec/features_helper.rb").to have_file_content <<~END - # Require this file for feature tests - require_relative './spec_helper' - - require 'capybara' - require 'capybara/rspec' - - RSpec.configure do |config| - config.include RSpec::FeatureExampleGroup - - config.include Capybara::DSL, feature: true - config.include Capybara::RSpecMatchers, feature: true - end - END - - # - # spec/support/capybara.rb - # - expect("spec/support/capybara.rb").to have_file_content <<~END - module RSpec - module FeatureExampleGroup - def self.included(group) - group.metadata[:type] = :feature - Capybara.app = Hanami.app - end - end - end - END - - # - # spec//views/app_layout_spec.rb - # - expect("spec/web/views/app_layout_spec.rb").to have_file_content <<~END - require "spec_helper" - - RSpec.describe Web::Views::AppLayout, type: :view do - let(:layout) { Web::Views::AppLayout.new({ format: :html }, "contents") } - let(:rendered) { layout.render } - - it 'contains app name' do - expect(rendered).to include('Web') - end - end - END - end - end - end # rspec - - context "missing" do - it "returns error" do - output = "`' is not a valid test framework. Please use one of: `rspec', `minitest'" - - run_cmd "hanami new bookshelf --test=", output, exit_status: 1 - end - end # missing - - context "unknown" do - it "returns error" do - output = "`foo' is not a valid test framework. Please use one of: `rspec', `minitest'" - - run_cmd "hanami new bookshelf --test=foo", output, exit_status: 1 - end - end # unknown - end # test -end diff --git a/spec/integration/cli/new_spec.rb b/spec/integration/cli/new_spec.rb deleted file mode 100644 index 23f1ec10..00000000 --- a/spec/integration/cli/new_spec.rb +++ /dev/null @@ -1,970 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "hanami new", type: :integration do - it "generates vanilla project" do - project = "bookshelf" - output = <<-OUT - create .hanamirc - create .env.development - create .env.test - create README.md - create Gemfile - create config.ru - create config/boot.rb - create config/environment.rb - create lib/#{project}.rb - create public/.gitkeep - create config/initializers/.gitkeep - create lib/#{project}/entities/.gitkeep - create lib/#{project}/repositories/.gitkeep - create lib/#{project}/mailers/.gitkeep - create lib/#{project}/mailers/templates/.gitkeep - create spec/#{project}/entities/.gitkeep - create spec/#{project}/repositories/.gitkeep - create spec/#{project}/mailers/.gitkeep - create spec/support/.gitkeep - create db/migrations/.gitkeep - create Rakefile - create .rspec - create spec/spec_helper.rb - create spec/features_helper.rb - create spec/support/capybara.rb - create db/schema.sql - create .gitignore - run git init . from "." - create apps/web/app.rb - create apps/web/config/routes.rb - create apps/web/views/app_layout.rb - create apps/web/templates/app.html.erb - create apps/web/assets/favicon.ico - create apps/web/controllers/.gitkeep - create apps/web/assets/images/.gitkeep - create apps/web/assets/javascripts/.gitkeep - create apps/web/assets/stylesheets/.gitkeep - create spec/web/features/.gitkeep - create spec/web/controllers/.gitkeep - create spec/web/views/app_layout_spec.rb - insert config/environment.rb - insert config/environment.rb - append .env.development - append .env.test - OUT - - run_cmd "hanami new #{project}", output - - within_project_directory(project) do - # Assert it's an initialized Git repository - run_cmd "git status", default_git_branch - - # - # .hanamirc - # - expect(".hanamirc").to have_file_content <<~END - project=#{project} - test=rspec - template=erb - END - - # - # .env.development - # - expect(".env.development").to have_file_content(%r{# Define ENV variables for development environment}) - expect(".env.development").to have_file_content(%r{DATABASE_URL="sqlite://db/#{project}_development.sqlite"}) - expect(".env.development").to have_file_content(%r{SERVE_STATIC_ASSETS="true"}) - expect(".env.development").to have_file_content(%r{WEB_SESSIONS_SECRET="[\w]{64}"}) - - # - # .env.test - # - expect(".env.test").to have_file_content(%r{# Define ENV variables for test environment}) - expect(".env.test").to have_file_content(%r{DATABASE_URL="sqlite://db/#{project}_test.sqlite"}) - expect(".env.test").to have_file_content(%r{SERVE_STATIC_ASSETS="true"}) - expect(".env.test").to have_file_content(%r{WEB_SESSIONS_SECRET="[\w]{64}"}) - - # - # README.md - # - expect("README.md").to have_file_content <<~END - # Bookshelf - - Welcome to your new Hanami project! - - ## Setup - - How to run tests: - - ``` - % bundle exec rake - ``` - - How to run the development console: - - ``` - % bundle exec hanami console - ``` - - How to run the development server: - - ``` - % bundle exec hanami server - ``` - - How to prepare (create and migrate) DB for `development` and `test` environments: - - ``` - % bundle exec hanami db prepare - - % HANAMI_ENV=test bundle exec hanami db prepare - ``` - -Explore Hanami [guides](https://guides.hanamirb.org/), [API docs](http://docs.hanamirb.org/#{Hanami::VERSION}/), or jump in [chat](http://chat.hanamirb.org) for help. Enjoy! 🌸 -END - - # - # Gemfile - # - if Platform.match?(engine: :ruby) - expect('Gemfile').to have_file_content <<-END -source 'https://rubygems.org' - -gem 'rake' -gem 'hanami', '#{Hanami::Version.gem_requirement}' -gem 'hanami-model', '~> 1.3' - -gem 'sqlite3' - -group :development do - # Code reloading - # See: https://guides.hanamirb.org/projects/code-reloading - gem 'shotgun', platforms: :ruby - gem 'hanami-webconsole' -end - -group :test, :development do - gem 'dotenv', '~> 2.4' -end - -group :test do - gem 'rspec' - gem 'capybara' -end - -group :production do - # gem 'puma' -end -END - end - - if Platform.match?(engine: :jruby) - expect("Gemfile").to have_file_content <<~END - source 'https://rubygems.org' - - gem 'rake' - gem 'hanami', '#{Hanami::Version.gem_requirement}' - gem 'hanami-model', '~> 1.3' - - gem 'jdbc-sqlite3' - - group :test, :development do - gem 'dotenv', '~> 2.4' - end - - group :test do - gem 'rspec' - gem 'capybara' - end - - group :production do - # gem 'puma' - end - END - end - - # - # config.ru - # - expect('config.ru').to have_file_content <<-END - require_relative 'config/environment' - - run Hanami.app - END - - # - # config/boot.rb - # - expect("config/boot.rb").to have_file_content <<~END - require_relative './environment' - Hanami.boot - END - - # - # config/environment.rb - # - expect('config/environment.rb').to have_file_content <<-END - require 'bundler/setup' - require 'hanami/setup' - require 'hanami/model' - require_relative '../lib/#{project}' - require_relative '../apps/web/app' - - Hanami.configure do - mount Web::App, at: '/' - - model do - ## - # Database adapter - # - # Available options: - # - # * SQL adapter - # adapter :sql, 'sqlite://db/#{project}_development.sqlite3' - # adapter :sql, 'postgresql://localhost/#{project}_development' - # adapter :sql, 'mysql://localhost/#{project}_development' - # - adapter :sql, ENV.fetch('DATABASE_URL') - - ## - # Migrations - # - migrations 'db/migrations' - schema 'db/schema.sql' - end - - mailer do - root 'lib/#{project}/mailers' - - # See https://guides.hanamirb.org/mailers/delivery - delivery :test - end - - environment :development do - # See: https://guides.hanamirb.org/projects/logging - logger level: :debug - end - - environment :production do - logger level: :info, formatter: :json, filter: [] - - mailer do - delivery :smtp, address: ENV.fetch('SMTP_HOST'), port: ENV.fetch('SMTP_PORT') - end - end - end - END - - project_module = Hanami::Utils::String.new(project).classify - # - # lib/.rb - # - expect("lib/#{project}.rb").to have_file_content <<~END - module #{project_module} - end - END - - # - # public/.gitkeep - # - expect("public/.gitkeep").to be_an_existing_file - - # - # config/initializers/.gitkeep - # - expect("config/initializers/.gitkeep").to be_an_existing_file - - # - # lib//entities/.gitkeep - # - expect("lib/#{project}/entities/.gitkeep").to be_an_existing_file - - # - # lib//mailers/.gitkeep - # - expect("lib/#{project}/mailers/.gitkeep").to be_an_existing_file - - # - # lib//mailers/templates/.gitkeep - # - expect("lib/#{project}/mailers/templates/.gitkeep").to be_an_existing_file - - # - # spec//entities/.gitkeep - # - expect("spec/#{project}/entities/.gitkeep").to be_an_existing_file - - # - # spec//repositories/.gitkeep - # - expect("spec/#{project}/repositories/.gitkeep").to be_an_existing_file - - # - # spec//mailers/.gitkeep - # - expect("spec/#{project}/mailers/.gitkeep").to be_an_existing_file - - # - # spec/support/.gitkeep - # - expect("spec/support/.gitkeep").to be_an_existing_file - - # - # Rakefile - # - expect("Rakefile").to have_file_content <<~END - require 'rake' - require 'hanami/rake_tasks' - - begin - require 'rspec/core/rake_task' - RSpec::Core::RakeTask.new(:spec) - task default: :spec - rescue LoadError - end - END - - # - # spec/spec_helper.rb - # - expect("spec/spec_helper.rb").to have_file_content <<~END - # Require this file for unit tests - ENV['HANAMI_ENV'] ||= 'test' - - require_relative '../config/environment' - Hanami.boot - Hanami::Utils.require!("\#{__dir__}/support") - - # This file was generated by the `rspec --init` command. Conventionally, all - # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. - # The generated `.rspec` file contains `--require spec_helper` which will cause - # this file to always be loaded, without a need to explicitly require it in any - # files. - # - # Given that it is always loaded, you are encouraged to keep this file as - # light-weight as possible. Requiring heavyweight dependencies from this file - # will add to the boot time of your test suite on EVERY test run, even for an - # individual file that may not need all of that loaded. Instead, consider making - # a separate helper file that requires the additional dependencies and performs - # the additional setup, and require it from the spec files that actually need - # it. - # - # The `.rspec` file also contains a few flags that are not defaults but that - # users commonly want. - # - # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration - RSpec.configure do |config| - # rspec-expectations config goes here. You can use an alternate - # assertion/expectation library such as wrong or the stdlib/minitest - # assertions if you prefer. - config.expect_with :rspec do |expectations| - # This option will default to `true` in RSpec 4. It makes the `description` - # and `failure_message` of custom matchers include text for helper methods - # defined using `chain`, e.g.: - # be_bigger_than(2).and_smaller_than(4).description - # # => "be bigger than 2 and smaller than 4" - # ...rather than: - # # => "be bigger than 2" - expectations.include_chain_clauses_in_custom_matcher_descriptions = true - end - - # rspec-mocks config goes here. You can use an alternate test double - # library (such as bogus or mocha) by changing the `mock_with` option here. - config.mock_with :rspec do |mocks| - # Prevents you from mocking or stubbing a method that does not exist on - # a real object. This is generally recommended, and will default to - # `true` in RSpec 4. - mocks.verify_partial_doubles = true - end - - # The settings below are suggested to provide a good initial experience - # with RSpec, but feel free to customize to your heart's content. - =begin - # These two settings work together to allow you to limit a spec run - # to individual examples or groups you care about by tagging them with - # `:focus` metadata. When nothing is tagged with `:focus`, all examples - # get run. - config.filter_run :focus - config.run_all_when_everything_filtered = true - - # Allows RSpec to persist some state between runs in order to support - # the `--only-failures` and `--next-failure` CLI options. We recommend - # you configure your source control system to ignore this file. - config.example_status_persistence_file_path = "spec/examples.txt" - - # Limits the available syntax to the non-monkey patched syntax that is - # recommended. For more details, see: - # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax - # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ - # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching - config.disable_monkey_patching! - - # This setting enables warnings. It's recommended, but in many cases may - # be too noisy due to issues in dependencies. - config.warnings = false - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = 'doc' - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed - =end - end - END - - # - # spec/features_helper.rb - # - expect("spec/features_helper.rb").to have_file_content <<~END - # Require this file for feature tests - require_relative './spec_helper' - - require 'capybara' - require 'capybara/rspec' - - RSpec.configure do |config| - config.include RSpec::FeatureExampleGroup - - config.include Capybara::DSL, feature: true - config.include Capybara::RSpecMatchers, feature: true - end - END - - # - # .gitignore - # - expect(".gitignore").to have_file_content <<-END -/db/*.sqlite -/public/assets* -/tmp -.env.local -.env.*.local -END - - # - # apps/web/app.rb - # - expect("apps/web/app.rb").to have_file_content <<-END -require 'hanami/helpers' -require 'hanami/assets' - -module Web - class App < Hanami::App - configure do - ## - # BASIC - # - - # Define the root path of this app. - # All paths specified in this configuration are relative to path below. - # - root __dir__ - - # Relative load paths where this app will recursively load the - # code. - # - # When you add new directories, remember to add them here. - # - load_paths << [ - 'controllers', - 'views' - ] - - # Handle exceptions with HTTP statuses (true) or don't catch them (false). - # Defaults to true. - # See: http://www.rubydoc.info/gems/hanami-controller/#Exceptions_management - # - # handle_exceptions true - - ## - # HTTP - # - - # Routes definitions for this app - # See: http://www.rubydoc.info/gems/hanami-router#Usage - # - routes 'config/routes' - - # URI scheme used by the routing system to generate absolute URLs - # Defaults to "http" - # - # scheme 'https' - - # URI host used by the routing system to generate absolute URLs - # Defaults to "localhost" - # - # host 'example.org' - - # URI port used by the routing system to generate absolute URLs - # Argument: An object coercible to integer, defaults to 80 if the scheme - # is http and 443 if it's https - # - # This should only be configured if app listens to non-standard ports - # - # port 443 - - # Enable cookies - # Argument: boolean to toggle the feature - # A Hash with options - # - # Options: - # :domain - The domain (String - nil by default, not required) - # :path - Restrict cookies to a relative URI - # (String - nil by default) - # :max_age - Cookies expiration expressed in seconds - # (Integer - nil by default) - # :secure - Restrict cookies to secure connections - # (Boolean - Automatically true when using HTTPS) - # See #scheme and #ssl? - # :httponly - Prevent JavaScript access (Boolean - true by default) - # - # cookies true - # or - # cookies max_age: 300 - - # Enable sessions - # Argument: Symbol the Rack session adapter - # A Hash with options - # - # See: http://www.rubydoc.info/gems/rack/Rack/Session/Cookie - # - # sessions :cookie, secret: ENV['WEB_SESSIONS_SECRET'] - - # Configure Rack middleware for this app - # - # middleware.use Rack::Protection - - # Default format for the requests that don't specify an HTTP_ACCEPT header - # Argument: A symbol representation of a mime type, defaults to :html - # - # default_request_format :html - - # Default format for responses that don't consider the request format - # Argument: A symbol representation of a mime type, defaults to :html - # - # default_response_format :html - - ## - # TEMPLATES - # - - # The layout to be used by all views - # - layout :app # It will load Web::Views::AppLayout - - # The relative path to templates - # - templates 'templates' - - ## - # ASSETS - # - assets do - # JavaScript compressor - # - # Supported engines: - # - # * :builtin - # * :uglifier - # * :yui - # * :closure - # - # See: https://guides.hanamirb.org/assets/compressors - # - # In order to skip JavaScript compression comment the following line - javascript_compressor :builtin - - # Stylesheet compressor - # - # Supported engines: - # - # * :builtin - # * :yui - # * :sass - # - # See: https://guides.hanamirb.org/assets/compressors - # - # In order to skip stylesheet compression comment the following line - stylesheet_compressor :builtin - - # Specify sources for assets - # - sources << [ - 'assets' - ] - end - - ## - # SECURITY - # - - # X-Frame-Options is a HTTP header supported by modern browsers. - # It determines if a web page can or cannot be included via and - #