diff --git a/.rubocop.yml b/.rubocop.yml index 2060050..72138c1 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,6 +8,7 @@ AllCops: TargetRubyVersion: 2.7 NewCops: enable Exclude: + - bin/**/* - lib/generators/**/templates/**/* - gemfiles/**/* - vendor/**/* diff --git a/CHANGELOG.md b/CHANGELOG.md index e7021b5..3762164 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Setup rspec-html-matchers and use it for complex components specs (#65) +### Fixed +- Fix errors methods in `BaseComponent` and `FieldComponent` (#71) + ## [0.1.0] - 2021-09-16 ### Added @@ -22,4 +25,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [Unreleased]: https://github.com/pantographe/view_component-form/compare/v0.1.0...HEAD [0.1.0]: https://github.com/pantographe/view_component-form/releases/tag/v0.1.0 - diff --git a/app/components/view_component/form/field_component.rb b/app/components/view_component/form/field_component.rb index ec3c529..ec65e4c 100644 --- a/app/components/view_component/form/field_component.rb +++ b/app/components/view_component/form/field_component.rb @@ -41,7 +41,7 @@ def value def object_method_names @object_method_names ||= begin - object_method_names = [method_name] + object_method_names = [method_name.to_sym] if method_name.end_with?("_id") && object.respond_to?(singular_association_method_name) object_method_names << singular_association_method_name elsif method_name.end_with?("_ids") && object.respond_to?(collection_association_method_name) diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 0000000..a6c7852 --- /dev/null +++ b/bin/rspec @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +bundle_binstub = File.expand_path("../bundle", __FILE__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rspec-core", "rspec") diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b098d86..c3d66ab 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,7 +3,9 @@ if ENV.fetch("COVERAGE", false) require "simplecov" SimpleCov.start do - minimum_coverage 90 + add_filter "/spec" + + minimum_coverage 89 maximum_coverage_drop 2 end end diff --git a/spec/view_component/form/base_component_spec.rb b/spec/view_component/form/base_component_spec.rb new file mode 100644 index 0000000..28e0190 --- /dev/null +++ b/spec/view_component/form/base_component_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +RSpec.describe ViewComponent::Form::BaseComponent, type: :component do + let(:object_klass) do + Class.new do + include ActiveModel::Model + + attr_accessor :first_name + + validates :first_name, presence: true, length: { minimum: 2 } + + class << self + def name + "User" + end + end + end + end + + let(:object) { object_klass.new } + let(:form) { form_with(object) } + let(:options) { {} } + + let(:component) { described_class.new(form, object_name, options) } + + describe "#object_errors?" do + before { object.validate } + + context "with valid object" do + let(:object) { object_klass.new(first_name: "John") } + + it { expect(component.object_errors?).to eq(false) } + end + + context "with invalid object" do + let(:object) { object_klass.new(first_name: "") } + + it { expect(component.object_errors?).to eq(true) } + end + end +end diff --git a/spec/view_component/form/field_component_spec.rb b/spec/view_component/form/field_component_spec.rb new file mode 100644 index 0000000..3b2c82b --- /dev/null +++ b/spec/view_component/form/field_component_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +RSpec.describe ViewComponent::Form::FieldComponent, type: :component do + let(:object_klass) do + Class.new do + include ActiveModel::Model + + attr_accessor :first_name + + validates :first_name, presence: true, length: { minimum: 2 } + + class << self + def name + "User" + end + end + end + end + + let(:object) { object_klass.new } + let(:form) { form_with(object) } + let(:options) { {} } + + let(:component) { described_class.new(form, object_name, :first_name, options) } + + describe "#method_errors" do + before { object.validate } + + context "with valid object" do + let(:object) { object_klass.new(first_name: "John") } + + it { expect(component.method_errors).to eq([]) } + end + + context "with invalid object" do + let(:object) { object_klass.new(first_name: "") } + + it { expect(component.method_errors).to eq(["Can't be blank", "Is too short (minimum is 2 characters)"]) } + end + end + + describe "#method_errors?" do + before { object.validate } + + context "with valid object" do + let(:object) { object_klass.new(first_name: "John") } + + it { expect(component.method_errors?).to eq(false) } + end + + context "with invalid object" do + let(:object) { object_klass.new(first_name: "") } + + it { expect(component.method_errors?).to eq(true) } + end + end + + describe "#value" do + let(:object) { object_klass.new(first_name: "John") } + + it { expect(component.value).to eq("John") } + end + + describe "#object_method_names" do + it { expect(component.object_method_names).to eq(%i[first_name]) } + + pending "test with belongs_to for _id" + pending "test with has_many for _ids" + end +end