rafters 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6eda33be9a4b9d6483e2ca5ab9cca57f42900f31
4
- data.tar.gz: ee6926c5bb02bc6fda0884bba1a917040e072371
3
+ metadata.gz: 46aa108c7fdb1430b81316137e96b4597788c632
4
+ data.tar.gz: 40bc5436d5e593f804b3d31bedc38a425ac73a79
5
5
  SHA512:
6
- metadata.gz: 37924228164a3e2507c090fd4b4d5200db0e95fd33b299bdf6b3f0f0f090636190b06c66f09dc3135c0e3b0bdc50755b2473bc6d192d87ade571f454c948ef11
7
- data.tar.gz: 9a2ecc6cd6ffc2d08aa4105e365b6673b2a2b45796bc210563ead3d78e5b626b8842f64a30383e59760474b82af73983e5e2b992ff9aae59a5af6b43d0c6205c
6
+ metadata.gz: 750fa198c767793cfec5e397b060ae88fbab408b28b3617827e6f25cf50618fdd2d6d733dc34dcbba42c4016397099f0316ce1d7ed15c571234e100413f2e491
7
+ data.tar.gz: 65f55f6c3c41678d035a9e1520f848a7f9ede30a34a81390a7686e26ca870944fd37fedc59a61d90d319c6b43f983e8bb610affa04a5d17c128b11dc9ef43700
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  # jquery-rails is used by the dummy application
9
+ gem "rails"
9
10
  gem "jquery-rails"
10
11
  gem "sqlite3"
