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

Introduce support for hanami generate part #18

Merged
merged 6 commits into from
Oct 26, 2023

Conversation

jodosha
Copy link
Member

@jodosha jodosha commented Oct 23, 2023

Feature

Support RSpec generation for hanami generate part (see hanami/cli#117)

App

$ bundle exec hanami generate part user
# ...
Created spec/views/parts/user_spec.rb
# frozen_string_literal: true

RSpec.describe Bookshelf::Views::Parts::User do
  it "works" do
    expect(subject).to be_kind_of(described_class)
  end
end

Slice

$ bundle exec hanami generate part user --slice=admin
# ...
Created spec/slices/admin/views/parts/user_spec.rb
# frozen_string_literal: true

RSpec.describe Admin::Views::Parts::User do
  it "works" do
    expect(subject).to be_kind_of(described_class)
  end
end

Ref hanami/cli#117
Ref hanami/cli#113

@jodosha jodosha added the enhancement New feature or request label Oct 23, 2023
@jodosha jodosha added this to the v2.1.0 milestone Oct 23, 2023
@jodosha jodosha requested review from timriley and a team October 23, 2023 08:41
@jodosha jodosha self-assigned this Oct 23, 2023
Copy link
Member

@timriley timriley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality-wise, this all looks good!

Though I wonder if there might be a slightly more instructive shape we could give the generated spec file.

There's one real issue with the current spec file: it doesn't really reflect the shape this file will need to take once the tests become real. At that stage, we'll need to be initialising the part manually and passing a value in.

So could we possibly get a little bit closer with our default files? Something like this?

# frozen_string_literal: true

RSpec.describe Bookshelf::Views::Parts::User do

  # TODO: detect if we're on a modern enough ruby, then make this `(value:)`, which is so much nicer
  subject(:part) { described_class.new(value: value) }

  let(:value) {
    # Replace this with your domain object
    Object.new
  }

  it "works" do
    expect(subject).to be_kind_of(described_class)
  end
end

With this as the default spec file, the user:

  • Knows they need to pass a value to their part
  • Has the code already set up to do so
  • Just needs to replace the code inside let(:value)
  • And after that, everything is good to go :)

What do you think?

@jodosha
Copy link
Member Author

jodosha commented Oct 23, 2023

@timriley A few considerations 👇 .

value is needed parts

Yes, we must introduce value in specs otherwise, they crash.

Failures:

  1) Bookshelf::Views::Parts::Author works
     Failure/Error: expect(subject).to be_kind_of(described_class)

     ArgumentError:
       missing keyword: :value

value is requested for base parts

The problem is that the base part is expecting value: as well.

The base part is defined as MyApp::Part < Hanami::View::Part.

Failures:

  1) Bookshelf::Views::Part works
     Failure/Error: expect(subject).to be_kind_of(described_class)

     ArgumentError:
       missing keyword: :value

⚠️ We need to fix this problem in hanami/view.

Proposal for the generated spec

# frozen_string_literal: true

RSpec.describe Bookshelf::Views::Parts::Author do
  subject { described_class.new(value:) }
  let(:value) { double("author") }

  it "works" do
    expect(subject).to be_kind_of(described_class)
  end
end

Notes:

  1. subject vs subject(:part): it's subject for consistency with the action spec generator.
  2. let(:value) it uses double("author") (instead Object.new) to use RSpec way to use doubles. Users can also leverage RSpec verified doubles for extra safety.

@jodosha
Copy link
Member Author

jodosha commented Oct 24, 2023

@timriley More considerations on base part and value.

Given the following base part, located at app/views/part.rb:

# auto_register: false
# frozen_string_literal: true

module Bookshelf
  module Views
    class Part < Hanami::View::Part
      def inspekt
        helper.html.tag(:code, value.inspect)
      end
    end
  end
end

How do I unit-test this?
Here's a hypothetical code at spec/views/part_spec.rb:

# frozen_string_literal: true

RSpec.describe Bookshelf::Views::Part do
  subject { described_class.new(value:) }

  describe "#inspekt" do
    let(:value) { Client.new }

    it "works" do
      expect(subject.inspekt).to eq(%(<code>#{value.inspect}</code>))
    end
  end
end

With that concrete example, how can we generate a useful, ready-to-go spec file for the base part?
Maybe we can generate a spec, similar to the one that we generate for parts:

# frozen_string_literal: true

RSpec.describe Bookshelf::Views::Part do
  subject { described_class.new(value:) }
  let(:value) { double("obj") }

  it "works" do
    expect(subject).to be_kind_of(described_class)
  end
end

@timriley
Copy link
Member

timriley commented Oct 24, 2023

Your Proposal for the generated spec is perfect, @jodosha!

Also, your proposal just above for the base part's spec looks great to me too!

Two thumbs up!

Copy link
Member

@timriley timriley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@jodosha jodosha merged commit b8cfe6e into main Oct 26, 2023
6 checks passed
@jodosha jodosha deleted the feature/view-part-generator branch October 26, 2023 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants