Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow plain ruby objects #90

Merged
merged 4 commits into from Jan 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .rubocop.yml
Expand Up @@ -17,3 +17,5 @@ Style/TrailingCommaInHashLiteral:
Enabled: false
Style/TrailingCommaInArrayLiteral:
Enabled: false
Naming/MethodParameterName:
Enabled: false
3 changes: 2 additions & 1 deletion lib/govuk_design_system_formbuilder/base.rb
Expand Up @@ -34,7 +34,8 @@ def field_id(link_errors: false)
end

def has_errors?
@builder.object.errors.any? &&
@builder.object.respond_to?(:errors) &&
@builder.object.errors.any? &&
@builder.object.errors.messages.dig(@attribute_name).present?
end

Expand Down
Expand Up @@ -38,6 +38,10 @@
it_behaves_like 'a field that supports setting the legend via localisation'
it_behaves_like 'a field that supports setting the hint via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
let(:described_element) { ['input', { with: { type: 'checkbox' }, count: projects.size }] }
end

describe 'check boxes' do
specify 'output should contain the correct number of check boxes' do
expect(subject).to have_tag('div', with: { 'data-module' => 'govuk-checkboxes' }) do |cb|
Expand Down
Expand Up @@ -28,6 +28,10 @@
it_behaves_like 'a field that supports setting the hint via localisation'
it_behaves_like 'a field that supports setting the legend via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
let(:described_element) { 'fieldset' }
end

context 'when no block is supplied' do
subject { builder.send(*args) }
specify { expect { subject }.to raise_error(NoMethodError, /undefined method.*call/) }
Expand Down
4 changes: 4 additions & 0 deletions spec/govuk_design_system_formbuilder/builder/date_spec.rb
Expand Up @@ -62,6 +62,10 @@
it_behaves_like 'a field that supports setting the legend via localisation'
it_behaves_like 'a field that supports setting the hint via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
let(:described_element) { ['input', { count: 3 }] }
end

specify 'should output a form group with fieldset, date group and 3 inputs and labels' do
expect(subject).to have_tag('div', with: { class: 'govuk-form-group' }) do |fg|
expect(fg).to have_tag('fieldset', with: { class: 'govuk-fieldset' }) do |fs|
Expand Down
Expand Up @@ -289,5 +289,14 @@
expect(subject).to be_nil
end
end

context 'when the object does not support errors' do
let(:object) { Guest.example }
subject { builder.send(method) }

specify 'an error should be raised' do
expect { subject }.to raise_error(NoMethodError, /errors/)
end
end
end
end
4 changes: 4 additions & 0 deletions spec/govuk_design_system_formbuilder/builder/file_spec.rb
Expand Up @@ -40,6 +40,10 @@
it_behaves_like 'a field that supports setting the label via localisation'
it_behaves_like 'a field that supports setting the hint via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
let(:described_element) { ['input', with: { type: 'file' }] }
end

describe 'additional attributes' do
subject { builder.send(method, attribute, accept: 'image/*', multiple: true) }

Expand Down
Expand Up @@ -44,6 +44,10 @@
it_behaves_like 'a field that supports setting the hint via localisation'
it_behaves_like 'a field that supports setting the legend via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
let(:described_element) { ['input', { with: { type: 'radio' }, count: colours.size }] }
end

context 'radio buttons' do
specify 'each radio button should have the correct classes' do
expect(subject).to have_tag('input', with: { class: %w(govuk-radios__input) }, count: colours.size)
Expand Down
Expand Up @@ -32,6 +32,12 @@
it_behaves_like 'a field that supports setting the hint via localisation'
it_behaves_like 'a field that supports setting the legend via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
subject { builder.send(*args) {} }

let(:described_element) { 'fieldset' }
end

