garnish 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 +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
|