Skip to content

Commit

Permalink
add components specs
Browse files Browse the repository at this point in the history
  • Loading branch information
juan-apa committed Mar 6, 2024
1 parent 8d35c2c commit 1d08887
Show file tree
Hide file tree
Showing 5 changed files with 397 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/warped/emails/slottable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module Slottable
extend ActiveSupport::Concern

included do
class_attribute :slots, default: { one: {}, many: {} }
class_attribute :slots, default: { one: {}, many: {} }, instance_accessor: false
end

class_methods do
Expand Down Expand Up @@ -57,6 +57,10 @@ def #{name}
RUBY
end
end

def slots
@slots ||= self.class.slots.deep_dup
end
end
end
end
69 changes: 69 additions & 0 deletions spec/warped/emails/components/base_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# frozen_string_literal: true

RSpec.describe Warped::Emails::Base do
let(:base) { Warped::Emails::Base.new }

describe "#template" do
it "raises NotImplementedError" do
expect { base.template }.to raise_error(NotImplementedError)
end
end

describe "#content" do
context "when the content block is not set" do
it "returns nil" do
expect(base.content).to be_nil
end
end

context "when the content block is set" do
before { base.instance_variable_set(:@content_block, "<h1>Sample Content</h1>") }

it "returns the content block" do
expect(base.content).to eq("<h1>Sample Content</h1>")
end
end
end

describe "#helpers" do
context "when the view context is not set" do
it "raises ArgumentError" do
expect do
base.helpers
end.to raise_error(ArgumentError,
"helpers cannot be used during initialization, as it depends on the view context")
end
end

context "when the view context is set" do
let(:view_context) { double("view_context") }
before { base.instance_variable_set(:@view_context, view_context) }

it "returns the view context" do
expect(base.helpers).to eq(view_context)
end
end
end

describe "#render_in" do
let(:view_context) { double("view_context") }

before do
allow(view_context).to receive(:content_tag).with(:h1, "Sample Content").and_return("<h1>Sample Content</h1>")
allow(view_context).to receive(:capture).and_yield
allow(base).to receive(:template).and_return("<span>Template</span>")
end

subject { base.render_in(view_context) { |base| base.content_tag(:h1, "Sample Content") } }

it "sets the view context" do
subject
expect(base.view_context).to eq(view_context)
end

it "sets the content block" do
expect(subject).to eq("<span>Template</span>")
expect(base.content).to eq("<h1>Sample Content</h1>")
end
end
end
22 changes: 22 additions & 0 deletions spec/warped/emails/components/valid_components_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

def components
%w[
Warped::Emails::Align
Warped::Emails::Button
Warped::Emails::Divider
Warped::Emails::Heading
Warped::Emails::Link
Warped::Emails::Layouts::Main
Warped::Emails::Spacer
Warped::Emails::Text
]
end

RSpec.describe "Warped::Emails Components classes are valid" do
components.each do |component|
it "#{component} is valid" do
expect { Object.const_get(component) }.not_to raise_error
end
end
end
75 changes: 75 additions & 0 deletions spec/warped/emails/slottable_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# frozen_string_literal: true

require "action_view"

RSpec.describe Warped::Emails::Slottable do
let(:test_class) do
Class.new(Warped::Emails::Base) do
include Warped::Emails::Slottable
end
end

it "adds the slots class attribute" do
expect(test_class.slots).to eq(one: {}, many: {})
expect(test_class.new.slots).to eq(one: {}, many: {})
end

it "adds the slots_one class method" do
expect(test_class).to respond_to(:slots_one)
end

it "adds the slots_many class method" do
expect(test_class).to respond_to(:slots_many)
end

describe ".slots_one" do
before { test_class.slots_one(:header) }

it "adds the with_header method" do
component = test_class.new
expect(component).to respond_to(:with_header)
expect do
component.with_header do
"<h1>Header</h1>"
end
end.to change { component.slots[:one][:header] }.from(nil).to(be_a(Proc))
end

it "adds the header method" do
component = test_class.new
component.instance_variable_set(:@view_context, ActionView::Base.new([], {}, nil))

expect(component).to respond_to(:header)

component.with_header { "<h1>Header</h1>" }

expect(component.header).to eq("&lt;h1&gt;Header&lt;/h1&gt;")
end
end

describe ".slots_many" do
before { test_class.slots_many(:headers) }

it "adds the with_headers method" do
component = test_class.new
expect(component).to respond_to(:with_header)
expect do
component.with_header do
"<h1>Header</h1>"
end
end.to change { component.slots[:many][:headers] }.from(nil).to([be_a(Proc)])
end

it "adds the headers method" do
component = test_class.new
component.instance_variable_set(:@view_context, ActionView::Base.new([], {}, nil))

expect(component).to respond_to(:headers)

component.with_header { "<h1>Header1</h1>" }
component.with_header { "<h1>Header2</h1>" }

expect(component.headers).to eq(["&lt;h1&gt;Header1&lt;/h1&gt;", "&lt;h1&gt;Header2&lt;/h1&gt;"])
end
end
end
Loading

0 comments on commit 1d08887

Please sign in to comment.