Skip to content

Commit b6d8d6e

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 9b5bd5c commit b6d8d6e

File tree

5 files changed

+52
-7
lines changed

5 files changed

+52
-7
lines changed

README.md

Lines changed: 16 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,21 @@ 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+
section :collection, skip: true
60+
section :fancy_collection
61+
62+
def fancy_collection
63+
collection.map(&:fancy)
64+
end
65+
end
66+
67+
FancyIndexPage.new(Account.find(99)).to_h
68+
```
69+
5570
## Development
5671

5772
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: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ class << self
77
attr_accessor :i18n_scope
88

99
def section(name, options = {})
10-
@__sections ||= []
10+
@__sections ||= {}
1111

1212
n = name.to_sym
13-
if @__sections.map(&:first).include?(n)
14-
raise "Section #{n} already exists"
15-
end
13+
return @__sections.delete(n) if options[:skip]
14+
raise "Section #{n} already exists" if @__sections.key?(n)
1615

1716
n = define_section_method(n, options)
18-
@__sections << [n, options]
17+
@__sections[n] = options
1918
end
2019

2120
def url_helper(name)
@@ -30,6 +29,10 @@ def define_section_method(n, options)
3029
define_method(n) { instance_exec(&options[:value]) }
3130
n
3231
end
32+
33+
def inherited(subclass)
34+
subclass.instance_variable_set(:@__sections, @__sections.dup)
35+
end
3336
end
3437

3538
def to_h(options = {})
@@ -51,7 +54,7 @@ def page_methods(options)
5154
methods = self.class.instance_variable_get(:"@__sections") || []
5255
except = Array(options[:except])
5356
only = Array(options[:only])
54-
methods.reject do |(name, opts)|
57+
methods.reject do |name, opts|
5558
(except.any? && except.include?(name)) ||
5659
(only.any? && !only.include?(name)) ||
5760
__hide?(opts)

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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# frozen_string_literal: true
2+
3+
class InheritedPage < ExamplePage
4+
section :baz, skip: true
5+
section :bam
6+
7+
def bam
8+
baz.upcase
9+
end
10+
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(bar: "test", 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)