presenter 0.1.0

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Vladimir Bobes Tuzinsky
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,146 @@
1
+ = Presenter gem
2
+
3
+ This gem is mainly targeted at Rails developers who:
4
+
5
+ * need to execute a search based on request parameters
6
+ * load records from a database for cached fragments
7
+ * have a lot of view-related logic in models
8
+
9
+ It will help you to:
10
+
11
+ * process request parameters (with simple typecasting)
12
+ * cleanup your models and controller
13
+ * postpone querying database until really needed (if needed at all)
14
+ * ... more ...
15
+
16
+ == Installation
17
+
18
+ As usual:
19
+
20
+ gem install presenter
21
+
22
+ To keep your code organized, create a directory "app/presenters" in your project and add this line to your environment.rb (or application.rb if you use Rails 3):
23
+
24
+ config.load_paths << Rails.root.join("app", "presenters").to_s
25
+
26
+ Now you can have your presenters in the app/presenters directory and they'll be loaded automatically.
27
+
28
+ == Basic usage
29
+
30
+ Presenter:
31
+
32
+ # app/presenters/users_presenter.rb
33
+ class UsersPresenter < Presenter
34
+
35
+ # following parameters will be extracted from the params hash and
36
+ # properly typecasted. Nils, blanks and empty arrays will be discarded.
37
+ # If a parameter's value is an array, all values in the array will
38
+ # be typecasted
39
+ key :name, String
40
+ key :age, Integer
41
+
42
+ # this creates method "users", which calls and memoizes method "find_user".
43
+ presents :users
44
+
45
+ private
46
+
47
+ def find_users
48
+ scope = User
49
+ scope = scope.scoped(:conditions => { :name => name }) if first_name
50
+ scope = scope.scoped(:conditions => { :age => age }) if age
51
+ scope
52
+ end
53
+ end
54
+
55
+ Controller:
56
+
57
+ # app/controllers/users_controller.rb
58
+ class UsersController < ApplicationController
59
+
60
+ def index
61
+ @users_presenter = UsersPresenter.new(params)
62
+ end
63
+ end
64
+
65
+ View:
66
+
67
+ # app/views/users/index.html.haml
68
+ %ul
69
+ - @users_presenter.users.each do |user|
70
+ %li= user.name
71
+
72
+ == Mixins
73
+
74
+ If some of the code in your models is used only inside views (formatting and such),
75
+ you may extract this code to a module and mix it from the presenter:
76
+
77
+ # app/presenters/user_mixin.rb
78
+ module UserMixin
79
+ def age_cca
80
+ age < 20 ? "too young" : age >= 30 ? "30+" : age
81
+ end
82
+ end
83
+
84
+ Then tell the presented to use the module:
85
+
86
+ # app/presenters/users_presenter.rb
87
+ ...
88
+ presents :users, UserMixin
89
+ ...
90
+
91
+ Now you can use the new method in your views:
92
+
93
+ # app/views/users/index.html.haml
94
+ %ul
95
+ - @users_presenter.users.each do |user|
96
+ %li
97
+ = user.name
98
+ = user.age_cca
99
+
100
+ == Typecasting
101
+
102
+ These types are supported out of the box:
103
+ +Object+, +Boolean+, +Float+, +Integer+, +String+, +Time+.
104
+
105
+ All of these can be +nil+, single value or an array of values.
106
+
107
+ It is also possible to add support for your custom types by implementing class
108
+ method "typecast" for the given class. This would add support for price type:
109
+
110
+ # lib/price.rb
111
+ class Price
112
+
113
+ attr :value
114
+
115
+ def initialize(value)
116
+ @value = value
117
+ end
118
+
119
+ def to_s
120
+ if @value
121
+ "$" + @value.to_s.reverse.scan(/\d{1,3}/).join(",").reverse
122
+ else
123
+ ""
124
+ end
125
+ end
126
+
127
+ def self.typecast(value, options = {})
128
+ new value.to_s.scan(/\d+/).join.to_i if value
129
+ end
130
+ end
131
+
132
+ == Note on Patches/Pull Requests
133
+
134
+ As usual:
135
+
136
+ * Fork the project.
137
+ * Make your feature addition or bug fix.
138
+ * Add tests for it. This is important so I don't break it in a
139
+ future version unintentionally.
140
+ * Commit, do not mess with rakefile, version, or history.
141
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
142
+ * Send me a pull request. Bonus points for topic branches.
143
+
144
+ == Copyright
145
+
146
+ Copyright (c) 2010 Vladimir Bobes Tuzinsky. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "presenter"
8
+ gem.summary = %Q{Simplifies usage of Presenter pattern in Rails}
9
+ gem.description = %Q{Simplifies usage of Presenter pattern in Rails}
10
+ gem.email = "vladimir.tuzinsky@gmail.com"
11
+ gem.homepage = "http://github.com/bobes/presenter"
12
+ gem.authors = ["Vladimir Bobes Tuzinsky"]
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/test_*.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/test_*.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+ task :test => :check_dependencies
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
46
+
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "presenter #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,3 @@
1
+ major: 0
2
+ minor: 1
3
+ patch: 0
data/lib/presenter.rb ADDED
@@ -0,0 +1,11 @@
1
+ gem 'activesupport', '>= 2.3'
2
+
3
+ require 'active_support'
4
+
5
+ class Presenter
6
+ end
7
+
8
+ Dir[File.join(File.dirname(__FILE__), "presenter", "*.rb")].each do |file|
9
+ require file
10
+ end
11
+
@@ -0,0 +1,98 @@
1
+ class Presenter
2
+
3
+ module Core
4
+
5
+ def self.included(model)
6
+ model.class_eval do
7
+ extend ClassMethods
8
+ include InstanceMethods
9
+ end
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+
15
+ def key(*args)
16
+ key = Key.new(*args)
17
+ keys[key.name.to_sym] = key
18
+ create_accessors_for(key)
19
+ end
20
+
21
+ def presents(*names)
22
+ mixin = names.pop if names.last.is_a?(Module)
23
+ names.each { |name| create_finder_for(name, mixin) }
24
+ end
25
+
26
+ def keys
27
+ @keys ||= superclass.respond_to?(:keys) ? superclass.keys.dup : {}
28
+ end
29
+
30
+ private
31
+
32
+ def create_accessors_for(key)
33
+ module_eval <<-EOS, __FILE__, __LINE__ + 1
34
+ def #{key.name}
35
+ values.include?(:#{key.name}) ? values[:#{key.name}] : keys[:#{key.name}].default_value
36
+ end
37
+
38
+ def #{key.name}=(value)
39
+ values[:#{key.name}] = keys[:#{key.name}].typecast(value)
40
+ end
41
+
42
+ def #{key.name}?
43
+ #{key.name}.respond_to?(:empty?) ? !#{key.name}.empty? : !!#{key.name}
44
+ end
45
+ EOS
46
+ end
47
+
48
+ def create_finder_for(name, mixin = nil)
49
+ @mixins ||= {}
50
+ @mixins[name] = mixin
51
+ module_eval <<-EOS, __FILE__, __LINE__ + 1
52
+ def #{name}
53
+ @collections ||= {}
54
+ @collections[:#{name}] ||= wrap_#{name}(find_#{name})
55
+ end
56
+
57
+ private
58
+
59
+ def wrap_#{name}(items)
60
+ if mixin = self.class.instance_variable_get("@mixins")[:#{name}]
61
+ items.each { |item| item.extend(mixin) }
62
+ end
63
+ items
64
+ end
65
+
66
+ def find_#{name}
67
+ raise NotImplementedError.new("find_#{name} method not implemented")
68
+ end
69
+ EOS
70
+ end
71
+ end
72
+
73
+ module InstanceMethods
74
+
75
+ def initialize(params = nil)
76
+ if params
77
+ params.each do |name, value|
78
+ self.send "#{name}=", value if keys[name.to_sym]
79
+ end
80
+ end
81
+ end
82
+
83
+ def keys
84
+ self.class.keys
85
+ end
86
+
87
+ def values
88
+ @values ||= {}
89
+ end
90
+
91
+ def params
92
+ @values.delete_if { |key, value| value.nil? || (value.respond_to?(:empty?) && value.empty?) }
93
+ end
94
+ end
95
+
96
+ include Core
97
+ end
98
+
@@ -0,0 +1,31 @@
1
+ class Key
2
+
3
+ attr_accessor :name
4
+
5
+ def initialize(*args)
6
+ @options = args.last.is_a?(Hash) ? args.pop : {}
7
+ @name, @type = args.shift.to_s, args.shift || Object
8
+ @default_value = @options.delete(:default)
9
+ @options = nil if @type.method(:typecast).arity == 1
10
+ end
11
+
12
+ def typecast(value)
13
+ if value.is_a?(Array)
14
+ array = value.map { |v| typecast(v) }.compact
15
+ array.any? ? array : nil
16
+ elsif value.nil? || (value.respond_to?(:empty?) && value.empty?)
17
+ nil
18
+ else
19
+ @options ? @type.typecast(value, @options) : @type.typecast(value)
20
+ end
21
+ end
22
+
23
+ def default_value
24
+ value = @default_value.is_a?(Proc) ? @default_value.call : @default_value
25
+ @type.typecast(value)
26
+ end
27
+
28
+ def to_s
29
+ "#<Key: name=#{name}, type=#{type}>"
30
+ end
31
+ end
@@ -0,0 +1,64 @@
1
+ class Boolean
2
+
3
+ def self.typecast(value)
4
+ if ["true", "1"].include?(value.to_s.downcase)
5
+ true
6
+ elsif ["false", "0"].include?(value.to_s.downcase)
7
+ false
8
+ else
9
+ nil
10
+ end
11
+ end
12
+ end
13
+
14
+ class Float
15
+
16
+ def self.typecast(value)
17
+ value_to_f = value.to_f
18
+ value_to_f == 0 && value.to_s !~ /^0*\.?0+/ ? nil : value_to_f
19
+ end
20
+ end
21
+
22
+ class Integer
23
+
24
+ def self.typecast(value)
25
+ value_to_i = value.to_i
26
+ value_to_i == 0 && value.to_s !~ /^(0x|0b)?0+/ ? nil : value_to_i
27
+ end
28
+ end
29
+
30
+ class Object
31
+
32
+ def self.typecast(value)
33
+ value
34
+ end
35
+ end
36
+
37
+ class String
38
+
39
+ def self.typecast(value)
40
+ value.nil? ? nil : value.to_s
41
+ end
42
+ end
43
+
44
+ class Time
45
+
46
+ def self.typecast(value, options = {})
47
+ if value.is_a?(Time)
48
+ value
49
+ elsif value.is_a?(Hash)
50
+ Time.local(*value.values_at(:year, :month, :day, :hour, :minute, :second))
51
+ elsif value.is_a?(Date)
52
+ Time.local(value.year, value.month, value.day)
53
+ else
54
+ begin
55
+ dt = Date._strptime(value.to_s, options[:format] || "%a %b %d %H:%M:%S %Z %Y")
56
+ time = Time.local(dt[:year], dt[:mon], dt[:mday], dt[:hour], dt[:min], dt[:sec])
57
+ time += (time.utc_offset - dt[:offset]) if dt[:offset]
58
+ time
59
+ rescue StandardError => e
60
+ nil
61
+ end
62
+ end
63
+ end
64
+ end
data/presenter.gemspec ADDED
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{presenter}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Vladimir Bobes Tuzinsky"]
12
+ s.date = %q{2010-03-31}
13
+ s.description = %q{Simplifies usage of Presenter pattern in Rails}
14
+ s.email = %q{vladimir.tuzinsky@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION.yml",
26
+ "lib/presenter.rb",
27
+ "lib/presenter/core.rb",
28
+ "lib/presenter/key.rb",
29
+ "lib/presenter/types.rb",
30
+ "presenter.gemspec",
31
+ "test/helper.rb",
32
+ "test/test_core.rb",
33
+ "test/test_key.rb",
34
+ "test/test_presenter.rb",
35
+ "test/test_types.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/bobes/presenter}
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.6}
41
+ s.summary = %q{Simplifies usage of Presenter pattern in Rails}
42
+ s.test_files = [
43
+ "test/helper.rb",
44
+ "test/test_core.rb",
45
+ "test/test_key.rb",
46
+ "test/test_presenter.rb",
47
+ "test/test_types.rb"
48
+ ]
49
+
50
+ if s.respond_to? :specification_version then
51
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
52
+ s.specification_version = 3
53
+
54
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
55
+ else
56
+ end
57
+ else
58
+ end
59
+ end
60
+
data/test/helper.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ require 'presenter'
7
+
8
+ class Test::Unit::TestCase
9
+
10
+ def self.test(name, &block)
11
+ test_name = "test_#{name.gsub(/\s+/,'_')}".downcase
12
+ define_method(test_name, &block)
13
+ end
14
+ end
data/test/test_core.rb ADDED
@@ -0,0 +1,142 @@
1
+ require "helper"
2
+
3
+ class TestCode < Test::Unit::TestCase
4
+
5
+ test "module can be included" do
6
+ klass = Class.new do
7
+ include Presenter::Core
8
+ key :name
9
+ end
10
+ instance = klass.new
11
+ instance.name = "Fred"
12
+ end
13
+
14
+ test "key defines accessors" do
15
+ klass = Class.new do
16
+ include Presenter::Core
17
+ key :name
18
+ end
19
+ instance = klass.new
20
+ instance.name = "Fred"
21
+ assert_equal "Fred", instance.name
22
+ assert_equal true, instance.name?
23
+ end
24
+
25
+ test "keys are inheritable" do
26
+ a = Class.new do
27
+ include Presenter::Core
28
+ key :name
29
+ end
30
+ b = Class.new(a) do
31
+ key :age
32
+ end
33
+ c = Class.new(a) do
34
+ key :role
35
+ end
36
+ assert a.keys[:name], b.keys[:name]
37
+ assert c.keys[:age].nil?
38
+ end
39
+
40
+ test "setter casts" do
41
+ klass = Class.new do
42
+ include Presenter::Core
43
+ Object.const_set :CustomType, Class.new
44
+ def CustomType.typecast(value)
45
+ value.to_s.reverse
46
+ end
47
+ key :name, CustomType
48
+ end
49
+ instance = klass.new
50
+ instance.name = "Fred"
51
+ assert_equal "derF", instance.name
52
+ end
53
+
54
+ test "accepts params in initializer" do
55
+ klass = Class.new do
56
+ include Presenter::Core
57
+ key :name, String
58
+ key :age, Integer
59
+ end
60
+ instance = klass.new(:name => "Fred", "age" => "35")
61
+ assert_equal "Fred", instance.name
62
+ assert_equal 35, instance.age
63
+ end
64
+
65
+ test "getters return default values" do
66
+ klass = Class.new do
67
+ include Presenter::Core
68
+ key :name, :default => "Unknown"
69
+ end
70
+ assert_equal "Unknown", klass.new.name
71
+ end
72
+
73
+ test "nil in params takes precendence before default value" do
74
+ klass = Class.new do
75
+ include Presenter::Core
76
+ key :name, :default => "Unknown"
77
+ end
78
+ instance = klass.new :name => nil
79
+ assert_nil instance.name
80
+ end
81
+
82
+ test "getters cast default values" do
83
+ klass = Class.new do
84
+ include Presenter::Core
85
+ key :age, String, :default => 35
86
+ end
87
+ assert_equal "35", klass.new.age
88
+ end
89
+
90
+ test "default values support procs" do
91
+ age = Time.now.to_i
92
+ klass = Class.new do
93
+ include Presenter::Core
94
+ key :age, String, :default => lambda { age }
95
+ end
96
+ assert_equal age.to_s, klass.new.age
97
+ end
98
+
99
+ test "presents defines collection reader" do
100
+ klass = Class.new do
101
+ include Presenter::Core
102
+ presents :users
103
+ def find_users; ["user1", "user2"] end
104
+ end
105
+ assert_equal ["user1", "user2"], klass.new.users
106
+ end
107
+
108
+ test "collection readers cache finders results" do
109
+ klass = Class.new do
110
+ include Presenter::Core
111
+ presents :hits
112
+ def find_hits; @count ||= 0; @count += 1 end
113
+ end
114
+ assert_equal 1, klass.new.hits
115
+ assert_equal 1, klass.new.hits
116
+ end
117
+
118
+ test "collection readers can mixin module in items" do
119
+ mod = Module.new do
120
+ def name; "John Doe" end
121
+ end
122
+ klass = Class.new do
123
+ include Presenter::Core
124
+ presents :users, mod
125
+ def find_users; ["user1", "user2"] end
126
+ end
127
+ users = klass.new.users
128
+ assert_equal ["user1", "user2"], users
129
+ assert_equal "John Doe", users.first.name
130
+ end
131
+
132
+ test "params returns cleaned up value hash" do
133
+ klass = Class.new do
134
+ include Presenter::Core
135
+ key :name
136
+ key :age
137
+ key :role, :default => :guest
138
+ end
139
+ instance = klass.new :name => "John Doe"
140
+ assert_equal({ :name => "John Doe" }, instance.params)
141
+ end
142
+ end
data/test/test_key.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "helper"
2
+
3
+ class TestKey < Test::Unit::TestCase
4
+
5
+ test "cast to array" do
6
+ key = Key.new :name, String
7
+ assert_equal ["1", "2", "three"], key.typecast([1, "2", "three"])
8
+ assert_equal ["1", "three"], key.typecast([1, nil, "three"])
9
+ assert_equal nil, key.typecast([""])
10
+ assert_equal nil, key.typecast([nil])
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ require "helper"
2
+
3
+ class TestPresenter < Test::Unit::TestCase
4
+
5
+ test "includes Core" do
6
+ assert Presenter.constants.include?("Core")
7
+ end
8
+ end
@@ -0,0 +1,48 @@
1
+ require "helper"
2
+
3
+ class TestTypes < Test::Unit::TestCase
4
+
5
+ test "cast to boolean" do
6
+ assert_equal true, Boolean.typecast(true)
7
+ assert_equal true, Boolean.typecast("true")
8
+ assert_equal true, Boolean.typecast(1)
9
+ assert_equal true, Boolean.typecast("1")
10
+ assert_equal false, Boolean.typecast(false)
11
+ assert_equal false, Boolean.typecast("false")
12
+ assert_equal false, Boolean.typecast(0)
13
+ assert_equal false, Boolean.typecast("0")
14
+ assert_nil Boolean.typecast(123)
15
+ assert_nil Boolean.typecast("huh?")
16
+ end
17
+
18
+ test "cast to float" do
19
+ assert_equal 35.5, Float.typecast("35.5")
20
+ assert_nil Float.typecast("huh?")
21
+ end
22
+
23
+ test "cast to integer" do
24
+ assert_equal 35, Integer.typecast(35)
25
+ assert_equal 35, Integer.typecast("35")
26
+ assert_equal 35, Integer.typecast("35.5")
27
+ assert_nil Integer.typecast("huh?")
28
+ end
29
+
30
+ test "cast to string" do
31
+ assert_equal "35", String.typecast(35)
32
+ assert_equal "true", String.typecast(true)
33
+ assert_equal "false", String.typecast(false)
34
+ assert_equal "anything", String.typecast("anything")
35
+ assert_nil String.typecast(nil)
36
+ end
37
+
38
+ test "cast to time" do
39
+ assert_equal Time.local(2009, 12, 28, 10, 35, 25), Time.typecast({
40
+ :year => "2009", :month => "12", :day => "28", :hour => "10", :minute => "35", :second => "25"
41
+ })
42
+ assert_equal Time.utc(2009, 12, 28, 9, 35, 25), Time.typecast("Mon Dec 28 11:35:25 +0200 2009")
43
+ assert_equal Time.local(2009, 12, 28, 9, 35), Time.typecast("28/12/2009 09:35", :format => "%d/%m/%Y %H:%M")
44
+ assert_equal Time.local(2009, 12, 28, 10, 35, 25), Time.typecast(Time.local(2009, 12, 28, 10, 35, 25))
45
+ assert_equal Time.utc(2009, 12, 28, 10, 35, 25), Time.typecast(Time.utc(2009, 12, 28, 10, 35, 25))
46
+ assert_equal Time.local(2009, 12, 28), Time.typecast(Date.new(2009, 12, 28))
47
+ end
48
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: presenter
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
+ - Vladimir Bobes Tuzinsky
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-31 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Simplifies usage of Presenter pattern in Rails
22
+ email: vladimir.tuzinsky@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE
29
+ - README.rdoc
30
+ files:
31
+ - .document
32
+ - .gitignore
33
+ - LICENSE
34
+ - README.rdoc
35
+ - Rakefile
36
+ - VERSION.yml
37
+ - lib/presenter.rb
38
+ - lib/presenter/core.rb
39
+ - lib/presenter/key.rb
40
+ - lib/presenter/types.rb
41
+ - presenter.gemspec
42
+ - test/helper.rb
43
+ - test/test_core.rb
44
+ - test/test_key.rb
45
+ - test/test_presenter.rb
46
+ - test/test_types.rb
47
+ has_rdoc: true
48
+ homepage: http://github.com/bobes/presenter
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --charset=UTF-8
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.6
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Simplifies usage of Presenter pattern in Rails
77
+ test_files:
78
+ - test/helper.rb
79
+ - test/test_core.rb
80
+ - test/test_key.rb
81
+ - test/test_presenter.rb
82
+ - test/test_types.rb