keynote 0.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of keynote might be problematic. Click here for more details.

@@ -0,0 +1,6 @@
1
+ # encoding: UTF-8
2
+
3
+ module Keynote
4
+ class TestCase < ::ActionView::TestCase
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: UTF-8
2
+
3
+ module Keynote
4
+ # @private
5
+ VERSION = "0.0.1"
6
+ end
@@ -0,0 +1,106 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'helper'
4
+ require 'rails/generators'
5
+ require 'fileutils'
6
+
7
+ describe "generators" do
8
+ def invoke_generator(*args)
9
+ FileUtils.mkdir_p(output_path)
10
+
11
+ args.push '--quiet'
12
+
13
+ retval = Rails::Generators.invoke 'presenter', args,
14
+ :behavior => :invoke,
15
+ :destination_root => output_path
16
+
17
+ assert retval, 'Generator must succeed'
18
+ yield retval.drop(2)
19
+ ensure
20
+ FileUtils.rm_rf(output_path)
21
+ end
22
+
23
+ def output_path
24
+ File.expand_path('../../tmp', __FILE__)
25
+ end
26
+
27
+ def file_contents(path)
28
+ file_contents = File.read(File.join(output_path, path))
29
+ end
30
+
31
+ it "should generate a presenter and Test::Unit file" do
32
+ Rails.application.config.generators do |g|
33
+ g.test_framework :test_unit, :spec => true
34
+ end
35
+
36
+ invoke_generator 'post' do |files|
37
+ files.must_equal %w(
38
+ app/presenters/post_presenter.rb
39
+ test/unit/presenters/post_presenter_test.rb
40
+ )
41
+
42
+ file_contents('app/presenters/post_presenter.rb').
43
+ must_match /class PostPresenter < Keynote::Presenter/
44
+
45
+ file_contents('test/unit/presenters/post_presenter_test.rb').
46
+ must_match /class PostPresenterTest < Keynote::TestCase/
47
+ end
48
+ end
49
+
50
+ it "should generate a presenter and RSpec file" do
51
+ Rails.application.config.generators do |g|
52
+ g.test_framework :rspec
53
+ end
54
+
55
+ invoke_generator 'post' do |files|
56
+ files.must_equal %w(
57
+ app/presenters/post_presenter.rb
58
+ spec/presenters/post_presenter_spec.rb
59
+ )
60
+
61
+ file_contents('app/presenters/post_presenter.rb').
62
+ must_match /class PostPresenter < Keynote::Presenter/
63
+
64
+ file_contents('spec/presenters/post_presenter_spec.rb').
65
+ must_match /describe PostPresenter do/
66
+ end
67
+ end
68
+
69
+ it "should generate a presenter and MiniTest::Rails spec file" do
70
+ Rails.application.config.generators do |g|
71
+ g.test_framework :mini_test, :spec => true
72
+ end
73
+
74
+ invoke_generator 'post' do |files|
75
+ files.must_equal %w(
76
+ app/presenters/post_presenter.rb
77
+ test/presenters/post_presenter_test.rb
78
+ )
79
+
80
+ file_contents('app/presenters/post_presenter.rb').
81
+ must_match /class PostPresenter < Keynote::Presenter/
82
+
83
+ file_contents('test/presenters/post_presenter_test.rb').
84
+ must_match /describe PostPresenter do/
85
+ end
86
+ end
87
+
88
+ it "should generate a presenter and MiniTest::Rails unit file" do
89
+ Rails.application.config.generators do |g|
90
+ g.test_framework :mini_test, :spec => false
91
+ end
92
+
93
+ invoke_generator 'post' do |files|
94
+ files.must_equal %w(
95
+ app/presenters/post_presenter.rb
96
+ test/presenters/post_presenter_test.rb
97
+ )
98
+
99
+ file_contents('app/presenters/post_presenter.rb').
100
+ must_match /class PostPresenter < Keynote::Presenter/
101
+
102
+ file_contents('test/presenters/post_presenter_test.rb').
103
+ must_match /class PostPresenterTest < Keynote::MiniTest::TestCase/
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,84 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'minitest/spec'
4
+ require 'minitest/autorun'
5
+ require 'mocha'
6
+
7
+ require 'pry'
8
+
9
+ require 'rails'
10
+ require 'action_controller/railtie'
11
+ require 'action_mailer/railtie'
12
+ require 'rails/test_unit/railtie'
13
+
14
+ require 'keynote'
15
+
16
+ ## Initialize our test app (by Jose Valim: https://gist.github.com/1942658)
17
+
18
+ class TestApp < Rails::Application
19
+ config.active_support.deprecation = :log
20
+ config.eager_load = false
21
+
22
+ config.secret_token = 'a' * 100
23
+ end
24
+
25
+ class HelloController < ActionController::Base
26
+ def world
27
+ render :text => "Hello world!", :layout => false
28
+ end
29
+ end
30
+
31
+ TestApp.initialize!
32
+
33
+ # We have to define this class because it's hard-coded into the definition of
34
+ # ActiveSupport::TestCase, which will load regardless of whether we load
35
+ # ActiveRecord.
36
+ module ActiveRecord
37
+ class Model
38
+ end
39
+ end
40
+
41
+ ## Examples
42
+
43
+ class EmptyPresenter < Keynote::Presenter
44
+ end
45
+
46
+ class NormalPresenter < Keynote::Presenter
47
+ presents :model
48
+
49
+ def some_bad_js
50
+ "<script>alert('pwnt');</script>"
51
+ end
52
+
53
+ def some_bad_html
54
+ html do
55
+ div { text some_bad_js }
56
+ div { some_bad_js }
57
+ div some_bad_js
58
+ end
59
+ end
60
+ end
61
+
62
+ class Normal
63
+ end
64
+
65
+ module Keynote
66
+ class NestedPresenter < Keynote::Presenter
67
+ presents :model
68
+
69
+ def generate_div
70
+ html do
71
+ div.hi! do
72
+ link_to '#', 'Hello'
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ class Nested
79
+ end
80
+ end
81
+
82
+ class CombinedPresenter < Keynote::Presenter
83
+ presents :model_1, :model_2
84
+ end
@@ -0,0 +1,98 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'helper'
4
+
5
+ describe Keynote do
6
+ describe "with a normal presenter" do
7
+ let(:model) { Normal.new }
8
+
9
+ it "should find and instantiate implicitly" do
10
+ p = Keynote.present(:view, model)
11
+
12
+ p.wont_be_nil
13
+ p.must_be_instance_of NormalPresenter
14
+
15
+ p.view.must_equal :view
16
+ p.model.must_equal model
17
+ end
18
+
19
+ it "should find and instantiate explicitly" do
20
+ p = Keynote.present(:view, :normal, 'hello')
21
+
22
+ p.wont_be_nil
23
+ p.must_be_instance_of NormalPresenter
24
+
25
+ p.view.must_equal :view
26
+ p.model.must_equal 'hello'
27
+ end
28
+
29
+ it "should integrate with Rumble" do
30
+ p = Keynote.present(:view, model)
31
+ rx = /<div>&lt;script&gt;alert\(/
32
+
33
+ p.some_bad_html.scan(rx).count.must_equal 3
34
+ end
35
+ end
36
+
37
+ describe "with a nested presenter" do
38
+ let(:model) { Keynote::Nested.new }
39
+
40
+ it "should find and instantiate implicitly" do
41
+ p = Keynote.present(:view, model)
42
+
43
+ p.wont_be_nil
44
+ p.must_be_instance_of Keynote::NestedPresenter
45
+
46
+ p.view.must_equal :view
47
+ p.model.must_equal model
48
+ end
49
+
50
+ it "should find and instantiate explicitly" do
51
+ p = Keynote.present(:view, :"keynote/nested", 'hello')
52
+
53
+ p.wont_be_nil
54
+ p.must_be_instance_of Keynote::NestedPresenter
55
+
56
+ p.view.must_equal :view
57
+ p.model.must_equal 'hello'
58
+ end
59
+ end
60
+
61
+ describe "memoization" do
62
+ it "should memoize on the model instance(s)" do
63
+ model_1 = Normal.new
64
+ model_2 = Normal.new
65
+
66
+ presented_1 = Keynote.present(:view, model_1)
67
+ presented_2 = Keynote.present(:view, model_1)
68
+
69
+ presented_1.must_be :equal?, presented_2
70
+
71
+ presented_3 = Keynote.present(:view, :combined, model_1, model_2)
72
+ presented_4 = Keynote.present(:view, :combined, model_1, model_2)
73
+ presented_5 = Keynote.present(:view, :combined, model_2, model_1)
74
+
75
+ presented_3.wont_be :equal?, presented_1
76
+ presented_3.must_be :equal?, presented_4
77
+ presented_3.wont_be :equal?, presented_5
78
+ end
79
+
80
+ it "shouldn't memoize if there are no models" do
81
+ presenter_1 = Keynote.present(:view, :empty)
82
+ presenter_2 = Keynote.present(:view, :empty)
83
+
84
+ presenter_1.wont_be :equal?, presenter_2
85
+ end
86
+
87
+ it "should update the view every time" do
88
+ model = Normal.new
89
+
90
+ presenter_1 = Keynote.present(:view, model)
91
+ presenter_1.view.must_equal :view
92
+
93
+ presenter_2 = Keynote.present(:view_2, model)
94
+ presenter_2.must_be :equal?, presenter_1
95
+ presenter_2.view.must_equal :view_2
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,116 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'helper'
4
+
5
+ TestPresenter = Keynote::Presenter
6
+
7
+ describe Keynote::Presenter do
8
+ describe "delegation" do
9
+ let(:klass) do
10
+ Class.new(TestPresenter) do
11
+ presents :grizzly, :bear
12
+ delegate :adams, :to => :grizzly
13
+ delegate :man, :to => :grizzly, :prefix => true
14
+ end
15
+ end
16
+
17
+ it "should be able to use ActiveSupport Module#delegate method" do
18
+ mock = mock()
19
+ mock.expects(:adams)
20
+ mock.expects(:man)
21
+
22
+ klass.new(nil, mock, nil).tap do |p|
23
+ p.adams
24
+ p.grizzly_man
25
+ end
26
+ end
27
+ end
28
+
29
+ describe ".presents" do
30
+ it "should take just the view context by default" do
31
+ klass = Class.new(TestPresenter)
32
+
33
+ klass.new(1).instance_variable_get(:@view).must_equal 1
34
+ end
35
+
36
+ describe "with two parameters" do
37
+ let(:klass) do
38
+ Class.new(TestPresenter) do
39
+ presents :grizzly, :bear
40
+ end
41
+ end
42
+
43
+ it "should let you specify other objects to take" do
44
+ klass.new(1, 2, 3).instance_eval do
45
+ @view.must_equal 1
46
+ @grizzly.must_equal 2
47
+ @bear.must_equal 3
48
+ end
49
+ end
50
+
51
+ it "should not be callable with the wrong arity" do
52
+ proc { klass.new(1, 2) }.must_raise ArgumentError
53
+ end
54
+
55
+ it "should generate readers for the objects" do
56
+ klass.new(1, 2, 3).tap do |p|
57
+ p.view.must_equal 1
58
+ p.grizzly.must_equal 2
59
+ p.bear.must_equal 3
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "#present" do
66
+ it "should pass its view context through to the new presenter" do
67
+ mock = mock()
68
+ mock.expects(:pizza)
69
+
70
+ p1 = TestPresenter.new(mock)
71
+ p2 = p1.present(:test)
72
+
73
+ p1.wont_equal p2
74
+ p2.pizza
75
+ end
76
+ end
77
+
78
+ describe "#method_missing" do
79
+ it "should pass unknown method calls through to the view" do
80
+ mock = mock()
81
+ mock.expects(:talking).with(:heads)
82
+
83
+ object = Class.new do
84
+ define_method(:talking) do |arg|
85
+ mock.talking(arg)
86
+ end
87
+ private :talking
88
+ end.new
89
+
90
+ TestPresenter.new(object).talking(:heads)
91
+ end
92
+
93
+ it "should respond_to? methods of the view" do
94
+ object = Class.new do
95
+ define_method(:talking) do |arg|
96
+ end
97
+ private :talking
98
+ end.new
99
+
100
+ TestPresenter.new(object).respond_to?(:talking).must_equal true
101
+ end
102
+
103
+ it "should raise unknown methods at the presenter, not the view" do
104
+ err = nil
105
+
106
+ begin
107
+ TestPresenter.new(Object.new).talking(:heads)
108
+ rescue NoMethodError => e
109
+ err = e
110
+ end
111
+
112
+ err.wont_be_nil
113
+ err.message.must_match /#<Keynote::Presenter:/
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'helper'
4
+
5
+ describe Keynote::Railtie do
6
+ let(:controller) { HelloController.new }
7
+ let(:context) { controller.view_context }
8
+
9
+ it "should make the present method available to controllers" do
10
+ controller.must_respond_to :present
11
+ end
12
+
13
+ it "should make the present and p methods available to views" do
14
+ context.must_respond_to :present
15
+ context.must_respond_to :p
16
+ end
17
+
18
+ it "should pass present call from controller to Keynote.present" do
19
+ context = stub
20
+ controller.stubs(:view_context).returns(context)
21
+
22
+ Keynote.expects(:present).with(context, :dallas, :leeloo, :multipass)
23
+
24
+ controller.present(:dallas, :leeloo, :multipass)
25
+ end
26
+
27
+ it "should pass present call from view to Keynote.present" do
28
+ Keynote.expects(:present).with(context, :dallas, :leeloo, :multipass)
29
+
30
+ context.present(:dallas, :leeloo, :multipass)
31
+ end
32
+ end