new-age 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/NewAge.gemspec +26 -0
- data/README.markdown +39 -0
- data/Rakefile +1 -0
- data/lib/NewAge.rb +102 -0
- data/lib/NewAge/version.rb +3 -0
- data/lib/new-age.rb +1 -0
- data/spec/new_age_spec.rb +72 -0
- data/spec/rspec_helper.rb +25 -0
- data/spec/support/shared/contexts.rb +32 -0
- metadata +124 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/NewAge.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "NewAge/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "new-age"
|
7
|
+
s.version = NewAge::VERSION
|
8
|
+
s.authors = ["Iain Barnett"]
|
9
|
+
s.email = ["iainspeed@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/yb66/NewAge"
|
11
|
+
s.summary = %q{Handling the input and output of people's ages in years and months}
|
12
|
+
s.description = %q{Handling the input and output of people's ages in years and months}
|
13
|
+
|
14
|
+
s.rubyforge_project = "NewAge"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "yard"
|
24
|
+
s.add_development_dependency "reek"
|
25
|
+
s.add_development_dependency "redcarpet"
|
26
|
+
end
|
data/README.markdown
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
## Welcome to the New Age! ##
|
2
|
+
|
3
|
+
Excuse me while I light some scented candles...
|
4
|
+
|
5
|
+
Handling age as an input is pain. Should it be 12.5? 12 years? Two separate fields on a form, one for year, one for month?
|
6
|
+
|
7
|
+
puts NewAge "12y 5m" #=> "12 years 5 months"
|
8
|
+
|
9
|
+
NewAge("28").age #=> {years: 28, months: 0}
|
10
|
+
|
11
|
+
puts NewAge "9 months" #=> "0 years 9 months"
|
12
|
+
|
13
|
+
NewAge("72 y 6m").to_s #=> "72 years 6 months"
|
14
|
+
NewAge("72 y 6m").to_s( "%d YEARS" ) #=> "72 YEARS"
|
15
|
+
|
16
|
+
puts NewAge "12.5" #=> 12 years 5 months
|
17
|
+
# No, I don't think it should be 6 months.
|
18
|
+
|
19
|
+
puts NewAge "12.11" #=> 12 years 11 months
|
20
|
+
puts NewAge "12 11" #=> 12 years 11 months
|
21
|
+
puts NewAge "12-11" #=> 12 years 11 months
|
22
|
+
puts NewAge "12" #=> 12 years 0 months
|
23
|
+
puts NewAge "12 m" #=> 0 years 12 months
|
24
|
+
|
25
|
+
There's nothing but years and months as that is all I need for now. The validation is not very strict, just enough to let two numbers in that are recognised as a year and a month.
|
26
|
+
|
27
|
+
## Licence ##
|
28
|
+
|
29
|
+
This is under the MIT Licence.
|
30
|
+
|
31
|
+
Copyright (c) 2012 Iain Barnett
|
32
|
+
|
33
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
34
|
+
|
35
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
36
|
+
|
37
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
38
|
+
|
39
|
+
In other words, be good.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/NewAge.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative "./NewAge/version.rb"
|
4
|
+
|
5
|
+
# @see NewAge::Age#initialize
|
6
|
+
def NewAge( opts=nil )
|
7
|
+
NewAge::Age.new opts
|
8
|
+
end
|
9
|
+
|
10
|
+
module NewAge
|
11
|
+
|
12
|
+
module Helpers
|
13
|
+
|
14
|
+
# Pass in a string with either two numbers,
|
15
|
+
# or one number for just a year, or a number with an indicator such as "m" or "y", like so:
|
16
|
+
# "n years m months" or
|
17
|
+
# "n" for years only or
|
18
|
+
# "n m months" or
|
19
|
+
# "m months" or
|
20
|
+
# "n y m m" or
|
21
|
+
# "n yrs m mths" or something similar. It may accept things like "11 minutes" (it will think you mean 11 months) because it's not *that* concerned about being exact, so be careful.
|
22
|
+
# @example
|
23
|
+
# parse( "15 y 6 m" ) => {years: 15, months: 6}
|
24
|
+
# @param [String] s
|
25
|
+
# @return [Hash]
|
26
|
+
def parse( s )
|
27
|
+
raise ArgumentError, "Must provide a string to parse!" if s.nil? || s.empty?
|
28
|
+
age = {}
|
29
|
+
case s
|
30
|
+
when /^(\d+)$/ then
|
31
|
+
age[:years] = $1.to_i
|
32
|
+
when /^(\d+)\D+(\d+)\D*/
|
33
|
+
age[:years] = $1.to_i
|
34
|
+
age[:months] = $2.to_i
|
35
|
+
when /^(\d+)\s*m\w*$/
|
36
|
+
age[:months] = $1.to_i
|
37
|
+
else
|
38
|
+
raise ArgumentError, %q!The string wasn't in a format NewAge recognises, try `n years m months`!
|
39
|
+
end
|
40
|
+
|
41
|
+
age = {years: 0, months: 0}.merge age # to stop errors from nils
|
42
|
+
|
43
|
+
raise ArgumentError, "There are only 12 months in a year." if age[:months] >= 12
|
44
|
+
|
45
|
+
raise ArgumentError, "The longest confirmed human life span was Jeanne Calment's at 122 years, 164 days. I doubt you need more than that." if age[:years] >= 122 && age[:months] >= 7
|
46
|
+
|
47
|
+
raise ArgumentError, "I wasn't born yesterday!" if age[:years].zero? && age[:months].zero?
|
48
|
+
|
49
|
+
age
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Transform inputs into atomicised numbers for a person's age.
|
54
|
+
class Age
|
55
|
+
extend Helpers
|
56
|
+
|
57
|
+
DEFAULTS = {years: 0, months: 0}
|
58
|
+
|
59
|
+
FORMAT = "%d years %d months"
|
60
|
+
|
61
|
+
def format=( s )
|
62
|
+
@format = s
|
63
|
+
end
|
64
|
+
|
65
|
+
def format
|
66
|
+
@format ||= FORMAT
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def []( key )
|
71
|
+
@age[key]
|
72
|
+
end
|
73
|
+
|
74
|
+
def []=( key, value )
|
75
|
+
@age[key] = value
|
76
|
+
end
|
77
|
+
|
78
|
+
# @overload new( Hash )
|
79
|
+
# @param [Hash] opts Options hash
|
80
|
+
# @option opts [Integer] years
|
81
|
+
# @option opts [Integer] months
|
82
|
+
# @overload new( String )
|
83
|
+
# @param (see Helpers#parse)
|
84
|
+
# @example
|
85
|
+
# age = NewAge::Age.new( years: 5, months: 11 )
|
86
|
+
# age = NewAge::Age.new( "28" )
|
87
|
+
def initialize( opts=nil )
|
88
|
+
opts = Age.parse(opts) if opts.kind_of? String
|
89
|
+
opts ||= {}
|
90
|
+
@age = DEFAULTS.merge opts
|
91
|
+
end
|
92
|
+
|
93
|
+
attr_accessor :age
|
94
|
+
|
95
|
+
|
96
|
+
# @param [optional, String] format A sprintf format string.
|
97
|
+
def to_s( format=nil )
|
98
|
+
format ||= self.format
|
99
|
+
sprintf format, @age[:years], @age[:months]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/new-age.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "./NewAge.rb"
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative './rspec_helper.rb'
|
4
|
+
|
5
|
+
describe "Age" do
|
6
|
+
describe :parse do
|
7
|
+
context "Given valid data" do
|
8
|
+
|
9
|
+
NewAge::RSpec::Helpers.all_together.each do |input,(ymd,output)|
|
10
|
+
it "should return a hash with #{output} in it given #{input}" do
|
11
|
+
NewAge::Age.parse( input ) == {years: ymd.first, months: ymd[1]}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
context "Given invalid data" do
|
16
|
+
context "i.e. no data at all" do
|
17
|
+
context "no arguments" do
|
18
|
+
it "should probably throw a wobbly" do
|
19
|
+
expect { NewAge::Age.parse }.to raise_error(ArgumentError)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
context "nil argument" do
|
23
|
+
it "should probably throw a wobbly" do
|
24
|
+
expect { NewAge::Age.parse nil }.to raise_error(ArgumentError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
context "i.e. bad data" do
|
29
|
+
context "Silly things" do
|
30
|
+
let(:bad_data) { "Hacky sack" }
|
31
|
+
it "should probably throw a wobbly" do
|
32
|
+
expect { NewAge::Age.parse bad_data }.to raise_error(ArgumentError)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
context "Someone with no age" do
|
36
|
+
let(:bad_data) { "0y 0m" }
|
37
|
+
it "should probably throw a wobbly" do
|
38
|
+
expect { NewAge::Age.parse bad_data }.to raise_error(ArgumentError)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
context "Someone far too old to be human" do
|
42
|
+
let(:bad_data) { "123y 7m" }
|
43
|
+
it "should probably throw a wobbly" do
|
44
|
+
expect { NewAge::Age.parse bad_data }.to raise_error(ArgumentError)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
describe "to_s" do
|
52
|
+
context "Given no format" do
|
53
|
+
NewAge::RSpec::Helpers.all_together.each do |input,(ymd,output)|
|
54
|
+
it "should return an output of #{output} given #{input}" do
|
55
|
+
age = NewAge::Age.new( input )
|
56
|
+
age.to_s.should == output
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
context "Given a format" do
|
61
|
+
context " of n yrs n mths" do
|
62
|
+
NewAge::RSpec::Helpers.all_together.each do |input,(ymd,output)|
|
63
|
+
it "should return an output of #{ymd[0]} yrs #{ymd[1]} mnths given #{input}" do
|
64
|
+
age = NewAge::Age.new( input )
|
65
|
+
age.to_s( "%d yrs %d mnths" ).should == "#{ymd[0]} yrs #{ymd[1]} mnths"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require_relative "../lib/NewAge.rb"
|
5
|
+
|
6
|
+
|
7
|
+
Spec_dir = File.expand_path( File.dirname __FILE__ )
|
8
|
+
|
9
|
+
|
10
|
+
require "logger"
|
11
|
+
logger = Logger.new STDOUT
|
12
|
+
logger.level = Logger::DEBUG
|
13
|
+
logger.datetime_format = '%a %d-%m-%Y %H%M '
|
14
|
+
LOgger = logger
|
15
|
+
|
16
|
+
|
17
|
+
Dir[ File.join( Spec_dir, "/support/**/*.rb")].each do |f|
|
18
|
+
logger.info "requiring #{f}"
|
19
|
+
require f
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# RSpec.configure do |c|
|
24
|
+
# c.include NewAge::RSpec::Helpers
|
25
|
+
# end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module NewAge
|
4
|
+
module RSpec
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
def self.all_together
|
8
|
+
space_or_not = [" ", ""]
|
9
|
+
|
10
|
+
delims = %w{, . -} << " "
|
11
|
+
|
12
|
+
y_specifier = ["year", "years", "y", "ys", "yrs", "" ]
|
13
|
+
m_specifier = ["month", "months", "m", "ms", "mths", "" ]
|
14
|
+
|
15
|
+
yn = ((1..121).to_a.shuffle[0 .. y_specifier.length - 2 ]).shuffle
|
16
|
+
|
17
|
+
mn = ((1..11).to_a.shuffle[0 .. m_specifier.length - 2 ]).shuffle
|
18
|
+
|
19
|
+
n_spread = yn.flat_map{|y| mn.map{|m| [y,m] }} + (yn * (y_specifier.length - 1)).map{|y| [y,0]} + (mn * ( m_specifier.length - 1)).map{|m| [0,m]}
|
20
|
+
|
21
|
+
ymd = []; n_spread.zip( delims.cycle ).flatten.each_slice(3){|x| ymd << x }; ymd.uniq!
|
22
|
+
|
23
|
+
|
24
|
+
inputs = ymd.map{|y,m,d| "#{y}#{space_or_not.sample}#{y_specifier.sample}#{d}#{m}#{space_or_not.sample}#{m_specifier.sample}" }
|
25
|
+
# a real rag tag of inputs!
|
26
|
+
|
27
|
+
all_together = Hash[ inputs.zip( ymd.zip ymd.map{|y,m,_| "#{y} years #{m} months" } ) ]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: new-age
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.10
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Iain Barnett
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: yard
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: reek
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: redcarpet
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Handling the input and output of people's ages in years and months
|
79
|
+
email:
|
80
|
+
- iainspeed@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- .rspec
|
87
|
+
- Gemfile
|
88
|
+
- NewAge.gemspec
|
89
|
+
- README.markdown
|
90
|
+
- Rakefile
|
91
|
+
- lib/NewAge.rb
|
92
|
+
- lib/NewAge/version.rb
|
93
|
+
- lib/new-age.rb
|
94
|
+
- spec/new_age_spec.rb
|
95
|
+
- spec/rspec_helper.rb
|
96
|
+
- spec/support/shared/contexts.rb
|
97
|
+
homepage: https://github.com/yb66/NewAge
|
98
|
+
licenses: []
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project: NewAge
|
117
|
+
rubygems_version: 1.8.25
|
118
|
+
signing_key:
|
119
|
+
specification_version: 3
|
120
|
+
summary: Handling the input and output of people's ages in years and months
|
121
|
+
test_files:
|
122
|
+
- spec/new_age_spec.rb
|
123
|
+
- spec/rspec_helper.rb
|
124
|
+
- spec/support/shared/contexts.rb
|