showcase 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 693362b089b6c475cdc2604804aa9f4b48d216ff
4
+ data.tar.gz: dcf7d634807feca412dfe996c1876f27dcf9476a
5
+ SHA512:
6
+ metadata.gz: 893a1c780c5ade2491d71ee16f2a36726ef9d956188d0183fc7272d645ee805c5bc553a04f80cfb65aeec0b4e9220e6115583473295e9a85938e094b829eee47
7
+ data.tar.gz: 9793dce8c7bfafd7a05e1df6c8249ffb4a9cbb538f82e8a38ef972ef3bf3178712da947e0e5268b150f1c20180f5656950c39807a45c989f639166ee5ff70acd
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ script: "bundle exec rspec spec"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in basic_presenter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Stefano Verna
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,72 @@
1
+ # Showcase [![Build Status](https://travis-ci.org/welaika/showcase.png?branch=master)](https://travis-ci.org/welaika/showcase)
2
+
3
+ The most basic presenter implementation in town (< 100 lines of code). Framework agnostic, works with Rails, Padrino or simply Sinatra.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'showcase'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install showcase
18
+
19
+ ## Usage
20
+
21
+ Include Showcase::Helpers as additional helper module.
22
+
23
+ ```ruby
24
+ class ApplicationController < ActionController::Base
25
+ helper Showcase::Helpers
26
+ end
27
+ ```
28
+
29
+ You can now instantiate new presenters in your controller/views using the included helpers:
30
+
31
+ ```ruby
32
+ # this is the object that needs to be presented
33
+ person = Person.new
34
+
35
+ # automatically infers presenter class to use based on person's class name
36
+ present(person) # => returns a PersonPresenter instance
37
+
38
+ # you can also explicitly tell what presenter to use
39
+ present(person, AdminPresenter) # => returns an AdminPresenter instance
40
+
41
+ # explicit presenter and context
42
+ present(person, PersonPresenter, context)
43
+
44
+ # maps each person in the collection with a presenter
45
+ present_collection([ people ]) # => returns an array of PeoplePresenters
46
+ ```
47
+
48
+ Define your presenters i.e. in a `app/presenters` folder:
49
+
50
+ ```ruby
51
+ class ProjectPresenter < Showcase::Presenter
52
+ # automatically wraps the attribute into a PersonPresenter
53
+ presents :person
54
+
55
+ # expects project.task to return an enumerable. automatically wraps each task in a TaskPresenter presenter
56
+ presents_collection :tasks
57
+
58
+ # you can use `context`, or the shortcut `h`, to access the view context.
59
+ # `object` refers to the object being presented
60
+ def title
61
+ h.link_to object.title, object
62
+ end
63
+ end
64
+ ```
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Generates a presenter for a model with the given name.
3
+
4
+ Example:
5
+ rails generate shocase:presenter user
6
+
7
+ This will create:
8
+ app/presenters/user_presenter.rb
@@ -0,0 +1,11 @@
1
+ module Showcase
2
+ module Generators
3
+ class PresenterGenerator < ::Rails::Generators::NamedBase
4
+ source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
5
+
6
+ def create_presenter
7
+ template 'presenter.rb', File.join('app/presenters', class_path, "#{file_name}_presenter.rb")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %>Presenter < Showcase::Presenter
3
+ end
4
+ <% end -%>
@@ -0,0 +1,18 @@
1
+ module Showcase
2
+ module Helpers
3
+ def present(obj, klass = nil, context = self)
4
+ if obj.is_a? ::Showcase::Presenter
5
+ obj
6
+ else
7
+ klass ||= "#{obj.class.name}Presenter".constantize
8
+ klass.new(obj, context)
9
+ end
10
+ end
11
+
12
+ def present_collection(obj, klass = nil, context = self)
13
+ obj.map { |o| present(o, klass, context) }
14
+ end
15
+ end
16
+ end
17
+
18
+
@@ -0,0 +1,39 @@
1
+ require 'delegate'
2
+ require 'active_support/inflector'
3
+ require 'showcase/helpers'
4
+
5
+ module Showcase
6
+ class Presenter < SimpleDelegator
7
+ include Helpers
8
+
9
+ attr_reader :context
10
+
11
+ alias :object :__getobj__
12
+ alias :h :context
13
+
14
+ def class
15
+ object.class
16
+ end
17
+
18
+ def initialize(obj, context)
19
+ super(obj)
20
+ @context = context
21
+ end
22
+
23
+ def self.presents(*attrs)
24
+ attrs.each do |attr|
25
+ define_method attr do
26
+ present(object.send(attr), nil, context)
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.presents_collection(*attrs)
32
+ attrs.each do |attr|
33
+ define_method attr do
34
+ present_collection(object.send(attr), nil, context)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Showcase
2
+ VERSION = "0.0.1"
3
+ end
data/lib/showcase.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'showcase/version'
2
+ require 'showcase/presenter'
3
+
4
+ module Showcase
5
+ end
data/showcase.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'showcase/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "showcase"
8
+ gem.version = Showcase::VERSION
9
+ gem.authors = ["Stefano Verna"]
10
+ gem.email = ["stefano.verna@welaika.com"]
11
+ gem.description = %q{A barebone and framework agnostic presenter implementation}
12
+ gem.summary = %q{A barebone and framework agnostic presenter implementation}
13
+ gem.homepage = "https://github.com/welaika/showcase"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "activesupport"
21
+ gem.add_development_dependency "rspec"
22
+ end
data/spec/fixtures.rb ADDED
@@ -0,0 +1,39 @@
1
+ class Person < Struct.new(:name)
2
+ end
3
+
4
+ class Project < Struct.new(:name)
5
+ def owner
6
+ Person.new("Stefano Verna")
7
+ end
8
+
9
+ def collaborators
10
+ [ Person.new("Ju Liu") ]
11
+ end
12
+
13
+ def dummy
14
+ "foobar"
15
+ end
16
+ end
17
+
18
+ class PersonPresenter < Showcase::Presenter
19
+ def sex
20
+ 'male'
21
+ end
22
+ end
23
+
24
+ class ProjectPresenter < Showcase::Presenter
25
+ presents :owner
26
+ presents_collection :collaborators
27
+
28
+ def name
29
+ "Presented #{object.name}"
30
+ end
31
+
32
+ def context_foo
33
+ h.foo
34
+ end
35
+ end
36
+
37
+ class Context
38
+ include Showcase::Helpers
39
+ end
@@ -0,0 +1,83 @@
1
+ require 'showcase'
2
+ require_relative './fixtures'
3
+
4
+ describe Showcase::Presenter do
5
+
6
+ let(:context) { stub(:context, foo: 'bar') }
7
+ let(:object) { Project.new('Showcase') }
8
+ let(:subject) { ProjectPresenter.new(object, context) }
9
+
10
+ it 'takes the object and a context as parameters' do
11
+ subject.object.should == object
12
+ subject.context.should == context
13
+ end
14
+
15
+ it 'preserves original .class' do
16
+ subject.class.should == Project
17
+ end
18
+
19
+ it 'delegates methods to object' do
20
+ subject.dummy.should == 'foobar'
21
+ end
22
+
23
+ it 'allows overriding of methods' do
24
+ subject.name.should == 'Presented Showcase'
25
+ end
26
+
27
+ it 'allows .h as shortcut to access the context' do
28
+ subject.context_foo.should == 'bar'
29
+ end
30
+
31
+ describe '#presents' do
32
+ it 'wraps the specified attributes inside a presenter' do
33
+ subject.owner.sex.should == 'male'
34
+ end
35
+ end
36
+
37
+ describe '#presents_collection' do
38
+ it 'wraps the specifieed collection attributes inside a presenter' do
39
+ subject.collaborators.first.sex.should == 'male'
40
+ end
41
+ end
42
+ end
43
+
44
+ describe Showcase::Helpers do
45
+ let(:object) { Person.new('Steve Ballmer') }
46
+ let(:context) { Context.new }
47
+
48
+ describe '.present' do
49
+ context 'when the passed object is already a Showcase::Base' do
50
+ it 'returns the object itself' do
51
+ presenter = PersonPresenter.new(object, stub)
52
+ context.present(presenter).should == presenter
53
+ end
54
+ end
55
+ context 'when the object still needs to be presented' do
56
+ it 'instanciate a new presenter, inferring the class' do
57
+ PersonPresenter.stub(:new).with(object, context).and_return 'Presenter'
58
+ context.present(object, PersonPresenter).should == 'Presenter'
59
+ end
60
+ it 'the presenter class to use can be specified as the second parameter' do
61
+ ProjectPresenter.stub(:new).with(object, context).and_return 'Presenter'
62
+ context.present(object, ProjectPresenter).should == 'Presenter'
63
+ end
64
+ it 'the context to use can be specified as third parameter' do
65
+ different_context = stub
66
+ context.present(object, ProjectPresenter, different_context).context.should == different_context
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '.present_collection' do
72
+ it 'returns a presenter for each object in the collection' do
73
+ collection = [ Person.new('Mark'), Person.new('Luke') ]
74
+
75
+ PersonPresenter.stub(:new).with(collection[0], context).and_return 'foo'
76
+ PersonPresenter.stub(:new).with(collection[1], context).and_return 'bar'
77
+
78
+ presented_collection = context.present_collection(collection)
79
+ presented_collection.should == [ 'foo', 'bar' ]
80
+ end
81
+ end
82
+
83
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: showcase
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Stefano Verna
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A barebone and framework agnostic presenter implementation
42
+ email:
43
+ - stefano.verna@welaika.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .travis.yml
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - lib/generators/showcase/presenter/USAGE
55
+ - lib/generators/showcase/presenter/presenter_generator.rb
56
+ - lib/generators/showcase/presenter/templates/presenter.rb
57
+ - lib/showcase.rb
58
+ - lib/showcase/helpers.rb
59
+ - lib/showcase/presenter.rb
60
+ - lib/showcase/version.rb
61
+ - showcase.gemspec
62
+ - spec/fixtures.rb
63
+ - spec/showcase_spec.rb
64
+ homepage: https://github.com/welaika/showcase
65
+ licenses: []
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.0.0
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: A barebone and framework agnostic presenter implementation
87
+ test_files:
88
+ - spec/fixtures.rb
89
+ - spec/showcase_spec.rb