styler 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Simon Hafner aka Tass
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,10 @@
1
+ = Stylist
2
+
3
+ == Summary
4
+
5
+ This implements view-aware models, yet not. It's using the ProxyClass pattern.
6
+
7
+ == See
8
+
9
+ IRC:: #rango@irc.freenode.net
10
+ Baretest:: http://github.com/apeiros/baretest
@@ -0,0 +1,23 @@
1
+ require 'rango/mixins/rendering'
2
+ require 'styler'
3
+ module Styler
4
+ module Style
5
+ module InstanceMethods
6
+ include Rango::ImplicitRendering
7
+ end
8
+ end
9
+ end
10
+
11
+ module Styler
12
+ module RangoMixin
13
+ include Rango::ImplicitRendering
14
+ def render(template, *models)
15
+ @__controller = self
16
+ models.each {|name|
17
+ instance_variable_set("@#{name}",::Styler.new_style_for(instance_variable_get("@#{name}")))
18
+ }
19
+ super
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,95 @@
1
+ module Styler
2
+ module Style
3
+ module ClassMethods
4
+ # Add all the methods that will call other model instances here.
5
+ # As there are no collection-styles, set up complicated stuff in :prepare
6
+ def association(*methods)
7
+ methods.each do |m|
8
+ define_method(m) {|*args, &block|
9
+ assoc = @model.send(m, *args, &block)
10
+ ::Styler.new_style_for(assoc,serialize_to_hash.merge({@model.class.to_s.downcase.split('::').last => self}))
11
+ }
12
+ end
13
+ end
14
+
15
+ def delegate(*methods)
16
+ methods.each do |m|
17
+ define_method(m) {
18
+ @model.send(m)
19
+ }
20
+ end
21
+ end
22
+
23
+ def delegate_to_controller(*methods)
24
+ methods.each do |m|
25
+ define_method(m) {
26
+ @__controller.send(m)
27
+ }
28
+ end
29
+ end
30
+
31
+ def style_for(model)
32
+ Styler::STYLES.merge!({model => self})
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ def initialize(model, context={})
38
+ serialize_from_hash(context)
39
+ @model = model
40
+ @type ||= :default
41
+ end
42
+
43
+ attr_reader :model, :request
44
+
45
+ # Use like style.as(:widget)
46
+ def as(type)
47
+ @type = type
48
+ self
49
+ end
50
+
51
+ # Use this method to add something to the context
52
+ def with(context)
53
+ serialize_from_hash(context)
54
+ self
55
+ end
56
+
57
+ # This is the final hook, define :prepare if you need to add some stuff
58
+ # Set @template_path if you want a custom path.
59
+ def to_s
60
+ prepare if respond_to?(:prepare)
61
+ render(@template_path || compile_template_path)
62
+ end
63
+
64
+ # This method compiles the default template path.
65
+ def compile_template_path
66
+ "#{__class__.to_s.downcase.gsub('::','/')}/#{@type}"
67
+ end
68
+
69
+ alias_method :__class__, :class
70
+ # I don't like this, but it's needed for routers that check the class if
71
+ # you use resource-based routers (like CRUDtree).
72
+ def class
73
+ @model.class
74
+ end
75
+
76
+ private
77
+ def serialize_from_hash(hash)
78
+ hash.each {|key,value|
79
+ name = (key.to_s =~ /^@/) ? key.to_s : "@#{key}"
80
+ instance_variable_set(name, value)
81
+ }
82
+ end
83
+
84
+ def serialize_to_hash
85
+ Hash[instance_variables.map {|name| [name, instance_variable_get(name)]}]
86
+ end
87
+ end
88
+
89
+ def self.included(receiver)
90
+ receiver.extend ClassMethods
91
+ receiver.send :include, InstanceMethods
92
+ receiver.delegate_to_controller :request
93
+ end
94
+ end
95
+ end
data/lib/styler.rb ADDED
@@ -0,0 +1,20 @@
1
+ require_relative 'styler/style'
2
+ module Styler
3
+ STYLES = {}
4
+
5
+ def new_style_for(model, context={})
6
+ if model.respond_to? :map
7
+ model.map {|ele| model_to_style(ele, context)}
8
+ else
9
+ model_to_style(model, context)
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def model_to_style(model, context)
16
+ (style = STYLES[model.class]) ? style.new(model, context) : model
17
+ end
18
+
19
+ extend self
20
+ end
data/test/setup.rb ADDED
@@ -0,0 +1,54 @@
1
+ $LOAD_PATH.unshift(File.expand_path("#{__FILE__}/../../lib")) # Add PROJECT/lib to $LOAD_PATH
2
+ require 'styler'
3
+ require 'ruby-debug'
4
+
5
+ # I don't like adding dependencies if I don't need to :-)
6
+ module Styler::Style
7
+ module InstanceMethods
8
+ def render(*args)
9
+ [ args,
10
+ Hash[instance_variables.map {|name| [name, instance_variable_get(name)]} ]
11
+ ]
12
+ end
13
+ end
14
+ end
15
+
16
+ module Model
17
+ class Foo
18
+ def foo
19
+ Model::Bar::Foo.new
20
+ end
21
+ def fooz
22
+ [Model::Bar::Foo.new, Model::Bar::Foo.new]
23
+ end
24
+ def hello
25
+ :hello
26
+ end
27
+ end
28
+ end
29
+ module Style
30
+ class Foo
31
+ include Styler::Style
32
+ style_for Model::Foo
33
+ association :foo
34
+ association :fooz
35
+ delegate :hello
36
+ def context; {}; end
37
+ end
38
+ end
39
+ module Model
40
+ module Bar
41
+ class Foo
42
+ end
43
+ end
44
+ end
45
+ module Style
46
+ class Bar
47
+ include Styler::Style
48
+ style_for Model::Bar::Foo
49
+ end
50
+ end
51
+ module Model
52
+ class Baz
53
+ end
54
+ end
@@ -0,0 +1,58 @@
1
+ BareTest.suite do
2
+ suite "Styler" do
3
+ suite "Style" do
4
+ suite "ClassMethods" do
5
+ suite "#association" do
6
+ setup :assoc, "a single association" do
7
+ @style = Styler.new_style_for(Model::Foo.new).foo
8
+ @result_class = Style::Bar
9
+ end
10
+ setup :assoc, "an association collection" do
11
+ @style = Styler.new_style_for(Model::Foo.new).fooz
12
+ @result_class = Style::Bar
13
+ end
14
+ assert "it maps models to stylers in :assoc" do
15
+ if @style.respond_to? :each
16
+ @style.all? {|style| equal(style.__class__,@result_class)}
17
+ else
18
+ equal(@style.__class__, @result_class)
19
+ end
20
+ end
21
+ end
22
+ suite "#delegate" do
23
+ setup do
24
+ @styler = Styler.new_style_for(Model::Foo.new)
25
+ end
26
+ assert "it delegates to the model" do
27
+ equal :hello, @styler.hello
28
+ end
29
+ end
30
+ end
31
+ suite "InstanceMethods" do
32
+ suite "#to_s" do
33
+ setup :style, "a style" do
34
+ @model = Model::Foo.new
35
+ @style = ::Styler.new_style_for(@model)
36
+ @result = [["style/foo/default"], {:@model => @model, :@type => :default}]
37
+ end
38
+ setup :style, "a complex style" do
39
+ @model = Model::Foo.new
40
+ @style = ::Styler.new_style_for(@model)
41
+ @style.with(:bla => "foo")
42
+ @result = [["style/foo/default"], {:@model => @model, :@type => :default, :@bla => "foo"}]
43
+ end
44
+ setup :style, "a style with context" do
45
+ model = Model::Foo.new
46
+ style = ::Styler.new_style_for(model)
47
+ style.with(:bla => "foo")
48
+ @style = style.foo
49
+ @result = [["style/bar/default"], {:@foo => style, :@model => @style.model, :@type => :default, :@bla => "foo"}]
50
+ end
51
+ assert "it renders :style correctly" do
52
+ equal(@result, @style.to_s)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,31 @@
1
+ BareTest.suite "Styler" do
2
+ suite "Styler" do
3
+ suite "Style finding" do
4
+ setup :model, "a model without namespace" do
5
+ @model = Model::Foo.new
6
+ @result = Style::Foo
7
+ end
8
+ setup :model, "a model with namespace" do
9
+ @model = Model::Bar::Foo.new
10
+ @result = Style::Bar
11
+ end
12
+ setup :model, "a model without style" do
13
+ @model = Model::Baz.new
14
+ @result = Model::Baz
15
+ end
16
+ setup :model, "a model collection" do
17
+ @model = [Model::Foo.new, Model::Bar::Foo.new, Model::Foo.new, Model::Baz.new]
18
+ @result = [Style::Foo, Style::Bar, Style::Foo, Model::Baz]
19
+ end
20
+ assert "#new_style_for finds the right Styler object for :model" do
21
+ if @model.respond_to? :each
22
+ @model.each_with_index.all?{ |model,id|
23
+ Styler.new_style_for(model, {}).is_a? @result[id]
24
+ }
25
+ else
26
+ Styler.new_style_for(@model, {}).is_a? @result
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: styler
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Simon Hafner aka Tass
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain:
16
+ date: 2010-02-28 00:00:00 +01:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: This gem implements the presenter pattern with a mixin to use with rango.
21
+ email: hafnersimon@gmail.com
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files: []
27
+
28
+ files:
29
+ - lib/styler/mixins/rango.rb
30
+ - lib/styler/style.rb
31
+ - lib/styler.rb
32
+ - test/setup.rb
33
+ - test/suite/lib/styler/style.rb
34
+ - test/suite/lib/styler.rb
35
+ - LICENSE
36
+ - README.rdoc
37
+ has_rdoc: true
38
+ homepage: http://github.com/Tass/styler
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ~>
49
+ - !ruby/object:Gem::Version
50
+ segments:
51
+ - 1
52
+ - 9
53
+ version: "1.9"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.3.6
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: This implements view-aware models, yet not.
68
+ test_files: []
69
+