parse 0.0.1.1
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 +17 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/CHANGELOG +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +138 -0
- data/Rakefile +6 -0
- data/lib/parse/version.rb +3 -0
- data/lib/parse.rb +102 -0
- data/parse.gemspec +29 -0
- data/spec/parse_spec.rb +8 -0
- data/spec/parse_ver0_0_1_spec.rb +160 -0
- data/spec/spec_helper.rb +6 -0
- metadata +161 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7d04d59e0d0c1eadc1d912f109697f28b18eb6bc
|
4
|
+
data.tar.gz: c0207dac3109de5a81e8265e0e339138392f76a9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2047276d42adf38a1b31af30d8610ed1daae0254765c4051ed381a15da44504b345f90cf83f57fc83bdfab84dd89700dc21793f8eecd06c5f31148453ae85d25
|
7
|
+
data.tar.gz: 392dc0723a262777f89086320a34c9ae50eec4197fce5f174ac087cd91b29538c660bb96a4d7fe0b39f108dc853ce32956aa59eae7a44aed91bf47f39a913365
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Seamus Abshere
|
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,138 @@
|
|
1
|
+
# Parse
|
2
|
+
|
3
|
+
Detect and convert short strings into integers, floats, dates, times, booleans, arrays, and hashes - "like a human would".
|
4
|
+
|
5
|
+
## Note on versions
|
6
|
+
|
7
|
+
You can always use `Parse.parse`. It will always point to the most recent version of the algorithm (currently `Parse.ver0_0_1`).
|
8
|
+
|
9
|
+
If the algorithm changes and you need the old version, you can reference it by its version number. For example, `Parse.ver0_0_1`.
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
You get the idea:
|
14
|
+
|
15
|
+
Parse.parse("15,000") #=> 15000
|
16
|
+
Parse.parse("$123.4") #=> 123.4
|
17
|
+
Parse.parse("(10,000,000.00)") #=> -10000000.0
|
18
|
+
Parse.parse("true") #=> true
|
19
|
+
Parse.parse("no") #=> true
|
20
|
+
Parse.parse("1982-01-01") #=> Fri, 01 Jan 1982
|
21
|
+
Parse.parse("2010-05-05 13:42:16 Z") #=> 2010-05-05 10:42:16 -0300
|
22
|
+
Parse.parse("2010-05-05 13:42:16 -02:00") #=> 2010-05-05 12:42:16 -0300
|
23
|
+
Parse.parse("100%") #=> 1.0
|
24
|
+
Parse.parse("50%") #=> 0.5
|
25
|
+
Parse.parse("12/25/82", date: :us) #=> Sat, 25 Dec 1982
|
26
|
+
Parse.parse("25/12/82", date: :euro) #=> Sat, 25 Dec 1982
|
27
|
+
Parse.parse("#DIV/0") #=> Infinity
|
28
|
+
Parse.parse("") #=> nil
|
29
|
+
Parse.parse("nil") #=> nil
|
30
|
+
Parse.parse("#NAME?") #=> nil
|
31
|
+
Parse.parse("NaN") #=> NaN
|
32
|
+
Parse.parse(".NaN") #=> NaN
|
33
|
+
Parse.parse("-.inf") #=> -Infinity
|
34
|
+
Parse.parse("Inf") #=> "Inf"
|
35
|
+
Parse.parse(":no_symbols") #=> ":no_symbols"
|
36
|
+
|
37
|
+
More esoteric stuff:
|
38
|
+
|
39
|
+
Parse.parse("-") #=> nil
|
40
|
+
Parse.parse("?") #=> nil
|
41
|
+
Parse.parse("-8e-05") #=> -8.0e-05
|
42
|
+
Parse.parse("-1_2.5e-1_3") #=> -1.25e-12
|
43
|
+
Parse.parse("05753") #=> 5753
|
44
|
+
Parse.parse("15_000") #=> 15000
|
45
|
+
Parse.parse("15_00_0") #=> 15000
|
46
|
+
Parse.parse("15.0") #=> 15.0
|
47
|
+
Parse.parse("15,000.0") #=> 15000.0
|
48
|
+
Parse.parse("15_000.0") #=> 15000.0
|
49
|
+
Parse.parse("15_00_0.0") #=> 15000.0
|
50
|
+
Parse.parse("0015") #=> 15
|
51
|
+
Parse.parse("0015.0") #=> 15.0
|
52
|
+
Parse.parse("0_015.0") #=> 15.0
|
53
|
+
Parse.parse("0x15") #=> 21
|
54
|
+
Parse.parse("0o15") #=> 13
|
55
|
+
Parse.parse("8e-05") #=> 8.0e-05
|
56
|
+
Parse.parse("1_2.5e-1_3") #=> 1.25e-12
|
57
|
+
Parse.parse("0$123.4") #=> 123.4
|
58
|
+
Parse.parse("$15,000") #=> 15000
|
59
|
+
Parse.parse("0$15,000") #=> 15000
|
60
|
+
Parse.parse("$123_456") #=> 123456
|
61
|
+
Parse.parse("$123_456.7") #=> 123456.7
|
62
|
+
Parse.parse("10,000,000") #=> 10000000
|
63
|
+
Parse.parse("10,000,000.00") #=> 10000000.0
|
64
|
+
Parse.parse("$10,000,000.00") #=> 10000000.0
|
65
|
+
Parse.parse("0$10,000,000.00") #=> 10000000.0
|
66
|
+
Parse.parse("$010,000,000.00") #=> 10000000.0
|
67
|
+
Parse.parse("-15") #=> -15
|
68
|
+
Parse.parse("-15,000") #=> -15000
|
69
|
+
Parse.parse("-15_000") #=> -15000
|
70
|
+
Parse.parse("-15_00_0") #=> -15000
|
71
|
+
Parse.parse("-15.0") #=> -15.0
|
72
|
+
Parse.parse("-15,000.0") #=> -15000.0
|
73
|
+
Parse.parse("-15_000.0") #=> -15000.0
|
74
|
+
Parse.parse("-15_00_0.0") #=> -15000.0
|
75
|
+
Parse.parse("00-15") #=> -15
|
76
|
+
Parse.parse("00-15.0") #=> -15.0
|
77
|
+
Parse.parse("0_0-15.0") #=> "0_0-15.0"
|
78
|
+
Parse.parse("-0x15") #=> -21
|
79
|
+
Parse.parse("-0o15") #=> -13
|
80
|
+
Parse.parse("-$123.4") #=> -123.4
|
81
|
+
Parse.parse("($123.4)") #=> -123.4
|
82
|
+
Parse.parse("0($123.4)") #=> -123.4
|
83
|
+
Parse.parse("-$15,000") #=> -15000
|
84
|
+
Parse.parse("($15,000)") #=> -15000
|
85
|
+
Parse.parse("-$123_456") #=> -123456
|
86
|
+
Parse.parse("($123_456)") #=> -123456
|
87
|
+
Parse.parse("-$123_456.7") #=> -123456.7
|
88
|
+
Parse.parse("($123_456.7)") #=> -123456.7
|
89
|
+
Parse.parse("-10,000,000") #=> -10000000
|
90
|
+
Parse.parse("(10,000,000)") #=> -10000000
|
91
|
+
Parse.parse("-10,000,000.00") #=> -10000000.0
|
92
|
+
Parse.parse("(10,000,000.00)") #=> -10000000.0
|
93
|
+
Parse.parse("1,200") #=> 1200
|
94
|
+
Parse.parse("1,200.0") #=> 1200.0
|
95
|
+
Parse.parse("1,2") #=> 12
|
96
|
+
Parse.parse("1,20") #=> 120
|
97
|
+
Parse.parse("1,2.0") #=> 12.0
|
98
|
+
Parse.parse("1.0,2") #=> "1.0,2"
|
99
|
+
Parse.parse("1.0,2.0") #=> "1.0,2.0"
|
100
|
+
Parse.parse("-1,200") #=> -1200
|
101
|
+
Parse.parse("-1,200.0") #=> -1200.0
|
102
|
+
Parse.parse("-1,2") #=> -12
|
103
|
+
Parse.parse("-1,20") #=> -120
|
104
|
+
Parse.parse("-1,2.0") #=> -12.0
|
105
|
+
Parse.parse("-1.0,2") #=> "-1.0,2"
|
106
|
+
Parse.parse("-1.0,2.0") #=> "-1.0,2.0"
|
107
|
+
Parse.parse("01,200") #=> 1200
|
108
|
+
Parse.parse("01,200.0") #=> 1200.0
|
109
|
+
Parse.parse("01,2") #=> 12
|
110
|
+
Parse.parse("01,20") #=> 120
|
111
|
+
Parse.parse("01,2.0") #=> 12.0
|
112
|
+
Parse.parse("01.0,2") #=> "01.0,2"
|
113
|
+
Parse.parse("01.0,2.0") #=> "01.0,2.0"
|
114
|
+
Parse.parse("#hello") #=> "#hello"
|
115
|
+
Parse.parse("\n#hello\n#world") #=> "#hello #world"
|
116
|
+
Parse.parse("hello\nworld") #=> "hello world"
|
117
|
+
Parse.parse(",1") #=> ",1"
|
118
|
+
Parse.parse(",1,") #=> ",1,"
|
119
|
+
|
120
|
+
Note how, for better or worse, it effectively acts as a YAML or JSON parser, but doesn't do CSV:
|
121
|
+
|
122
|
+
Parse.parse("1,2,3") #=> "1,2,3"
|
123
|
+
Parse.parse("[1,2,3]") #=> [1, 2, 3]
|
124
|
+
Parse.parse("---\na: 1\n") #=> {"a"=>1}
|
125
|
+
Parse.parse("---\n:a: 1\n") #=> {":a"=>1}
|
126
|
+
Parse.parse("---\na: 1\n5: |-\n c\n 3\n") #=> {"a"=>1, 5=>"c\n3"}
|
127
|
+
Parse.parse("{\"a\":1}") #=> {"a"=>1}
|
128
|
+
Parse.parse("{\"a\":1,\"5\":\"c\\n3\"}") #=> {"a"=>1, "5"=>"c\n3"}
|
129
|
+
|
130
|
+
## Wishlist
|
131
|
+
|
132
|
+
1. allow specifying `date: '%Y/%m/%d'` for strptime
|
133
|
+
1. allow hinting like `type: Integer` or `type: Date`
|
134
|
+
1. deprecate this whole thing in favor of YAML 1.2?
|
135
|
+
|
136
|
+
## Copyright
|
137
|
+
|
138
|
+
2014 Seamus Abshere
|
data/Rakefile
ADDED
data/lib/parse.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require "parse/version"
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
require 'yaml'
|
5
|
+
require 'safe_yaml/load'
|
6
|
+
|
7
|
+
module Parse
|
8
|
+
# only need to deal with stuff not caught by YAML or JSON
|
9
|
+
NULL = [ '', '-', '?', 'N/A', 'n/a', 'NULL', 'null', '#REF!', '#NAME?', 'NIL', 'nil', 'NA', 'na', '#VALUE!', '#NULL!'] # from bigml's list
|
10
|
+
NAN = [ 'NaN' ]
|
11
|
+
INFINITY = [ '#DIV/0', 'Infinity' ]
|
12
|
+
NEG_INFINITY = [ '-Infinity' ]
|
13
|
+
DATE = {
|
14
|
+
euro: ['%d-%m-%Y', '%d-%m-%y'],
|
15
|
+
us: ['%m-%d-%Y', '%m-%d-%y'],
|
16
|
+
}
|
17
|
+
|
18
|
+
def self.parse(raw, options = nil)
|
19
|
+
ver0_0_1 raw, options
|
20
|
+
end
|
21
|
+
|
22
|
+
# @private
|
23
|
+
# use YAML to parse stuff like '1.5'
|
24
|
+
# ruby's yaml is 1.1, which means it does weird stuff with '001' (fixed in 1.2, which jruby has)
|
25
|
+
def self.ver0_0_1(raw, options = nil)
|
26
|
+
return raw unless raw.is_a? String
|
27
|
+
|
28
|
+
memo = raw.strip
|
29
|
+
|
30
|
+
return nil if NULL.include? memo
|
31
|
+
return 1.0/0 if INFINITY.include? memo
|
32
|
+
return -1.0/0 if NEG_INFINITY.include? memo
|
33
|
+
return 0.0/0 if NAN.include? memo
|
34
|
+
|
35
|
+
if options and options[:date]
|
36
|
+
yyyy, yy = DATE.fetch options[:date]
|
37
|
+
memo.sub!(/0+/, '')
|
38
|
+
memo.gsub! '/', '-'
|
39
|
+
if memo =~ /\d{4,}/ # yyyy
|
40
|
+
return Date.strptime(memo, yyyy)
|
41
|
+
else
|
42
|
+
return Date.strptime(memo, yy)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
not_numeric = nil
|
47
|
+
not_numeric ||= memo =~ /,\d{1,2},/ # comma not used for thousands, like 10,20,30
|
48
|
+
not_numeric ||= memo =~ /\..*,/ # comma following a period, like 1.0,2
|
49
|
+
not_numeric ||= memo =~ /\A[^(+\-\$0-9%]/ # starts with letter or smth
|
50
|
+
possible_numeric = !not_numeric
|
51
|
+
accounting_negative = nil
|
52
|
+
percentage = nil
|
53
|
+
|
54
|
+
if possible_numeric
|
55
|
+
accounting_negative = memo =~ /\A[0$]*\([0$]*/
|
56
|
+
percentage = memo.end_with?('%')
|
57
|
+
memo.sub! /%\z/, '' if percentage
|
58
|
+
memo.delete!('()') if accounting_negative # accounting negative
|
59
|
+
# in yaml 1.1, anything starting with zero is treated as octal... in 1.2, it's 0o
|
60
|
+
memo.sub!(/0+/, '') if memo =~ /\A[+\-]?0+[+\-\$]?[1-9]+/ # leading zeros
|
61
|
+
memo.delete!('$') if memo =~ /\A[+\-]?0*\$/
|
62
|
+
if memo.include?(',')
|
63
|
+
a, b = memo.split('.', 2)
|
64
|
+
a.delete! ','
|
65
|
+
memo = b ? [a, b].join('.') : a
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
not_safe_for_yaml = nil
|
70
|
+
not_safe_for_yaml ||= memo.include?('#')
|
71
|
+
not_safe_for_yaml ||= not_numeric && memo =~ /\A[\d,]+\z/ #1,2,3, maybe a csv
|
72
|
+
safe_for_yaml = !not_safe_for_yaml
|
73
|
+
|
74
|
+
if safe_for_yaml
|
75
|
+
begin
|
76
|
+
memo = SafeYAML.load memo
|
77
|
+
rescue
|
78
|
+
$stderr.puts "#{memo.inspect} => #{$!}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if possible_numeric
|
83
|
+
case memo
|
84
|
+
when /\A[+\-]?[\d._]+[eE][+\-]?[\d._]+\z/
|
85
|
+
# scientific notation
|
86
|
+
memo = memo.to_f
|
87
|
+
when /\A[+\-]?0o/
|
88
|
+
# octal per yaml 1.2
|
89
|
+
memo = memo.to_i 8
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
if memo.is_a?(String)
|
94
|
+
# compress whitespace
|
95
|
+
memo.gsub! /\s+/, ' '
|
96
|
+
end
|
97
|
+
|
98
|
+
memo = memo / 100.0 if percentage
|
99
|
+
memo = -memo if accounting_negative
|
100
|
+
memo
|
101
|
+
end
|
102
|
+
end
|
data/parse.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'parse/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "parse"
|
8
|
+
spec.version = Parse::VERSION
|
9
|
+
spec.authors = ["Seamus Abshere"]
|
10
|
+
spec.email = ["seamus@abshere.net"]
|
11
|
+
spec.summary = %q{Detect and convert short strings into integers, floats, dates, times, booleans, arrays, and hashes - "like a human would". Based on YAML and JSON.}
|
12
|
+
spec.description = %q{Detect and convert short strings into integers, floats, dates, times, booleans, arrays, and hashes - "like a human would". Based on YAML and JSON.}
|
13
|
+
spec.homepage = "https://github.com/seamusabshere/parse"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'safe_yaml'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency 'multi_json'
|
27
|
+
spec.add_development_dependency 'activesupport'
|
28
|
+
spec.add_development_dependency 'pry'
|
29
|
+
end
|
data/spec/parse_spec.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Parse do
|
4
|
+
{
|
5
|
+
'' => nil,
|
6
|
+
'nil' => nil,
|
7
|
+
'15' => 15,
|
8
|
+
'15,000' => 15_000,
|
9
|
+
'15_000' => 15_000,
|
10
|
+
'15_00_0' => 15_000,
|
11
|
+
'15.0' => 15.0,
|
12
|
+
'15,000.0' => 15_000.0,
|
13
|
+
'15_000.0' => 15_000.0,
|
14
|
+
'15_00_0.0' => 15_000.0,
|
15
|
+
'0015' => 15, # not octal
|
16
|
+
'0015.0' => 15.0, # not octal
|
17
|
+
'0_015.0' => 15.0, # just weird
|
18
|
+
'0x15' => 0x15, # hex
|
19
|
+
'0o15' => 015, # octal
|
20
|
+
'8e-05' => 8e-05,
|
21
|
+
'1_2.5e-1_3' => 12.5e-13,
|
22
|
+
'$123.4' => 123.4,
|
23
|
+
'0$123.4' => 123.4,
|
24
|
+
'$15,000' => 15_000,
|
25
|
+
'0$15,000' => 15_000,
|
26
|
+
'$123_456' => 123_456,
|
27
|
+
'$123_456.7' => 123_456.7,
|
28
|
+
'10,000,000' => 10_000_000,
|
29
|
+
'10,000,000.00' => 10_000_000.0,
|
30
|
+
'$10,000,000.00' => 10_000_000.0,
|
31
|
+
'0$10,000,000.00' => 10_000_000.0,
|
32
|
+
'$010,000,000.00' => 10_000_000.0,
|
33
|
+
|
34
|
+
'-15' => -15,
|
35
|
+
'-15,000' => -15_000,
|
36
|
+
'-15_000' => -15_000,
|
37
|
+
'-15_00_0' => -15_000,
|
38
|
+
'-15.0' => -15.0,
|
39
|
+
'-15,000.0' => -15_000.0,
|
40
|
+
'-15_000.0' => -15_000.0,
|
41
|
+
'-15_00_0.0' => -15_000.0,
|
42
|
+
'00-15' => -15, # not octal
|
43
|
+
'00-15.0' => -15.0, # not octal
|
44
|
+
'0_0-15.0' => '0_0-15.0', # just weird
|
45
|
+
'-0x15' => -0x15, # hex
|
46
|
+
'-0o15' => -015, # octal
|
47
|
+
'-8e-05' => -8e-05,
|
48
|
+
'-1_2.5e-1_3' => -12.5e-13,
|
49
|
+
'-$123.4' => -123.4,
|
50
|
+
'($123.4)' => -123.4,
|
51
|
+
'0($123.4)' => -123.4,
|
52
|
+
'-$15,000' => -15_000,
|
53
|
+
'($15,000)' => -15_000,
|
54
|
+
'-$123_456' => -123_456,
|
55
|
+
'($123_456)' => -123_456,
|
56
|
+
'-$123_456.7' => -123_456.7,
|
57
|
+
'($123_456.7)' => -123_456.7,
|
58
|
+
'-10,000,000' => -10_000_000,
|
59
|
+
'(10,000,000)' => -10_000_000,
|
60
|
+
'-10,000,000.00' => -10_000_000.0,
|
61
|
+
'(10,000,000.00)' => -10_000_000.0,
|
62
|
+
'-10000000' => -10_000_000,
|
63
|
+
'(10000000)' => -10_000_000,
|
64
|
+
'-10000000.00' => -10_000_000.0,
|
65
|
+
'(10000000.00)' => -10_000_000.0,
|
66
|
+
'1,200' => 1_200,
|
67
|
+
'1,200.0' => 1_200.0,
|
68
|
+
'1,2' => 12,
|
69
|
+
'1,20' => 120,
|
70
|
+
'1,2.0' => 12.0,
|
71
|
+
'1.0,2' => '1.0,2',
|
72
|
+
'1.0,2.0' => '1.0,2.0',
|
73
|
+
'-1,200' => -1_200,
|
74
|
+
'-1,200.0' => -1_200.0,
|
75
|
+
'-1,2' => -12,
|
76
|
+
'-1,20' => -120,
|
77
|
+
'-1,2.0' => -12.0,
|
78
|
+
'-1.0,2' => '-1.0,2',
|
79
|
+
'-1.0,2.0' => '-1.0,2.0',
|
80
|
+
'01,200' => 1_200,
|
81
|
+
'01,200.0' => 1_200.0,
|
82
|
+
'01,2' => 12,
|
83
|
+
'01,20' => 120,
|
84
|
+
'01,2.0' => 12.0,
|
85
|
+
'01.0,2' => '01.0,2',
|
86
|
+
'01.0,2.0' => '01.0,2.0',
|
87
|
+
|
88
|
+
'05753' => 5753,
|
89
|
+
'true' => true,
|
90
|
+
'yes' => true,
|
91
|
+
'false' => false,
|
92
|
+
'no' => false,
|
93
|
+
'#DIV/0' => (1.0/0),
|
94
|
+
'#NAME?' => nil,
|
95
|
+
'Inf' => 'Inf',
|
96
|
+
'Infinity' => (1.0/0),
|
97
|
+
'-Infinity' => -(1.0/0),
|
98
|
+
'NaN' => 0.0/0, # need the dot
|
99
|
+
'.NaN' => 0.0/0, # NaN
|
100
|
+
'-.inf' => -(1.0/0), # -Infinity
|
101
|
+
'-' => nil, # per bigml
|
102
|
+
'?' => nil,
|
103
|
+
'1982-01-01' => Date.new(1982,1,1),
|
104
|
+
'2010-05-05 13:42:16 Z' => Time.parse('2010-05-05 13:42:16 Z'),
|
105
|
+
'2010-05-05 13:42:16 -02:00' => Time.parse('2010-05-05 13:42:16 -02:00'),
|
106
|
+
":not_a_symbol" => ':not_a_symbol',
|
107
|
+
'#hello' => '#hello',
|
108
|
+
"\n#hello\n#world" => '#hello #world',
|
109
|
+
"hello\nworld" => 'hello world', # whitespace compression
|
110
|
+
|
111
|
+
'0%' => 0.0,
|
112
|
+
'100%' => 1.0,
|
113
|
+
'50%' => 0.5,
|
114
|
+
'5%' => 0.05,
|
115
|
+
'00000%' => 0.0,
|
116
|
+
'0000100%' => 1.0,
|
117
|
+
'000050%' => 0.5,
|
118
|
+
'00005%' => 0.05,
|
119
|
+
|
120
|
+
['12/25/82', {date: :us}] => Date.new(1982,12,25),
|
121
|
+
['12/25/1982', {date: :us}] => Date.new(1982,12,25),
|
122
|
+
['25/12/82', {date: :euro}] => Date.new(1982,12,25),
|
123
|
+
['25/12/1982', {date: :euro}] => Date.new(1982,12,25),
|
124
|
+
['12-25-82', {date: :us}] => Date.new(1982,12,25),
|
125
|
+
['12-25-1982', {date: :us}] => Date.new(1982,12,25),
|
126
|
+
['25-12-82', {date: :euro}] => Date.new(1982,12,25),
|
127
|
+
['25-12-1982', {date: :euro}] => Date.new(1982,12,25),
|
128
|
+
|
129
|
+
'12/25/82' => '12/25/82',
|
130
|
+
|
131
|
+
',1' => ',1', # not a csv parser
|
132
|
+
',1,' => ',1,', # not a csv parser
|
133
|
+
'1,2,3' => '1,2,3', # not a csv parser
|
134
|
+
'[1,2,3]' => [1,2,3],
|
135
|
+
YAML.dump('a' => 1) => { 'a' => 1 },
|
136
|
+
YAML.dump(a: 1) => { ':a' => 1 }, # doesn't parse symbols
|
137
|
+
YAML.dump('a' => 1, 5 => "c\n3") => { 'a' => 1, 5 => "c\n3" },
|
138
|
+
MultiJson.dump(a: 1) => { 'a' => 1 }, # json always loses symbols
|
139
|
+
MultiJson.dump(a: 1, 5 => "c\n3") => { 'a' => 1, '5' => "c\n3" },
|
140
|
+
}.each do |input, expected|
|
141
|
+
it "parses #{input.inspect} as #{expected.inspect}" do
|
142
|
+
input = Array.wrap input
|
143
|
+
got = Parse.ver0_0_1(*input)
|
144
|
+
# $lines << [ "Parse.parse(#{input.inspect})".ljust(45), "#=> #{got.inspect}" ].join
|
145
|
+
if expected.is_a?(Float) and expected.nan?
|
146
|
+
expect(got.nan?).to eq(true)
|
147
|
+
else
|
148
|
+
expect(got).to eq(expected)
|
149
|
+
end
|
150
|
+
|
151
|
+
input_with_spaces = [ "\t" + input[0] + "\t", input[1] ]
|
152
|
+
got_with_spaces = Parse.ver0_0_1(*input_with_spaces)
|
153
|
+
if expected.is_a?(Float) and expected.nan?
|
154
|
+
expect(got.nan?).to eq(true)
|
155
|
+
else
|
156
|
+
expect(got_with_spaces).to eq(expected)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: parse
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Seamus Abshere
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: safe_yaml
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: multi_json
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activesupport
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Detect and convert short strings into integers, floats, dates, times,
|
112
|
+
booleans, arrays, and hashes - "like a human would". Based on YAML and JSON.
|
113
|
+
email:
|
114
|
+
- seamus@abshere.net
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".gitignore"
|
120
|
+
- ".rspec"
|
121
|
+
- ".travis.yml"
|
122
|
+
- CHANGELOG
|
123
|
+
- Gemfile
|
124
|
+
- LICENSE.txt
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- lib/parse.rb
|
128
|
+
- lib/parse/version.rb
|
129
|
+
- parse.gemspec
|
130
|
+
- spec/parse_spec.rb
|
131
|
+
- spec/parse_ver0_0_1_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
homepage: https://github.com/seamusabshere/parse
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
metadata: {}
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 2.2.1
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: Detect and convert short strings into integers, floats, dates, times, booleans,
|
157
|
+
arrays, and hashes - "like a human would". Based on YAML and JSON.
|
158
|
+
test_files:
|
159
|
+
- spec/parse_spec.rb
|
160
|
+
- spec/parse_ver0_0_1_spec.rb
|
161
|
+
- spec/spec_helper.rb
|