11
12
 
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  [![Build Status](https://travis-ci.org/andyhite/rafters.png?branch=master)](https://travis-ci.org/andyhite/rafters)
4
4
  [![Gem Version](https://badge.fury.io/rb/rafters.png)](http://badge.fury.io/rb/rafters)
5
5
  [![Code Climate](https://codeclimate.com/github/andyhite/rafters.png)](https://codeclimate.com/github/andyhite/rafters)
6
+ [![Coverage Status](https://coveralls.io/repos/andyhite/rafters/badge.png)](https://coveralls.io/r/andyhite/rafters)
6
7
 
7
8
  Rafters lets you think about each page of your application as a collection of small pieces instead of monolithic, difficult to maintain
8
9
  views.
@@ -61,12 +62,12 @@ The two most important files generated above are `app/rafters/[name]/[name]_comp
61
62
 
62
63
  ### Rendering a component
63
64
 
64
- You can render components anywhere - in your view, in your controller, in another component, etc. - but the most common place will (obviously) be in your views. To render a component, call `render_component [symbolized, underscored name]` in one of your app views. For example:
65
+ You can render components anywhere - in your view, in your controller, in another component, etc. - but the most common place will (obviously) be in your views. To render a component, call `render_component :component_name, as: "unique-identifier"` in one of your app views. For example:
65
66
 
66
67
  ```erb
67
68
  ...
68
69
  <div class="main">
69
- <%= render_component :heading %>
70
+ <%= render_component :heading, as: "page-heading" %>
70
71
  </div>
71
72
  ...
72
73
  ```
@@ -147,7 +148,7 @@ Setting values are specified when rendering a component:
147
148
  ```erb
148
149
  ...
149
150
  <div class="main">
150
- <%= render_component :posts, published: true %>
151
+ <%= render_component :posts, as: "published-posts", settings: { published: true } %>
151
152
  </div>
152
153
  ...
153
154
  ```
@@ -2,13 +2,17 @@ module Rafters::Component
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  attr_writer :controller
5
+ attr_reader :identifier
5
6
 
6
7
  included do
7
- attribute :settings
8
+ attributes :settings, :identifier
8
9
  end
9
10
 
10
- def initialize(settings = {})
11
- @settings = settings
11
+ def initialize(options = {})
12
+ raise IdentifierMissing unless options.has_key?(:as)
13
+
14
+ @identifier = options.delete(:as)
15
+ @settings = options.delete(:settings) || {}
12
16
  end
13
17
 
14
18
  def name(without_postfix = false)
@@ -16,10 +20,6 @@ module Rafters::Component
16
20
  without_postfix ? _name.gsub(/_component/, '') : _name
17
21
  end
18
22
 
19
- def identifier
20
- @identifier ||= "#{name}-#{random_identifier}"
21
- end
22
-
23
23
  def template_name
24
24
  @_template_name ||= begin
25
25
  _template_name = (self.class._template_name || self.class.name.underscore)
@@ -43,7 +43,7 @@ module Rafters::Component
43
43
  end
44
44
 
45
45
  def settings
46
- @_settings ||= Hashie::Mash.new(@settings.reverse_merge(overrides).reverse_merge(defaults))
46
+ @_settings ||= Hashie::Mash.new(defaults.merge(@settings).merge(overrides))
47
47
  end
48
48
 
49
49
  def defaults
@@ -55,8 +55,10 @@ module Rafters::Component
55
55
  end
56
56
 
57
57
  def overrides
58
+ return {} if @controller.nil?
59
+
58
60
  @_overrides ||= Hashie::Mash.new.tap do |_overrides|
59
- (controller(:params)[name(true)] || {}).each do |name, value|
61
+ (controller(:params)[identifier] || {}).each do |name, value|
60
62
  _overrides[name] = value
61
63
  end
62
64
  end
@@ -78,14 +80,6 @@ module Rafters::Component
78
80
 
79
81
  private
80
82
 
81
- def random_seed
82
- rand(DateTime.now.to_i).to_s
83
- end
84
-
85
- def random_identifier
86
- Digest::MD5.hexdigest(random_seed)[0..6]
87
- end
88
-
89
83
  module ClassMethods
90
84
  attr_accessor :_attributes, :_defaults, :_template_name
91
85
 
@@ -112,6 +106,6 @@ module Rafters::Component
112
106
  end
113
107
  end
114
108
 
115
- class SettingRequired < StandardError; end
109
+ class IdentifierMissing < StandardError; end
116
110
  class InvalidSetting < StandardError; end
117
111
  end
@@ -8,23 +8,23 @@ module Rafters::ComponentContext
8
8
  alias_method_chain :render, :component
9
9
  end
10
10
 
11
- def component_attributes(name, settings = {})
12
- component = component(name, settings)
11
+ def component_attributes(name, options = {})
12
+ component = component(name, options)
13
13
  component.as_json
14
14
  end
15
15
 
16
- def render_component(name, settings = {}, template_name = nil)
17
- component = component(name, settings)
18
- component_renderer.render(component, template_name)
16
+ def render_component(name, options = {})
17
+ component = component(name, options)
18
+ component_renderer.render(component)
19
19
  end
20
20
 
21
21
  def render_with_component(*args, &block)
22
22
  if params[:component]
23
- component, settings = params[:component], params[:settings]
23
+ component, settings = params[:component], params[:options]
24
24
 
25
25
  respond_to do |format|
26
- format.html { render_without_component(text: render_component(component, settings)) }
27
- format.json { render_without_component(json: component_attributes(component, settings)) }
26
+ format.html { render_without_component(text: render_component(component, options)) }
27
+ format.json { render_without_component(json: component_attributes(component, options)) }
28
28
  end
29
29
  else
30
30
  render_without_component(*args, &block)
@@ -37,8 +37,8 @@ module Rafters::ComponentContext
37
37
  @_component_renderer ||= Rafters::ComponentRenderer.new(self)
38
38
  end
39
39
 
40
- def component(name, settings = {})
40
+ def component(name, options = {})
41
41
  component_klass = "#{name}_component".classify.constantize
42
- component = component_klass.new(settings)
42
+ component = component_klass.new(options)
43
43
  end
44
44
  end
@@ -7,15 +7,13 @@ class Rafters::ComponentRenderer
7
7
  end
8
8
  end
9
9
 
10
- def render(component, template_name = nil)
10
+ def render(component)
11
11
  component.controller = @controller
12
12
 
13
- template_name = (template_name || component.template_name)
14
-
15
13
  store(component)
16
14
 
17
15
  @controller.view_context.content_tag(:div, class: "component", id: component.identifier) do
18
- @controller.view_context.render(file: "/#{template_name}", locals: component.attributes)
16
+ @controller.view_context.render(file: "/#{component.template_name}", locals: component.attributes)
19
17
  end
20
18
  end
21
19
 
@@ -1,3 +1,3 @@
1
1
  module Rafters
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.0"
3
3
  end
data/rafters.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "rspec-rails", "~> 2.14"
25
25
  spec.add_development_dependency "capybara", "~> 2.1"
26
26
  spec.add_development_dependency "yard", "~> 0.8"
27
+ spec.add_development_dependency 'coveralls', "~> 0.6.7"
27
28
 
28
29
  spec.add_dependency "rails", "> 3.2"
29
30
  spec.add_dependency "sprockets", "> 2.2"
@@ -1,5 +1,5 @@
1
1
  <h2><%= link_to_if settings.link_to_post?, post.title, post_path(post.id) %></h2>
2
2
 
3
- <%= render_component :author, id: post.author.id %>
3
+ <%= render_component :author, as: "author-#{post.author.id}", settings: { id: post.author.id } %>
4
4
 
5
5
  <%= simple_format post.body %>
@@ -1,5 +1,5 @@
1
1
  <div class="posts">
2
2
  <% posts.each do |post| %>
3
- <%= render_component :post, post: post, link_to_post: true %>
3
+ <%= render_component :post, as: "post-#{post.id}", settings: { post: post, link_to_post: true } %>
4
4
  <% end %>
5
5
  </div>
@@ -1,10 +1,10 @@
1
1
  <div class="main">
2
2
  <div class="content">
3
- <%= render_component :heading, title: "Posts" %>
4
- <%= render_component :posts %>
3
+ <%= render_component :heading, as: "heading", settings: { title: "Posts" } %>
4
+ <%= render_component :posts, as: "posts" %>
5
5
  </div>
6
6
 
7
7
  <div class="sidebar">
8
- <%= render_component :links %>
8
+ <%= render_component :links, as: "links" %>
9
9
  </div>
10
10
  </div>
@@ -18,21 +18,14 @@ describe Rafters::ComponentContext do
18
18
 
19
19
  describe "#render_component" do
20
20
  it "renders the provided component" do
21
- renderer.should_receive(:render).with(instance_of(FooComponent), nil)
22
- controller.render_component(:foo)
21
+ renderer.should_receive(:render).with(instance_of(FooComponent))
22
+ controller.render_component(:foo, as: "foo")
23
23
  end
24
24
 
25
25
  context "with settings" do
26
26
  it "renders the provided component with the given settings" do
27
- FooComponent.should_receive(:new).with({ test: true })
28
- controller.render_component(:foo, test: true)
29
- end
30
- end
31
-
32
- context "with a specified template name" do
33
- it "renders the provided component using the given template name" do
34
- renderer.should_receive(:render).with(instance_of(FooComponent), "template_name")
35
- controller.render_component(:foo, {}, "template_name")
27
+ FooComponent.should_receive(:new).with({ as: "foo", settings: { test: true } })
28
+ controller.render_component(:foo, { as: "foo", settings: { test: true } })
36
29
  end
37
30
  end
38
31
  end
@@ -35,12 +35,5 @@ describe Rafters::ComponentRenderer do
35
35
  view_context.should_receive(:render).with(file: "/template", locals: { title: "Foo" })
36
36
  subject.render(component)
37
37
  end
38
-
39
- context "with a specified template name" do
40
- it "renders the component with the specified template" do
41
- view_context.should_receive(:render).with(file: "/custom_template", locals: { title: "Foo" })
42
- subject.render(component, "custom_template")
43
- end
44
- end
45
38
  end
46
39
  end
@@ -17,7 +17,7 @@ describe Rafters::Component do
17
17
  HeadingComponent.send(:define_method, :title, -> { "Lorem Ipsum" })
18
18
  HeadingComponent.attribute(:title)
19
19
 
20
- heading = HeadingComponent.new
20
+ heading = HeadingComponent.new(as: "heading")
21
21
  heading.attributes.should have_key(:title)
22
22
  end
23
23
  end
@@ -28,7 +28,7 @@ describe Rafters::Component do
28
28
  HeadingComponent.send(:define_method, :subtitle, -> { "Dolor Sit Amet" })
29
29
  HeadingComponent.attributes(:title, :subtitle)
30
30
 
31
- heading = HeadingComponent.new
31
+ heading = HeadingComponent.new(as: "heading")
32
32
  heading.attributes.keys.map(&:to_sym).should include(:title)
33
33
  heading.attributes.keys.map(&:to_sym).should include(:subtitle)
34
34
  end
@@ -38,7 +38,7 @@ describe Rafters::Component do
38
38
  it "adds default values to the component settings" do
39
39
  HeadingComponent.defaults(foo: "bar")
40
40
 
41
- heading = HeadingComponent.new
41
+ heading = HeadingComponent.new(as: "heading")
42
42
  heading.settings.foo.should == "bar"
43
43
  end
44
44
  end
@@ -49,15 +49,15 @@ describe Rafters::Component do
49
49
  HeadingComponent.attribute(:title)
50
50
  end
51
51
 
52
- subject { HeadingComponent.new }
52
+ subject { HeadingComponent.new(as: "heading") }
53
53
 
54
54
  it "returns the registered attributes and their values" do
55
- subject.attributes.should == Hashie::Mash.new({ title: "Lorem Ipsum", settings: {} })
55
+ subject.attributes.should == Hashie::Mash.new({ title: "Lorem Ipsum", identifier: "heading", settings: {} })
56
56
  end
57
57
  end
58
58
 
59
59
  describe "#settings" do
60
- subject { HeadingComponent.new({ type: "h2" }) }
60
+ subject { HeadingComponent.new(as: "heading", settings: { type: "h2" }) }
61
61
 
62
62
  it "returns the provided settings" do
63
63
  subject.settings.should == Hashie::Mash.new({ type: "h2" })
@@ -70,7 +70,7 @@ describe Rafters::Component do
70
70
  end
71
71
 
72
72
  describe "#template_name" do
73
- subject { HeadingComponent.new }
73
+ subject { HeadingComponent.new(as: "heading") }
74
74
 
75
75
  context "with no specified template name" do
76
76
  it "returns the inferred template name" do
@@ -103,7 +103,7 @@ describe Rafters::Component do
103
103
  end
104
104
 
105
105
  describe "#controller" do
106
- subject { HeadingComponent.new }
106
+ subject { HeadingComponent.new(as: "heading") }
107
107
 
108
108
  let(:controller) { Object.new }
109
109
 
@@ -132,8 +132,8 @@ describe Rafters::Component do
132
132
  end
133
133
 
134
134
  context "when there is neither a method nor an instance variable with the given name in the controller" do
135
- it "raises an error" do
136
- -> { subject.controller(:doesnt_exist) }.should raise_error(Rafters::Component::ControllerMethodOrVariableMissing)
135
+ it "returns nil" do
136
+ subject.controller(:doesnt_exist).should == nil
137
137
  end
138
138
  end
139
139
  end
@@ -141,7 +141,7 @@ describe Rafters::Component do
141
141
  after do
142
142
  # A little housekeeping after each spec runs, so that
143
143
  # we have fresh values for each class attribute
144
- HeadingComponent._attributes = [:settings]
144
+ HeadingComponent._attributes = [:settings, :identifier]
145
145
  HeadingComponent._defaults = {}
146
146
  HeadingComponent._template_name = nil
147
147
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,11 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
5
+ SimpleCov.start do
6
+ add_filter 'spec/dummy'
7
+ end
8
+
1
9
  ENV["RAILS_ENV"] ||= 'test'
2
10
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
3
11
  require 'rspec/rails'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rafters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Hite
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-11 00:00:00.000000000 Z
11
+ date: 2013-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.8'
97
+ - !ruby/object:Gem::Dependency
98
+ name: coveralls
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 0.6.7
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 0.6.7
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rails
99
113
  requirement: !ruby/object:Gem::Requirement