context 'when a block containing radio buttons is supplied' do
specify 'output should be a form group containing a form group and fieldset' do
expect(subject).to have_tag('div', with: { class: 'govuk-form-group' }) do |fg|
Expand Down
4 changes: 4 additions & 0 deletions spec/govuk_design_system_formbuilder/builder/select_spec.rb
Expand Up @@ -30,6 +30,10 @@
it_behaves_like 'a field that supports setting the label via localisation'
it_behaves_like 'a field that supports setting the hint via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
let(:described_element) { 'select' }
end

specify 'output should be a form group containing a label and select box' do
expect(subject).to have_tag('div', with: { class: 'govuk-form-group' }) do |fg|
expect(fg).to have_tag('select')
Expand Down
Expand Up @@ -59,6 +59,10 @@
it_behaves_like 'a field that supports setting the label via localisation'
it_behaves_like 'a field that supports setting the hint via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
let(:described_element) { 'textarea' }
end

specify 'should have the correct classes' do
expect(subject).to have_tag('textarea', with: { class: 'govuk-textarea' })
end
Expand Down
47 changes: 39 additions & 8 deletions spec/support/examples.rb
@@ -1,9 +1,25 @@
class Person
class Project
include ActiveModel::Model
attr_accessor(:id, :name, :description)
end

class Being
attr_accessor(
:name,
:born_on,
:gender,
:over_18,
:favourite_colour,
:favourite_colour_reason,
:projects,
:project_responsibilities,
:cv,
:photo
)
end

class Person < Being
include ActiveModel::Model
attr_accessor(:name, :born_on, :gender, :over_18, :favourite_colour, :favourite_colour_reason)
attr_accessor(:projects, :project_responsibilities)
attr_accessor(:cv)
attr_accessor(:photo)

validates :name, presence: { message: 'Enter a name' }
validates :favourite_colour, presence: { message: 'Choose a favourite colour' }
Expand Down Expand Up @@ -35,7 +51,22 @@ def photo_must_be_jpeg
end
end

class Project
include ActiveModel::Model
attr_accessor(:id, :name, :description)
class Guest < Being
def initialize(name:, favourite_colour:, projects:, cv:, born_on:)
self.name = name
self.favourite_colour = favourite_colour
self.projects = projects
self.cv = cv
self.born_on = born_on
end

def self.example
new(
name: 'Minnie von Mouse',
favourite_colour: 'red',
projects: [4, 5, 6],
cv: 'Basic vocabulary',
born_on: Date.new(1974, 7, 1)
)
end
end
12 changes: 12 additions & 0 deletions spec/support/shared/shared_error_examples.rb
Expand Up @@ -50,4 +50,16 @@
expect(subject).not_to have_tag('span', with: { class: 'govuk-error-message' })
end
end

context 'when the object does not support errors' do
let(:object) { Guest.example }

specify 'should correctly render the form group' do
expect(subject).to have_tag('div', with: { class: 'govuk-form-group' })
end

specify 'no error should be raised' do
expect { subject }.not_to raise_error
end
end
end
19 changes: 19 additions & 0 deletions spec/support/shared/shared_plain_ruby_object_examples.rb
@@ -0,0 +1,19 @@
class Biscuit
attr_accessor :name, :weight, :calories

def initialize(name, weight, calories)
self.name = name
self.weight = weight
self.calories = calories
end
end

shared_examples 'a field that accepts a plain ruby object' do
let(:object) { Biscuit.new('Pick-up!', 28, 143) }
let(:object_name) { :biscuit }
let(:attribute) { :calories }

specify 'should render the element successfully' do
expect(subject).to have_tag(*described_element)
end
end
4 changes: 4 additions & 0 deletions spec/support/shared/shared_text_field_examples.rb
Expand Up @@ -40,6 +40,10 @@
it_behaves_like 'a field that supports setting the label via localisation'
it_behaves_like 'a field that supports setting the hint via localisation'

it_behaves_like 'a field that accepts a plain ruby object' do
let(:described_element) { 'input' }
end

context 'extra attributes' do
let(:regular_args) { { label: { text: 'What should we call you?' } } }

Expand Down