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