dm_ruby_extensions 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rspec +3 -0
- data/Gemfile +7 -0
- data/LICENSE +22 -0
- data/README.md +89 -0
- data/Rakefile +7 -0
- data/dm_ruby_extensions.gemspec +21 -0
- data/lib/dm_ruby_extensions.rb +15 -0
- data/lib/dm_ruby_extensions/extend_array.rb +46 -0
- data/lib/dm_ruby_extensions/extend_date.rb +23 -0
- data/lib/dm_ruby_extensions/extend_datetime.rb +22 -0
- data/lib/dm_ruby_extensions/extend_fixnum.rb +16 -0
- data/lib/dm_ruby_extensions/extend_hash.rb +109 -0
- data/lib/dm_ruby_extensions/extend_nil.rb +36 -0
- data/lib/dm_ruby_extensions/extend_numeric.rb +8 -0
- data/lib/dm_ruby_extensions/extend_string.rb +193 -0
- data/lib/dm_ruby_extensions/extend_time.rb +11 -0
- data/lib/dm_ruby_extensions/version.rb +3 -0
- data/spec/extensions/array_spec.rb +39 -0
- data/spec/extensions/date_spec.rb +29 -0
- data/spec/extensions/datetime_spec.rb +29 -0
- data/spec/extensions/fixnum_spec.rb +20 -0
- data/spec/extensions/hash_spec.rb +55 -0
- data/spec/extensions/nil_spec.rb +34 -0
- data/spec/extensions/numeric_spec.rb +14 -0
- data/spec/extensions/string_spec.rb +113 -0
- data/spec/extensions/time_spec.rb +16 -0
- data/spec/spec_helper.rb +85 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 062e84718734bf691ec38ab67f2a9465178f3c80
|
4
|
+
data.tar.gz: 72ccb7dbc6f0e758b53ea5077a3f0132052de08f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 54a75c8ac9d30a8095178ce580d969f41f954face5835825ed1a730c2bbbc43a4a3b22e0ac20bf0ea237acc86fa0d5ee5b47a5122d05d418060afd4fc999dc5a
|
7
|
+
data.tar.gz: 3133f59828e0906e4060b4afeb21b9b1bd1469e7daec0a840c099451000d4d682025b1323cb118ce6489f6ca10752c7beb7926fdc088472897cf001590e71372
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright 2013 digitalMoksha LLC
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# DmRubyExtensions
|
2
|
+
|
3
|
+
Adds some simple convienence methods to some Ruby classes, for use in the digitalMoksha gems. Although some of these can be found in other libraries, this includes a small handful and removes the dependency on another large library.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'dm_ruby_extensions'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install dm_ruby_extensions
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
#### Array
|
22
|
+
|
23
|
+
* extract_options!
|
24
|
+
* closest_max
|
25
|
+
* xss_aware_join
|
26
|
+
* css_join
|
27
|
+
|
28
|
+
#### Date
|
29
|
+
|
30
|
+
* to_age
|
31
|
+
* localize
|
32
|
+
|
33
|
+
#### DateTime
|
34
|
+
|
35
|
+
* to_age
|
36
|
+
* localize
|
37
|
+
|
38
|
+
#### Fixnum
|
39
|
+
|
40
|
+
* factorial
|
41
|
+
* as_boolean
|
42
|
+
|
43
|
+
#### Hash
|
44
|
+
|
45
|
+
* convert_date
|
46
|
+
* convert_datetime
|
47
|
+
* url_query_string
|
48
|
+
* rekey
|
49
|
+
* rekey!
|
50
|
+
|
51
|
+
#### Nil
|
52
|
+
|
53
|
+
* to_s_default
|
54
|
+
* as_boolean
|
55
|
+
* to_age
|
56
|
+
* sql_wildcard
|
57
|
+
|
58
|
+
#### Numeric
|
59
|
+
|
60
|
+
* percent_of
|
61
|
+
|
62
|
+
#### String
|
63
|
+
|
64
|
+
* to_s_default
|
65
|
+
* as_boolean
|
66
|
+
* as_css_size
|
67
|
+
* sql_wildcard
|
68
|
+
* replace_non_alphanumeric
|
69
|
+
* expand_url
|
70
|
+
* absolute_url?
|
71
|
+
* smart_titlecase
|
72
|
+
* smart_capitalize
|
73
|
+
* smart_capitalize!
|
74
|
+
* smart_truncate
|
75
|
+
* name_case
|
76
|
+
* name_case!
|
77
|
+
|
78
|
+
#### Time
|
79
|
+
|
80
|
+
* localize
|
81
|
+
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dm_ruby_extensions/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "dm_ruby_extensions"
|
8
|
+
gem.version = DmRubyExtensions::VERSION
|
9
|
+
gem.authors = ["Brett Walker"]
|
10
|
+
gem.email = ["github@digitalmoksha.com"]
|
11
|
+
gem.description = %q{Ruby base class extensions}
|
12
|
+
gem.summary = %q{Simple Ruby base class extensions}
|
13
|
+
gem.homepage = "https://github.com/digitalmoksha/dm_ruby_extensions"
|
14
|
+
gem.licenses = ['MIT']
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'activesupport', '~> 4.0'
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "dm_ruby_extensions/version"
|
2
|
+
require "dm_ruby_extensions/extend_array"
|
3
|
+
require "dm_ruby_extensions/extend_date"
|
4
|
+
require "dm_ruby_extensions/extend_datetime"
|
5
|
+
require "dm_ruby_extensions/extend_hash"
|
6
|
+
require "dm_ruby_extensions/extend_nil"
|
7
|
+
require "dm_ruby_extensions/extend_string"
|
8
|
+
require "dm_ruby_extensions/extend_time"
|
9
|
+
require "dm_ruby_extensions/extend_fixnum"
|
10
|
+
require "dm_ruby_extensions/extend_numeric"
|
11
|
+
|
12
|
+
require 'active_support/core_ext/string'
|
13
|
+
|
14
|
+
module DmRubyExtensions
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
class Array
|
3
|
+
|
4
|
+
# Extract options from a set of arguments. Removes and returns the last element in the array if it's a hash, otherwise returns a blank hash.
|
5
|
+
#
|
6
|
+
# def options(*args)
|
7
|
+
# args.extract_options!
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# options(1, 2) # => {}
|
11
|
+
# options(1, 2, :a => :b) # => {:a=>:b}
|
12
|
+
#------------------------------------------------------------------------------
|
13
|
+
def extract_options!
|
14
|
+
last.is_a?(::Hash) ? pop : {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Return the value that is closest to the value in the array, rounded down.
|
18
|
+
# [0,5,7,8,11,16].closest_max(6) => 5
|
19
|
+
# [0,5,7,8,11,16].closest_max(7) => 7
|
20
|
+
#------------------------------------------------------------------------------
|
21
|
+
def closest_max(value)
|
22
|
+
self.select{|item| item <= value}.max
|
23
|
+
end
|
24
|
+
|
25
|
+
# able to join safe and unsafe strings
|
26
|
+
#------------------------------------------------------------------------------
|
27
|
+
def xss_aware_join(delimiter = '')
|
28
|
+
''.html_safe.tap do |str|
|
29
|
+
each_with_index do |element, i|
|
30
|
+
str << delimiter if i > 0
|
31
|
+
str << element
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# given an array of css classes/styles, join them into one string.
|
37
|
+
# only join non-nil/non-empty strings, and return nil if the result
|
38
|
+
# is an empty string (rails tag methods will not include the
|
39
|
+
# attribute if it is nil, which is desirable for cleaner html)
|
40
|
+
#------------------------------------------------------------------------------
|
41
|
+
def css_join(delimiter = '')
|
42
|
+
str = self.flatten.delete_if {|x| x.nil? || x == ''}.join(' ')
|
43
|
+
str == '' ? nil : str
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Date
|
2
|
+
|
3
|
+
# http://stackoverflow.com/questions/819263/get-persons-age-in-ruby
|
4
|
+
#------------------------------------------------------------------------------
|
5
|
+
def to_age
|
6
|
+
now = Time.now.utc.to_date
|
7
|
+
now.year - self.year - ((now.month > self.month || (now.month == self.month && now.day >= self.day)) ? 0 : 1)
|
8
|
+
end
|
9
|
+
|
10
|
+
#------------------------------------------------------------------------------
|
11
|
+
def localize(options = {})
|
12
|
+
options = {:format => options} if options.class == String
|
13
|
+
I18n.localize(self, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create a unique sortable index for this date
|
17
|
+
#------------------------------------------------------------------------------
|
18
|
+
def to_index
|
19
|
+
yday + (year-2000) * 1000
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
class DateTime
|
3
|
+
|
4
|
+
#------------------------------------------------------------------------------
|
5
|
+
def to_age
|
6
|
+
(DateTime.now - self).to_i / 365
|
7
|
+
end
|
8
|
+
|
9
|
+
#------------------------------------------------------------------------------
|
10
|
+
def localize(options = {})
|
11
|
+
options = {:format => options} if options.class == String
|
12
|
+
I18n.localize(self, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a unique sortable index for this date
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
def to_index
|
18
|
+
yday + (year-2000) * 1000
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Fixnum
|
2
|
+
|
3
|
+
# Factorial of number
|
4
|
+
# 5.factorial == 5 x 4 x 3 x 2 x 1 == 120
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
def factorial
|
7
|
+
return 1 if self.zero?
|
8
|
+
(1..self).inject(:*)
|
9
|
+
end
|
10
|
+
|
11
|
+
#------------------------------------------------------------------------------
|
12
|
+
def as_boolean
|
13
|
+
(self > 0) ? true : false
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
class Hash
|
3
|
+
|
4
|
+
# takes a Hash (like the params hash), and converts the Rails date attributes
|
5
|
+
# to a real Date object.
|
6
|
+
# {'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23}.convert_date(:start_date)
|
7
|
+
#------------------------------------------------------------------------------
|
8
|
+
def convert_date(date_symbol_or_string)
|
9
|
+
attribute = date_symbol_or_string.to_s
|
10
|
+
return nil if self[attribute + '(1i)'].nil? || self[attribute + '(2i)'].nil? || self[attribute + '(3i)'].nil?
|
11
|
+
return Date.new(self[attribute + '(1i)'].to_i, self[attribute + '(2i)'].to_i, self[attribute + '(3i)'].to_i)
|
12
|
+
end
|
13
|
+
|
14
|
+
# takes a Hash (like the params hash), and converts the Rails datetime attributes
|
15
|
+
# to a real Date object.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
def convert_datetime(date_symbol_or_string)
|
18
|
+
attribute = date_symbol_or_string.to_s
|
19
|
+
return nil if self[attribute + '(1i)'].nil? || self[attribute + '(2i)'].nil? || self[attribute + '(3i)'].nil? || self[attribute + '(4i)'].nil? || self[attribute + '(5i)'].nil?
|
20
|
+
return Time.local(self[attribute + '(1i)'].to_i, self[attribute + '(2i)'].to_i, self[attribute + '(3i)'].to_i, self[attribute + '(4i)'].to_i, self[attribute + '(5i)'].to_i)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Convert hash of parameters to a query string
|
24
|
+
#------------------------------------------------------------------------------
|
25
|
+
def url_query_string(leading_slash = true)
|
26
|
+
(leading_slash ? "/?" : "?") << URI.escape(self.collect{|k,v| "#{k}=#{v}"}.join('&'))
|
27
|
+
end
|
28
|
+
|
29
|
+
# Borrowed from https://github.com/rubyworks/facets
|
30
|
+
#------------------------------------------------------------------------------
|
31
|
+
# Rekey a hash:
|
32
|
+
#
|
33
|
+
# rekey()
|
34
|
+
# rekey(from_key => to_key, ...)
|
35
|
+
# rekey{|from_key| to_key}
|
36
|
+
# rekey{|from_key, value| to_key}
|
37
|
+
#
|
38
|
+
# If a key map is given, then the first key is changed to the second key.
|
39
|
+
#
|
40
|
+
# foo = { :a=>1, :b=>2 }
|
41
|
+
# foo.rekey(:a=>'a') #=> { 'a'=>1, :b=>2 }
|
42
|
+
# foo.rekey(:b=>:x) #=> { :a =>1, :x=>2 }
|
43
|
+
# foo.rekey('foo'=>'bar') #=> { :a =>1, :b=>2 }
|
44
|
+
#
|
45
|
+
# If a block is given, converts all keys in the Hash accroding to the
|
46
|
+
# given block procedure.
|
47
|
+
#
|
48
|
+
# foo = { :name=>'Gavin', :wife=>:Lisa }
|
49
|
+
# foo.rekey{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
|
50
|
+
# foo #=> { :name =>"Gavin", :wife=>:Lisa }
|
51
|
+
#
|
52
|
+
# If no key map or block is given, then all keys are converted
|
53
|
+
# to Symbols.
|
54
|
+
#
|
55
|
+
# Raises an ArgumentError if both a +key_map+ and a block are given.
|
56
|
+
# If both are needed just call #rekey twice.
|
57
|
+
#
|
58
|
+
# TODO: If `nil` is returned by block should the key be set to `nil` or the orignal key?
|
59
|
+
#
|
60
|
+
# CREDIT: Trans, Gavin Kistner
|
61
|
+
|
62
|
+
def rekey(key_map=nil, &block)
|
63
|
+
raise ArgumentError, "argument or block" if key_map && block
|
64
|
+
|
65
|
+
if !(key_map or block)
|
66
|
+
block = lambda{|k| k.to_sym}
|
67
|
+
end
|
68
|
+
|
69
|
+
if block
|
70
|
+
hash = dup.clear
|
71
|
+
if block.arity.abs == 1
|
72
|
+
each_pair do |k, v|
|
73
|
+
hash[block[k]] = v #hash[block[k] || k] = v
|
74
|
+
end
|
75
|
+
else
|
76
|
+
each_pair do |k, v|
|
77
|
+
hash[block[k,v]] = v #hash[block[k,v] || k] = v
|
78
|
+
end
|
79
|
+
end
|
80
|
+
else
|
81
|
+
#hash = dup.clear # to keep default_proc
|
82
|
+
#(keys - key_map.keys).each do |key|
|
83
|
+
# hash[key] = self[key]
|
84
|
+
#end
|
85
|
+
#key_map.each do |from, to|
|
86
|
+
# hash[to] = self[from] if key?(from)
|
87
|
+
#end
|
88
|
+
hash = dup # to keep default_proc
|
89
|
+
key_map.each_pair do |from, to|
|
90
|
+
hash[to] = hash.delete(from) if hash.key?(from)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
hash
|
95
|
+
end
|
96
|
+
|
97
|
+
# Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
|
98
|
+
#
|
99
|
+
# foo = { :name=>'Gavin', :wife=>:Lisa }
|
100
|
+
# foo.rekey!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
|
101
|
+
# foo #=> { "name"=>"Gavin", "wife"=>:Lisa }
|
102
|
+
#
|
103
|
+
# CREDIT: Trans, Gavin Kistner
|
104
|
+
|
105
|
+
def rekey!(key_map=nil, &block)
|
106
|
+
replace(rekey(key_map, &block))
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# If nil, then return a default string
|
2
|
+
#------------------------------------------------------------------------------
|
3
|
+
class NilClass #:nodoc:
|
4
|
+
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
def to_s_default(default_str = 'n/a')
|
7
|
+
default_str
|
8
|
+
end
|
9
|
+
|
10
|
+
#------------------------------------------------------------------------------
|
11
|
+
def as_boolean
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
def to_age
|
17
|
+
0
|
18
|
+
end
|
19
|
+
|
20
|
+
#------------------------------------------------------------------------------
|
21
|
+
def sql_wildcard
|
22
|
+
"%"
|
23
|
+
end
|
24
|
+
|
25
|
+
#------------------------------------------------------------------------------
|
26
|
+
def utc
|
27
|
+
""
|
28
|
+
end
|
29
|
+
|
30
|
+
# if nil + something, just return something
|
31
|
+
#------------------------------------------------------------------------------
|
32
|
+
def +(y)
|
33
|
+
y
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# If the string is empty, then return a default string
|
2
|
+
#------------------------------------------------------------------------------
|
3
|
+
class String #:nodoc:
|
4
|
+
|
5
|
+
# If the string is empty, return a default value, otherwise the string
|
6
|
+
#------------------------------------------------------------------------------
|
7
|
+
def to_s_default(default_str = 'n/a')
|
8
|
+
(empty? || strip.empty?) ? default_str : self.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
#------------------------------------------------------------------------------
|
12
|
+
def as_boolean
|
13
|
+
(self == 'true' || self == 'yes' || self == '1') ? true : false
|
14
|
+
end
|
15
|
+
|
16
|
+
# given a css type of size (like a width), make it into a valid css value
|
17
|
+
#------------------------------------------------------------------------------
|
18
|
+
def as_css_size
|
19
|
+
size = self
|
20
|
+
size += 'px' unless size.blank? || size.end_with?('px', '%', 'em') || size == 'auto' || size == 'inherit'
|
21
|
+
return size
|
22
|
+
end
|
23
|
+
|
24
|
+
# Adds SQL wildcard cahracters to begin/end of string for use in LIKE statements
|
25
|
+
#------------------------------------------------------------------------------
|
26
|
+
def sql_wildcard
|
27
|
+
"%#{self}%"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Replace non-alphanumbic character
|
31
|
+
#------------------------------------------------------------------------------
|
32
|
+
def replace_non_alphanumeric(replacement = '')
|
33
|
+
self.gsub /[^\w\.\-]/, replacement
|
34
|
+
end
|
35
|
+
|
36
|
+
# Santize the string
|
37
|
+
# Note: File.basename doesn't work right with Windows paths on Unix
|
38
|
+
#------------------------------------------------------------------------------
|
39
|
+
def sanitize_filename
|
40
|
+
name = self.strip
|
41
|
+
#--- get only the filename, not the whole path
|
42
|
+
name.gsub! /^.*(\\|\/)/, ''
|
43
|
+
|
44
|
+
#--- Finally, replace all non alphanumeric, underscore or periods with underscore
|
45
|
+
name.gsub! /[^\w\.\-]/, '_'
|
46
|
+
return name
|
47
|
+
end
|
48
|
+
|
49
|
+
# if a relative url path is given, then expand it by prepending the supplied
|
50
|
+
# path.
|
51
|
+
#------------------------------------------------------------------------------
|
52
|
+
def expand_url(path = '')
|
53
|
+
if self.blank? || self.absolute_url?
|
54
|
+
return self
|
55
|
+
else
|
56
|
+
return path + self
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Test if a url is absolute
|
61
|
+
#------------------------------------------------------------------------------
|
62
|
+
def absolute_url?
|
63
|
+
(self.include?('://') || self.start_with?('/')) ? true : false
|
64
|
+
end
|
65
|
+
|
66
|
+
#------------------------------------------------------------------------------
|
67
|
+
|
68
|
+
# Ruby version of John Gruber's TitleCase.pl, from http://github.com/samsouder/titlecase
|
69
|
+
# Used for better capitalizing titles and sentences
|
70
|
+
#------------------------------------------------------------------------------
|
71
|
+
def smart_titlecase
|
72
|
+
small_words = %w(a an and as at but by en for if in of on or the to v v. via vs vs. von)
|
73
|
+
|
74
|
+
x = split(" ").map do |word|
|
75
|
+
# note: word could contain non-word characters!
|
76
|
+
# downcase all small_words, capitalize the rest
|
77
|
+
small_words.include?(word.gsub(/\W/, "").downcase) ? word.downcase! : word.smart_capitalize!
|
78
|
+
word
|
79
|
+
end
|
80
|
+
# capitalize first and last words
|
81
|
+
x.first.smart_capitalize!
|
82
|
+
x.last.smart_capitalize!
|
83
|
+
# small words after colons are capitalized
|
84
|
+
x.join(" ").gsub(/:\s?(\W*#{small_words.join("|")}\W*)\s/) { ": #{$1.smart_capitalize} " }
|
85
|
+
end
|
86
|
+
|
87
|
+
#------------------------------------------------------------------------------
|
88
|
+
def smart_capitalize
|
89
|
+
# ignore any leading crazy characters and capitalize the first real character
|
90
|
+
if self =~ /^['"\(\[']*([a-z])/
|
91
|
+
i = index($1)
|
92
|
+
x = self[i,self.length]
|
93
|
+
# word with capitals and periods mid-word are left alone
|
94
|
+
self[i,1] = self[i,1].upcase unless x =~ /[A-Z]/ or x =~ /\.\w+/
|
95
|
+
end
|
96
|
+
self
|
97
|
+
end
|
98
|
+
|
99
|
+
#------------------------------------------------------------------------------
|
100
|
+
def smart_capitalize!
|
101
|
+
replace(smart_capitalize)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Truncate the string to a set or words, or sentences.
|
105
|
+
# string.smart_truncate(:sentences => 3)
|
106
|
+
# string.smart_truncate(:words => 12)
|
107
|
+
# From http://stackoverflow.com/questions/1293573/rails-smart-text-truncation
|
108
|
+
#------------------------------------------------------------------------------
|
109
|
+
def smart_truncate(opts = {})
|
110
|
+
opts = {:words => 12}.merge(opts)
|
111
|
+
if opts[:sentences]
|
112
|
+
return self.split(/\.(\s|$)+/).reject{ |s| s.strip.empty? }[0, opts[:sentences]].map{|s| s.strip}.join('. ') + '...'
|
113
|
+
end
|
114
|
+
a = self.split(/\s/) # or /[ ]+/ to only split on spaces
|
115
|
+
n = opts[:words]
|
116
|
+
a[0...n].join(' ') + (a.size > n ? '...' : '')
|
117
|
+
end
|
118
|
+
#------------------------------------------------------------------------------
|
119
|
+
|
120
|
+
# http://github.com/tenderlove/namecase
|
121
|
+
# NameCase is a Ruby implementation of Lingua::EN::NameCase, a library for
|
122
|
+
# converting strings/names to be properly cased. This is good for converting
|
123
|
+
# denormalized data to human friendly data.
|
124
|
+
#------------------------------------------------------------------------------
|
125
|
+
def name_case(options = {})
|
126
|
+
options = { :lazy => true, :irish => true }.merge options
|
127
|
+
|
128
|
+
# Skip if string is mixed case
|
129
|
+
if options[:lazy]
|
130
|
+
first_letter_lower = self[0] == self.downcase[0]
|
131
|
+
all_lower_or_upper = (self.downcase == self || self.upcase == self)
|
132
|
+
|
133
|
+
return self unless first_letter_lower || all_lower_or_upper
|
134
|
+
end
|
135
|
+
|
136
|
+
localstring = downcase
|
137
|
+
localstring.gsub!(/\b\w/) { |first| first.upcase }
|
138
|
+
localstring.gsub!(/\'\w\b/) { |c| c.downcase } # Lowercase 's
|
139
|
+
|
140
|
+
if options[:irish]
|
141
|
+
if localstring =~ /\bMac[A-Za-z]{2,}[^aciozj]\b/ or localstring =~ /\bMc/
|
142
|
+
match = localstring.match(/\b(Ma?c)([A-Za-z]+)/)
|
143
|
+
localstring.gsub!(/\bMa?c[A-Za-z]+/) { match[1] + match[2].capitalize }
|
144
|
+
|
145
|
+
# Now fix "Mac" exceptions
|
146
|
+
localstring.gsub!(/\bMacEdo/, 'Macedo')
|
147
|
+
localstring.gsub!(/\bMacEvicius/, 'Macevicius')
|
148
|
+
localstring.gsub!(/\bMacHado/, 'Machado')
|
149
|
+
localstring.gsub!(/\bMacHar/, 'Machar')
|
150
|
+
localstring.gsub!(/\bMacHin/, 'Machin')
|
151
|
+
localstring.gsub!(/\bMacHlin/, 'Machlin')
|
152
|
+
localstring.gsub!(/\bMacIas/, 'Macias')
|
153
|
+
localstring.gsub!(/\bMacIulis/, 'Maciulis')
|
154
|
+
localstring.gsub!(/\bMacKie/, 'Mackie')
|
155
|
+
localstring.gsub!(/\bMacKle/, 'Mackle')
|
156
|
+
localstring.gsub!(/\bMacKlin/, 'Macklin')
|
157
|
+
localstring.gsub!(/\bMacKmin/, 'Mackmin')
|
158
|
+
localstring.gsub!(/\bMacQuarie/, 'Macquarie')
|
159
|
+
end
|
160
|
+
localstring.gsub!('Macmurdo','MacMurdo')
|
161
|
+
end
|
162
|
+
|
163
|
+
# Fixes for "son (daughter) of" etc
|
164
|
+
localstring.gsub!(/\bAl(?=\s+\w)/, 'al') # al Arabic or forename Al.
|
165
|
+
localstring.gsub!(/\bAp\b/, 'ap') # ap Welsh.
|
166
|
+
localstring.gsub!(/\bBen(?=\s+\w)/,'ben') # ben Hebrew or forename Ben.
|
167
|
+
localstring.gsub!(/\bDell([ae])\b/,'dell\1') # della and delle Italian.
|
168
|
+
localstring.gsub!(/\bD([aeiou])\b/,'d\1') # da, de, di Italian; du French; do Brasil
|
169
|
+
localstring.gsub!(/\bD([ao]s)\b/,'d\1') # das, dos Brasileiros
|
170
|
+
localstring.gsub!(/\bDe([lr])\b/,'de\1') # del Italian; der Dutch/Flemish.
|
171
|
+
localstring.gsub!(/\bEl\b/,'el') # el Greek or El Spanish.
|
172
|
+
localstring.gsub!(/\bLa\b/,'la') # la French or La Spanish.
|
173
|
+
localstring.gsub!(/\bL([eo])\b/,'l\1') # lo Italian; le French.
|
174
|
+
localstring.gsub!(/\bVan(?=\s+\w)/,'van') # van German or forename Van.
|
175
|
+
localstring.gsub!(/\bVon\b/,'von') # von Dutch/Flemish
|
176
|
+
|
177
|
+
# Fix roman numeral names
|
178
|
+
localstring.gsub!(
|
179
|
+
/ \b ( (?: [Xx]{1,3} | [Xx][Ll] | [Ll][Xx]{0,3} )?
|
180
|
+
(?: [Ii]{1,3} | [Ii][VvXx] | [Vv][Ii]{0,3} )? ) \b /x
|
181
|
+
) { |match| match.upcase }
|
182
|
+
|
183
|
+
localstring
|
184
|
+
end
|
185
|
+
|
186
|
+
# Modifies _str_ in place and properly namecases the string.
|
187
|
+
#------------------------------------------------------------------------------
|
188
|
+
def name_case!
|
189
|
+
self.gsub!(self, self.name_case)
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
class Time
|
3
|
+
|
4
|
+
#------------------------------------------------------------------------------
|
5
|
+
def localize(options = {})
|
6
|
+
options = {:format => options} if options.class == String
|
7
|
+
I18n.localize(self, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe Array do
|
5
|
+
|
6
|
+
describe 'closest_max' do
|
7
|
+
#------------------------------------------------------------------------------
|
8
|
+
it 'return the value that is closest to the value in the array, rounded down' do
|
9
|
+
expect([0,5,7,8,11,16].closest_max(6)).to eq 5
|
10
|
+
expect([0,5,7,8,11,16].closest_max(7)).to eq 7
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'extract_options!' do
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
it "Removes and returns the last element in the array if it's a hash, otherwise returns a blank hash" do
|
17
|
+
args = [1, 2, {:a => :b}]
|
18
|
+
expect(args.extract_options!).to eq ({:a => :b})
|
19
|
+
expect(args).to eq [1, 2]
|
20
|
+
expect(args.extract_options!).to eq ({})
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'xss_aware_join' do
|
25
|
+
it 'safely join safe and unsafe strings' do
|
26
|
+
safe = "<p>Safe</p>".html_safe
|
27
|
+
unsafe = "<script></script>"
|
28
|
+
expect([safe, unsafe].xss_aware_join).to eq "<p>Safe</p><script></script>"
|
29
|
+
expect([safe, unsafe].xss_aware_join.class).to eq ActiveSupport::SafeBuffer
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'css_join' do
|
34
|
+
it 'given an array of css classes/styles, join them into one string' do
|
35
|
+
classes = ['panel', '', 'panel-body', nil, 'red']
|
36
|
+
expect(classes.css_join(' ')).to eq 'panel panel-body red'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe Date do
|
5
|
+
|
6
|
+
describe 'to_age' do
|
7
|
+
it 'return number of years since now', pending: 'not sure how to test' do
|
8
|
+
expect(Date.new(1967, 1, 23).to_age).to eq 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'localize' do
|
13
|
+
it 'localize the date based on the format' do
|
14
|
+
I18n.enforce_available_locales = false
|
15
|
+
I18n.locale = :en
|
16
|
+
date = Date.new(2012, 11, 23)
|
17
|
+
expect(date.localize).to eq '2012-11-23'
|
18
|
+
expect(date.localize(format: :short)).to eq 'Nov 23'
|
19
|
+
expect(date.localize('%b %Y')).to eq 'Nov 2012'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'to_index' do
|
24
|
+
it 'creates unique sortable index for a date' do
|
25
|
+
date = Date.new(2012, 11, 23)
|
26
|
+
expect(date.to_index).to eq 12328
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe DateTime do
|
5
|
+
|
6
|
+
describe 'to_age' do
|
7
|
+
it 'return number of years since now', pending: 'not sure how to test' do
|
8
|
+
expect(DateTime.new(1967, 1, 23).to_age).to eq 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'localize' do
|
13
|
+
it 'localize the date based on the format' do
|
14
|
+
I18n.enforce_available_locales = false
|
15
|
+
I18n.locale = :en
|
16
|
+
date = DateTime.new(2012, 11, 23, 8, 35)
|
17
|
+
expect(date.localize).to eq 'Fri, 23 Nov 2012 08:35:00 +0000'
|
18
|
+
expect(date.localize(format: :short)).to eq '23 Nov 08:35'
|
19
|
+
expect(date.localize('%b %Y')).to eq 'Nov 2012'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'to_index' do
|
24
|
+
it 'creates unique sortable index for a date' do
|
25
|
+
date = Date.new(2012, 11, 23)
|
26
|
+
expect(date.to_index).to eq 12328
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe Fixnum do
|
5
|
+
|
6
|
+
describe 'factorial' do
|
7
|
+
#------------------------------------------------------------------------------
|
8
|
+
it 'return the factorial of the number' do
|
9
|
+
expect(5.factorial).to eq 120
|
10
|
+
expect(1.factorial).to eq 1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'as_boolean' do
|
15
|
+
specify { expect(1.as_boolean).to be_truthy }
|
16
|
+
specify { expect(0.as_boolean).to be_falsey }
|
17
|
+
specify { expect(20.as_boolean).to be_truthy }
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe Hash do
|
5
|
+
|
6
|
+
describe 'convert_date' do
|
7
|
+
#------------------------------------------------------------------------------
|
8
|
+
it 'converts a rails date hash' do
|
9
|
+
datehash = {'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23}
|
10
|
+
expect(datehash.convert_date(:start_date)).to eq Date.new(2012, 11, 23)
|
11
|
+
expect(datehash.convert_date(:end_date)).to eq nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'convert_datetime' do
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
it 'converts a rails datetime hash' do
|
18
|
+
datehash = {'start_date(1i)' => 2012, 'start_date(2i)' => 11, 'start_date(3i)' => 23, 'start_date(4i)' => 8, 'start_date(5i)' => 35}
|
19
|
+
expect(datehash.convert_datetime(:start_date)).to eq Time.local(2012, 11, 23, 8, 35)
|
20
|
+
expect(datehash.convert_datetime(:end_date)).to eq nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'url_query_string' do
|
25
|
+
#------------------------------------------------------------------------------
|
26
|
+
it 'converts hash of parameters to a query string' do
|
27
|
+
params = {tag: 'shoe', as_admin: '1'}
|
28
|
+
expect(params.url_query_string).to eq '/?tag=shoe&as_admin=1'
|
29
|
+
expect(params.url_query_string(false)).to eq '?tag=shoe&as_admin=1'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'rekey' do
|
34
|
+
#------------------------------------------------------------------------------
|
35
|
+
it 'if a key map is given, then the first key is changed to the second key.' do
|
36
|
+
foo = { :a => 1, :b => 2 }
|
37
|
+
expect(foo.rekey(:a=>'a')).to eq({ 'a' => 1, :b => 2 })
|
38
|
+
expect(foo.rekey(:b=>:x)).to eq({ :a => 1, :x => 2 })
|
39
|
+
expect(foo.rekey('foo'=>'bar')).to eq({ :a => 1, :b => 2 })
|
40
|
+
end
|
41
|
+
|
42
|
+
#------------------------------------------------------------------------------
|
43
|
+
it 'converts all keys in the Hash accroding to the given block procedure' do
|
44
|
+
foo = { :name=>'Gavin', :wife=>:Lisa }
|
45
|
+
expect(foo.rekey{ |k| k.to_s }).to eq({ "name" => "Gavin", "wife" => :Lisa })
|
46
|
+
end
|
47
|
+
|
48
|
+
#------------------------------------------------------------------------------
|
49
|
+
it 'converts all keys to symbols' do
|
50
|
+
foo = { 'name' => 'Gavin', 'wife' => :Lisa }
|
51
|
+
expect(foo.rekey).to eq({ :name => "Gavin", :wife => :Lisa })
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe NilClass do
|
5
|
+
|
6
|
+
describe 'to_s_default' do
|
7
|
+
it 'returns default string' do
|
8
|
+
expect(nil.to_s_default).to eq 'n/a'
|
9
|
+
expect(nil.to_s_default('--')).to eq '--'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'as_boolean' do
|
14
|
+
specify { expect(nil.as_boolean).to eq false }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'to_age' do
|
18
|
+
specify { expect(nil.to_age).to eq 0}
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'sql_wildcard' do
|
22
|
+
specify { expect(nil.sql_wildcard).to eq '%' }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'utc' do
|
26
|
+
specify { expect(nil.utc).to eq '' }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '+(y)' do
|
30
|
+
specify { expect(nil + 12).to eq 12 }
|
31
|
+
specify { expect(nil + 'foo').to eq 'foo' }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe Numeric do
|
5
|
+
|
6
|
+
describe 'percent_of' do
|
7
|
+
it 'returns percentage of number' do
|
8
|
+
expect(25.percent_of(100)).to eq 25
|
9
|
+
expect(25.percent_of(80)).to eq 31
|
10
|
+
expect(25.percent_of(80, 2)).to eq 31.25
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe String do
|
5
|
+
|
6
|
+
describe 'to_s_default' do
|
7
|
+
specify { expect('foobar'.to_s_default).to eq 'foobar'}
|
8
|
+
specify { expect(''.to_s_default).to eq 'n/a'}
|
9
|
+
specify { expect(''.to_s_default('--')).to eq '--'}
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'as_boolean' do
|
13
|
+
specify { expect('true'.as_boolean).to be_truthy }
|
14
|
+
specify { expect('yes'.as_boolean).to be_truthy }
|
15
|
+
specify { expect('1'.as_boolean).to be_truthy }
|
16
|
+
specify { expect('false'.as_boolean).to be_falsey }
|
17
|
+
specify { expect('foo'.as_boolean).to be_falsey }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'as_css_size' do
|
21
|
+
specify { expect('50'.as_css_size).to eq '50px'}
|
22
|
+
specify { expect(''.as_css_size).to eq ''}
|
23
|
+
specify { expect('50px'.as_css_size).to eq '50px'}
|
24
|
+
specify { expect('50%'.as_css_size).to eq '50%'}
|
25
|
+
specify { expect('50em'.as_css_size).to eq '50em'}
|
26
|
+
specify { expect('auto'.as_css_size).to eq 'auto'}
|
27
|
+
specify { expect('inherit'.as_css_size).to eq 'inherit'}
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'sql_wildcard' do
|
31
|
+
specify { expect('foobar'.sql_wildcard).to eq '%foobar%'}
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'replace_non_alphanumeric' do
|
35
|
+
specify { expect('fo9o^()b ar'.replace_non_alphanumeric).to eq 'fo9obar' }
|
36
|
+
specify { expect('fo9o^()b ar'.replace_non_alphanumeric('*')).to eq 'fo9o***b**ar' }
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'sanitize_filename' do
|
40
|
+
specify { expect('foobar.doc'.sanitize_filename).to eq 'foobar.doc'}
|
41
|
+
specify { expect('/user/home/foobar.doc'.sanitize_filename).to eq 'foobar.doc'}
|
42
|
+
specify { expect('/user/home/f9o o(b+a^r.d*c'.sanitize_filename).to eq 'f9o_o_b_a_r.d_c'}
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'expand_url' do
|
46
|
+
specify { expect('/home/foobar.doc'.expand_url).to eq '/home/foobar.doc' }
|
47
|
+
specify { expect('foobar.doc'.expand_url).to eq 'foobar.doc' }
|
48
|
+
specify { expect('foobar.doc'.expand_url('/home/')).to eq '/home/foobar.doc' }
|
49
|
+
specify { expect('/foobar.doc'.expand_url('/home/')).to eq '/foobar.doc' }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'absolute_url?' do
|
53
|
+
specify { expect('/home/foo'.absolute_url?).to be_truthy }
|
54
|
+
specify { expect('://home/foo'.absolute_url?).to be_truthy }
|
55
|
+
specify { expect('home/foo'.absolute_url?).to be_falsey }
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'smart_titlecase' do
|
59
|
+
specify { expect('a sample title and text: a treatsie'.smart_titlecase).to eq 'A Sample Title and Text: A Treatsie'}
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'smart_capitalize' do
|
63
|
+
specify { expect('foobar'.smart_capitalize).to eq 'Foobar' }
|
64
|
+
specify { expect('fooBar'.smart_capitalize).to eq 'fooBar' }
|
65
|
+
specify { expect('(foobar)'.smart_capitalize).to eq '(Foobar)' }
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'smart_truncate' do
|
69
|
+
specify { expect('One time. Two times. 3 times. 4 times.'.smart_truncate(sentences: 3)).to eq 'One time. Two times. 3 times...' }
|
70
|
+
specify { expect('one two three and four five six and seven and yet another eight'.smart_truncate(words: 6)).to eq 'one two three and four five...' }
|
71
|
+
specify { expect('one two three and four five six and seven and yet another eight'.smart_truncate).to eq 'one two three and four five six and seven and yet another...' }
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'name_case' do
|
75
|
+
before :each do
|
76
|
+
@proper_names = [
|
77
|
+
"Keith", "Leigh-Williams", "McCarthy",
|
78
|
+
"O'Callaghan", "St. John", "von Streit",
|
79
|
+
"van Dyke", "Van", "ap Llwyd Dafydd",
|
80
|
+
"al Fahd", "Al",
|
81
|
+
"el Grecco",
|
82
|
+
"ben Gurion", "Ben",
|
83
|
+
"da Vinci",
|
84
|
+
"di Caprio", "du Pont", "de Legate",
|
85
|
+
"del Crond", "der Sind", "van der Post",
|
86
|
+
"von Trapp", "la Poisson", "le Figaro",
|
87
|
+
"Mack Knife", "Dougal MacDonald",
|
88
|
+
# Mac exceptions
|
89
|
+
"Machin", "Machlin", "Machar",
|
90
|
+
"Mackle", "Macklin", "Mackie",
|
91
|
+
"Macquarie", "Machado", "Macevicius",
|
92
|
+
"Maciulis", "Macias", "MacMurdo",
|
93
|
+
# Roman numerals
|
94
|
+
"Henry VIII", "Louis III", "Louis XIV",
|
95
|
+
"Charles II", "Fred XLIX",
|
96
|
+
]
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'handles each proper name' do
|
100
|
+
@proper_names.each do |name|
|
101
|
+
expect(name.downcase.name_case).to eq name
|
102
|
+
expect(name.name_case).to eq name
|
103
|
+
# assert_equal(name, NameCase(name))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'handles multibyte' do
|
108
|
+
proper_cased = 'Iñtërnâtiônàlizætiøn'
|
109
|
+
expect(proper_cased.downcase.name_case).to eq proper_cased
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm_ruby_extensions'
|
3
|
+
|
4
|
+
describe Time do
|
5
|
+
|
6
|
+
describe 'localize' do
|
7
|
+
it 'localize the date based on the format' do
|
8
|
+
I18n.enforce_available_locales = false
|
9
|
+
I18n.locale = :en
|
10
|
+
time = Time.parse("2012-11-23 08:35 utc")
|
11
|
+
expect(time.localize).to eq 'Fri, 23 Nov 2012 08:35:00 +0000'
|
12
|
+
expect(time.localize(format: :short)).to eq '23 Nov 08:35'
|
13
|
+
expect(time.localize('%b %Y')).to eq 'Nov 2012'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# This file was generated by the `rails generate rspec:install` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause this
|
4
|
+
# file to always be loaded, without a need to explicitly require it in any files.
|
5
|
+
#
|
6
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
7
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
8
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
9
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
10
|
+
# a separate helper file that requires the additional dependencies and performs
|
11
|
+
# the additional setup, and require it from the spec files that actually need it.
|
12
|
+
#
|
13
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
14
|
+
# users commonly want.
|
15
|
+
#
|
16
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
17
|
+
RSpec.configure do |config|
|
18
|
+
# rspec-expectations config goes here. You can use an alternate
|
19
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
20
|
+
# assertions if you prefer.
|
21
|
+
config.expect_with :rspec do |expectations|
|
22
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
23
|
+
# and `failure_message` of custom matchers include text for helper methods
|
24
|
+
# defined using `chain`, e.g.:
|
25
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
26
|
+
# # => "be bigger than 2 and smaller than 4"
|
27
|
+
# ...rather than:
|
28
|
+
# # => "be bigger than 2"
|
29
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
30
|
+
end
|
31
|
+
|
32
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
33
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
34
|
+
config.mock_with :rspec do |mocks|
|
35
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
36
|
+
# a real object. This is generally recommended, and will default to
|
37
|
+
# `true` in RSpec 4.
|
38
|
+
mocks.verify_partial_doubles = true
|
39
|
+
end
|
40
|
+
|
41
|
+
# The settings below are suggested to provide a good initial experience
|
42
|
+
# with RSpec, but feel free to customize to your heart's content.
|
43
|
+
=begin
|
44
|
+
# These two settings work together to allow you to limit a spec run
|
45
|
+
# to individual examples or groups you care about by tagging them with
|
46
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
47
|
+
# get run.
|
48
|
+
config.filter_run :focus
|
49
|
+
config.run_all_when_everything_filtered = true
|
50
|
+
|
51
|
+
# Limits the available syntax to the non-monkey patched syntax that is recommended.
|
52
|
+
# For more details, see:
|
53
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
54
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
55
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
56
|
+
config.disable_monkey_patching!
|
57
|
+
|
58
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
59
|
+
# file, and it's useful to allow more verbose output when running an
|
60
|
+
# individual spec file.
|
61
|
+
if config.files_to_run.one?
|
62
|
+
# Use the documentation formatter for detailed output,
|
63
|
+
# unless a formatter has already been configured
|
64
|
+
# (e.g. via a command-line flag).
|
65
|
+
config.default_formatter = 'doc'
|
66
|
+
end
|
67
|
+
|
68
|
+
# Print the 10 slowest examples and example groups at the
|
69
|
+
# end of the spec run, to help surface which specs are running
|
70
|
+
# particularly slow.
|
71
|
+
config.profile_examples = 10
|
72
|
+
|
73
|
+
# Run specs in random order to surface order dependencies. If you find an
|
74
|
+
# order dependency and want to debug it, you can fix the order by providing
|
75
|
+
# the seed, which is printed after each run.
|
76
|
+
# --seed 1234
|
77
|
+
config.order = :random
|
78
|
+
|
79
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
80
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
81
|
+
# test failures related to randomization by passing the same `--seed` value
|
82
|
+
# as the one that triggered the failure.
|
83
|
+
Kernel.srand config.seed
|
84
|
+
=end
|
85
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dm_ruby_extensions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brett Walker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
description: Ruby base class extensions
|
28
|
+
email:
|
29
|
+
- github@digitalmoksha.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".gitignore"
|
35
|
+
- ".rspec"
|
36
|
+
- Gemfile
|
37
|
+
- LICENSE
|
38
|
+
- README.md
|
39
|
+
- Rakefile
|
40
|
+
- dm_ruby_extensions.gemspec
|
41
|
+
- lib/dm_ruby_extensions.rb
|
42
|
+
- lib/dm_ruby_extensions/extend_array.rb
|
43
|
+
- lib/dm_ruby_extensions/extend_date.rb
|
44
|
+
- lib/dm_ruby_extensions/extend_datetime.rb
|
45
|
+
- lib/dm_ruby_extensions/extend_fixnum.rb
|
46
|
+
- lib/dm_ruby_extensions/extend_hash.rb
|
47
|
+
- lib/dm_ruby_extensions/extend_nil.rb
|
48
|
+
- lib/dm_ruby_extensions/extend_numeric.rb
|
49
|
+
- lib/dm_ruby_extensions/extend_string.rb
|
50
|
+
- lib/dm_ruby_extensions/extend_time.rb
|
51
|
+
- lib/dm_ruby_extensions/version.rb
|
52
|
+
- spec/extensions/array_spec.rb
|
53
|
+
- spec/extensions/date_spec.rb
|
54
|
+
- spec/extensions/datetime_spec.rb
|
55
|
+
- spec/extensions/fixnum_spec.rb
|
56
|
+
- spec/extensions/hash_spec.rb
|
57
|
+
- spec/extensions/nil_spec.rb
|
58
|
+
- spec/extensions/numeric_spec.rb
|
59
|
+
- spec/extensions/string_spec.rb
|
60
|
+
- spec/extensions/time_spec.rb
|
61
|
+
- spec/spec_helper.rb
|
62
|
+
homepage: https://github.com/digitalmoksha/dm_ruby_extensions
|
63
|
+
licenses:
|
64
|
+
- MIT
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 2.4.5
|
83
|
+
signing_key:
|
84
|
+
specification_version: 4
|
85
|
+
summary: Simple Ruby base class extensions
|
86
|
+
test_files:
|
87
|
+
- spec/extensions/array_spec.rb
|
88
|
+
- spec/extensions/date_spec.rb
|
89
|
+
- spec/extensions/datetime_spec.rb
|
90
|
+
- spec/extensions/fixnum_spec.rb
|
91
|
+
- spec/extensions/hash_spec.rb
|
92
|
+
- spec/extensions/nil_spec.rb
|
93
|
+
- spec/extensions/numeric_spec.rb
|
94
|
+
- spec/extensions/string_spec.rb
|
95
|
+
- spec/extensions/time_spec.rb
|
96
|
+
- spec/spec_helper.rb
|