obviews 0.0.1.alpha → 0.1.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.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
3
  # Declare your gem's dependencies in obviews.gemspec.
4
4
  # Bundler will treat runtime dependencies like base dependencies, and
@@ -6,7 +6,7 @@ source "http://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  # jquery-rails is used by the dummy application
9
- gem "jquery-rails"
9
+ # gem "jquery-rails"
10
10
 
11
11
  # Declare any dependencies that are still in development here instead of in
12
12
  # your gemspec. These might include edge Rails or gems from your path or
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- obviews (0.0.1.alpha)
4
+ obviews (0.1.0)
5
5
  rails (~> 3.2.3)
6
6
 
7
7
  GEM
@@ -34,23 +34,34 @@ GEM
34
34
  activesupport (3.2.4)
35
35
  i18n (~> 0.6)
36
36
  multi_json (~> 1.0)
37
+ addressable (2.2.8)
37
38
  arel (3.0.2)
38
39
  builder (3.0.0)
40
+ capybara (1.1.2)
41
+ mime-types (>= 1.16)
42
+ nokogiri (>= 1.3.3)
43
+ rack (>= 1.0.0)
44
+ rack-test (>= 0.5.4)
45
+ selenium-webdriver (~> 2.0)
46
+ xpath (~> 0.1.4)
47
+ childprocess (0.3.2)
48
+ ffi (~> 1.0.6)
39
49
  diff-lcs (1.1.3)
40
50
  erubis (2.7.0)
51
+ ffi (1.0.11)
41
52
  hike (1.2.1)
42
53
  i18n (0.6.0)
43
54
  journey (1.0.3)
44
- jquery-rails (2.0.2)
45
- railties (>= 3.2.0, < 5.0)
46
- thor (~> 0.14)
47
55
  json (1.7.3)
56
+ libwebsocket (0.1.3)
57
+ addressable
48
58
  mail (2.4.4)
49
59
  i18n (>= 0.4.0)
50
60
  mime-types (~> 1.16)
51
61
  treetop (~> 1.4.8)
52
62
  mime-types (1.18)
53
63
  multi_json (1.3.6)
64
+ nokogiri (1.5.2)
54
65
  polyglot (0.3.3)
55
66
  rack (1.4.1)
56
67
  rack-cache (1.2)
@@ -90,6 +101,13 @@ GEM
90
101
  activesupport (>= 3.0)
91
102
  railties (>= 3.0)
92
103
  rspec (~> 2.10.0)
104
+ rubyzip (0.9.8)
105
+ selenium-webdriver (2.21.2)
106
+ childprocess (>= 0.2.5)
107
+ ffi (~> 1.0)
108
+ libwebsocket (~> 0.1.3)
109
+ multi_json (~> 1.0)
110
+ rubyzip
93
111
  sprockets (2.1.3)
94
112
  hike (~> 1.2)
95
113
  rack (~> 1.0)
@@ -100,11 +118,13 @@ GEM
100
118
  polyglot
101
119
  polyglot (>= 0.3.1)
102
120
  tzinfo (0.3.33)
121
+ xpath (0.1.4)
122
+ nokogiri (~> 1.3)
103
123
 
104
124
  PLATFORMS
105
125
  ruby
106
126
 
107
127
  DEPENDENCIES
108
- jquery-rails
128
+ capybara
109
129
  obviews!
110
130
  rspec-rails (~> 2.10)
