model_formatter 0.0.3

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 ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ debug.log
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
data/CHANGELOG ADDED
@@ -0,0 +1,5 @@
1
+ *svn*
2
+ * added option to pass instance of a formatter
3
+ * added options to instantiation of the formatter
4
+ * added precision options to currency formatter, which now also stores currencies as an integer
5
+ * exposed formatters as class methods
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in model_formatter.gemspec
4
+ gemspec
5
+
6
+ gem 'rails'
7
+ gem 'rake', '0.8.7'
8
+ gem 'sqlite3'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005 Geoffrey Grosenbach
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.md ADDED
@@ -0,0 +1,62 @@
1
+ ## Overview
2
+
3
+ The ModelFormatter module allows you to easily handle fields that need to be formatted or stripped
4
+ of formatting as they are set or retrieved from the database. You can designate one or more of your
5
+ columns as "formatted columns" like in this example:
6
+
7
+ class Widget < ActiveRecord::Base
8
+ # Set an integer field as a symbol
9
+ format_column :some_integer, :as => :integer
10
+
11
+ # Specify the type as a class
12
+ format_column :sales_tax, :as => Formatters::FormatCurrency
13
+ format_column :sales_tax, :as => Formatters::FormatCurrency.new(:precision => 4)
14
+
15
+ # Change the prefix of the generated methods and specify type as a symbol
16
+ format_column :sales_tax, :prefix => 'fmt_', :as => :currency, :options => {:precision => 4}
17
+
18
+ # Use specific procedures to convert the data +from+ and +to+ the target
19
+ format_column :area, :from => Proc.new {|value, options| number_with_delimiter sprintf('%2d', value)},
20
+ :to => Proc.new {|str, options| str.gsub(/,/, '')}
21
+
22
+ # Use a block to define the formatter methods
23
+ format_column :sales_tax do
24
+ def from(value, options = {})
25
+ number_to_currency value
26
+ end
27
+ def to(str, options = {})
28
+ str.gsub(/[\$,]/, '')
29
+ end
30
+ end
31
+
32
+ ...
33
+ end
34
+
35
+ The methods of this module are automatically included into `ActiveRecord::Base`
36
+ as class methods, so that you can use them in your models.
37
+
38
+
39
+ ## Documentation
40
+
41
+ For more detailed documentation, create the rdocs with the following command:
42
+
43
+ rake rdoc
44
+
45
+
46
+ ## Running Unit Tests
47
+
48
+ By default, the ModelFormatter plugin uses the mysql +test+ database, running on +localhost+. To run the tests, enter the following:
49
+
50
+ rake
51
+
52
+
53
+ ## Bugs & Feedback
54
+
55
+ Please file a bug report at http://github.com/bfolkens/model-formatter/issues
56
+
57
+ [![Build Status](https://secure.travis-ci.org/bfolkens/model-formatter.png)](http://travis-ci.org/bfolkens/model-formatter)
58
+
59
+ ## Credits
60
+
61
+ Sebastian Kanthak's file_column plugin - used for ideas and best practices.
62
+
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
9
+ desc 'Test the model_formatter plugin.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the model_formatter plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'ModelFormatter'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
data/lib/formatters.rb ADDED
@@ -0,0 +1,8 @@
1
+ module Formatters
2
+ FORMATTERS_BASE_PATH = File.join(File.dirname(__FILE__), 'formatters') unless defined? FORMATTERS_BASE_PATH
3
+
4
+ require File.join(FORMATTERS_BASE_PATH, 'format.rb')
5
+ Dir[File.join(FORMATTERS_BASE_PATH, 'format_*.rb')].each do |formatter|
6
+ require formatter
7
+ end
8
+ end
@@ -0,0 +1,23 @@
1
+ module Formatters
2
+ class Format
3
+ def initialize(options = {})
4
+ end
5
+
6
+ def from(value, options = {})
7
+ raise FormatNotDefinedException
8
+ end
9
+
10
+ def to(str, options = {})
11
+ raise FormatNotDefinedException
12
+ end
13
+ end
14
+
15
+ class FormattingException < Exception
16
+ end
17
+
18
+ class FormatNotDefinedException < Exception
19
+ end
20
+
21
+ class FormatNotFoundException < Exception
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module Formatters
2
+ class FormatBoolean < Format
3
+ def initialize(options = {})
4
+ @on = 'yes'
5
+ @off = 'no'
6
+ end
7
+
8
+ def from(value, options = {})
9
+ value ? @on : @off
10
+ end
11
+
12
+ def to(str, options = {})
13
+ str == @on
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'action_view'
3
+
4
+ module Formatters
5
+ class FormatCurrency < Format
6
+ include ActionView::Helpers::NumberHelper
7
+
8
+ def initialize(options = {})
9
+ @precision = options[:precision] || 2
10
+ end
11
+
12
+ def from(value, options = {})
13
+ options = {:precision => @precision}.merge(options)
14
+ number_to_currency(value.to_f / (10 ** @precision), options)
15
+ end
16
+
17
+ def to(str, options = {})
18
+ return nil if str.nil? or str.empty?
19
+ val = str.gsub(/[^0-9.\-]/, '').to_f
20
+ (val * (10 ** @precision)) unless val.nil?
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'action_view'
3
+
4
+ module Formatters
5
+ class FormatDecimal < Format
6
+ include ActionView::Helpers::NumberHelper
7
+
8
+ def initialize(options = {})
9
+ end
10
+
11
+ def from(value, options = {})
12
+ options = {:precision => 3, :delimiter => ','}.merge(options)
13
+ number_with_precision value, options
14
+ end
15
+
16
+ def to(str, options = {})
17
+ return nil if str.nil? or str.empty?
18
+ str.gsub(/,/, '').to_f
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'action_view'
3
+
4
+ module Formatters
5
+ class FormatInteger < Format
6
+ include ActionView::Helpers::NumberHelper
7
+
8
+ def initialize(options = {})
9
+ end
10
+
11
+ def from(value, options = {})
12
+ options = {:delimiter => ','}.merge(options)
13
+ number_with_delimiter value, options
14
+ end
15
+
16
+ def to(str, options = {})
17
+ return nil if str.nil? or str.empty?
18
+ str.gsub(/,/, '').to_i
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'action_view'
3
+
4
+ module Formatters
5
+ class FormatPercent < Format
6
+ include ActionView::Helpers::NumberHelper
7
+
8
+ def initialize(options = {})
9
+ end
10
+
11
+ def from(value, options = {})
12
+ number_to_percentage value, options
13
+ end
14
+
15
+ def to(str, options = {})
16
+ return nil if str.nil? or str.empty?
17
+ str.gsub(/[^0-9\.\-]/, '').to_f
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'action_view'
3
+
4
+ module Formatters
5
+ class FormatPhone < Format
6
+ include ActionView::Helpers::NumberHelper
7
+
8
+ def initialize(options = {})
9
+ end
10
+
11
+ def from(value, options = {})
12
+ number_to_phone value, options
13
+ end
14
+
15
+ def to(str, options = {})
16
+ return nil if str.nil? or str.empty?
17
+ str.gsub(/[^0-9]/, '').to_i
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,222 @@
1
+ class Object
2
+ # The hidden singleton lurks behind everyone
3
+ def metaclass; class << self; self; end; end
4
+ def meta_eval &blk; metaclass.instance_eval &blk; end
5
+
6
+ # Adds methods to a metaclass
7
+ def meta_def name, &blk
8
+ meta_eval { define_method name, &blk }
9
+ end
10
+
11
+ # Defines an instance method within a class
12
+ def class_def name, &blk
13
+ class_eval { define_method name, &blk }
14
+ end
15
+ end
16
+
17
+ module ModelFormatter # :nodoc:
18
+ DEFAULT_FORMAT_PREFIX = 'formatted_'
19
+
20
+ def self.append_features(base) # :nodoc:
21
+ super
22
+ base.extend(ClassMethods)
23
+ end
24
+
25
+ def self.init_options(defaults, model, attr) # :nodoc:
26
+ options = defaults.dup
27
+ options[:attr] = attr
28
+ options[:prefix] ||= DEFAULT_FORMAT_PREFIX
29
+ options[:formatted_attr] ||= "#{options[:prefix]}#{attr}"
30
+
31
+ # If :as is set, then it must be either a formatter Class, formatter Object, Symbol, or String
32
+ options[:formatter] = formatter_for(options[:as], options[:options]) unless options[:as].nil?
33
+
34
+ # Define the formatter from a :block if :block is defined
35
+ options[:formatter] = define_formatter(attr, &options[:block]) unless options[:block].nil?
36
+
37
+ # Define :formatter from a block based on :from and :to if they're both set
38
+ if !options[:from].nil? and !options[:to].nil?
39
+ options[:formatter] = Module.new
40
+ options[:formatter].class.send :define_method, :from, options[:from]
41
+ options[:formatter].class.send :define_method, :to, options[:to]
42
+ end
43
+
44
+ # If :as is still not defined raise an error
45
+ raise 'No formatting options have been defined.' if options[:formatter].nil?
46
+
47
+ options
48
+ end
49
+
50
+ # Define a formatter like the actual physical classes
51
+ # this could easily be done with text and an eval...
52
+ # but this should be faster
53
+ def self.define_formatter(attr, &formatter) # :nodoc:
54
+ # The convention is to name these custom formatters
55
+ # differently than the other formatting classes
56
+ class_name = "CustomFormat#{attr.to_s.camelize}"
57
+
58
+ # Create a class in the same module as the others
59
+ clazz = Class.new(Formatters::Format)
60
+ silence_warnings do
61
+ Formatters.const_set class_name, clazz
62
+ end
63
+
64
+ # Define the class body
65
+ clazz.class_eval &formatter
66
+ return clazz.new
67
+ end
68
+
69
+ # Return the formatter for a class, formatter object, symbol, or
70
+ # string defining the name of a formatter class. If it's a symbol, check
71
+ # the Formatters module for the class that matches the camelized name
72
+ # of the symbol with 'Format' prepended. Options hash is passed to the
73
+ # instantiation of the formatter object.
74
+ def self.formatter_for(type_name, options = {}) # :nodoc:
75
+ # If the type_name is an instance of a formatter, just return with it
76
+ return type_name if type_name.is_a? Formatters::Format
77
+
78
+ # If the type_name is a class just assign it to the formatter_class for instantiation later
79
+ formatter_class = type_name if type_name.is_a? Class
80
+
81
+ # Format a symbol or string into a formatter_class
82
+ if type_name.is_a? Symbol or type_name.is_a? String
83
+ type_name = type_name.to_s.camelize
84
+
85
+ # Construct the class name from the type_name
86
+ formatter_name = "Format#{type_name}"
87
+ formatter_class = nil
88
+ begin
89
+ formatter_class = Formatters.const_get(formatter_name)
90
+ rescue NameError => ne
91
+ # Ignore this, caught below
92
+ end
93
+ end
94
+
95
+ # Make sure the name of this is found in the Formatters module and that
96
+ # it's the correct superclass
97
+ return formatter_class.new(options) unless formatter_class.nil? or
98
+ formatter_class.superclass != Formatters::Format
99
+
100
+ raise Formatters::FormatNotFoundException.new("Cannot find formatter 'Formatters::#{formatter_name}'")
101
+ end
102
+
103
+ require File.dirname(__FILE__) + '/formatters.rb'
104
+
105
+ # == Usage
106
+ # class Widget < ActiveRecord::Base
107
+ # # Set an integer field as a symbol
108
+ # format_column :some_integer, :as => :integer
109
+ #
110
+ # # Specify the type as a class
111
+ # format_column :sales_tax, :as => Formatters::FormatCurrency
112
+ # format_column :sales_tax, :as => Formatters::FormatCurrency.new(:precision => 4)
113
+ #
114
+ # # Change the prefix of the generated methods and specify type as a symbol
115
+ # format_column :sales_tax, :prefix => 'fmt_', :as => :currency, :options => {:precision => 4}
116
+ #
117
+ # # Use specific procedures to convert the data +from+ and +to+ the target
118
+ # format_column :area, :from => Proc.new {|value, options| number_with_delimiter sprintf('%2d', value)},
119
+ # :to => Proc.new {|str, options| str.gsub(/,/, '')}
120
+ #
121
+ # # Use a block to define the formatter methods
122
+ # format_column :sales_tax do
123
+ # def from(value, options = {})
124
+ # number_to_currency value
125
+ # end
126
+ # def to(str, options = {})
127
+ # str.gsub(/[\$,]/, '')
128
+ # end
129
+ # end
130
+ #
131
+ # ...
132
+ # end
133
+ module ClassMethods
134
+
135
+ # You can override the default options with +model_formatter+'s +options+ parameter
136
+ DEFAULT_OPTIONS = {
137
+ :prefix => nil,
138
+ :formatted_attr => nil,
139
+ :as => nil,
140
+ :from => nil,
141
+ :to => nil,
142
+ :options => {}
143
+ }.freeze
144
+
145
+ # After calling "<tt>format_column :sales_tax</tt>" as in the example above, a number of instance methods
146
+ # will automatically be generated, all prefixed by "formatted_" unless :prefix or :formatter_attr
147
+ # have been set:
148
+ #
149
+ # * <tt>Widget.sales_tax_formatter(value)</tt>: Format the sales tax and return the formatted version
150
+ # * <tt>Widget.sales_tax_unformatter(str)</tt>: "Un"format sales tax and return the unformatted version
151
+ # * <tt>Widget#formatted_sales_tax=(value)</tt>: This will set the <tt>sales_tax</tt> of the widget using the value stripped of its formatting.
152
+ # * <tt>Widget#formatted_sales_tax</tt>: This will return the <tt>sales_tax</tt> of the widget using the formatter specified in the options to +format+.
153
+ # * <tt>Widget#sales_tax_formatting_options</tt>: Access the options this formatter was created with. Useful for declaring field length and later referencing it in display helpers.
154
+ #
155
+ # === Options:
156
+ # * <tt>:formatted_attr</tt> - The actual name used for the formatted attribute. By default, the formatted attribute
157
+ # name is composed of the <tt>:prefix</tt>, followed by the name of the attribute.
158
+ # * <tt>:prefix</tt> - Change the prefix prepended to the formatted columns. By default, formatted columns
159
+ # are prepended with "formatted_".
160
+ # * <tt>:as</tt> - Format the column as the specified format. This can be provided in either a String,
161
+ # a Symbol, or as a Class reference to the formatter. The class should subclass Formatters::Format and define <tt>from(value, options = {})</tt> and <tt>to(str, options = {})</tt>.
162
+ # * <tt>:from</tt> - Data coming from the attribute retriever method is sent to this +Proc+, then returned as a
163
+ # manipulated attribute.
164
+ # * <tt>:to</tt> - Data being sent to the attribute setter method is sent to this +Proc+ first to be manipulated,
165
+ # and the returned attribute is then sent to the attribute setter.
166
+ # * <tt>:options</tt> - Passed to the formatter blocks, instantiating formatter classes and/or methods as additional formatting options.
167
+ def format_column(attr, options={}, &fmt_block)
168
+ options[:block] = fmt_block if block_given?
169
+ options = DEFAULT_OPTIONS.merge(options) if options
170
+
171
+ # Create the actual options
172
+ my_options = ModelFormatter::init_options(options,
173
+ ActiveSupport::Inflector.underscore(self.name).to_s,
174
+ attr.to_s)
175
+
176
+
177
+ # Create the class methods
178
+ attr_fmt_options_accessor = "#{my_options[:formatted_attr]}_formatting_options".to_sym
179
+ attr_formatter_method = "#{my_options[:formatted_attr]}_formatter".to_sym
180
+ attr_unformatter_method = "#{my_options[:formatted_attr]}_unformatter".to_sym
181
+
182
+ metaclass.class_eval do
183
+ # Create an options accessor
184
+ define_method attr_fmt_options_accessor do
185
+ my_options
186
+ end
187
+
188
+ # Define a formatter accessor
189
+ define_method attr_formatter_method do |value|
190
+ return value if value.nil?
191
+
192
+ from_method = my_options[:formatter].method(:from)
193
+ from_method.call(value, my_options[:options])
194
+ end
195
+
196
+ # Define an unformatter accessor
197
+ define_method attr_unformatter_method do |str|
198
+ to_method = my_options[:formatter].method(:to)
199
+ to_method.call(str, my_options[:options])
200
+ end
201
+ end
202
+
203
+ # Define the instance method formatter for attr
204
+ define_method my_options[:formatted_attr] do |*params|
205
+ value = self.send(attr, *params)
206
+ self.class.send attr_formatter_method, value
207
+ end
208
+
209
+ # Define the instance method unformatter for attr
210
+ define_method my_options[:formatted_attr] + '=' do |str|
211
+ value = self.class.send(attr_unformatter_method, str)
212
+ self.send(attr.to_s + '=', value)
213
+ end
214
+ end
215
+
216
+ def is_formatted?(attr)
217
+ !public_methods.reject {|method| method !~ /#{attr.to_s}_formatting_options$/}.empty?
218
+ end
219
+ end
220
+ end
221
+
222
+ ActiveRecord::Base.send(:include, ModelFormatter)
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "model_formatter"
6
+ s.version = '0.0.3'
7
+ s.authors = ["Brad Folkens", "Tyler Rick"]
8
+ s.email = ["bfolkens@gmail.com", "tyler@tylerrick.com"]
9
+ s.homepage = "https://github.com/bfolkens/model-formatter"
10
+ s.summary = %q{Allows you to easily handle fields in Rails / ActiveRecord that need to be formatted or stripped of formatting as they are set or retrieved from the database.}
11
+ s.description = s.summary
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_paths = ["lib"]
17
+ end
@@ -0,0 +1,11 @@
1
+ require 'logger'
2
+
3
+ ActiveRecord::Base.logger = Logger.new("debug.log")
4
+ ActiveRecord::Base.establish_connection(
5
+ :adapter => "sqlite3",
6
+ :database => ":memory:",
7
+ :timeout => 500
8
+ )
9
+
10
+ load File.dirname(__FILE__) + "/fixtures/schema.rb"
11
+
@@ -0,0 +1,2 @@
1
+ class Entry < ActiveRecord::Base
2
+ end
@@ -0,0 +1,11 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :entries, :force => true do |t|
3
+ t.column :some_integer, :integer
4
+ t.column :some_boolean, :boolean
5
+ t.column :sales_tax, :integer
6
+ t.column :super_precise_tax, :integer
7
+ t.column :area, :float
8
+ t.column :complex_field, :string
9
+ t.column :phone, :integer
10
+ end
11
+ end
@@ -0,0 +1,136 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'active_support'
4
+ require 'active_record'
5
+ require 'action_view'
6
+
7
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
8
+ $:.unshift File.expand_path(File.dirname(__FILE__))
9
+
10
+ require 'connection'
11
+ require 'model_formatter'
12
+ require 'fixtures/entry'
13
+
14
+
15
+ class ModelFormatterTest < Test::Unit::TestCase
16
+ def setup
17
+ Entry.format_column :some_integer, :as => :integer
18
+ Entry.format_column :some_boolean, :prefix => 'fmt_', :as => :boolean
19
+
20
+ Entry.format_column :sales_tax, :as => :currency, :options => {:precision => 3}
21
+ Entry.format_column :super_precise_tax, :as => Formatters::FormatCurrency.new(:precision => 6)
22
+
23
+ Entry.format_column :area, :from => Proc.new {|value, options| sprintf('%2d', value) + options[:sample_format]},
24
+ :to => Proc.new {|str, options| str.gsub(/[^0-9]/, '').to_i},
25
+ :options => {:sample_format => ' sq. ft.'}
26
+
27
+ Entry.format_column :complex_field do
28
+ def from(value, options = {})
29
+ 'bouya ' + value
30
+ end
31
+
32
+ def to(str, options = {})
33
+ str.gsub(/^bouya /, '')
34
+ end
35
+ end
36
+
37
+ Entry.format_column :phone, :as => :phone
38
+ end
39
+
40
+ def test_should_define_format_accessors
41
+ assert Entry.respond_to?('formatted_some_integer_formatter')
42
+ assert Entry.respond_to?('formatted_some_integer_unformatter')
43
+ end
44
+
45
+ def test_should_define_getters
46
+ assert Entry.new.respond_to?('formatted_some_integer')
47
+ assert Entry.new.respond_to?('fmt_some_boolean')
48
+ assert Entry.new.respond_to?('formatted_sales_tax')
49
+ assert Entry.new.respond_to?('formatted_super_precise_tax')
50
+ assert Entry.new.respond_to?('formatted_area')
51
+ assert Entry.new.respond_to?('formatted_complex_field')
52
+ assert Entry.new.respond_to?('formatted_phone')
53
+ end
54
+
55
+ def test_should_define_setters
56
+ assert Entry.new.respond_to?('formatted_some_integer=')
57
+ assert Entry.new.respond_to?('fmt_some_boolean=')
58
+ assert Entry.new.respond_to?('formatted_sales_tax=')
59
+ assert Entry.new.respond_to?('formatted_super_precise_tax=')
60
+ assert Entry.new.respond_to?('formatted_area=')
61
+ assert Entry.new.respond_to?('formatted_complex_field=')
62
+ assert Entry.new.respond_to?('formatted_phone=')
63
+ end
64
+
65
+ def test_should_know_formatters
66
+ assert !Entry.is_formatted?(:id)
67
+
68
+ assert Entry.is_formatted?(:some_integer)
69
+ assert Entry.is_formatted?(:some_boolean)
70
+ assert Entry.is_formatted?(:sales_tax)
71
+
72
+ assert Entry.is_formatted?('super_precise_tax')
73
+ assert Entry.is_formatted?('area')
74
+ assert Entry.is_formatted?('complex_field')
75
+ assert Entry.is_formatted?('phone')
76
+ end
77
+
78
+ def test_should_respond_to_basic_definition
79
+ e = Entry.new
80
+
81
+ assert_equal '3,123', Entry.formatted_some_integer_formatter(3123)
82
+ e.some_integer = 3123
83
+ assert_equal '3,123', e.formatted_some_integer
84
+
85
+ assert_equal 3123, Entry.formatted_some_integer_unformatter('3,123')
86
+ e.formatted_some_integer = '3,123'
87
+ assert_equal 3123, e.some_integer
88
+ end
89
+
90
+ def test_should_respond_to_proc_definition
91
+ e = Entry.new
92
+
93
+ assert_equal '3123 sq. ft.', Entry.formatted_area_formatter(3123)
94
+ e.area = 3123
95
+ assert_equal '3123 sq. ft.', e.formatted_area
96
+
97
+ assert_equal 3123, Entry.formatted_area_unformatter('3123 sq. ft.')
98
+ e.formatted_area = '3123 sq. ft.'
99
+ assert_equal 3123, e.area
100
+ end
101
+
102
+ def test_should_respond_to_block_definition
103
+ e = Entry.new
104
+
105
+ assert_equal 'bouya test me', Entry.formatted_complex_field_formatter('test me')
106
+ e.complex_field = 'test me'
107
+ assert_equal 'bouya test me', e.formatted_complex_field
108
+
109
+ assert_equal 'here and bouya there', Entry.formatted_complex_field_unformatter('bouya here and bouya there')
110
+ e.formatted_complex_field = 'bouya here and bouya there'
111
+ assert_equal 'here and bouya there', e.complex_field
112
+ end
113
+
114
+ def test_should_pass_options_upon_instantiation
115
+ e = Entry.new
116
+
117
+ # Check format accessors
118
+ assert_equal '$12,412.292', Entry.formatted_sales_tax_formatter(12412292)
119
+ assert_equal 12412292, Entry.formatted_sales_tax_unformatter('$12,412.292')
120
+
121
+ # Check symbol use
122
+ e.sales_tax = 12412292
123
+ assert_equal '$12,412.292', e.formatted_sales_tax
124
+
125
+ e.formatted_sales_tax = '$12,412.292'
126
+ assert_equal 12412292, e.sales_tax
127
+
128
+ # Check instance use
129
+ e.super_precise_tax = 12412292888
130
+ assert_equal '$12,412.292888', e.formatted_super_precise_tax
131
+
132
+ e.formatted_super_precise_tax = '$12,412.292888'
133
+ assert_equal 12412292888, e.super_precise_tax
134
+ end
135
+ end
136
+
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: model_formatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brad Folkens
9
+ - Tyler Rick
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-10-10 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: Allows you to easily handle fields in Rails / ActiveRecord that need
16
+ to be formatted or stripped of formatting as they are set or retrieved from the
17
+ database.
18
+ email:
19
+ - bfolkens@gmail.com
20
+ - tyler@tylerrick.com
21
+ executables: []
22
+ extensions: []
23
+ extra_rdoc_files: []
24
+ files:
25
+ - .gitignore
26
+ - .travis.yml
27
+ - CHANGELOG
28
+ - Gemfile
29
+ - MIT-LICENSE
30
+ - README.md
31
+ - Rakefile
32
+ - lib/formatters.rb
33
+ - lib/formatters/format.rb
34
+ - lib/formatters/format_boolean.rb
35
+ - lib/formatters/format_currency.rb
36
+ - lib/formatters/format_decimal.rb
37
+ - lib/formatters/format_integer.rb
38
+ - lib/formatters/format_percent.rb
39
+ - lib/formatters/format_phone.rb
40
+ - lib/model_formatter.rb
41
+ - model_formatter.gemspec
42
+ - test/connection.rb
43
+ - test/fixtures/entry.rb
44
+ - test/fixtures/schema.rb
45
+ - test/model_formatter_test.rb
46
+ homepage: https://github.com/bfolkens/model-formatter
47
+ licenses: []
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ segments:
59
+ - 0
60
+ hash: 126899651837855101
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ segments:
68
+ - 0
69
+ hash: 126899651837855101
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 1.8.23.2
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Allows you to easily handle fields in Rails / ActiveRecord that need to be
76
+ formatted or stripped of formatting as they are set or retrieved from the database.
77
+ test_files: []