obviews 0.0.1.alpha → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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