garnish 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/Guardfile +15 -0
- data/README.rdoc +2 -0
- data/Rakefile +11 -0
- data/garnish.gemspec +24 -0
- data/lib/garnish.rb +6 -0
- data/lib/garnish/controller.rb +18 -0
- data/lib/garnish/converter.rb +47 -0
- data/lib/garnish/presenter.rb +50 -0
- data/lib/garnish/presenter/relationships.rb +28 -0
- data/lib/garnish/responder.rb +19 -0
- data/lib/garnish/version.rb +3 -0
- data/spec/garnish/controller_spec.rb +17 -0
- data/spec/garnish/converter_spec.rb +62 -0
- data/spec/garnish/presenter/relationships_spec.rb +34 -0
- data/spec/garnish/presenter_spec.rb +75 -0
- data/spec/spec_helper.rb +37 -0
- metadata +92 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
guard 'bundler' do
|
2
|
+
watch('Gemfile')
|
3
|
+
# Uncomment next line if Gemfile contain `gemspec' command
|
4
|
+
# watch(/^.+\.gemspec/)
|
5
|
+
end
|
6
|
+
|
7
|
+
guard 'spork', :rspec_env => { 'RAILS_ENV' => 'test' }, :cucumber => false, :wait => 40 do
|
8
|
+
watch('Gemfile')
|
9
|
+
watch('Gemfile.lock')
|
10
|
+
watch('spec/spec_helper.rb')
|
11
|
+
end
|
12
|
+
|
13
|
+
guard 'rspec', :cli => "--drb", :version => 2, :rvm => ['1.9.3'] do
|
14
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
15
|
+
end
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
data/garnish.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "garnish/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "garnish"
|
7
|
+
s.version = Garnish::VERSION
|
8
|
+
s.authors = ["brianp"]
|
9
|
+
s.email = ["brian.o.pearce@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Provides the decorator design pattern}
|
12
|
+
s.description = %q{Provides an easy to use and transparent system for implementing the Decorator Pattern}
|
13
|
+
|
14
|
+
s.rubyforge_project = "garnish"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "rails", '~> 3.0.9'
|
24
|
+
end
|
data/lib/garnish.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Garnish
|
2
|
+
module Controller
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def garnish(options = {}, &block)
|
7
|
+
self.responder = Garnish::Responder
|
8
|
+
respond_to :html
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
if defined? ActionController
|
15
|
+
ActionController::Base.class_eval do
|
16
|
+
include Garnish::Controller
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Garnish
|
2
|
+
module Converter
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def class_exists?(class_name)
|
7
|
+
klass = Module.const_get(class_name)
|
8
|
+
return klass.is_a?(Class)
|
9
|
+
rescue NameError
|
10
|
+
return false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module InstanceMethods
|
15
|
+
|
16
|
+
def convert(record, view = nil)
|
17
|
+
view ||= self.template
|
18
|
+
|
19
|
+
if record.respond_to?(:each)
|
20
|
+
klass = record.first.class
|
21
|
+
else
|
22
|
+
klass = record.class
|
23
|
+
end
|
24
|
+
|
25
|
+
presenter_name = "#{klass.to_s}Presenter"
|
26
|
+
|
27
|
+
if self.class_exists?(presenter_name.to_sym)
|
28
|
+
if record.respond_to?(:each)
|
29
|
+
presenter = record.map{ |v| presenter_name.constantize.new(v, view) }
|
30
|
+
else
|
31
|
+
presenter = presenter_name.constantize.new(record, view)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
presenter
|
36
|
+
end
|
37
|
+
|
38
|
+
def class_exists?(class_name)
|
39
|
+
klass = Module.const_get(class_name)
|
40
|
+
return klass.is_a?(Class)
|
41
|
+
rescue NameError
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Garnish
|
2
|
+
module Presenter
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
include Garnish::Presenter::Relationships
|
5
|
+
|
6
|
+
included do
|
7
|
+
attr_accessor :record
|
8
|
+
attr_accessor :template
|
9
|
+
attr_accessor :record_class
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
def initialize(r, t)
|
14
|
+
self.record = r
|
15
|
+
self.template = t
|
16
|
+
self.record_class = r.class
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to?(method, include_private = false)
|
20
|
+
if self.methods.include?(method)
|
21
|
+
super
|
22
|
+
else
|
23
|
+
self.record.respond_to?(method)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def method_missing(method, *args, &block)
|
30
|
+
begin
|
31
|
+
# Check the record being presented first
|
32
|
+
# If method doesn't exists check the template for helper convenience
|
33
|
+
self.record.send(method, *args, &block)
|
34
|
+
rescue NoMethodError
|
35
|
+
self.template.send(method, *args, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def method_missing(method, *args, &block)
|
45
|
+
record_class.send(method, *args, &block)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Garnish
|
2
|
+
module Presenter
|
3
|
+
module Relationships
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Garnish::Converter
|
6
|
+
|
7
|
+
included do
|
8
|
+
relationships = self.record_class.relations.keys
|
9
|
+
|
10
|
+
relationships.map do |key|
|
11
|
+
define_method key do
|
12
|
+
arry = self.record.send(key)
|
13
|
+
arry = convert(arry)
|
14
|
+
arry
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def record_class
|
21
|
+
str = self.to_s
|
22
|
+
str.slice!("Presenter")
|
23
|
+
str.constantize
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Garnish
|
2
|
+
class Responder < ActionController::Responder
|
3
|
+
include Garnish::Converter
|
4
|
+
def to_html
|
5
|
+
vars = controller.instance_variables.reject {|x| x.to_s.include?("@_")}
|
6
|
+
|
7
|
+
vars.each do |var|
|
8
|
+
record = controller.instance_variable_get(var.to_s)
|
9
|
+
|
10
|
+
presenter = convert(record, controller.view_context)
|
11
|
+
|
12
|
+
controller.instance_variable_set(var.to_s, presenter)
|
13
|
+
end
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "A Garnished Controller" do
|
4
|
+
|
5
|
+
subject { TestController }
|
6
|
+
|
7
|
+
it "should have the garnish method defined" do
|
8
|
+
subject.respond_to?(:garnish).should be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should set the responder to Garnish::Responder" do
|
12
|
+
subject.garnish
|
13
|
+
subject.responder.should equal Garnish::Responder
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "A Garnish Converter" do
|
4
|
+
|
5
|
+
context "instance" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@test_class = TestClass.new
|
9
|
+
@template = Class.new
|
10
|
+
@test_presenter = TestClassPresenter.new(@test_class, @template)
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { @test_presenter }
|
14
|
+
|
15
|
+
it "should define class_exists?" do
|
16
|
+
subject.respond_to?(:class_exists?).should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return true from class_exists if class exists" do
|
20
|
+
subject.class_exists?(:TestClassPresenter).should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return false from class_exists if class doesn't exists" do
|
24
|
+
subject.class_exists?(:BadClass).should be_false
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with a template" do
|
28
|
+
it "should take a record variable and wrap it in a presenter if a presenter exists" do
|
29
|
+
presenter = subject.convert(@test_class, @template)
|
30
|
+
presenter.class.should equal TestClassPresenter
|
31
|
+
presenter.record.should equal @test_class
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "without a template" do
|
36
|
+
it "should take a record variable and wrap it in a presenter if a presenter exists" do
|
37
|
+
presenter = subject.convert(@test_class)
|
38
|
+
presenter.class.should equal TestClassPresenter
|
39
|
+
presenter.record.should equal @test_class
|
40
|
+
presenter.template.should equal @template
|
41
|
+
end
|
42
|
+
end end
|
43
|
+
|
44
|
+
context "class" do
|
45
|
+
subject { TestClassPresenter }
|
46
|
+
|
47
|
+
it "should define class_exists?" do
|
48
|
+
subject.respond_to?(:class_exists?).should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return true from class_exists if class exists" do
|
52
|
+
subject.class_exists?(:TestClassPresenter).should be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return false from class_exists if class doesn't exists" do
|
56
|
+
subject.class_exists?(:BadClass).should be_false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "A Presenter Relationship" do
|
4
|
+
|
5
|
+
context "instance" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@test_class = TestClass.new
|
9
|
+
@template = Class.new
|
10
|
+
@test_presenter = TestClassPresenter.new(@test_class, @template)
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { @test_presenter }
|
14
|
+
|
15
|
+
it "should have the records relationships defined" do
|
16
|
+
subject.respond_to?(:users).should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
context "class" do
|
22
|
+
subject { TestClassPresenter }
|
23
|
+
|
24
|
+
it "should return record_class" do
|
25
|
+
subject.record_class.should equal TestClass
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not have the records relationships defined" do
|
29
|
+
subject.respond_to?(:users).should be_false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "A Presenter" do
|
4
|
+
context "should initialize" do
|
5
|
+
it "with record and no template" do
|
6
|
+
TestClassPresenter.new(TestClass.new, nil).should be_true
|
7
|
+
end
|
8
|
+
|
9
|
+
context "and populate" do
|
10
|
+
before(:each) do
|
11
|
+
@test_class = TestClass.new
|
12
|
+
@template = Class.new
|
13
|
+
@test_presenter = TestClassPresenter.new(@test_class, @template)
|
14
|
+
end
|
15
|
+
|
16
|
+
subject {@test_presenter}
|
17
|
+
|
18
|
+
it "the record field" do
|
19
|
+
subject.record.should equal @test_class
|
20
|
+
end
|
21
|
+
|
22
|
+
it "the template field" do
|
23
|
+
subject.template.should equal @template
|
24
|
+
end
|
25
|
+
|
26
|
+
it "the record_class field" do
|
27
|
+
subject.record_class.should equal @test_class.class
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "class should delgate" do
|
33
|
+
subject { TestClassPresenter }
|
34
|
+
|
35
|
+
it "method missing to non presenter class" do
|
36
|
+
TestClass.should_receive(:test_method).and_raise(NoMethodError)
|
37
|
+
lambda {subject.test_method}.should raise_error
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "instance should" do
|
42
|
+
before(:each) do
|
43
|
+
@test_class = TestClass.new
|
44
|
+
@template = Class.new
|
45
|
+
@test_presenter = TestClassPresenter.new(@test_class, @template)
|
46
|
+
end
|
47
|
+
|
48
|
+
subject { @test_presenter }
|
49
|
+
|
50
|
+
context "delegate" do
|
51
|
+
it "method missing to record if method is missing" do
|
52
|
+
@test_class.should_receive(:test_method).and_return("Success!")
|
53
|
+
subject.test_method.should match "Success!"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "method missing to template if record lacks method" do
|
57
|
+
@template.should_receive(:test_method).and_return("Success!")
|
58
|
+
subject.test_method.should match "Success!"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "respond_to? to record if method doesn't exist" do
|
62
|
+
@test_class.should_receive(:respond_to?).with(:test_method).and_return(true)
|
63
|
+
subject.respond_to?(:test_method).should be_true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "not delegate" do
|
68
|
+
it "respond_to? when methods exisits" do
|
69
|
+
@test_class.should_not_receive(:respond_to?)
|
70
|
+
subject.respond_to?(:respond_to?).should be_true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
Bundler.require(:development)
|
5
|
+
|
6
|
+
require 'active_support/all'
|
7
|
+
require 'action_controller'
|
8
|
+
require 'garnish'
|
9
|
+
|
10
|
+
# Spork.prefork do
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.mock_with :rspec
|
15
|
+
|
16
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
17
|
+
config.filter_run :focus => true
|
18
|
+
config.run_all_when_everything_filtered = true
|
19
|
+
end
|
20
|
+
# end
|
21
|
+
|
22
|
+
# Spork.each_run do
|
23
|
+
|
24
|
+
# end
|
25
|
+
|
26
|
+
class TestClass
|
27
|
+
def self.relations
|
28
|
+
{:users => []}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class TestClassPresenter
|
33
|
+
include Garnish::Presenter
|
34
|
+
end
|
35
|
+
|
36
|
+
class TestController < ActionController::Base
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: garnish
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- brianp
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-11-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70236155352860 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70236155352860
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rails
|
27
|
+
requirement: &70236155352360 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.0.9
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70236155352360
|
36
|
+
description: Provides an easy to use and transparent system for implementing the Decorator
|
37
|
+
Pattern
|
38
|
+
email:
|
39
|
+
- brian.o.pearce@gmail.com
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- .travis.yml
|
46
|
+
- Gemfile
|
47
|
+
- Guardfile
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- garnish.gemspec
|
51
|
+
- lib/garnish.rb
|
52
|
+
- lib/garnish/controller.rb
|
53
|
+
- lib/garnish/converter.rb
|
54
|
+
- lib/garnish/presenter.rb
|
55
|
+
- lib/garnish/presenter/relationships.rb
|
56
|
+
- lib/garnish/responder.rb
|
57
|
+
- lib/garnish/version.rb
|
58
|
+
- spec/garnish/controller_spec.rb
|
59
|
+
- spec/garnish/converter_spec.rb
|
60
|
+
- spec/garnish/presenter/relationships_spec.rb
|
61
|
+
- spec/garnish/presenter_spec.rb
|
62
|
+
- spec/spec_helper.rb
|
63
|
+
homepage: ''
|
64
|
+
licenses: []
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project: garnish
|
83
|
+
rubygems_version: 1.8.10
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: Provides the decorator design pattern
|
87
|
+
test_files:
|
88
|
+
- spec/garnish/controller_spec.rb
|
89
|
+
- spec/garnish/converter_spec.rb
|
90
|
+
- spec/garnish/presenter/relationships_spec.rb
|
91
|
+
- spec/garnish/presenter_spec.rb
|
92
|
+
- spec/spec_helper.rb
|