From a491c87b54f332706aab320bdbcc18ebeb467420 Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Mon, 19 Jul 2021 22:21:34 +0800 Subject: [PATCH 01/15] Add http_verbs option Example: http_verbs: %w[get head] http_verbs: %w[post get head put patch delete] http_verbs: :all --- lib/loaf/configuration.rb | 5 +++- lib/loaf/crumb.rb | 3 ++ lib/loaf/view_extensions.rb | 10 +++++-- spec/support/dummy_view.rb | 28 +++++++++++++++++-- spec/unit/configuration_spec.rb | 3 +- .../view_extensions/breadcrumb_trail_spec.rb | 27 ++++++++++++++++++ 6 files changed, 69 insertions(+), 7 deletions(-) diff --git a/lib/loaf/configuration.rb b/lib/loaf/configuration.rb index f5a8c0f..002f30a 100644 --- a/lib/loaf/configuration.rb +++ b/lib/loaf/configuration.rb @@ -4,7 +4,8 @@ module Loaf class Configuration VALID_ATTRIBUTES = [ :locales_path, - :match + :match, + :http_verbs ].freeze attr_accessor(*VALID_ATTRIBUTES) @@ -13,6 +14,8 @@ class Configuration DEFAULT_MATCH = :inclusive + DEFAULT_HTTP_VERBS = [:get] + # Setup this configuration # # @api public diff --git a/lib/loaf/crumb.rb b/lib/loaf/crumb.rb index 9fe1de1..4652fd4 100644 --- a/lib/loaf/crumb.rb +++ b/lib/loaf/crumb.rb @@ -10,10 +10,13 @@ class Crumb attr_reader :match + attr_reader :http_verbs + def initialize(name, url, options = {}) @name = name || raise_name_error @url = url || raise_url_error @match = options.fetch(:match, Loaf.configuration.match) + @http_verbs = options.fetch(:http_verbs, Loaf.configuration.http_verbs) freeze end diff --git a/lib/loaf/view_extensions.rb b/lib/loaf/view_extensions.rb index bcd158a..bbf4c27 100644 --- a/lib/loaf/view_extensions.rb +++ b/lib/loaf/view_extensions.rb @@ -52,7 +52,11 @@ def breadcrumb_trail(options = {}) _breadcrumbs.each do |crumb| name = title_for(crumb.name) path = url_for(_expand_url(crumb.url)) - current = current_crumb?(path, options.fetch(:match) { crumb.match }) + current = current_crumb?( + path, + options.fetch(:match) { crumb.match }, + options.fetch(:http_verbs) { crumb.http_verbs } + ) yield(Loaf::Breadcrumb[name, path, current]) end @@ -65,8 +69,8 @@ def breadcrumb_trail(options = {}) # the pattern to match on # # @api public - def current_crumb?(path, pattern = :inclusive) - return false unless request.get? || request.head? + def current_crumb?(path, pattern = :inclusive, http_verbs = [:get]) + return false unless http_verbs == :all || http_verbs.any? {|verb| request.send("#{verb}?")} origin_path = URI::DEFAULT_PARSER.unescape(path).force_encoding(Encoding::BINARY) diff --git a/spec/support/dummy_view.rb b/spec/support/dummy_view.rb index 3632830..0ad9297 100644 --- a/spec/support/dummy_view.rb +++ b/spec/support/dummy_view.rb @@ -3,9 +3,29 @@ class DummyView < ActionView::Base module FakeRequest class Request - attr_accessor :path, :fullpath, :protocol, :host_with_port + attr_accessor :path, :fullpath, :protocol, :host_with_port, :_request_method def get? - true + _request_method == nil ? true : _request_method == 'GET' + end + + def post? + _request_method == nil ? false : _request_method == 'POST' + end + + def put? + _request_method == nil ? false : _request_method == 'PUT' + end + + def patch? + _request_method == nil ? false : _request_method == 'PATCH' + end + + def delete? + _request_method == nil ? false : _request_method == 'DELETE' + end + + def head? + _request_method == nil ? false : _request_method == 'HEAD' end end def request @@ -51,4 +71,8 @@ def set_path(path) request.protocol = "http://" request.host_with_port = "www.example.com" end + + def set_request_method(method) + request._request_method = method.upcase.to_s + end end diff --git a/spec/unit/configuration_spec.rb b/spec/unit/configuration_spec.rb index b90bfde..715dff0 100644 --- a/spec/unit/configuration_spec.rb +++ b/spec/unit/configuration_spec.rb @@ -19,7 +19,8 @@ config = Loaf::Configuration.new expect(config.to_hash).to eq({ locales_path: "/", - match: :inclusive + match: :inclusive, + http_verbs: [:get] }) end diff --git a/spec/unit/view_extensions/breadcrumb_trail_spec.rb b/spec/unit/view_extensions/breadcrumb_trail_spec.rb index 11658bb..95ea91c 100644 --- a/spec/unit/view_extensions/breadcrumb_trail_spec.rb +++ b/spec/unit/view_extensions/breadcrumb_trail_spec.rb @@ -280,4 +280,31 @@ expect(view.breadcrumb_trail.map(&:url)).to eq(%w[/ /posts /posts/1]) expect(view.breadcrumb_trail(match: :exact).map(&:current?)).to eq([false, false, true]) end + + it "match current path with :http_verbs" do + view = DummyView.new + view.breadcrumb("posts", "/posts", http_verbs: [:get, :post]) + view.set_path("/posts") + view.set_request_method(:post) + + expect(view.breadcrumb_trail.map(&:to_a)).to eq([["posts", "/posts", true]]) + end + + it "fail to match current path with :http_verbs" do + view = DummyView.new + view.breadcrumb("posts", "/posts") + view.set_path("/posts") + view.set_request_method(:post) + + expect(view.breadcrumb_trail.map(&:to_a)).to eq([["posts", "/posts", false]]) + end + + it "match current path with :http_verbs => :all" do + view = DummyView.new + view.breadcrumb("posts", "/posts", http_verbs: :all) + view.set_path("/posts") + view.set_request_method(:delete) + + expect(view.breadcrumb_trail.map(&:to_a)).to eq([["posts", "/posts", true]]) + end end From 288cb8cd9e6a2616f0f5860aeb7563c037daa107 Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Mon, 19 Jul 2021 22:23:02 +0800 Subject: [PATCH 02/15] Add integration tests for http_verbs --- spec/integration/breadcrumb_trail_spec.rb | 48 +++++++++++++++++++ .../app/controllers/onboard_controller.rb | 29 +++++++++++ .../app/views/onboard/setup.html.erb | 3 ++ .../app/views/onboard/step1.html.erb | 2 + .../app/views/onboard/step2.html.erb | 2 + .../app/views/onboard/step3.html.erb | 2 + .../app/views/onboard/step4.html.erb | 2 + .../app/views/onboard/step5.html.erb | 2 + .../app/views/onboard/step6.html.erb | 1 + spec/rails_app/config/routes.rb | 7 +++ 10 files changed, 98 insertions(+) create mode 100644 spec/rails_app/app/controllers/onboard_controller.rb create mode 100644 spec/rails_app/app/views/onboard/setup.html.erb create mode 100644 spec/rails_app/app/views/onboard/step1.html.erb create mode 100644 spec/rails_app/app/views/onboard/step2.html.erb create mode 100644 spec/rails_app/app/views/onboard/step3.html.erb create mode 100644 spec/rails_app/app/views/onboard/step4.html.erb create mode 100644 spec/rails_app/app/views/onboard/step5.html.erb create mode 100644 spec/rails_app/app/views/onboard/step6.html.erb diff --git a/spec/integration/breadcrumb_trail_spec.rb b/spec/integration/breadcrumb_trail_spec.rb index bda6c72..17b2667 100644 --- a/spec/integration/breadcrumb_trail_spec.rb +++ b/spec/integration/breadcrumb_trail_spec.rb @@ -70,4 +70,52 @@ ) end end + + it 'match to Non-GET methods' do + visit onboard_path + + expect(page).to have_selector('h1', text: 'Onboard') + page.within '#breadcrumbs' do + expect(page).to have_content('Onboard') + end + + click_link 'Step 1' # GET + expect(page).to have_selector('h1', text: 'Step 1') + page.within '#breadcrumbs' do + expect(page.html).to include('Onboard') + end + page.within '#breadcrumbs .selected' do + expect(page.html).to include('Step 1') + end + + click_on 'Save & Next' # POST + expect(page).to have_selector('h1', text: 'Step 2') + page.within '#breadcrumbs .selected' do + expect(page.html).to include('Step 2') + end + + click_on 'Save & Next' # PUT + expect(page).to have_selector('h1', text: 'Step 3') + page.within '#breadcrumbs .selected' do + expect(page.html).to include('Step 3') + end + + click_on 'Save & Next' # PATCH + expect(page).to have_selector('h1', text: 'Step 4') + page.within '#breadcrumbs .selected' do + expect(page.html).to include('Step 4') + end + + click_on 'Save & Next' # DELETE + expect(page).to have_selector('h1', text: 'Step 5') + page.within '#breadcrumbs .selected' do + expect(page.html).to include('Step 5') + end + + click_on 'Save & Next' # GET + expect(page).to have_selector('h1', text: 'Step 6') + page.within '#breadcrumbs .selected' do + expect(page.html).to include('Step 6') + end + end end diff --git a/spec/rails_app/app/controllers/onboard_controller.rb b/spec/rails_app/app/controllers/onboard_controller.rb new file mode 100644 index 0000000..1dd8914 --- /dev/null +++ b/spec/rails_app/app/controllers/onboard_controller.rb @@ -0,0 +1,29 @@ +class OnboardController < ApplicationController + + breadcrumb 'Onboard', :onboard_path, match: :exact + + def setup + case params[:step] + when '1' + breadcrumb 'Step 1', onboard_step_path(step: 1), match: :exact, http_verbs: [:get] + render 'step1' + when '2' + breadcrumb 'Step 2', onboard_step_path(step: 2), match: :exact, http_verbs: [:get, :post] + render 'step2' + when '3' + breadcrumb 'Step 3', onboard_step_path(step: 3), match: :exact, http_verbs: [:get, :put] + render 'step3' + when '4' + breadcrumb 'Step 4', onboard_step_path(step: 4), match: :exact, http_verbs: [:get, :patch] + render 'step4' + when '5' + breadcrumb 'Step 5', onboard_step_path(step: 5), match: :exact, http_verbs: [:get, :delete] + render 'step5' + when '6' + breadcrumb 'Step 6', onboard_step_path(step: 6), match: :exact, http_verbs: :all + render 'step6' + else + render 'setup' + end + end +end \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/setup.html.erb b/spec/rails_app/app/views/onboard/setup.html.erb new file mode 100644 index 0000000..40c556e --- /dev/null +++ b/spec/rails_app/app/views/onboard/setup.html.erb @@ -0,0 +1,3 @@ +

