Skip to content

Commit

Permalink
Allow to inherit one page from another
Browse files Browse the repository at this point in the history
To allow reuse of common sections and to allow to add
or remove sections for specific cases.
  • Loading branch information
Envek committed Nov 26, 2017
1 parent 9f730b9 commit adc3a72
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 11 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Or install it yourself as:
## Usage

```ruby
class class IndexPage < Tram::Page
class IndexPage < Tram::Page
# See dry-initializer
param :account
option :readonly, optional: true
Expand Down Expand Up @@ -52,6 +52,22 @@ IndexPage.new(Account.find(99)).to_h(except: :collection)
IndexPage.new(Account.find(99)).to_h(only: :collection)
```

Inheritance of page objects is supported:

```ruby
class FancyIndexPage < IndexPage
inherit_section :title
section :fancy_collection
inherit_section :index_url, if: :readonly_on?

def fancy_collection
collection.map(&:fancy)
end
end

FancyIndexPage.new(Account.find(99)).to_h # => { :title => "…", fancy_collection: […] }
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Expand Down
12 changes: 11 additions & 1 deletion lib/tram/page.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# frozen_string_literal: true

require "dry-initializer"
require_relative "page/section"

class Tram::Page
extend ::Dry::Initializer

Expand All @@ -14,7 +17,14 @@ def section(name, options = {})

section = Section.new(name, options)
sections[name] = section
define_method(name, &section.block) if section.block
define_method(name, &section.value) if section.value
end

def inherit_section(name, option_overrides={})
name = name.to_sym
parent_section = superclass.sections[name]
options = Tram::Page::Section.dry_initializer.attributes(parent_section)
section(name, options.merge(option_overrides))
end

def url_helper(name)
Expand Down
24 changes: 15 additions & 9 deletions lib/tram/page/section.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ class Tram::Page
class Section
extend Dry::Initializer
param :name, proc(&:to_sym)
option :method, proc(&:to_s), default: -> { name }, as: :method_name
option :value, proc(&:to_proc), optional: true, as: :block
option :if, proc(&:to_s), optional: true, as: :positive
option :unless, proc(&:to_s), optional: true, as: :negative
option :skip, true.method(:&), optional: true
option :method, proc(&:to_s), default: -> { name }
option :value, proc(&:to_proc), optional: true
option :if, proc(&:to_s), optional: true
option :unless, proc(&:to_s), optional: true

# @param [Tram::Page] page
# @return [Hash] a part of the section
Expand All @@ -24,13 +23,20 @@ def call(page)
private

def skip_on?(page)
return true if skip
return true if positive && !page.public_send(positive)
return true if negative && page.public_send(negative)
return true if attributes[:if] && !page.__send__(attributes[:if])
return true if attributes[:unless] && page.__send__(attributes[:unless])
end

def value_at(page)
block ? page.instance_exec(&block) : page.public_send(method_name)
if attributes[:value]
page.instance_exec(&attributes[:value])
else
page.public_send(attributes[:method])
end
end

def attributes
@attributes ||= self.class.dry_initializer.attributes(self)
end
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require "tram/page"
require "support/blank_page"
require "support/example_page"
require "support/inherited_page"

RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
Expand Down
15 changes: 15 additions & 0 deletions spec/support/inherited_page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

class InheritedPage < ExamplePage
inherit_section :foo
inherit_section :bar, if: :no_bar
section :bam

def bam
baz.upcase
end

def no_bar
!bar
end
end
16 changes: 16 additions & 0 deletions spec/tram/inherited_page_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

require "spec_helper"

RSpec.describe InheritedPage do
subject { described_class.new("test") }

it "returns data hash with new and without skipped fields" do
expect(subject.to_h).to eq(foo: "test", bam: "TEST")
end

it "doesn't change behaviour of the parent class" do
expect(described_class.superclass.new("test").to_h).to \
eq(bar: "test", foo: "test", baz: "test")
end
end

0 comments on commit adc3a72

Please sign in to comment.