diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 34f91a6..4711efd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,3 +22,5 @@ jobs: bundler-cache: true - name: Linting run: bundle exec rubocop + - name: Run tests + run: bundle exec rspec diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..c99d2e7 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/Gemfile b/Gemfile index 2ac289f..43cf402 100644 --- a/Gemfile +++ b/Gemfile @@ -6,3 +6,8 @@ gemspec gem "rubocop" gem "rubocop-rails-omakase", require: false, group: [ :development ] +gem "rspec" +gem "actionview" +gem "activemodel" +gem "nokogiri" +gem "uri" # necessary on github actions diff --git a/Gemfile.lock b/Gemfile.lock index 3884190..76e2a48 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,15 +9,15 @@ PATH GEM remote: https://rubygems.org/ specs: - actionview (8.0.1) - activesupport (= 8.0.1) + actionview (7.2.2.1) + activesupport (= 7.2.2.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activemodel (8.0.1) - activesupport (= 8.0.1) - activesupport (8.0.1) + activemodel (7.2.2.1) + activesupport (= 7.2.2.1) + activesupport (7.2.2.1) base64 benchmark (>= 0.3) bigdecimal @@ -29,7 +29,6 @@ GEM minitest (>= 5.1) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) - uri (>= 0.13.1) ast (2.4.2) base64 (0.2.0) benchmark (0.4.0) @@ -38,12 +37,13 @@ GEM concurrent-ruby (1.3.5) connection_pool (2.5.0) crass (1.0.6) + diff-lcs (1.5.1) drb (2.2.1) erubi (1.13.1) i18n (1.14.7) concurrent-ruby (~> 1.0) json (2.9.1) - language_server-protocol (3.17.0.3) + language_server-protocol (3.17.0.4) logger (1.6.5) loofah (2.24.0) crass (~> 1.0.2) @@ -66,11 +66,11 @@ GEM nokogiri (1.18.2-x86_64-linux-musl) racc (~> 1.4) parallel (1.26.3) - parser (3.3.7.0) + parser (3.3.7.1) ast (~> 2.4.1) racc racc (1.8.1) - rack (3.1.8) + rack (3.1.9) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -80,17 +80,30 @@ GEM nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) rainbow (3.1.1) regexp_parser (2.10.0) - rubocop (1.70.0) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.2) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.2) + rubocop (1.71.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.36.2, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.37.0) + rubocop-ast (1.38.0) parser (>= 3.3.1.0) rubocop-minitest (0.36.0) rubocop (>= 1.61, < 2.0) @@ -98,7 +111,7 @@ GEM rubocop-performance (1.23.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.29.0) + rubocop-rails (2.29.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.52.0, < 2.0) @@ -128,9 +141,14 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES + actionview + activemodel dsfr-form_builder! + nokogiri + rspec rubocop rubocop-rails-omakase + uri BUNDLED WITH 2.6.2 diff --git a/spec/dsfr-form_builder_spec.rb b/spec/dsfr-form_builder_spec.rb new file mode 100644 index 0000000..4756680 --- /dev/null +++ b/spec/dsfr-form_builder_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +class TestHelper + include ActionView::Helpers::FormHelper + include ActionView::Helpers::FormTagHelper +end + +class Record + include ActiveModel::Model + attr_accessor :name +end + +RSpec.describe Dsfr::FormBuilder do + let(:helper) { TestHelper.new } + let(:object) { Record.new(name: 'Jean Paul') } + let(:builder) { Dsfr::FormBuilder.new(:record, object, helper, {}) } + + describe '#dsfr_text_field' do + it 'generates the correct HTML' do + expect(builder.dsfr_text_field(:name)).to match_html(<<~HTML) +
+ + +
+ HTML + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..0b25346 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,21 @@ +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end + + config.shared_context_metadata_behavior = :apply_to_host_groups + config.disable_monkey_patching! + config.warnings = true +end + +require 'uri' # necessary on github actions +require 'action_view' +require 'active_support' +require 'active_model' +require 'nokogiri' + +Dir[File.expand_path('{../lib/**/*.rb,support/**/*.rb}', __dir__)].sort.each { |f| require f } diff --git a/spec/support/matchers/html_matcher.rb b/spec/support/matchers/html_matcher.rb new file mode 100644 index 0000000..314cfc9 --- /dev/null +++ b/spec/support/matchers/html_matcher.rb @@ -0,0 +1,36 @@ +RSpec::Matchers.define :match_html do |expected| + def normalize_html(html) + # important to strip around the raw HTML input + doc = Nokogiri::HTML.fragment(html.strip) + # strip all attributes values + doc.traverse do |node| + if node.respond_to?(:attributes) + node.attributes.each do |name, attr| + attr.value = attr.value.strip + end + end + end + # remove all whitespaces between tags + doc.to_s.gsub(/>\s+<') + end + + def beautify_html(html) + # cf https://stackoverflow.com/a/7839017 + Nokogiri::XML(html, &:noblanks).to_s.sub('', '') + end + + match do |actual| + @actual = actual + normalize_html(expected) == normalize_html(actual) + end + + failure_message do + <<~MSG + --- Expected --- + #{beautify_html(expected)} + + --- Actual --- + #{beautify_html(@actual)} + MSG + end +end