Onboard

+ +<%= link_to 'Step 1', onboard_step_path(step: 1) %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step1.html.erb b/spec/rails_app/app/views/onboard/step1.html.erb new file mode 100644 index 0000000..3332270 --- /dev/null +++ b/spec/rails_app/app/views/onboard/step1.html.erb @@ -0,0 +1,2 @@ +

Step 1

+<%= button_to 'Save & Next', onboard_step_path(step: 2), method: :post %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step2.html.erb b/spec/rails_app/app/views/onboard/step2.html.erb new file mode 100644 index 0000000..92530d4 --- /dev/null +++ b/spec/rails_app/app/views/onboard/step2.html.erb @@ -0,0 +1,2 @@ +

Step 2

+<%= button_to 'Save & Next', onboard_step_path(step: 3), method: :put %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step3.html.erb b/spec/rails_app/app/views/onboard/step3.html.erb new file mode 100644 index 0000000..20cb1a5 --- /dev/null +++ b/spec/rails_app/app/views/onboard/step3.html.erb @@ -0,0 +1,2 @@ +

Step 3

+<%= button_to 'Save & Next', onboard_step_path(step: 4), method: :patch %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step4.html.erb b/spec/rails_app/app/views/onboard/step4.html.erb new file mode 100644 index 0000000..5d24b46 --- /dev/null +++ b/spec/rails_app/app/views/onboard/step4.html.erb @@ -0,0 +1,2 @@ +

Step 4

+<%= button_to 'Save & Next', onboard_step_path(step: 5), method: :delete %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step5.html.erb b/spec/rails_app/app/views/onboard/step5.html.erb new file mode 100644 index 0000000..7ec3806 --- /dev/null +++ b/spec/rails_app/app/views/onboard/step5.html.erb @@ -0,0 +1,2 @@ +

Step 5

+<%= button_to 'Save & Next', onboard_step_path(step: 6), method: :get %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step6.html.erb b/spec/rails_app/app/views/onboard/step6.html.erb new file mode 100644 index 0000000..0f72669 --- /dev/null +++ b/spec/rails_app/app/views/onboard/step6.html.erb @@ -0,0 +1 @@ +

Step 6