@@ -0,0 +1,53 @@
1
+ # Obviews
2
+
3
+
4
+
5
+
6
+ ## Example
7
+
8
+ In the controller
9
+
10
+ ```ruby
11
+ class PostsController < ApplicationController
12
+ expose :blog, :posts
13
+
14
+ def index
15
+ end
16
+
17
+ def show
18
+ expose post: posts.first
19
+ end
20
+
21
+ private
22
+
23
+ def blog
24
+ @blog ||= Blog.first
25
+ end
26
+
27
+ def posts
28
+ blog.posts
29
+ end
30
+ end
31
+ ```
32
+
33
+
34
+ In the views:
35
+
36
+ ```haml
37
+ -# views/posts/index.html.haml
38
+ %h1= blog.title
39
+ = render posts
40
+
41
+ -# views/posts/show.html.haml
42
+ %h1= blog.title
43
+ = render post
44
+
45
+ -# views/posts/_post.html.haml
46
+ .post
47
+ %h2= post.title
48
+ %p= post.body
49
+ ```
50
+
51
+
52
+
53
+ This project rocks and uses MIT-LICENSE.
@@ -1,2 +1,4 @@
1
- module Obviews
2
- end
1
+ require 'obviews/controller'
2
+ require 'obviews/view'
3
+ require 'obviews/railtie'
4
+ require 'obviews/version'
@@ -0,0 +1,38 @@
1
+ require 'obviews/exposed_assigns'
2
+
3
+ module Obviews
4
+ module Controller
5
+ extend ActiveSupport::Concern
6
+
7
+ module Exposure
8
+ attr_writer :_exposed_methods
9
+ def _exposed_methods
10
+ @_exposed_methods ||= []
11
+ end
12
+
13
+ def _exposed_values
14
+ @_exposed_values ||= {}
15
+ end
16
+
17
+ def expose *methods
18
+ if methods.size == 1 and methods.first.is_a? Hash
19
+ _exposed_values.merge!(methods.first)
20
+ else
21
+ self._exposed_methods += methods.flatten
22
+ end
23
+ end
24
+ end
25
+
26
+ module ClassMethods
27
+ include Exposure
28
+ end
29
+ include Exposure
30
+
31
+ def view_assigns
32
+ exposed_methods = (self.class._exposed_methods + _exposed_methods).map(&:to_sym)
33
+ exposed_values = (self.class._exposed_values.merge(_exposed_values))
34
+ exposed_assigns = ExposedAssigns.new self, exposed_methods
35
+ exposed_assigns.merge! exposed_values
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,20 @@
1
+ module Obviews
2
+ class ExposedAssigns < Hash
3
+ def initialize object, exposed_methods
4
+ @exposed_methods = exposed_methods
5
+ super() do |assigns, key|
6
+ if @exposed_methods.include? key.to_sym
7
+ assigns[key] = object.send(key)
8
+ end
9
+ end
10
+ end
11
+
12
+ def keys
13
+ super + @exposed_methods
14
+ end
15
+
16
+ def inspect
17
+ "#<#{self.class}: @exposed_methods: (#{@exposed_methods.inspect}), hash: #{super}>"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module Obviews
2
+ class Railtie < Rails::Railtie
3
+ config.obviews = ActiveSupport::OrderedOptions.new
4
+ # config.obviews.memoize_by_default = true
5
+
6
+
7
+ initializer 'obviews.initialize' do
8
+ ActiveSupport.on_load(:action_controller) do
9
+ ActionController::Base.send :include, ::Obviews::Controller
10
+ end
11
+
12
+ ActiveSupport.on_load(:action_view) do
13
+ ActionView::Base.send :include, ::Obviews::View
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Obviews
2
- VERSION = '0.0.1.alpha'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -0,0 +1,18 @@
1
+ module Obviews
2
+ module View
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+ # Force this method definition since it's not in a module...
8
+ def assign(new_assigns)
9
+ @_assigns = new_assigns #.tap{ |a| a.keys.each { |k| a[k] } }
10
+ new_assigns.keys.each do |key|
11
+ define_singleton_method(key) { @_assigns[key] }
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
@@ -10,8 +10,8 @@ Gem::Specification.new do |s|
10
10
  s.authors = ['Elia Schito']
11
11
  s.email = ['elia@schito.me']
12
12
  s.homepage = 'http://elia.schito.me'
