diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72af34b..5c5dadd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,11 +27,11 @@ jobs: with: ruby-version: ${{ matrix.ruby }} - - name: Install dependencies - run: bundle && bundle exec appraisal install + - name: Set up Hotsheet + run: bin/setup - name: Run tests - run: bundle exec appraisal bin/check + run: bin/check lint: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 72abcd7..470369f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ /gemfiles +/spec/dummy/log +/spec/dummy/storage +/spec/dummy/tmp /Gemfile.lock +/spec/dummy/Gemfile.lock diff --git a/.rubocop.yml b/.rubocop.yml index 62edc86..ec7af56 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,3 +7,9 @@ AllCops: Exclude: - gemfiles/**/* - spec/dummy/db/schema.rb + +RSpec/ExampleLength: + CountAsOne: + - array + - hash + - method_call diff --git a/Appraisals b/Appraisals index 622ecd5..89a8c99 100644 --- a/Appraisals +++ b/Appraisals @@ -1,21 +1,25 @@ # frozen_string_literal: true -appraise "rails_6_1" do - gem "rails", "6.1.0" -end +appraise "rails_7_0" do + gem "rails", "~> 7.0.0" -appraise "rails_7" do - gem "rails", "7.0.0" + group :test do + gem "sqlite3", "~> 1.4" + end end appraise "rails_7_1" do - gem "rails", "7.1.0" + gem "rails", "~> 7.1.0" + + group :test do + gem "sqlite3", "~> 1.4" + end end appraise "rails_7_2" do - gem "rails", "7.2.0" + gem "rails", "~> 7.2.0" end -appraise "rails_8" do +appraise "rails_8_0" do gem "rails", "8.0.0.rc2" end diff --git a/Gemfile b/Gemfile index 8982eb0..91ecf0c 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,15 @@ gemspec group :test do gem "appraisal" + gem "better_errors" + gem "binding_of_caller" + gem "capybara" + gem "database_cleaner-active_record", require: false + gem "debug" + gem "faker", require: false + gem "puma" gem "renuocop", require: false - gem "rspec" + gem "rspec-rails" + gem "selenium-webdriver", require: false + gem "sqlite3" end diff --git a/app/controllers/hotsheet/pages_controller.rb b/app/controllers/hotsheet/pages_controller.rb index c2687ed..42b0813 100644 --- a/app/controllers/hotsheet/pages_controller.rb +++ b/app/controllers/hotsheet/pages_controller.rb @@ -17,9 +17,9 @@ def update # rubocop:disable Metrics/AbcSize record = model.find params[:id] if record.update model_params - flash[:notice] = t("hotsheet.success", record: record) + flash[:notice] = t("hotsheet.success", record: model.model_name.human) else - flash[:alert] = t("hotsheet.error", record: record, + flash[:alert] = t("hotsheet.error", record: model.model_name.human, errors: record.errors.full_messages.join(", ")) end diff --git a/app/views/hotsheet/pages/_editable_attribute.html.erb b/app/views/hotsheet/pages/_editable_attribute.html.erb index 39c4c2e..249baa5 100644 --- a/app/views/hotsheet/pages/_editable_attribute.html.erb +++ b/app/views/hotsheet/pages/_editable_attribute.html.erb @@ -7,7 +7,8 @@ data-editable-attribute-resource-id-value="<%= record.id %>">
+ data-action="click->editable-attribute#displayInputField" + role="button"> <%= record.public_send attribute %>
diff --git a/bin/check b/bin/check index 4dc482e..026f70d 100755 --- a/bin/check +++ b/bin/check @@ -1,5 +1,4 @@ #!/usr/bin/env sh -set -eu +set -e -cd spec/dummy -bundle exec rspec --fail-fast=3 -f documentation +bundle exec appraisal "$@" rspec --fail-fast=3 -f documentation diff --git a/bin/fastcheck b/bin/fastcheck index cbbe2d2..86d96a5 100755 --- a/bin/fastcheck +++ b/bin/fastcheck @@ -1,4 +1,4 @@ #!/usr/bin/env sh -set -eu +set -e -bundle exec rubocop -c .rubocop.yml +bundle exec rubocop -c .rubocop.yml "$@" diff --git a/bin/setup b/bin/setup index 65a22f3..8e8d8dc 100755 --- a/bin/setup +++ b/bin/setup @@ -1,10 +1,13 @@ #!/usr/bin/env sh -set -eu +set -e echo ---- Installing dependencies ---- bundle -cd spec/dummy -bundle +bundle exec appraisal install echo ---- Setting up database ---- -bundle exec rails db:drop db:setup +if [ -n "$CI" ]; then + bundle exec rails db:create db:schema:load +else + bundle exec rails db:drop db:setup +fi diff --git a/config/initializers/hotsheet/editable_attributes.rb b/config/initializers/hotsheet/editable_attributes.rb index eef7823..da6afdb 100644 --- a/config/initializers/hotsheet/editable_attributes.rb +++ b/config/initializers/hotsheet/editable_attributes.rb @@ -2,7 +2,7 @@ Rails.application.config.after_initialize do # rubocop:disable Metrics/BlockLength # Only run this initializer when running the Rails server - next unless defined? Rails::Server + next unless Rails.env.test? || defined? Rails::Server Hotsheet.configuration.models.each_key do |model| # rubocop:disable Metrics/BlockLength model.constantize.class_eval do diff --git a/spec/dummy/.gitignore b/spec/dummy/.gitignore deleted file mode 100644 index 9de3c5a..0000000 --- a/spec/dummy/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/log -/storage -/tmp - -/Gemfile.lock -/config/master.key diff --git a/spec/dummy/.ruby-version b/spec/dummy/.ruby-version deleted file mode 100644 index f13c6f4..0000000 --- a/spec/dummy/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -ruby-3.3.5 diff --git a/spec/dummy/Gemfile b/spec/dummy/Gemfile deleted file mode 100644 index 6fcd2df..0000000 --- a/spec/dummy/Gemfile +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -gem "hotsheet", path: "../.." -gem "puma" -gem "sqlite3" - -group :test do - gem "better_errors" - gem "binding_of_caller" - gem "debug" - gem "faker", require: false -end diff --git a/spec/dummy/config/credentials.yml.enc b/spec/dummy/config/credentials.yml.enc deleted file mode 100644 index 63db618..0000000 --- a/spec/dummy/config/credentials.yml.enc +++ /dev/null @@ -1 +0,0 @@ -+wVYTD9Mnl6Rf1JAYIyIPjhvtYDkCqJgxS3m4qoYM5OBIyYARdbgMLNr5p9dQGJlBCqMxQG+3gXIzRI7qRW7kI5jtMTf8Ja0R+8S0ipWAQYvAhuTsq8xJ76zHdIfQof/KGGv4UTicznWaTgcQpJXZ9yJXWvwIJytxQnvdRqOe3pQOCIpJoZVUK2DCyiN1tr+LjTpf3g7/WZk7SRvaZGBJJTgsqm6ADlRIJySCWTQ5K4gVBPho5eb/ZE6t7MmNSYFMfR6ShsLY2ZzgNErlVsQU7wppjkZ9jlVYHOEx6quRAF0Kto8H+tFpW+2QPpxP2qsNr1JqJCQrCs7sum43f96SMZQOlpWsEsuau4Uxd7X6MdJ56hDekHyh0pPIyWE4uTYAwlr1xgq0PTeTvrr2HSIXccNlH96--bIGNUFj/mpHdLvJ2--jXkPjXlqKXctom02A9nzJw== \ No newline at end of file diff --git a/spec/dummy/config/database.yml b/spec/dummy/config/database.yml index fa89ffc..be628ec 100644 --- a/spec/dummy/config/database.yml +++ b/spec/dummy/config/database.yml @@ -1,16 +1,11 @@ -default: &default +development: adapter: sqlite3 + database: storage/development.sqlite3 pool: <%= ENV.fetch "RAILS_MAX_THREADS", 5 %> timeout: 5000 -development: - <<: *default - database: storage/development.sqlite3 - test: - <<: *default + adapter: sqlite3 database: storage/test.sqlite3 - -production: - <<: *default - # database: path/to/persistent/storage/production.sqlite3 + pool: <%= ENV.fetch "RAILS_MAX_THREADS", 5 %> + timeout: 5000 diff --git a/spec/dummy/config/environments/test.rb b/spec/dummy/config/environments/test.rb index d9cac28..6a202ef 100644 --- a/spec/dummy/config/environments/test.rb +++ b/spec/dummy/config/environments/test.rb @@ -3,7 +3,6 @@ Rails.application.configure do config.action_controller.allow_forgery_protection = false config.action_controller.perform_caching = false - config.action_controller.raise_on_missing_callback_actions = true config.action_dispatch.show_exceptions = :all config.action_view.logger = nil config.active_record.migration_error = :raise diff --git a/spec/dummy/db/migrate/20241022111111_create_authors_and_posts.rb b/spec/dummy/db/migrate/20241022111111_create_authors_and_posts.rb index 6df8c2f..9741652 100644 --- a/spec/dummy/db/migrate/20241022111111_create_authors_and_posts.rb +++ b/spec/dummy/db/migrate/20241022111111_create_authors_and_posts.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class CreateAuthorsAndPosts < ActiveRecord::Migration[8.1] +class CreateAuthorsAndPosts < ActiveRecord::Migration[6.1] def change authors posts diff --git a/spec/dummy/db/migrate/20241104095444_create_more_models.rb b/spec/dummy/db/migrate/20241104095444_create_more_models.rb index a842c89..3e43f06 100644 --- a/spec/dummy/db/migrate/20241104095444_create_more_models.rb +++ b/spec/dummy/db/migrate/20241104095444_create_more_models.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class CreateMoreModels < ActiveRecord::Migration[8.1] +class CreateMoreModels < ActiveRecord::Migration[6.1] def change overflow_test different_db_name diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb index 5e6980d..f30f970 100644 --- a/spec/dummy/db/schema.rb +++ b/spec/dummy/db/schema.rb @@ -12,7 +12,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 20_241_104_095_444) do +ActiveRecord::Schema[6.1].define(version: 20_241_104_095_444) do create_table "authors", force: :cascade do |t| t.string "name" t.date "birthdate" diff --git a/spec/dummy/spec/spec_helper.rb b/spec/dummy/spec/spec_helper.rb deleted file mode 100644 index 7b82dc6..0000000 --- a/spec/dummy/spec/spec_helper.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -ENV["RAILS_ENV"] = "test" - -require "rspec/rails" -require_relative "config/environment" - -ActiveRecord::Migration.maintain_test_schema! - -RSpec.configure do |config| - Kernel.srand config.seed - - config.disable_monkey_patching! - config.filter_rails_from_backtrace! - config.infer_spec_type_from_file_location! - config.mock_with(:rspec) { |mocks| mocks.verify_partial_doubles = true } - config.order = :random - config.run_all_when_everything_filtered = true -end diff --git a/spec/lib/configuration_spec.rb b/spec/lib/configuration_spec.rb new file mode 100644 index 0000000..958cfd3 --- /dev/null +++ b/spec/lib/configuration_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "Hotsheet::Configuration" do + let(:config) do + Hotsheet.configure do |config| + config.model :Author do |model| + model.included_attributes = %i[name birthdate] + model.excluded_attributes = %i[created_at] + end + end + end + + it "has included and excluded attributes" do + expect(config).to be_a Hotsheet::Configuration::ModelConfig + expect(config.included_attributes).to eq %i[name birthdate] + expect(config.excluded_attributes).to eq %i[created_at] + end +end diff --git a/spec/dummy/spec/hotsheet_spec.rb b/spec/lib/version_spec.rb similarity index 65% rename from spec/dummy/spec/hotsheet_spec.rb rename to spec/lib/version_spec.rb index 6aa5a66..e9efc3b 100644 --- a/spec/dummy/spec/hotsheet_spec.rb +++ b/spec/lib/version_spec.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true -RSpec.describe Hotsheet do +require "spec_helper" + +RSpec.describe "Hotsheet::VERSION" do it "has a version number" do expect(Hotsheet::VERSION).not_to be_nil end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..ed492d2 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +ENV["RAILS_ENV"] = "test" + +require_relative "dummy/config/environment" +require "database_cleaner-active_record" +require "rspec/rails" +require "selenium-webdriver" + +%i[firefox firefox_headless].each do |driver| + Capybara.register_driver driver do |app| + args = ["--headless"] if driver == :firefox_headless + options = Selenium::WebDriver::Firefox::Options.new args: args + Capybara::Selenium::Driver.new app, browser: :firefox, options: options + end +end + +driver = ENV.fetch("SELENIUM_DRIVER", "firefox_headless").to_sym +Capybara.default_driver = :rack_test +Capybara.javascript_driver = driver +ActiveRecord::Migration.maintain_test_schema! + +RSpec.configure do |config| + Kernel.srand config.seed + + config.include Capybara::DSL + + config.disable_monkey_patching! + config.filter_rails_from_backtrace! + config.infer_spec_type_from_file_location! + config.mock_with(:rspec) { |mocks| mocks.verify_partial_doubles = true } + config.order = :random + config.run_all_when_everything_filtered = true + + config.before :all, type: :system do + FileUtils.rm_rf Rails.root.join "tmp/capybara" + driven_by driver, screen_size: [1280, 800] + end + + config.before :each, type: :system do + DatabaseCleaner.clean_with :truncation + end +end diff --git a/spec/system/editable_attributes_spec.rb b/spec/system/editable_attributes_spec.rb new file mode 100644 index 0000000..897cc1c --- /dev/null +++ b/spec/system/editable_attributes_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "editable attributes", :js do + let!(:author) { Author.create! name: "Stephen", birthdate: "1947-09-21", gender: "male" } + + describe "update strings" do + before do + visit "/hotsheet" + click_link "Author" + find(".readonly-attribute", text: "Stephen").click + fill_in "author_name", with: "King" + end + + it "updates attribute when pressing enter" do + find_by_id("author_name").native.send_keys :return + + expect(page).to have_content("King") + expect(author.reload.name).to eq("King") + end + + it "updates attribute when clicking outside the input" do + find("th", text: "name").click + + expect(page).to have_content("King") + expect(author.reload.name).to eq("King") + end + end +end