\ No newline at end of file diff --git a/spec/rails_app/config/routes.rb b/spec/rails_app/config/routes.rb index ff293a3..5d6c215 100644 --- a/spec/rails_app/config/routes.rb +++ b/spec/rails_app/config/routes.rb @@ -4,4 +4,11 @@ resources :posts do resources :comments end + + get '/onboard', to: 'onboard#setup', as: :onboard + get '/onboard/step/:step', to: 'onboard#setup', as: :onboard_step + post '/onboard/step/:step', to: 'onboard#setup' + patch '/onboard/step/:step', to: 'onboard#setup' + put '/onboard/step/:step', to: 'onboard#setup' + delete '/onboard/step/:step', to: 'onboard#setup' end From bbea64a23b3a541a2dba79e64aab787aae4516ce Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Mon, 19 Jul 2021 22:24:12 +0800 Subject: [PATCH 03/15] Add byebug and rspec focus --- .gitignore | 1 + Gemfile | 1 + spec/support/capybara.rb | 1 + 3 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 404ce1a..d5041ae 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ tmp *.o *.a mkmf.log +.byebug_history \ No newline at end of file diff --git a/Gemfile b/Gemfile index eca8bb8..c04ca17 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,7 @@ gem 'yard', '~> 0.9.24' gem 'capybara', '~> 3.30.0' gem 'rspec-rails', '~> 3.9.0' gem 'public_suffix', '~> 2.0.5' +gem 'byebug' group :metrics do gem 'coveralls', '0.8.23' diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 1ffbe95..c577633 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -3,6 +3,7 @@ RSpec.configure do |c| c.include Capybara::DSL, :file_path => /\bspec\/integration\// + c.filter_run_when_matching :focus => true end Capybara.default_driver = :rack_test Capybara.default_selector = :css From 47d50b75139b2b4f84da257fa71a58d8800ccdbf Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Mon, 19 Jul 2021 22:35:39 +0800 Subject: [PATCH 04/15] Update README for :http_verbs --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index 276b6d3..71e3d65 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ rails generate loaf:install * [2.1.1 controller](#211-controller) * [2.1.2 view](#212-view) * [2.1.3 :match](#213-match) + * [2.1.4 :http_verbs](#214-http_verbs) * [2.2 breadcrumb_trail](#22-breadcrumb_trail) * [3. Configuration](#3-configuration) * [4. Translation](#4-translation) @@ -207,6 +208,29 @@ To make a breadcrumb current based on the query parameters do: breadcrumb "Posts", posts_path(order: :desc), match: {order: :desc} ``` +#### 2.1.4 :http_verbs + +**Loaf** allows you to match on multiple HTTP verbs in order to make a breadcrumb current with the `:http_verbs` option. + +The `:http_verbs` key accepts `:all` or an array with following values: + +* `:get` +* `:post` +* `:put` +* `:patch` +* `:delete` +* `:head` + +Its default value is `[:get]` + +For example: + +```ruby +http_verbs: %w[get head] +http_verbs: %w[post get head] +http_verbs: :all +``` + ### 2.2 breadcrumb_trail In order to display breadcrumbs use the `breadcrumb_trail` view helper. It accepts optional argument of configuration options and can be used in two ways. From 989462d702d19edf4b8de850e6e4e825071431bc Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Tue, 20 Jul 2021 19:53:47 +0800 Subject: [PATCH 05/15] Remove byebug --- Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Gemfile b/Gemfile index c04ca17..eca8bb8 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,6 @@ gem 'yard', '~> 0.9.24' gem 'capybara', '~> 3.30.0' gem 'rspec-rails', '~> 3.9.0' gem 'public_suffix', '~> 2.0.5' -gem 'byebug' group :metrics do gem 'coveralls', '0.8.23' From 2299dedae4825c2d1bbc60218a61407791aac29e Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Tue, 20 Jul 2021 19:55:56 +0800 Subject: [PATCH 06/15] Change http_verbs default value to [:get, :head] --- README.md | 6 +++--- lib/loaf/configuration.rb | 2 +- spec/unit/configuration_spec.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 71e3d65..b716f71 100644 --- a/README.md +++ b/README.md @@ -221,13 +221,13 @@ The `:http_verbs` key accepts `:all` or an array with following values: * `:delete` * `:head` -Its default value is `[:get]` +Its default value is `[:get, :head]` For example: ```ruby -http_verbs: %w[get head] -http_verbs: %w[post get head] +http_verbs: %i[get head] +http_verbs: %i[post get head] http_verbs: :all ``` diff --git a/lib/loaf/configuration.rb b/lib/loaf/configuration.rb index 002f30a..04795a3 100644 --- a/lib/loaf/configuration.rb +++ b/lib/loaf/configuration.rb @@ -14,7 +14,7 @@ class Configuration DEFAULT_MATCH = :inclusive - DEFAULT_HTTP_VERBS = [:get] + DEFAULT_HTTP_VERBS = [:get, :head] # Setup this configuration # diff --git a/spec/unit/configuration_spec.rb b/spec/unit/configuration_spec.rb index 715dff0..edb131c 100644 --- a/spec/unit/configuration_spec.rb +++ b/spec/unit/configuration_spec.rb @@ -20,7 +20,7 @@ expect(config.to_hash).to eq({ locales_path: "/", match: :inclusive, - http_verbs: [:get] + http_verbs: [:get, :head] }) end From f94f2727505aee42f48b17694922cc20c604e6bc Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Tue, 20 Jul 2021 20:12:24 +0800 Subject: [PATCH 07/15] Fix some ruby style issues --- lib/loaf/configuration.rb | 6 +-- lib/loaf/view_extensions.rb | 4 +- spec/integration/breadcrumb_trail_spec.rb | 42 +++++++++---------- .../app/controllers/onboard_controller.rb | 40 +++++++++--------- .../app/views/onboard/setup.html.erb | 2 +- .../app/views/onboard/step1.html.erb | 2 +- .../app/views/onboard/step2.html.erb | 2 +- .../app/views/onboard/step3.html.erb | 2 +- .../app/views/onboard/step4.html.erb | 2 +- .../app/views/onboard/step5.html.erb | 2 +- spec/support/dummy_view.rb | 12 +++--- 11 files changed, 58 insertions(+), 58 deletions(-) diff --git a/lib/loaf/configuration.rb b/lib/loaf/configuration.rb index 04795a3..25d69e2 100644 --- a/lib/loaf/configuration.rb +++ b/lib/loaf/configuration.rb @@ -3,9 +3,9 @@ module Loaf class Configuration VALID_ATTRIBUTES = [ + :http_verbs, :locales_path, - :match, - :http_verbs + :match ].freeze attr_accessor(*VALID_ATTRIBUTES) @@ -14,7 +14,7 @@ class Configuration DEFAULT_MATCH = :inclusive - DEFAULT_HTTP_VERBS = [:get, :head] + DEFAULT_HTTP_VERBS = [:get, :head].freeze # Setup this configuration # diff --git a/lib/loaf/view_extensions.rb b/lib/loaf/view_extensions.rb index bbf4c27..ec3bd59 100644 --- a/lib/loaf/view_extensions.rb +++ b/lib/loaf/view_extensions.rb @@ -55,7 +55,7 @@ def breadcrumb_trail(options = {}) current = current_crumb?( path, options.fetch(:match) { crumb.match }, - options.fetch(:http_verbs) { crumb.http_verbs } + http_verbs: options.fetch(:http_verbs) { crumb.http_verbs } ) yield(Loaf::Breadcrumb[name, path, current]) @@ -69,7 +69,7 @@ def breadcrumb_trail(options = {}) # the pattern to match on # # @api public - def current_crumb?(path, pattern = :inclusive, http_verbs = [:get]) + def current_crumb?(path, pattern = :inclusive, http_verbs: Loaf.configuration.http_verbs) return false unless http_verbs == :all || http_verbs.any? {|verb| request.send("#{verb}?")} origin_path = URI::DEFAULT_PARSER.unescape(path).force_encoding(Encoding::BINARY) diff --git a/spec/integration/breadcrumb_trail_spec.rb b/spec/integration/breadcrumb_trail_spec.rb index 17b2667..90e9039 100644 --- a/spec/integration/breadcrumb_trail_spec.rb +++ b/spec/integration/breadcrumb_trail_spec.rb @@ -71,50 +71,50 @@ end end - it 'match to Non-GET methods' do + it "match to Non-GET methods" do visit onboard_path - expect(page).to have_selector('h1', text: 'Onboard') - page.within '#breadcrumbs' do - expect(page).to have_content('Onboard') + expect(page).to have_selector("h1", text: "Onboard") + page.within "#breadcrumbs" do + expect(page).to have_content("Onboard") end - click_link 'Step 1' # GET - expect(page).to have_selector('h1', text: 'Step 1') + click_link "Step 1" # GET + expect(page).to have_selector("h1", text: "Step 1") page.within '#breadcrumbs' do expect(page.html).to include('Onboard') end - page.within '#breadcrumbs .selected' do + page.within "#breadcrumbs .selected" do expect(page.html).to include('Step 1') end - click_on 'Save & Next' # POST - expect(page).to have_selector('h1', text: 'Step 2') - page.within '#breadcrumbs .selected' do + click_on "Save & Next" # POST + expect(page).to have_selector("h1", text: "Step 2") + page.within "#breadcrumbs .selected" do expect(page.html).to include('Step 2') end - click_on 'Save & Next' # PUT - expect(page).to have_selector('h1', text: 'Step 3') - page.within '#breadcrumbs .selected' do + click_on "Save & Next" # PUT + expect(page).to have_selector("h1", text: "Step 3") + page.within "#breadcrumbs .selected" do expect(page.html).to include('Step 3') end - click_on 'Save & Next' # PATCH - expect(page).to have_selector('h1', text: 'Step 4') + click_on "Save & Next" # PATCH + expect(page).to have_selector("h1", text: "Step 4") page.within '#breadcrumbs .selected' do expect(page.html).to include('Step 4') end - click_on 'Save & Next' # DELETE - expect(page).to have_selector('h1', text: 'Step 5') - page.within '#breadcrumbs .selected' do + click_on "Save & Next" # DELETE + expect(page).to have_selector("h1", text: "Step 5") + page.within "#breadcrumbs .selected" do expect(page.html).to include('Step 5') end - click_on 'Save & Next' # GET - expect(page).to have_selector('h1', text: 'Step 6') - page.within '#breadcrumbs .selected' do + click_on "Save & Next" # GET + expect(page).to have_selector("h1", text: "Step 6") + page.within "#breadcrumbs .selected" do expect(page.html).to include('Step 6') end end diff --git a/spec/rails_app/app/controllers/onboard_controller.rb b/spec/rails_app/app/controllers/onboard_controller.rb index 1dd8914..a7a7757 100644 --- a/spec/rails_app/app/controllers/onboard_controller.rb +++ b/spec/rails_app/app/controllers/onboard_controller.rb @@ -1,29 +1,29 @@ class OnboardController < ApplicationController - breadcrumb 'Onboard', :onboard_path, match: :exact + breadcrumb "Onboard", :onboard_path, match: :exact def setup case params[:step] - when '1' - breadcrumb 'Step 1', onboard_step_path(step: 1), match: :exact, http_verbs: [:get] - render 'step1' - when '2' - breadcrumb 'Step 2', onboard_step_path(step: 2), match: :exact, http_verbs: [:get, :post] - render 'step2' - when '3' - breadcrumb 'Step 3', onboard_step_path(step: 3), match: :exact, http_verbs: [:get, :put] - render 'step3' - when '4' - breadcrumb 'Step 4', onboard_step_path(step: 4), match: :exact, http_verbs: [:get, :patch] - render 'step4' - when '5' - breadcrumb 'Step 5', onboard_step_path(step: 5), match: :exact, http_verbs: [:get, :delete] - render 'step5' - when '6' - breadcrumb 'Step 6', onboard_step_path(step: 6), match: :exact, http_verbs: :all - render 'step6' + when "1" + breadcrumb "Step 1", onboard_step_path(step: 1), match: :exact, http_verbs: [:get] + render "step1" + when "2" + breadcrumb "Step 2", onboard_step_path(step: 2), match: :exact, http_verbs: [:get, :post] + render "step2" + when "3" + breadcrumb "Step 3", onboard_step_path(step: 3), match: :exact, http_verbs: [:get, :put] + render "step3" + when "4" + breadcrumb "Step 4", onboard_step_path(step: 4), match: :exact, http_verbs: [:get, :patch] + render "step4" + when "5" + breadcrumb "Step 5", onboard_step_path(step: 5), match: :exact, http_verbs: [:get, :delete] + render "step5" + when "6" + breadcrumb "Step 6", onboard_step_path(step: 6), match: :exact, http_verbs: :all + render "step6" else - render 'setup' + render "setup" end end end \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/setup.html.erb b/spec/rails_app/app/views/onboard/setup.html.erb index 40c556e..5b4fea4 100644 --- a/spec/rails_app/app/views/onboard/setup.html.erb +++ b/spec/rails_app/app/views/onboard/setup.html.erb @@ -1,3 +1,3 @@

