Skip to content

Commit adc3a72

Browse files
committed
Allow to inherit one page from another
To allow reuse of common sections and to allow to add or remove sections for specific cases.
1 parent 9f730b9 commit adc3a72

File tree

6 files changed

+75
-11
lines changed

6 files changed

+75
-11
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Or install it yourself as:
2121
## Usage
2222

2323
```ruby
24-
class class IndexPage < Tram::Page
24+
class IndexPage < Tram::Page
2525
# See dry-initializer
2626
param :account
2727
option :readonly, optional: true
@@ -52,6 +52,22 @@ IndexPage.new(Account.find(99)).to_h(except: :collection)
5252
IndexPage.new(Account.find(99)).to_h(only: :collection)
5353
```
5454

55+
Inheritance of page objects is supported:
56+
57+
```ruby
58+
class FancyIndexPage < IndexPage
59+
inherit_section :title
60+
section :fancy_collection
61+
inherit_section :index_url, if: :readonly_on?
62+
63+
def fancy_collection
64+
collection.map(&:fancy)
65+
end
66+
end
67+
68+
FancyIndexPage.new(Account.find(99)).to_h # => { :title => "…", fancy_collection: […] }
69+
```
70+
5571
## Development
5672

5773
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.

lib/tram/page.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# frozen_string_literal: true
22

3+
require "dry-initializer"
4+
require_relative "page/section"
5+
36
class Tram::Page
47
extend ::Dry::Initializer
58

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

1518
section = Section.new(name, options)
1619
sections[name] = section
17-
define_method(name, &section.block) if section.block
20+
define_method(name, &section.value) if section.value
21+
end
22+
23+
def inherit_section(name, option_overrides={})
24+
name = name.to_sym
25+
parent_section = superclass.sections[name]
26+
options = Tram::Page::Section.dry_initializer.attributes(parent_section)
27+
section(name, options.merge(option_overrides))
1828
end
1929

2030
def url_helper(name)

lib/tram/page/section.rb

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ class Tram::Page
99
class Section
1010
extend Dry::Initializer
1111
param :name, proc(&:to_sym)
12-
option :method, proc(&:to_s), default: -> { name }, as: :method_name
13-
option :value, proc(&:to_proc), optional: true, as: :block
14-
option :if, proc(&:to_s), optional: true, as: :positive
15-
option :unless, proc(&:to_s), optional: true, as: :negative
16-
option :skip, true.method(:&), optional: true
12+
option :method, proc(&:to_s), default: -> { name }
13+
option :value, proc(&:to_proc), optional: true
14+
option :if, proc(&:to_s), optional: true
15+
option :unless, proc(&:to_s), optional: true
1716

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

2625
def skip_on?(page)
27-
return true if skip
28-
return true if positive && !page.public_send(positive)
29-
return true if negative && page.public_send(negative)
26+
return true if attributes[:if] && !page.__send__(attributes[:if])
27+
return true if attributes[:unless] && page.__send__(attributes[:unless])
3028
end
3129

3230
def value_at(page)
33-
block ? page.instance_exec(&block) : page.public_send(method_name)
31+
if attributes[:value]
32+
page.instance_exec(&attributes[:value])
33+
else
34+
page.public_send(attributes[:method])
35+
end
36+
end
37+
38+
def attributes
39+
@attributes ||= self.class.dry_initializer.attributes(self)
3440
end
3541
end
3642
end

spec/spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
require "tram/page"
66
require "support/blank_page"
77
require "support/example_page"
8+
require "support/inherited_page"
89

910
RSpec.configure do |config|
1011
# Enable flags like --only-failures and --next-failure

spec/support/inherited_page.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
class InheritedPage < ExamplePage
4+
inherit_section :foo
5+
inherit_section :bar, if: :no_bar
6+
section :bam
7+
8+
def bam
9+
baz.upcase
10+
end
11+
12+
def no_bar
13+
!bar
14+
end
15+
end

spec/tram/inherited_page_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
require "spec_helper"
4+
5+
RSpec.describe InheritedPage do
6+
subject { described_class.new("test") }
7+
8+
it "returns data hash with new and without skipped fields" do
9+
expect(subject.to_h).to eq(foo: "test", bam: "TEST")
10+
end
11+
12+
it "doesn't change behaviour of the parent class" do
13+
expect(described_class.superclass.new("test").to_h).to \
14+
eq(bar: "test", foo: "test", baz: "test")
15+
end
16+
end

0 commit comments

Comments
 (0)