13
- s.summary = 'Secret business.'
14
- s.description = 'Secret business.'
13
+ s.summary = 'Restores the obvious OOP method interface between Rails controllers and views'
14
+ s.description = 'Restores the obvious OOP method interface between Rails controllers and views'
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -20,4 +20,5 @@ Gem::Specification.new do |s|
20
20
 
21
21
  s.add_runtime_dependency 'rails', '~> 3.2.3'
22
22
  s.add_development_dependency 'rspec-rails', '~> 2.10'
23
+ s.add_development_dependency 'capybara'
23
24
  end
@@ -0,0 +1 @@
1
+ --colour
@@ -1,3 +1,26 @@
1
1
  class ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
+ expose :blog
4
+
5
+ def index
6
+ blog.posts << post
7
+ @private_instance_var = 'Secret!'
8
+ expose :custom_title
9
+ expose :author => 'Elia Schito'
10
+ end
11
+
12
+
13
+ private
14
+
15
+ def custom_title
16
+ 'Hi World!'
17
+ end
18
+
19
+ def blog
20
+ @blog ||= Blog.new 'Whispered Thinking.', []
21
+ end
22
+
23
+ def post
24
+ @post ||= Post.new('post-title', 'post-body')
25
+ end
3
26
  end
@@ -0,0 +1,2 @@
1
+ class Blog < Struct.new(:title, :posts)
2
+ end
@@ -0,0 +1,2 @@
1
+ class Post < Struct.new(:title, :body)
2
+ end
@@ -0,0 +1,12 @@
1
+ <h1><%= blog.title %></h1>
2
+ <em><%= custom_title %></em>
3
+
4
+ <% blog.posts.each do |post| %>
5
+ <h2><%= post.title %></h2>
6
+ <p><%= post.body %></p>
7
+ <% end %>
8
+
9
+ <div class="footer">
10
+ <%= @private_instance_var %>
11
+ <%= author %>
12
+ </div>
@@ -1,58 +1,3 @@
1
1
  Dummy::Application.routes.draw do
2
- # The priority is based upon order of creation:
3
- # first created -> highest priority.
4
-
5
- # Sample of regular route:
6
- # match 'products/:id' => 'catalog#view'
7
- # Keep in mind you can assign values other than :controller and :action
8
-
9
- # Sample of named route:
10
- # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
11
- # This route can be invoked with purchase_url(:id => product.id)
12
-
13
- # Sample resource route (maps HTTP verbs to controller actions automatically):
14
- # resources :products
15
-
16
- # Sample resource route with options:
17
- # resources :products do
18
- # member do
19
- # get 'short'
20
- # post 'toggle'
21
- # end
22
- #
23
- # collection do
24
- # get 'sold'
25
- # end
26
- # end
27
-
28
- # Sample resource route with sub-resources:
29
- # resources :products do
30
- # resources :comments, :sales
31
- # resource :seller
32
- # end
33
-
34
- # Sample resource route with more complex sub-resources
35
- # resources :products do
36
- # resources :comments
37
- # resources :sales do
38
- # get 'recent', :on => :collection
39
- # end
40
- # end
41
-
42
- # Sample resource route within a namespace:
43
- # namespace :admin do
44
- # # Directs /admin/products/* to Admin::ProductsController
45
- # # (app/controllers/admin/products_controller.rb)
46
- # resources :products
47
- # end
48
-
49
- # You can have the root of your site routed with "root"
50
- # just remember to delete public/index.html.
51
- # root :to => 'welcome#index'
52
-
53
- # See how all your routes lay out with "rake routes"
54
-
55
- # This is a legacy wild controller route that's not recommended for RESTful applications.
56
- # Note: This route will make all actions in every controller accessible via GET requests.
57
- # match ':controller(/:action(/:id))(.:format)'
2
+ root to: 'application#index'
58
3
  end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'exposure' do