Onboard

-<%= link_to 'Step 1', onboard_step_path(step: 1) %> \ No newline at end of file +<%= link_to "Step 1", onboard_step_path(step: 1) %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step1.html.erb b/spec/rails_app/app/views/onboard/step1.html.erb index 3332270..0052960 100644 --- a/spec/rails_app/app/views/onboard/step1.html.erb +++ b/spec/rails_app/app/views/onboard/step1.html.erb @@ -1,2 +1,2 @@

Step 1

-<%= button_to 'Save & Next', onboard_step_path(step: 2), method: :post %> \ No newline at end of file +<%= button_to "Save & Next", onboard_step_path(step: 2), method: :post %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step2.html.erb b/spec/rails_app/app/views/onboard/step2.html.erb index 92530d4..0ea7e80 100644 --- a/spec/rails_app/app/views/onboard/step2.html.erb +++ b/spec/rails_app/app/views/onboard/step2.html.erb @@ -1,2 +1,2 @@

Step 2

-<%= button_to 'Save & Next', onboard_step_path(step: 3), method: :put %> \ No newline at end of file +<%= button_to "Save & Next", onboard_step_path(step: 3), method: :put %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step3.html.erb b/spec/rails_app/app/views/onboard/step3.html.erb index 20cb1a5..c0995eb 100644 --- a/spec/rails_app/app/views/onboard/step3.html.erb +++ b/spec/rails_app/app/views/onboard/step3.html.erb @@ -1,2 +1,2 @@

Step 3

-<%= button_to 'Save & Next', onboard_step_path(step: 4), method: :patch %> \ No newline at end of file +<%= button_to "Save & Next", onboard_step_path(step: 4), method: :patch %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step4.html.erb b/spec/rails_app/app/views/onboard/step4.html.erb index 5d24b46..e425a0d 100644 --- a/spec/rails_app/app/views/onboard/step4.html.erb +++ b/spec/rails_app/app/views/onboard/step4.html.erb @@ -1,2 +1,2 @@

Step 4

-<%= button_to 'Save & Next', onboard_step_path(step: 5), method: :delete %> \ No newline at end of file +<%= button_to "Save & Next", onboard_step_path(step: 5), method: :delete %> \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step5.html.erb b/spec/rails_app/app/views/onboard/step5.html.erb index 7ec3806..a28f358 100644 --- a/spec/rails_app/app/views/onboard/step5.html.erb +++ b/spec/rails_app/app/views/onboard/step5.html.erb @@ -1,2 +1,2 @@

Step 5

