Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions lib/hanami/rspec/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,13 @@ def call(options, **)
return if options[:skip_tests]

slice = inflector.underscore(Shellwords.shellescape(options[:slice])) if options[:slice]
name = inflector.underscore(Shellwords.shellescape(options[:name]))
key = inflector.underscore(Shellwords.shellescape(options[:name]))

namespace = slice ? inflector.camelize(slice) : app.namespace
base_path = slice ? "spec/slices/#{slice}" : "spec"

generator = Generators::Part.new(fs: fs, inflector: inflector)
generator.call(app.namespace, slice, name)
generator.call(key: key, namespace: namespace, base_path: base_path, app_namespace: app.namespace)
end
end
end
Expand Down
119 changes: 49 additions & 70 deletions lib/hanami/rspec/generators/part.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

require "erb"
require "hanami/cli/generators/app/ruby_class_file"

module Hanami
module RSpec
Expand All @@ -17,97 +17,76 @@ def initialize(fs:, inflector:)

# @since 2.1.0
# @api private
def call(app, slice, name)
context = Struct.new(
:camelized_app_name,
:camelized_slice_name,
:camelized_name,
:underscored_name
).new(
inflector.camelize(app),
slice ? inflector.camelize(slice) : nil,
inflector.camelize(name),
inflector.underscore(name)
)
def call(key:, namespace:, base_path:, app_namespace:)
ruby_class_file = part_ruby_class_file(key:, namespace:, base_path:)
spec_file_path = ruby_class_file.path.gsub(/\.rb$/, "_spec.rb")
part_class_name = ruby_class_file.fully_qualified_name

if slice
generate_for_slice(slice, context)
else
generate_for_app(context)
end
generate_base_part_specs(namespace:, base_path:, app_namespace:)
fs.write(spec_file_path, spec_content(part_class_name))
end

private

# @since 2.1.0
# @api private
def generate_for_slice(slice, context)
generate_base_part_for_app(context)
generate_base_part_for_slice(context, slice)
attr_reader :fs, :inflector

fs.write(
"spec/slices/#{slice}/views/parts/#{context.underscored_name}_spec.rb",
t("part_slice_spec.erb", context)
def part_ruby_class_file(key:, namespace:, base_path:)
Hanami::CLI::Generators::App::RubyClassFile.new(
fs: fs,
inflector: inflector,
namespace: namespace,
key: key,
base_path: base_path,
extra_namespace: "views/parts",
)
end

# @since 2.1.0
# @api private
def generate_for_app(context)
generate_base_part_for_app(context)
def generate_base_part_specs(namespace:, base_path:, app_namespace:)
if base_path != "spec"
generate_base_part_spec_at(fs.join("spec", "views", "part_spec.rb"), app_namespace)

fs.write(
"spec/views/parts/#{context.underscored_name}_spec.rb",
t("part_spec.erb", context)
)
end
generate_base_part_spec_at(fs.join(base_path, "views", "part_spec.rb"), namespace)
end

# @since 2.1.0
# @api private
def generate_base_part_for_app(context)
path = fs.join("spec", "views", "part_spec.rb")
return if fs.exist?(path)
def spec_content(class_name)
# Extract the part name from the class name for the let variable
part_name = class_name.split("::").last.downcase

fs.write(
path,
t("part_base_spec.erb", context)
)
<<~RUBY
# frozen_string_literal: true

RSpec.describe #{class_name} do
subject { described_class.new(value:) }
let(:value) { double("#{part_name}") }

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

# @since 2.1.0
# @api private
def generate_base_part_for_slice(context, slice)
path = "spec/slices/#{slice}/views/part_spec.rb"
def generate_base_part_spec_at(path, namespace)
return if fs.exist?(path)

fs.write(
path,
t("part_slice_base_spec.erb", context)
)
fs.write(path, base_part_spec_content(namespace))
end

# @since 2.1.0
# @api private
attr_reader :fs
def base_part_spec_content(namespace)
<<~RUBY
# frozen_string_literal: true

# @since 2.1.0
# @api private
attr_reader :inflector
RSpec.describe #{namespace}::Views::Part do
subject { described_class.new(value:) }
let(:value) { double("value") }

# @since 2.1.0
# @api private
def template(path, context)
require "erb"

ERB.new(
File.read(__dir__ + "/part/#{path}"),
trim_mode: "-"
).result(context.instance_eval { binding })
it "works" do
expect(subject).to be_kind_of(described_class)
end
end
RUBY
end

# @since 2.1.0
# @api private
alias_method :t, :template
end
end
end
Expand Down
10 changes: 0 additions & 10 deletions lib/hanami/rspec/generators/part/part_base_spec.erb

This file was deleted.

10 changes: 0 additions & 10 deletions lib/hanami/rspec/generators/part/part_slice_base_spec.erb

This file was deleted.

10 changes: 0 additions & 10 deletions lib/hanami/rspec/generators/part/part_slice_spec.erb

This file was deleted.

10 changes: 0 additions & 10 deletions lib/hanami/rspec/generators/part/part_spec.erb

This file was deleted.

1 change: 0 additions & 1 deletion spec/unit/hanami/rspec/commands/generate/part_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
let(:inflector) { Dry::Inflector.new }

let(:app_name) { "Bookshelf" }

let(:part_name) { "client" }

context "app" do
Expand Down