neo-rails 0.0.1
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +66 -0
- data/Rakefile +11 -0
- data/lib/assets/stylesheets/neo-rails.css +1 -0
- data/lib/assets/stylesheets/neo/rails/scenarios/render_scenarios_list.css.sass +8 -0
- data/lib/neo-rails.rb +1 -0
- data/lib/neo/rails.rb +11 -0
- data/lib/neo/rails/engine.rb +21 -0
- data/lib/neo/rails/exposure.rb +47 -0
- data/lib/neo/rails/mock.rb +67 -0
- data/lib/neo/rails/presenter.rb +23 -0
- data/lib/neo/rails/presenter/test_helper.rb +23 -0
- data/lib/neo/rails/scenarios.rb +111 -0
- data/lib/neo/rails/scenarios/rails_helper.rb +19 -0
- data/lib/neo/rails/scenarios/test_helper.rb +48 -0
- data/lib/neo/rails/version.rb +5 -0
- data/neo-rails.gemspec +20 -0
- data/test/helper.rb +8 -0
- data/test/mock_test.rb +33 -0
- data/test/presenter_test.rb +74 -0
- metadata +104 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Neo::Rails
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'neo-rails'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install neo-rails
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Presenter
|
22
|
+
|
23
|
+
In app/presenters/presenter.rb
|
24
|
+
|
25
|
+
class Presenter
|
26
|
+
include Neo::Rails::Presenter
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
class UserPresenter < Presenter
|
31
|
+
def initialize(user)
|
32
|
+
@user = user
|
33
|
+
end
|
34
|
+
|
35
|
+
def name
|
36
|
+
@user.name
|
37
|
+
end
|
38
|
+
|
39
|
+
def profile_path
|
40
|
+
view_context.link_to view_context.user_profile_path(@user), name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
In test/test_helper.rb
|
45
|
+
|
46
|
+
require 'neo/rails/presenter/test_helper'
|
47
|
+
|
48
|
+
Neo::Rails::Presenter::TestHelper.setup
|
49
|
+
|
50
|
+
### Scenarios
|
51
|
+
|
52
|
+
In app/assets/stylesheets/application.css:
|
53
|
+
|
54
|
+
//= require neo-rails
|
55
|
+
|
56
|
+
In app/layouts/application.html.haml
|
57
|
+
|
58
|
+
= render_scenarios_list
|
59
|
+
|
60
|
+
## Contributing
|
61
|
+
|
62
|
+
1. Fork it
|
63
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
64
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
65
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
66
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= require neo/rails/scenarios/render_scenarios_list
|
data/lib/neo-rails.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "neo/rails"
|
data/lib/neo/rails.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Neo
|
2
|
+
module Rails
|
3
|
+
class Engine < ::Rails::Engine
|
4
|
+
initializer "neo-rails.scenarios_helpers" do
|
5
|
+
require 'neo/rails/scenarios/rails_helper'
|
6
|
+
|
7
|
+
ActiveSupport.on_load(:action_view) do
|
8
|
+
include Neo::Rails::Scenarios::RailsHelper
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
initializer "neo-rails.presenter_method" do
|
13
|
+
ActiveSupport.on_load(:action_controller) do
|
14
|
+
before_filter do |controller|
|
15
|
+
Neo::Rails::Presenter.view_context = controller.view_context
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Neo
|
2
|
+
module Rails
|
3
|
+
# A really simple version of exposing variables to the view.
|
4
|
+
# Bases on attr_reader and helper_method.
|
5
|
+
module Exposure
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class UndeclaredVariableError < StandardError; end
|
9
|
+
|
10
|
+
included do
|
11
|
+
class_attribute :exposed_vars
|
12
|
+
self.exposed_vars = Set.new
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
# Defines the variables to be exposed.
|
17
|
+
def exposes(*names)
|
18
|
+
exposures = names.map(&:to_sym).reject { |name| exposed_vars.include?(name) }
|
19
|
+
self.exposed_vars.merge exposures
|
20
|
+
attr_reader *exposures
|
21
|
+
helper_method *exposures
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Expose an assign at the instance level.
|
26
|
+
#
|
27
|
+
# If the value is given with a block, just execute the block
|
28
|
+
# if a value was not set yet.
|
29
|
+
#
|
30
|
+
# Raise UndeclaredVariableError if access variable wasn't declared before.
|
31
|
+
def expose(key, value=nil)
|
32
|
+
name = key.to_sym
|
33
|
+
raise UndeclaredVariableError unless self.class.exposed_vars.include?(name)
|
34
|
+
|
35
|
+
value = yield if block_given?
|
36
|
+
|
37
|
+
self.instance_variable_set("@#{name}", value)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def exposed?(name)
|
43
|
+
instance_variable_get("@#{name}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
# A Mock can fake an object.
|
4
|
+
#
|
5
|
+
# This is useful when frontend developers want to fill a page with
|
6
|
+
# mock data. Mocks can pre-define interface for real data.
|
7
|
+
#
|
8
|
+
# == Usage
|
9
|
+
#
|
10
|
+
# app/mocks/user_mock.rb:
|
11
|
+
#
|
12
|
+
# class UserMock < Neo::Rails::Mock
|
13
|
+
# def age
|
14
|
+
# mock.tagged?(:old) ? 78 : 23
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# def name
|
18
|
+
# "Uncle bob"
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# def logged_in?
|
22
|
+
# true
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# def sexy?
|
26
|
+
# mock.tagged?(:sexy)
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# Further...
|
31
|
+
#
|
32
|
+
# old_man = UserMock.new(:old)
|
33
|
+
# old_man.age # => 78
|
34
|
+
# old_man.name # => "Uncle Bob"
|
35
|
+
#
|
36
|
+
# old_sexbomb = UserMock.new(:old, :sexy)
|
37
|
+
# old_sexbomb.age # => 78
|
38
|
+
# old_sexbomb.sexy? # => true
|
39
|
+
#
|
40
|
+
module Neo
|
41
|
+
module Rails
|
42
|
+
class Mock
|
43
|
+
attr_reader :mock
|
44
|
+
|
45
|
+
# Initializes a Mock with optional tag list.
|
46
|
+
def initialize(*args)
|
47
|
+
@mock = MockConfig.new(args)
|
48
|
+
end
|
49
|
+
|
50
|
+
class MockConfig
|
51
|
+
def initialize(args)
|
52
|
+
@tags = args
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns a human readable tag list.
|
56
|
+
def description
|
57
|
+
@tags.to_a.map { |tag| tag.to_s.capitalize }.join(", ")
|
58
|
+
end
|
59
|
+
|
60
|
+
# Checks if this mock is tagged with +tag+.
|
61
|
+
def tagged?(tag)
|
62
|
+
@tags.include?(tag)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Neo
|
2
|
+
module Rails
|
3
|
+
module Presenter
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
def view_context
|
7
|
+
Neo::Rails::Presenter.view_context
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def view_context
|
14
|
+
Thread.current[:neo_rails_presenter_view_context]
|
15
|
+
end
|
16
|
+
|
17
|
+
def view_context=(view_context)
|
18
|
+
Thread.current[:neo_rails_presenter_view_context] = view_context
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Neo
|
2
|
+
module Rails
|
3
|
+
module Presenter
|
4
|
+
module TestHelper
|
5
|
+
def setup
|
6
|
+
Presenter.view_context = FakeViewContext.instance
|
7
|
+
end
|
8
|
+
module_function :setup
|
9
|
+
|
10
|
+
class FakeViewContext
|
11
|
+
include Singleton
|
12
|
+
include ActionView::Helpers::TagHelper
|
13
|
+
include ActionView::Helpers::UrlHelper
|
14
|
+
include Sprockets::Helpers::RailsHelper
|
15
|
+
include Sprockets::Helpers::IsolatedHelper
|
16
|
+
include ::Rails.application.routes.url_helpers
|
17
|
+
|
18
|
+
attr_accessor :output_buffer
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Neo
|
2
|
+
module Rails
|
3
|
+
# Enables controller actions to have scenarios, which will be applied
|
4
|
+
# +before+ the execution of the action.
|
5
|
+
module Scenarios
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class DuplicatedScenario < StandardError; end
|
9
|
+
class ExposureMustBeIncludedFirst < StandardError; end
|
10
|
+
|
11
|
+
included do
|
12
|
+
if self < Neo::Rails::Exposure
|
13
|
+
class_attribute :scenarios
|
14
|
+
self.scenarios = Hash.new { |hash, action| hash[action] = {} }
|
15
|
+
before_filter :apply_scenario
|
16
|
+
helper_method :list_scenarios
|
17
|
+
else
|
18
|
+
raise ExposureMustBeIncludedFirst
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
# Defines a scenario
|
24
|
+
#
|
25
|
+
# == Usage
|
26
|
+
#
|
27
|
+
# class AController < ActionController::Base
|
28
|
+
# include Neo::Rails::Exposure
|
29
|
+
# include Neo::Rails::Scenarios
|
30
|
+
#
|
31
|
+
# exposes :foo
|
32
|
+
#
|
33
|
+
# def show
|
34
|
+
# ...
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# scenario :show, :a_scenario do
|
38
|
+
# expose :foo, "bar" # any expose calls on :foo will be ignored in the action
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# Raises DuplicatedScenario if there is already a scenario for the action with the same name
|
43
|
+
#
|
44
|
+
def scenario(action, name, options={}, &block)
|
45
|
+
scenario = Scenario.new(action, name, block, options)
|
46
|
+
|
47
|
+
raise DuplicatedScenario if self.scenarios[scenario.action][scenario.name]
|
48
|
+
|
49
|
+
self.scenarios[scenario.action][scenario.name] = scenario
|
50
|
+
end
|
51
|
+
|
52
|
+
def list_scenarios
|
53
|
+
self.scenarios.values.map(&:values).flatten
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Overwrites expose so it will only set the value once.
|
58
|
+
# see Neo::Rails::Exposure
|
59
|
+
def expose(name, value=nil)
|
60
|
+
if exposed?(name)
|
61
|
+
# nothing as set already via mock
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# List all defined scenarios
|
68
|
+
#
|
69
|
+
# Return an Array of +scenario+ objects
|
70
|
+
def list_scenarios
|
71
|
+
self.class.list_scenarios
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
# Applies a scenario as a before filter if there is one which fits.
|
77
|
+
def apply_scenario
|
78
|
+
action_key = params[:action].to_sym
|
79
|
+
scenario_key = params[:scenario].try(:to_sym)
|
80
|
+
if scenario_key && (scenario = self.class.scenarios[action_key][scenario_key])
|
81
|
+
instance_eval(&scenario.block)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Does this controller run a scenario right now?
|
86
|
+
def scenario?
|
87
|
+
params[:scenario]
|
88
|
+
end
|
89
|
+
|
90
|
+
# A simple class encapsulating a scenario:
|
91
|
+
# * the corresponding action
|
92
|
+
# * the scenario's name
|
93
|
+
# * an humanized name as label
|
94
|
+
# * the blocked which will be called when applying a scenario
|
95
|
+
class Scenario
|
96
|
+
attr_reader :action, :name, :block, :options
|
97
|
+
|
98
|
+
def initialize(action, name, block, options)
|
99
|
+
@action = action.to_sym
|
100
|
+
@name = name.to_sym
|
101
|
+
@block = block
|
102
|
+
@options = options
|
103
|
+
end
|
104
|
+
|
105
|
+
def label
|
106
|
+
"#{@action.to_s.humanize} -> #{@name.to_s.humanize}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Neo
|
2
|
+
module Rails
|
3
|
+
module Scenarios
|
4
|
+
module RailsHelper
|
5
|
+
def scenario_link(scenario)
|
6
|
+
link_to scenario.label, url_for(:action => scenario.action, :scenario => scenario.name, :id => 1), scenario.options
|
7
|
+
end
|
8
|
+
|
9
|
+
def render_scenarios_list
|
10
|
+
if ::Rails.env.development? && respond_to?(:list_scenarios) && (list = list_scenarios).any?
|
11
|
+
scenario_links = list.map { |scenario| content_tag(:li, scenario_link(scenario)) }
|
12
|
+
ul = content_tag(:ul, scenario_links.join.html_safe)
|
13
|
+
raw content_tag(:div, ul, :class => "neo-rails-scenarios-list")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Neo
|
2
|
+
module Rails
|
3
|
+
module Scenarios
|
4
|
+
# Useful test helpers for minitest (test/unit).
|
5
|
+
#
|
6
|
+
# == Usage
|
7
|
+
#
|
8
|
+
# require 'neo/rails/scenarios/test_helper'
|
9
|
+
#
|
10
|
+
# class ActionController::TestCase
|
11
|
+
# include Neo::Rails::Scenarios::TestHelper
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
module TestHelper
|
15
|
+
extend ActiveSupport::Concern
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
# Creates test methods for each defined scenario defined in controller.
|
19
|
+
def test_scenarios(options={})
|
20
|
+
controller_class = options.delete(:controller) || self.controller_class
|
21
|
+
raise "no controller_class defined? Use 'tests MyController'" unless controller_class
|
22
|
+
return unless controller_class.respond_to?(:list_scenarios)
|
23
|
+
scenarios = controller_class.list_scenarios
|
24
|
+
|
25
|
+
if except = options.delete(:except)
|
26
|
+
except = Set.new(Array(except))
|
27
|
+
scenarios.reject! { |scenario| except.include?(scenario.name) }
|
28
|
+
end
|
29
|
+
|
30
|
+
return if scenarios.empty?
|
31
|
+
|
32
|
+
scenarios.each do |scenario|
|
33
|
+
method = scenario.options[:method] || :get
|
34
|
+
path = scenario.action
|
35
|
+
scenario_name = scenario.name
|
36
|
+
|
37
|
+
test "test scenario #{controller_class}##{method} #{path.inspect}, :scenario => #{scenario_name.inspect}" do
|
38
|
+
|
39
|
+
send(method, path, :id => 1, :scenario => scenario_name)
|
40
|
+
assert_response :success
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/neo-rails.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/neo/rails/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jonas Thiel", "Peter Suschlik"]
|
6
|
+
gem.email = ["jt@neopoly.de", "ps@neopoly.de"]
|
7
|
+
gem.description = %q{Some Rails helpers}
|
8
|
+
gem.summary = %q{Rails mocks, presenters, exposure and scenarios}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "neo-rails"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Neo::Rails::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency "rake"
|
19
|
+
gem.add_development_dependency "minitest"
|
20
|
+
end
|
data/test/helper.rb
ADDED
data/test/mock_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
require 'neo/rails/mock'
|
4
|
+
|
5
|
+
class MockTest < NeoRailsCase
|
6
|
+
context :tagged do
|
7
|
+
let(:mock) { Neo::Rails::Mock.new(:foo, :bar) }
|
8
|
+
|
9
|
+
test "has mock_description" do
|
10
|
+
assert_equal "Foo, Bar", mock.mock.description
|
11
|
+
end
|
12
|
+
|
13
|
+
test "mock_tagged?" do
|
14
|
+
assert mock.mock.tagged?(:foo)
|
15
|
+
assert mock.mock.tagged?(:foo)
|
16
|
+
assert mock.mock.tagged?(:bar)
|
17
|
+
refute mock.mock.tagged?(:baz)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context :untagged do
|
22
|
+
let(:mock) { Neo::Rails::Mock.new }
|
23
|
+
|
24
|
+
test "has empty mock_description" do
|
25
|
+
assert_equal "", mock.mock.description
|
26
|
+
end
|
27
|
+
|
28
|
+
test "is not mock_tagged?" do
|
29
|
+
refute mock.mock.tagged?(:foo)
|
30
|
+
refute mock.mock.tagged?(:bar)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
require 'neo/rails/presenter'
|
4
|
+
|
5
|
+
class PresenterTest < NeoRailsCase
|
6
|
+
User = Struct.new(:name, :team)
|
7
|
+
Team = Struct.new(:name)
|
8
|
+
|
9
|
+
class BasePresenter
|
10
|
+
include Neo::Rails::Presenter
|
11
|
+
end
|
12
|
+
|
13
|
+
class UserPresenter < BasePresenter
|
14
|
+
def initialize(user)
|
15
|
+
@user = user
|
16
|
+
end
|
17
|
+
|
18
|
+
def name
|
19
|
+
@user.name
|
20
|
+
end
|
21
|
+
|
22
|
+
def team
|
23
|
+
@team ||= TeamPresenter.new(@user.team)
|
24
|
+
end
|
25
|
+
|
26
|
+
def link
|
27
|
+
view_context.link_to "/user/#{name}", name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TeamPresenter < BasePresenter
|
32
|
+
def initialize(team)
|
33
|
+
@team = team
|
34
|
+
end
|
35
|
+
|
36
|
+
def name
|
37
|
+
@team.name
|
38
|
+
end
|
39
|
+
|
40
|
+
def link
|
41
|
+
view_context.link_to "/team/#{name}", name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class ViewContext
|
46
|
+
def link_to(path, name)
|
47
|
+
%{<a href="#{path}">#{name}</a>}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
before do
|
52
|
+
Neo::Rails::Presenter.view_context = ViewContext.new
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:team) { Team.new("A-Team") }
|
56
|
+
let(:user) { User.new("Mr T.", team) }
|
57
|
+
|
58
|
+
context "with user_presenter" do
|
59
|
+
let(:user_presenter) { UserPresenter.new(user) }
|
60
|
+
|
61
|
+
test "creates a presenter providing current view_context" do
|
62
|
+
assert_instance_of ViewContext, user_presenter.view_context
|
63
|
+
end
|
64
|
+
|
65
|
+
test "shares view_context with sub presenters" do
|
66
|
+
assert_same user_presenter.view_context, user_presenter.team.view_context
|
67
|
+
end
|
68
|
+
|
69
|
+
test "uses view_context's methods" do
|
70
|
+
assert user_presenter.link
|
71
|
+
assert user_presenter.team.link
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: neo-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonas Thiel
|
9
|
+
- Peter Suschlik
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-08-06 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: minitest
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
description: Some Rails helpers
|
48
|
+
email:
|
49
|
+
- jt@neopoly.de
|
50
|
+
- ps@neopoly.de
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- Gemfile
|
57
|
+
- LICENSE
|
58
|
+
- README.md
|
59
|
+
- Rakefile
|
60
|
+
- lib/assets/stylesheets/neo-rails.css
|
61
|
+
- lib/assets/stylesheets/neo/rails/scenarios/render_scenarios_list.css.sass
|
62
|
+
- lib/neo-rails.rb
|
63
|
+
- lib/neo/rails.rb
|
64
|
+
- lib/neo/rails/engine.rb
|
65
|
+
- lib/neo/rails/exposure.rb
|
66
|
+
- lib/neo/rails/mock.rb
|
67
|
+
- lib/neo/rails/presenter.rb
|
68
|
+
- lib/neo/rails/presenter/test_helper.rb
|
69
|
+
- lib/neo/rails/scenarios.rb
|
70
|
+
- lib/neo/rails/scenarios/rails_helper.rb
|
71
|
+
- lib/neo/rails/scenarios/test_helper.rb
|
72
|
+
- lib/neo/rails/version.rb
|
73
|
+
- neo-rails.gemspec
|
74
|
+
- test/helper.rb
|
75
|
+
- test/mock_test.rb
|
76
|
+
- test/presenter_test.rb
|
77
|
+
homepage: ''
|
78
|
+
licenses: []
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.8.24
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: Rails mocks, presenters, exposure and scenarios
|
101
|
+
test_files:
|
102
|
+
- test/helper.rb
|
103
|
+
- test/mock_test.rb
|
104
|
+
- test/presenter_test.rb
|