-<%= button_to 'Save & Next', onboard_step_path(step: 6), method: :get %> \ No newline at end of file +<%= button_to "Save & Next", onboard_step_path(step: 6), method: :get %> \ No newline at end of file diff --git a/spec/support/dummy_view.rb b/spec/support/dummy_view.rb index 0ad9297..687ba3b 100644 --- a/spec/support/dummy_view.rb +++ b/spec/support/dummy_view.rb @@ -5,27 +5,27 @@ module FakeRequest class Request attr_accessor :path, :fullpath, :protocol, :host_with_port, :_request_method def get? - _request_method == nil ? true : _request_method == 'GET' + _request_method == nil ? true : _request_method == "GET" end def post? - _request_method == nil ? false : _request_method == 'POST' + _request_method == nil ? false : _request_method == "POST" end def put? - _request_method == nil ? false : _request_method == 'PUT' + _request_method == nil ? false : _request_method == "PUT" end def patch? - _request_method == nil ? false : _request_method == 'PATCH' + _request_method == nil ? false : _request_method == "PATCH" end def delete? - _request_method == nil ? false : _request_method == 'DELETE' + _request_method == nil ? false : _request_method == "DELETE" end def head? - _request_method == nil ? false : _request_method == 'HEAD' + _request_method == nil ? false : _request_method == "HEAD" end end def request From 9fa3f4581679d5074a34a3aa553f70ed264ef01f Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Tue, 20 Jul 2021 20:54:49 +0800 Subject: [PATCH 08/15] Refactor ViewExtensions#current_crumb? to use try --- lib/loaf/view_extensions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/loaf/view_extensions.rb b/lib/loaf/view_extensions.rb index ec3bd59..9cd87d8 100644 --- a/lib/loaf/view_extensions.rb +++ b/lib/loaf/view_extensions.rb @@ -70,7 +70,7 @@ def breadcrumb_trail(options = {}) # # @api public def current_crumb?(path, pattern = :inclusive, http_verbs: Loaf.configuration.http_verbs) - return false unless http_verbs == :all || http_verbs.any? {|verb| request.send("#{verb}?")} + return false unless http_verbs == :all || http_verbs.any? {|verb| request.try("#{verb}?")} origin_path = URI::DEFAULT_PARSER.unescape(path).force_encoding(Encoding::BINARY) From b8478a01f5b1e542a9e69ac7b87bb3d27ae85be3 Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Tue, 20 Jul 2021 20:56:39 +0800 Subject: [PATCH 09/15] Add more http_verbs options in README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b716f71..7cfb15e 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,10 @@ The `:http_verbs` key accepts `:all` or an array with following values: * `:patch` * `:delete` * `:head` +* `:options` +* `:link` +* `:unlink` +* `:trace` Its default value is `[:get, :head]` From aa45ffa3d9ab03d25d2d3efbd50b07b2623e3151 Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Wed, 28 Jul 2021 09:11:01 +0800 Subject: [PATCH 10/15] Fix more ruby style issues --- README.md | 2 +- lib/loaf/configuration.rb | 2 +- lib/loaf/view_extensions.rb | 16 ++++++++++++-- spec/integration/breadcrumb_trail_spec.rb | 2 +- .../app/controllers/onboard_controller.rb | 21 ++++++++++++------- spec/rails_app/config/routes.rb | 14 ++++++------- spec/unit/configuration_spec.rb | 2 +- 7 files changed, 39 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 7cfb15e..82aded2 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ The `:http_verbs` key accepts `:all` or an array with following values: * `:unlink` * `:trace` -Its default value is `[:get, :head]` +Its default value is `%i[get head]` For example: diff --git a/lib/loaf/configuration.rb b/lib/loaf/configuration.rb index 25d69e2..28d7535 100644 --- a/lib/loaf/configuration.rb +++ b/lib/loaf/configuration.rb @@ -14,7 +14,7 @@ class Configuration DEFAULT_MATCH = :inclusive - DEFAULT_HTTP_VERBS = [:get, :head].freeze + DEFAULT_HTTP_VERBS = %i[get head].freeze # Setup this configuration # diff --git a/lib/loaf/view_extensions.rb b/lib/loaf/view_extensions.rb index 9cd87d8..f0c2a9a 100644 --- a/lib/loaf/view_extensions.rb +++ b/lib/loaf/view_extensions.rb @@ -69,8 +69,8 @@ def breadcrumb_trail(options = {}) # the pattern to match on # # @api public - def current_crumb?(path, pattern = :inclusive, http_verbs: Loaf.configuration.http_verbs) - return false unless http_verbs == :all || http_verbs.any? {|verb| request.try("#{verb}?")} + def current_crumb?(path, pattern = :inclusive, http_verbs: nil) + return false unless match_http_verbs(http_verbs) origin_path = URI::DEFAULT_PARSER.unescape(path).force_encoding(Encoding::BINARY) @@ -132,5 +132,17 @@ def _expand_url(url) url end end + + # Check if the HTTP verbs are allowed + # + # @retun [Boolean] + # + # @api private + def match_http_verbs(http_verbs) + http_verbs ||= Loaf.configuration.http_verbs + return true if http_verbs == :all + + http_verbs.any? { |verb| request.try("#{verb}?") } + end end # ViewExtensions end # Loaf diff --git a/spec/integration/breadcrumb_trail_spec.rb b/spec/integration/breadcrumb_trail_spec.rb index 90e9039..275c78c 100644 --- a/spec/integration/breadcrumb_trail_spec.rb +++ b/spec/integration/breadcrumb_trail_spec.rb @@ -81,7 +81,7 @@ click_link "Step 1" # GET expect(page).to have_selector("h1", text: "Step 1") - page.within '#breadcrumbs' do + page.within "#breadcrumbs" do expect(page.html).to include('Onboard') end page.within "#breadcrumbs .selected" do diff --git a/spec/rails_app/app/controllers/onboard_controller.rb b/spec/rails_app/app/controllers/onboard_controller.rb index a7a7757..cff3117 100644 --- a/spec/rails_app/app/controllers/onboard_controller.rb +++ b/spec/rails_app/app/controllers/onboard_controller.rb @@ -1,26 +1,33 @@ -class OnboardController < ApplicationController +# frozen_string_literal: true +class OnboardController < ApplicationController breadcrumb "Onboard", :onboard_path, match: :exact def setup case params[:step] when "1" - breadcrumb "Step 1", onboard_step_path(step: 1), match: :exact, http_verbs: [:get] + breadcrumb "Step 1", onboard_step_path(step: 1), + match: :exact, http_verbs: %i[get] render "step1" when "2" - breadcrumb "Step 2", onboard_step_path(step: 2), match: :exact, http_verbs: [:get, :post] + breadcrumb "Step 2", onboard_step_path(step: 2), + match: :exact, http_verbs: %i[get post] render "step2" when "3" - breadcrumb "Step 3", onboard_step_path(step: 3), match: :exact, http_verbs: [:get, :put] + breadcrumb "Step 3", onboard_step_path(step: 3), + match: :exact, http_verbs: %i[get put] render "step3" when "4" - breadcrumb "Step 4", onboard_step_path(step: 4), match: :exact, http_verbs: [:get, :patch] + breadcrumb "Step 4", onboard_step_path(step: 4), + match: :exact, http_verbs: %i[get patch] render "step4" when "5" - breadcrumb "Step 5", onboard_step_path(step: 5), match: :exact, http_verbs: [:get, :delete] + breadcrumb "Step 5", onboard_step_path(step: 5), + match: :exact, http_verbs: %i[get delete] render "step5" when "6" - breadcrumb "Step 6", onboard_step_path(step: 6), match: :exact, http_verbs: :all + breadcrumb "Step 6", onboard_step_path(step: 6), + match: :exact, http_verbs: :all render "step6" else render "setup" diff --git a/spec/rails_app/config/routes.rb b/spec/rails_app/config/routes.rb index 5d6c215..e4a2921 100644 --- a/spec/rails_app/config/routes.rb +++ b/spec/rails_app/config/routes.rb @@ -1,14 +1,14 @@ RailsApp::Application.routes.draw do - root :to => 'home#index' + root :to => "home#index" resources :posts do resources :comments end - get '/onboard', to: 'onboard#setup', as: :onboard - get '/onboard/step/:step', to: 'onboard#setup', as: :onboard_step - post '/onboard/step/:step', to: 'onboard#setup' - patch '/onboard/step/:step', to: 'onboard#setup' - put '/onboard/step/:step', to: 'onboard#setup' - delete '/onboard/step/:step', to: 'onboard#setup' + get "/onboard", to: "onboard#setup", as: :onboard + get "/onboard/step/:step", to: "onboard#setup", as: :onboard_step + post "/onboard/step/:step", to: "onboard#setup" + patch "/onboard/step/:step", to: "onboard#setup" + put "/onboard/step/:step", to: "onboard#setup" + delete "/onboard/step/:step", to: "onboard#setup" end diff --git a/spec/unit/configuration_spec.rb b/spec/unit/configuration_spec.rb index edb131c..ab08e03 100644 --- a/spec/unit/configuration_spec.rb +++ b/spec/unit/configuration_spec.rb @@ -20,7 +20,7 @@ expect(config.to_hash).to eq({ locales_path: "/", match: :inclusive, - http_verbs: [:get, :head] + http_verbs: %i[get head] }) end From 64aa93d0783edb346c13a260dc1d282fe623abc1 Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Wed, 28 Jul 2021 20:01:07 +0800 Subject: [PATCH 11/15] Turn off PATCH test when running test for rails3.2 --- spec/integration/breadcrumb_trail_spec.rb | 10 ++++++---- .../app/controllers/onboard_controller.rb | 14 +++++++------- spec/rails_app/app/views/onboard/step3.html.erb | 6 +++++- spec/rails_app/config/routes.rb | 4 +++- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/spec/integration/breadcrumb_trail_spec.rb b/spec/integration/breadcrumb_trail_spec.rb index 275c78c..c18bc05 100644 --- a/spec/integration/breadcrumb_trail_spec.rb +++ b/spec/integration/breadcrumb_trail_spec.rb @@ -100,10 +100,12 @@ expect(page.html).to include('Step 3') end - click_on "Save & Next" # PATCH - expect(page).to have_selector("h1", text: "Step 4") - page.within '#breadcrumbs .selected' do - expect(page.html).to include('Step 4') + if Rails.version >= "4.0.0" + click_on "Save & Next" # PATCH + expect(page).to have_selector("h1", text: "Step 4") + page.within '#breadcrumbs .selected' do + expect(page.html).to include('Step 4') + end end click_on "Save & Next" # DELETE diff --git a/spec/rails_app/app/controllers/onboard_controller.rb b/spec/rails_app/app/controllers/onboard_controller.rb index cff3117..74e0e07 100644 --- a/spec/rails_app/app/controllers/onboard_controller.rb +++ b/spec/rails_app/app/controllers/onboard_controller.rb @@ -8,29 +8,29 @@ def setup when "1" breadcrumb "Step 1", onboard_step_path(step: 1), match: :exact, http_verbs: %i[get] - render "step1" + render :step1 when "2" breadcrumb "Step 2", onboard_step_path(step: 2), match: :exact, http_verbs: %i[get post] - render "step2" + render :step2 when "3" breadcrumb "Step 3", onboard_step_path(step: 3), match: :exact, http_verbs: %i[get put] - render "step3" + render :step3 when "4" breadcrumb "Step 4", onboard_step_path(step: 4), match: :exact, http_verbs: %i[get patch] - render "step4" + render :step4 when "5" breadcrumb "Step 5", onboard_step_path(step: 5), match: :exact, http_verbs: %i[get delete] - render "step5" + render :step5 when "6" breadcrumb "Step 6", onboard_step_path(step: 6), match: :exact, http_verbs: :all - render "step6" + render :step6 else - render "setup" + render :setup end end end \ No newline at end of file diff --git a/spec/rails_app/app/views/onboard/step3.html.erb b/spec/rails_app/app/views/onboard/step3.html.erb index c0995eb..1d9b7aa 100644 --- a/spec/rails_app/app/views/onboard/step3.html.erb +++ b/spec/rails_app/app/views/onboard/step3.html.erb @@ -1,2 +1,6 @@