4
+ it 'loads the modules' do
5
+ ActionView::Base.ancestors.should include(Obviews::View)
6
+ ActionController::Base.ancestors.should include(Obviews::Controller)
7
+ end
8
+
9
+ let(:controller) { ApplicationController.new }
10
+
11
+ it 'can see the content' do
12
+ visit '/'
13
+ page.should have_content controller.send(:blog).title
14
+
15
+ within '.footer' do
16
+ page.should_not have_content('Secret!')
17
+ page.should have_content('Elia Schito')
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Obviews::Controller do
4
+ let(:controller) { ApplicationController.new }
5
+ it 'responds to #expose' do
6
+ controller.should respond_to(:expose)
7
+ controller.class.should respond_to(:expose)
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Obviews::ExposedAssigns do
4
+ let(:object) { double('object', :a_method => 'a value') }
5
+
6
+ it 'lazily calls methods' do
7
+ exposed_assigns = described_class.new object, [:a_method]
8
+ object.should_receive :a_method
9
+ exposed_assigns[:a_method]
10
+ end
11
+
12
+ it 'returns the value' do
13
+ exposed_assigns = described_class.new object, [:a_method]
14
+ exposed_assigns[:a_method].should eq('a value')
15
+ end
16
+
17
+ it 'memoizes the value' do
18
+ exposed_assigns = described_class.new object, [:a_method]
19
+ exposed_assigns[:a_method]
20
+
21
+ object.should_not_receive :a_method
22
+ exposed_assigns[:a_method]
23
+ end
24
+
25
+ describe '#keys' do
26
+ context 'with merged hash' do
27
+ it 'has keys from both' do
28
+ exposed_assigns = described_class.new object, [:a_method]
29
+ exposed_assigns.merge! :another_method => 'another value'
30
+ exposed_assigns.keys.should include(:another_method)
31
+ exposed_assigns.keys.should include(:a_method)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV['RAILS_ENV'] ||= 'test'
3
+ require File.expand_path('../dummy/config/environment', __FILE__)
4
+ require 'rspec/rails'
5
+ require 'rspec/autorun'
6
+
7
+ # Requires supporting ruby files with custom matchers and macros, etc,
8
+ # in spec/support/ and its subdirectories.
9
+ Dir[Rails.root.join('spec/support/**/*.rb')].each {|f| require f}
10
+
11
+ RSpec.configure do |config|
12
+ # If true, the base class of anonymous controllers will be inferred
13
+ # automatically. This will be the default behavior in future versions of
14
+ # rspec-rails.
15
+ config.infer_base_class_for_anonymous_controllers = false
16
+ end
@@ -0,0 +1 @@
1
+ require 'capybara/rspec'
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: obviews
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha
5
- prerelease: 6
4
+ version: 0.1.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Elia Schito
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-01 00:00:00.000000000 Z
12
+ date: 2012-06-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70360182610540 !ruby/object:Gem::Requirement
16
+ requirement: &70206313573540 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.2.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70360182610540
24
+ version_requirements: *70206313573540
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec-rails
27
- requirement: &70360182609940 !ruby/object:Gem::Requirement
27
+ requirement: &70206313572480 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,8 +32,20 @@ dependencies:
32
32
  version: '2.10'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70360182609940
36
- description: Secret business.
35
+ version_requirements: *70206313572480
36
+ - !ruby/object:Gem::Dependency
37
+ name: capybara
38
+ requirement: &70206313571760 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70206313571760
47
+ description: Restores the obvious OOP method interface between Rails controllers and
48
+ views
37
49
  email:
38
50
  - elia@schito.me
39
51
  executables: []
@@ -41,15 +53,20 @@ extensions: []
41
53
  extra_rdoc_files: []
42
54
  files:
43
55
  - .gitignore
56
+ - .rspec
44
57
  - Gemfile
45
58
  - Gemfile.lock
46
59
  - MIT-LICENSE
47
- - README.rdoc
60
+ - README.md
48
61
  - Rakefile
49
62
  - lib/obviews.rb
63
+ - lib/obviews/controller.rb
64
+ - lib/obviews/exposed_assigns.rb
65
+ - lib/obviews/railtie.rb
50
66
  - lib/obviews/version.rb