Step 3

-<%= button_to "Save & Next", onboard_step_path(step: 4), method: :patch %> \ No newline at end of file +<% if Rails.version >= "4.0.0" %> + <%= button_to "Save & Next", onboard_step_path(step: 4), method: :patch %> +<% else %> + <%= button_to "Save & Next", onboard_step_path(step: 5), method: :delete %> +<% end %> \ No newline at end of file diff --git a/spec/rails_app/config/routes.rb b/spec/rails_app/config/routes.rb index e4a2921..0e9828e 100644 --- a/spec/rails_app/config/routes.rb +++ b/spec/rails_app/config/routes.rb @@ -8,7 +8,9 @@ get "/onboard", to: "onboard#setup", as: :onboard get "/onboard/step/:step", to: "onboard#setup", as: :onboard_step post "/onboard/step/:step", to: "onboard#setup" - patch "/onboard/step/:step", to: "onboard#setup" + if Rails.version >= "4.0.0" + patch "/onboard/step/:step", to: "onboard#setup" + end put "/onboard/step/:step", to: "onboard#setup" delete "/onboard/step/:step", to: "onboard#setup" end From e28ea0f9d863f3ded90866526ddd5aac0b8bf7fa Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Wed, 28 Jul 2021 20:15:20 +0800 Subject: [PATCH 12/15] Fix some style issues --- spec/rails_app/config/routes.rb | 2 +- spec/support/capybara.rb | 2 +- spec/support/dummy_view.rb | 30 ++++++++++++++----- .../view_extensions/breadcrumb_trail_spec.rb | 11 ++++--- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/spec/rails_app/config/routes.rb b/spec/rails_app/config/routes.rb index 0e9828e..30b0efc 100644 --- a/spec/rails_app/config/routes.rb +++ b/spec/rails_app/config/routes.rb @@ -1,5 +1,5 @@ RailsApp::Application.routes.draw do - root :to => "home#index" + root to: "home#index" resources :posts do resources :comments diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index c577633..21ed616 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -3,7 +3,7 @@ RSpec.configure do |c| c.include Capybara::DSL, :file_path => /\bspec\/integration\// - c.filter_run_when_matching :focus => true + c.filter_run_when_matching focus: true end Capybara.default_driver = :rack_test Capybara.default_selector = :css diff --git a/spec/support/dummy_view.rb b/spec/support/dummy_view.rb index 687ba3b..d33a175 100644 --- a/spec/support/dummy_view.rb +++ b/spec/support/dummy_view.rb @@ -3,29 +3,45 @@ class DummyView < ActionView::Base module FakeRequest class Request - attr_accessor :path, :fullpath, :protocol, :host_with_port, :_request_method + attr_accessor :path, + :fullpath, + :protocol, + :host_with_port, + :_request_method def get? - _request_method == nil ? true : _request_method == "GET" + return true if _request_method.nil? + + _request_method == "GET" end def post? - _request_method == nil ? false : _request_method == "POST" + return false if _request_method.nil? + + _request_method == "POST" end def put? - _request_method == nil ? false : _request_method == "PUT" + return false if _request_method.nil? + + _request_method == "PUT" end def patch? - _request_method == nil ? false : _request_method == "PATCH" + return false if _request_method.nil? + + _request_method == "PATCH" end def delete? - _request_method == nil ? false : _request_method == "DELETE" + return false if _request_method.nil? + + _request_method == "DELETE" end def head? - _request_method == nil ? false : _request_method == "HEAD" + return false if _request_method.nil? + + _request_method == "HEAD" end end def request diff --git a/spec/unit/view_extensions/breadcrumb_trail_spec.rb b/spec/unit/view_extensions/breadcrumb_trail_spec.rb index 95ea91c..5746943 100644 --- a/spec/unit/view_extensions/breadcrumb_trail_spec.rb +++ b/spec/unit/view_extensions/breadcrumb_trail_spec.rb @@ -283,11 +283,12 @@ it "match current path with :http_verbs" do view = DummyView.new - view.breadcrumb("posts", "/posts", http_verbs: [:get, :post]) + view.breadcrumb("posts", "/posts", http_verbs: %i[get post]) view.set_path("/posts") view.set_request_method(:post) - expect(view.breadcrumb_trail.map(&:to_a)).to eq([["posts", "/posts", true]]) + trail = view.breadcrumb_trail.map(&:to_a) + expect(trail).to eq([["posts", "/posts", true]]) end it "fail to match current path with :http_verbs" do @@ -296,7 +297,8 @@ view.set_path("/posts") view.set_request_method(:post) - expect(view.breadcrumb_trail.map(&:to_a)).to eq([["posts", "/posts", false]]) + trail = view.breadcrumb_trail.map(&:to_a) + expect(trail).to eq([["posts", "/posts", false]]) end it "match current path with :http_verbs => :all" do @@ -305,6 +307,7 @@ view.set_path("/posts") view.set_request_method(:delete) - expect(view.breadcrumb_trail.map(&:to_a)).to eq([["posts", "/posts", true]]) + trail = view.breadcrumb_trail.map(&:to_a) + expect(trail).to eq([["posts", "/posts", true]]) end end From 72b15901f724c23e071c2e6b52c876585aa1bbd1 Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Tue, 12 Oct 2021 12:21:16 +0800 Subject: [PATCH 13/15] Change http_verbs to request_methods --- README.md | 14 +++++++------- lib/loaf/configuration.rb | 6 +++--- lib/loaf/crumb.rb | 4 ++-- lib/loaf/view_extensions.rb | 16 ++++++++-------- .../app/controllers/onboard_controller.rb | 12 ++++++------ spec/unit/configuration_spec.rb | 2 +- .../view_extensions/breadcrumb_trail_spec.rb | 10 +++++----- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 82aded2..09c8e0a 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ rails generate loaf:install * [2.1.1 controller](#211-controller) * [2.1.2 view](#212-view) * [2.1.3 :match](#213-match) - * [2.1.4 :http_verbs](#214-http_verbs) + * [2.1.4 :request_methods](#214-request_methods) * [2.2 breadcrumb_trail](#22-breadcrumb_trail) * [3. Configuration](#3-configuration) * [4. Translation](#4-translation) @@ -208,11 +208,11 @@ To make a breadcrumb current based on the query parameters do: breadcrumb "Posts", posts_path(order: :desc), match: {order: :desc} ``` -#### 2.1.4 :http_verbs +#### 2.1.4 :request_methods -**Loaf** allows you to match on multiple HTTP verbs in order to make a breadcrumb current with the `:http_verbs` option. +**Loaf** allows you to match on multiple HTTP methods in order to make a breadcrumb current with the `:request_methods` option. -The `:http_verbs` key accepts `:all` or an array with following values: +The `:request_methods` key accepts `:all` or an array with following values: * `:get` * `:post` @@ -230,9 +230,9 @@ Its default value is `%i[get head]` For example: ```ruby -http_verbs: %i[get head] -http_verbs: %i[post get head] -http_verbs: :all +request_methods: %i[get head] +request_methods: %i[post get head] +request_methods: :all ``` ### 2.2 breadcrumb_trail diff --git a/lib/loaf/configuration.rb b/lib/loaf/configuration.rb index 28d7535..a062f53 100644 --- a/lib/loaf/configuration.rb +++ b/lib/loaf/configuration.rb @@ -3,9 +3,9 @@ module Loaf class Configuration VALID_ATTRIBUTES = [ - :http_verbs, :locales_path, - :match + :match, + :request_methods ].freeze attr_accessor(*VALID_ATTRIBUTES) @@ -14,7 +14,7 @@ class Configuration DEFAULT_MATCH = :inclusive - DEFAULT_HTTP_VERBS = %i[get head].freeze + DEFAULT_REQUEST_METHODS = %i[get head].freeze # Setup this configuration # diff --git a/lib/loaf/crumb.rb b/lib/loaf/crumb.rb index 4652fd4..d950249 100644 --- a/lib/loaf/crumb.rb +++ b/lib/loaf/crumb.rb @@ -10,13 +10,13 @@ class Crumb attr_reader :match - attr_reader :http_verbs + attr_reader :request_methods def initialize(name, url, options = {}) @name = name || raise_name_error @url = url || raise_url_error @match = options.fetch(:match, Loaf.configuration.match) - @http_verbs = options.fetch(:http_verbs, Loaf.configuration.http_verbs) + @request_methods = options.fetch(:request_methods, Loaf.configuration.request_methods) freeze end diff --git a/lib/loaf/view_extensions.rb b/lib/loaf/view_extensions.rb index f0c2a9a..4e03665 100644 --- a/lib/loaf/view_extensions.rb +++ b/lib/loaf/view_extensions.rb @@ -55,7 +55,7 @@ def breadcrumb_trail(options = {}) current = current_crumb?( path, options.fetch(:match) { crumb.match }, - http_verbs: options.fetch(:http_verbs) { crumb.http_verbs } + request_methods: options.fetch(:request_methods) { crumb.request_methods } ) yield(Loaf::Breadcrumb[name, path, current]) @@ -69,8 +69,8 @@ def breadcrumb_trail(options = {}) # the pattern to match on # # @api public - def current_crumb?(path, pattern = :inclusive, http_verbs: nil) - return false unless match_http_verbs(http_verbs) + def current_crumb?(path, pattern = :inclusive, request_methods: nil) + return false unless match_request_methods(request_methods) origin_path = URI::DEFAULT_PARSER.unescape(path).force_encoding(Encoding::BINARY) @@ -133,16 +133,16 @@ def _expand_url(url) end end - # Check if the HTTP verbs are allowed + # Check if the HTTP request methods are allowed # # @retun [Boolean] # # @api private - def match_http_verbs(http_verbs) - http_verbs ||= Loaf.configuration.http_verbs - return true if http_verbs == :all + def match_request_methods(request_methods) + request_methods ||= Loaf.configuration.request_methods + return true if request_methods == :all - http_verbs.any? { |verb| request.try("#{verb}?") } + request_methods.any? { |method| request.try("#{method}?") } end end # ViewExtensions end # Loaf diff --git a/spec/rails_app/app/controllers/onboard_controller.rb b/spec/rails_app/app/controllers/onboard_controller.rb index 74e0e07..f5266bb 100644 --- a/spec/rails_app/app/controllers/onboard_controller.rb +++ b/spec/rails_app/app/controllers/onboard_controller.rb @@ -7,27 +7,27 @@ def setup case params[:step] when "1" breadcrumb "Step 1", onboard_step_path(step: 1), - match: :exact, http_verbs: %i[get] + match: :exact, request_methods: %i[get] render :step1 when "2" breadcrumb "Step 2", onboard_step_path(step: 2), - match: :exact, http_verbs: %i[get post] + match: :exact, request_methods: %i[get post] render :step2 when "3" breadcrumb "Step 3", onboard_step_path(step: 3), - match: :exact, http_verbs: %i[get put] + match: :exact, request_methods: %i[get put] render :step3 when "4" breadcrumb "Step 4", onboard_step_path(step: 4), - match: :exact, http_verbs: %i[get patch] + match: :exact, request_methods: %i[get patch] render :step4 when "5" breadcrumb "Step 5", onboard_step_path(step: 5), - match: :exact, http_verbs: %i[get delete] + match: :exact, request_methods: %i[get delete] render :step5 when "6" breadcrumb "Step 6", onboard_step_path(step: 6), - match: :exact, http_verbs: :all + match: :exact, request_methods: :all render :step6 else render :setup diff --git a/spec/unit/configuration_spec.rb b/spec/unit/configuration_spec.rb index ab08e03..ed1bb3d 100644 --- a/spec/unit/configuration_spec.rb +++ b/spec/unit/configuration_spec.rb @@ -20,7 +20,7 @@ expect(config.to_hash).to eq({ locales_path: "/", match: :inclusive, - http_verbs: %i[get head] + request_methods: %i[get head] }) end diff --git a/spec/unit/view_extensions/breadcrumb_trail_spec.rb b/spec/unit/view_extensions/breadcrumb_trail_spec.rb index 5746943..a491c41 100644 --- a/spec/unit/view_extensions/breadcrumb_trail_spec.rb +++ b/spec/unit/view_extensions/breadcrumb_trail_spec.rb @@ -281,9 +281,9 @@ expect(view.breadcrumb_trail(match: :exact).map(&:current?)).to eq([false, false, true]) end - it "match current path with :http_verbs" do + it "match current path with :request_methods" do view = DummyView.new - view.breadcrumb("posts", "/posts", http_verbs: %i[get post]) + view.breadcrumb("posts", "/posts", request_methods: %i[get post]) view.set_path("/posts") view.set_request_method(:post) @@ -291,7 +291,7 @@ expect(trail).to eq([["posts", "/posts", true]]) end - it "fail to match current path with :http_verbs" do + it "fail to match current path with :request_methods" do view = DummyView.new view.breadcrumb("posts", "/posts") view.set_path("/posts") @@ -301,9 +301,9 @@ expect(trail).to eq([["posts", "/posts", false]]) end - it "match current path with :http_verbs => :all" do + it "match current path with :request_methods => :all" do view = DummyView.new - view.breadcrumb("posts", "/posts", http_verbs: :all) + view.breadcrumb("posts", "/posts", request_methods: :all) view.set_path("/posts") view.set_request_method(:delete) From b94519ac345d7fe0c17d41946b25018218eabb7b Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Fri, 25 Feb 2022 18:04:40 +0800 Subject: [PATCH 14/15] Fix more style issues --- .ruby-version | 1 + README.md | 4 +- lib/loaf/view_extensions.rb | 3 +- spec/integration/breadcrumb_trail_spec.rb | 70 +++++++++---------- spec/integration/configuration_spec.rb | 6 +- .../view_extensions/breadcrumb_trail_spec.rb | 6 +- 6 files changed, 45 insertions(+), 45 deletions(-) create mode 100644 .ruby-version diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..2c9b4ef --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.7.3 diff --git a/README.md b/README.md index 09c8e0a..c7db562 100644 --- a/README.md +++ b/README.md @@ -225,9 +225,9 @@ The `:request_methods` key accepts `:all` or an array with following values: * `:unlink` * `:trace` -Its default value is `%i[get head]` +It's defaults to `%i[get head]` -For example: +Here are some examples: ```ruby request_methods: %i[get head] diff --git a/lib/loaf/view_extensions.rb b/lib/loaf/view_extensions.rb index 4e03665..d4aa964 100644 --- a/lib/loaf/view_extensions.rb +++ b/lib/loaf/view_extensions.rb @@ -69,7 +69,7 @@ def breadcrumb_trail(options = {}) # the pattern to match on # # @api public - def current_crumb?(path, pattern = :inclusive, request_methods: nil) + def current_crumb?(path, pattern = :inclusive, request_methods: Loaf.configuration.request_methods) return false unless match_request_methods(request_methods) origin_path = URI::DEFAULT_PARSER.unescape(path).force_encoding(Encoding::BINARY) @@ -139,7 +139,6 @@ def _expand_url(url) # # @api private def match_request_methods(request_methods) - request_methods ||= Loaf.configuration.request_methods return true if request_methods == :all request_methods.any? { |method| request.try("#{method}?") } diff --git a/spec/integration/breadcrumb_trail_spec.rb b/spec/integration/breadcrumb_trail_spec.rb index c18bc05..289c3a2 100644 --- a/spec/integration/breadcrumb_trail_spec.rb +++ b/spec/integration/breadcrumb_trail_spec.rb @@ -8,62 +8,62 @@ it "shows root breadcrumb" do visit root_path - page.within '#breadcrumbs .selected' do - expect(page.html).to include('Home') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/", text: "Home") end end it "inherits controller breadcrumb and adds index action breadcrumb" do visit posts_path - page.within '#breadcrumbs' do - expect(page.html).to include('Home') + within "#breadcrumbs" do + expect(page).to have_link(href: "/", text: "Home") end - page.within '#breadcrumbs .selected' do - expect(page.html).to include('All Posts') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/posts", text: "All Posts") end end - it 'filters out controller breadcrumb and adds new action breadcrumb' do + it "filters out controller breadcrumb and adds new action breadcrumb" do visit new_post_path - page.within '#breadcrumbs' do - expect(page).to_not have_content('Home') - expect(page).to have_content('New Post') + within "#breadcrumbs" do + expect(page).to_not have_content("Home") + expect(page).to have_content("New Post") end end it "adds breadcrumb in view with path variable" do visit post_path(1) - page.within '#breadcrumbs .selected' do - expect(page.html).to include('Show Post in view') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/posts/1", text: "Show Post in view") end end - it 'is current when forced' do + it "is current when forced" do visit new_post_path expect(page.current_path).to eq(new_post_path) - page.within '#breadcrumbs' do - expect(page).to have_selector('li.selected', count: 2) - expect(page.html).to include('All') - expect(page.html).to include('New Post') + within "#breadcrumbs" do + expect(page).to have_selector("li.selected", count: 2) + expect(page).to have_link(href: "/posts", text: "All") + expect(page).to have_link(href: "/posts/new", text: "New Post") end end it "allows for procs in name and url" do visit post_comments_path(1) - page.within '#breadcrumbs .selected' do - expect(page.html).to include('Post comments') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/posts/1/comments", text: "Post comments") end end it "allows for procs in name and url without supplying the controller" do visit post_comments_path(1) - page.within "#breadcrumbs .selected" do + within "#breadcrumbs .selected" do expect(page.html).to include( ''\ "Post comments No Controller" @@ -75,49 +75,49 @@ visit onboard_path expect(page).to have_selector("h1", text: "Onboard") - page.within "#breadcrumbs" do + within "#breadcrumbs" do expect(page).to have_content("Onboard") end click_link "Step 1" # GET expect(page).to have_selector("h1", text: "Step 1") - page.within "#breadcrumbs" do - expect(page.html).to include('Onboard') + within "#breadcrumbs" do + expect(page).to have_link(href: "/onboard", text: "Onboard") end - page.within "#breadcrumbs .selected" do - expect(page.html).to include('Step 1') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/onboard/step/1", text: "Step 1") end click_on "Save & Next" # POST expect(page).to have_selector("h1", text: "Step 2") - page.within "#breadcrumbs .selected" do - expect(page.html).to include('Step 2') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/onboard/step/2", text: "Step 2") end click_on "Save & Next" # PUT expect(page).to have_selector("h1", text: "Step 3") - page.within "#breadcrumbs .selected" do - expect(page.html).to include('Step 3') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/onboard/step/3", text: "Step 3") end if Rails.version >= "4.0.0" click_on "Save & Next" # PATCH expect(page).to have_selector("h1", text: "Step 4") - page.within '#breadcrumbs .selected' do - expect(page.html).to include('Step 4') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/onboard/step/4", text: "Step 4") end end click_on "Save & Next" # DELETE expect(page).to have_selector("h1", text: "Step 5") - page.within "#breadcrumbs .selected" do - expect(page.html).to include('Step 5') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/onboard/step/5", text: "Step 5") end click_on "Save & Next" # GET expect(page).to have_selector("h1", text: "Step 6") - page.within "#breadcrumbs .selected" do - expect(page.html).to include('Step 6') + within "#breadcrumbs .selected" do + expect(page).to have_link(href: "/onboard/step/6", text: "Step 6") end end end diff --git a/spec/integration/configuration_spec.rb b/spec/integration/configuration_spec.rb index 4aae487..b6ff5db 100644 --- a/spec/integration/configuration_spec.rb +++ b/spec/integration/configuration_spec.rb @@ -1,10 +1,10 @@ # encoding: utf-8 -RSpec.describe 'setting configuration options' do +RSpec.describe "setting configuration options" do it "contains 'selected' inside the breadcrumb markup" do visit posts_path - page.within '#breadcrumbs' do - expect(page).to have_selector('.selected') + within "#breadcrumbs" do + expect(page).to have_selector(".selected") end end end diff --git a/spec/unit/view_extensions/breadcrumb_trail_spec.rb b/spec/unit/view_extensions/breadcrumb_trail_spec.rb index a491c41..c091690 100644 --- a/spec/unit/view_extensions/breadcrumb_trail_spec.rb +++ b/spec/unit/view_extensions/breadcrumb_trail_spec.rb @@ -281,7 +281,7 @@ expect(view.breadcrumb_trail(match: :exact).map(&:current?)).to eq([false, false, true]) end - it "match current path with :request_methods" do + it "matches the current path with :request_methods set to custom" do view = DummyView.new view.breadcrumb("posts", "/posts", request_methods: %i[get post]) view.set_path("/posts") @@ -291,7 +291,7 @@ expect(trail).to eq([["posts", "/posts", true]]) end - it "fail to match current path with :request_methods" do + it "fails to match current path with :request_methods set to default" do view = DummyView.new view.breadcrumb("posts", "/posts") view.set_path("/posts") @@ -301,7 +301,7 @@ expect(trail).to eq([["posts", "/posts", false]]) end - it "match current path with :request_methods => :all" do + it "matches current path with :request_methods set to :all" do view = DummyView.new view.breadcrumb("posts", "/posts", request_methods: :all) view.set_path("/posts") From c074e6d88e2e605a968ce8d552619cd8f94a7427 Mon Sep 17 00:00:00 2001 From: Hopper Gee Date: Fri, 25 Feb 2022 18:42:22 +0800 Subject: [PATCH 15/15] Fix a wrong proc config test --- spec/integration/breadcrumb_trail_spec.rb | 8 ++++---- spec/rails_app/app/controllers/comments_controller.rb | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/spec/integration/breadcrumb_trail_spec.rb b/spec/integration/breadcrumb_trail_spec.rb index 289c3a2..0b8d248 100644 --- a/spec/integration/breadcrumb_trail_spec.rb +++ b/spec/integration/breadcrumb_trail_spec.rb @@ -61,12 +61,12 @@ end it "allows for procs in name and url without supplying the controller" do - visit post_comments_path(1) + visit post_comments_path(1, no_controller: true) within "#breadcrumbs .selected" do - expect(page.html).to include( - ''\ - "Post comments No Controller" + expect(page).to have_link( + href: "/posts/1/comments?no_controller=true", + text: "Post comments No Controller" ) end end diff --git a/spec/rails_app/app/controllers/comments_controller.rb b/spec/rails_app/app/controllers/comments_controller.rb index c97a999..1375565 100644 --- a/spec/rails_app/app/controllers/comments_controller.rb +++ b/spec/rails_app/app/controllers/comments_controller.rb @@ -3,10 +3,12 @@ class Article < Struct.new(:id, :title); end class CommentsController < ApplicationController breadcrumb lambda { |c| c.find_article(c.params[:post_id]).title }, - lambda { |c| c.post_comments_path(c.params[:post_id]) } + lambda { |c| c.post_comments_path(c.params[:post_id]) }, + match: :exact breadcrumb -> { find_article(params[:post_id]).title + " No Controller" }, - -> { post_comments_path(params[:post_id], no_controller: true) } + -> { post_comments_path(params[:post_id], no_controller: true) }, + match: :exact def index end