51
- - lib/tasks/obviews_tasks.rake
67
+ - lib/obviews/view.rb
52
68
  - obviews.gemspec
69
+ - spec/dummy/.rspec
53
70
  - spec/dummy/README.rdoc
54
71
  - spec/dummy/Rakefile
55
72
  - spec/dummy/app/assets/javascripts/application.js
@@ -58,6 +75,9 @@ files:
58
75
  - spec/dummy/app/helpers/application_helper.rb
59
76
  - spec/dummy/app/mailers/.gitkeep
60
77
  - spec/dummy/app/models/.gitkeep
78
+ - spec/dummy/app/models/blog.rb
79
+ - spec/dummy/app/models/post.rb
80
+ - spec/dummy/app/views/application/index.html.erb
61
81
  - spec/dummy/app/views/layouts/application.html.erb
62
82
  - spec/dummy/config.ru
63
83
  - spec/dummy/config/application.rb
@@ -81,6 +101,11 @@ files:
81
101
  - spec/dummy/public/500.html
82
102
  - spec/dummy/public/favicon.ico
83
103
  - spec/dummy/script/rails
104
+ - spec/integration/exposure_spec.rb
105
+ - spec/obviews/controller_spec.rb
106
+ - spec/obviews/exposed_assigns_spec.rb
107
+ - spec/spec_helper.rb
108
+ - spec/support/capybara.rb
84
109
  homepage: http://elia.schito.me
85
110
  licenses: []
86
111
  post_install_message:
@@ -95,20 +120,24 @@ required_ruby_version: !ruby/object:Gem::Requirement
95
120
  version: '0'
96
121
  segments:
97
122
  - 0
98
- hash: -1500703088916366727
123
+ hash: -1538721513194098451
99
124
  required_rubygems_version: !ruby/object:Gem::Requirement
100
125
  none: false
101
126
  requirements:
102
- - - ! '>'
127
+ - - ! '>='
103
128
  - !ruby/object:Gem::Version
104
- version: 1.3.1
129
+ version: '0'
130
+ segments:
131
+ - 0
132
+ hash: -1538721513194098451
105
133
  requirements: []
106
134
  rubyforge_project:
107
135
  rubygems_version: 1.8.17
108
136
  signing_key:
109
137
  specification_version: 3
110
- summary: Secret business.
138
+ summary: Restores the obvious OOP method interface between Rails controllers and views
111
139
  test_files:
140
+ - spec/dummy/.rspec
112
141
  - spec/dummy/README.rdoc
113
142
  - spec/dummy/Rakefile
114
143
  - spec/dummy/app/assets/javascripts/application.js
@@ -117,6 +146,9 @@ test_files:
117
146
  - spec/dummy/app/helpers/application_helper.rb
118
147
  - spec/dummy/app/mailers/.gitkeep
119
148
  - spec/dummy/app/models/.gitkeep
149
+ - spec/dummy/app/models/blog.rb
150
+ - spec/dummy/app/models/post.rb
151
+ - spec/dummy/app/views/application/index.html.erb
120
152
  - spec/dummy/app/views/layouts/application.html.erb
121
153
  - spec/dummy/config.ru
122
154
  - spec/dummy/config/application.rb
@@ -140,3 +172,8 @@ test_files:
140
172
  - spec/dummy/public/500.html
141
173
  - spec/dummy/public/favicon.ico
142
174
  - spec/dummy/script/rails
175
+ - spec/integration/exposure_spec.rb
176
+ - spec/obviews/controller_spec.rb
177
+ - spec/obviews/exposed_assigns_spec.rb
178
+ - spec/spec_helper.rb
179
+ - spec/support/capybara.rb
@@ -1,3 +0,0 @@
1
- = Obviews
2
-
3
- This project rocks and uses MIT-LICENSE.
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :obviews do
3
- # # Task goes here
4
- # end