gedcom_ruby 0.3.1 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gedcom_ruby/date.rb +245 -0
- data/lib/gedcom_ruby/date_parser.rb +952 -0
- data/spec/date_spec.rb +44 -0
- data/spec/datepart_spec.rb +87 -0
- data/spec/gedcoms/3_indis.ged +6 -0
- data/spec/gedcoms/5_lines.ged +5 -0
- data/spec/gedcoms/linewrap_conc.ged +7 -0
- data/spec/gedcoms/linewrap_cont.ged +5 -0
- data/spec/gedcoms/simple.ged +48 -0
- data/spec/parser_spec.rb +135 -0
- data/spec/spec_helper.rb +7 -0
- metadata +23 -3
data/spec/date_spec.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
describe Date do
|
2
|
+
let(:date) { GEDCOM::Date.new("1 APRIL 2008") }
|
3
|
+
let(:date_range_from) { GEDCOM::Date.new("FROM APRIL 2007 TO JUNE 2008") }
|
4
|
+
let(:date_range_between) { GEDCOM::Date.new("BETWEEN 1 JANUARY 1970 AND 1 APRIL 2008") }
|
5
|
+
let(:date_bc) { GEDCOM::Date.new("25 JANUARY 1 BC") }
|
6
|
+
let(:date_year_span) { GEDCOM::Date.new("1 APRIL 2007/08") }
|
7
|
+
|
8
|
+
|
9
|
+
## ! Could definitely stand to beef this test up. About, Estimated, etc.
|
10
|
+
## Lot's of flags to test.
|
11
|
+
it "makes flags available" do
|
12
|
+
expect(date_range_from.format & GEDCOM::Date::FROMTO).to_not eq(0)
|
13
|
+
expect(date_range_between.format & GEDCOM::Date::BETWEEN).to_not eq(0)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "does comparison" do
|
17
|
+
expect(date <=> date_bc).to eq(1)
|
18
|
+
expect(date_bc <=> date).to eq(-1)
|
19
|
+
expect(date <=> date).to eq(0)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "gets first and last date from ranges" do
|
23
|
+
expect(date_range_from.is_range?).to be(true)
|
24
|
+
expect(date_range_between.is_range?).to eq(true)
|
25
|
+
|
26
|
+
expect(date_range_from.first.nil?).to eq(false)
|
27
|
+
expect(date_range_from.last.nil?).to eq(false)
|
28
|
+
expect(date_range_between.first.nil?).to eq(false)
|
29
|
+
expect(date_range_between.last.nil?).to eq(false)
|
30
|
+
|
31
|
+
expect(date_range_from.first <=> date_range_from.last).to eq(-1)
|
32
|
+
expect(date_range_between.first <=> date_range_between.last).to eq(-1)
|
33
|
+
end
|
34
|
+
|
35
|
+
# to_s currently works differently in the Ruby vs. C extension
|
36
|
+
# code, therefore this test is failing (in C)
|
37
|
+
it "converts to string" do
|
38
|
+
expect(date.to_s).to eq("1 Apr 2008")
|
39
|
+
expect(date_range_from.to_s).to eq("from Apr 2007 to Jun 2008")
|
40
|
+
expect(date_range_between.to_s).to eq("bet 1 Jan 1970 and 1 Apr 2008")
|
41
|
+
expect(date_bc.to_s).to eq("25 Jan 1 BC")
|
42
|
+
expect(date_year_span.to_s).to eq("1 Apr 2007-8")
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
describe DatePart do
|
2
|
+
let(:date) { GEDCOM::Date.new("1 APRIL 2008") }
|
3
|
+
let(:date_range_from) { GEDCOM::Date.new("FROM APRIL 2007 TO JUNE 2008") }
|
4
|
+
let(:date_range_between) { GEDCOM::Date.new("BETWEEN 1 JANUARY 1970 AND 1 APRIL 2008") }
|
5
|
+
let(:date_bc) { GEDCOM::Date.new("25 JANUARY 1 BC") }
|
6
|
+
let(:date_year_span) { GEDCOM::Date.new("1 APRIL 2007/08") }
|
7
|
+
let(:nonstandard) { GEDCOM::Date.safe_new("FIRST DAY OF 2008") }
|
8
|
+
let(:phrase) { GEDCOM::Date.safe_new("(independance day)") }
|
9
|
+
|
10
|
+
it "makes date type and flags available" do
|
11
|
+
expect(date.first.compliance | GEDCOM::DatePart::NONE).to eq(0)
|
12
|
+
#expect(nonstandard.first.compliance & GEDCOM::DatePart::NONSTANDARD).to_not eq(0)
|
13
|
+
expect(phrase.first.compliance & GEDCOM::DatePart::PHRASE).to_not eq(0)
|
14
|
+
|
15
|
+
expect(date_range_from.first.calendar | GEDCOM::DateType::DEFAULT).to eq(0)
|
16
|
+
expect(date_range_from.last.calendar | GEDCOM::DateType::DEFAULT).to eq(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "finds days" do
|
20
|
+
expect(date.first.has_day?).to eq(true)
|
21
|
+
expect(date.first.day).to eq(1)
|
22
|
+
|
23
|
+
expect(date_range_between.first.has_day?).to eq(true)
|
24
|
+
expect(date_range_between.first.day).to eq(1)
|
25
|
+
|
26
|
+
expect(date_range_between.last.has_day?).to eq(true)
|
27
|
+
expect(date_range_between.last.day).to eq(1)
|
28
|
+
|
29
|
+
expect(date_bc.first.has_day?).to eq(true)
|
30
|
+
expect(date_bc.first.day).to eq(25)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "finds months" do
|
34
|
+
expect(date.first.has_month?).to eq(true)
|
35
|
+
expect(date.first.month).to eq(4)
|
36
|
+
|
37
|
+
expect(date_range_between.first.has_month?).to eq(true)
|
38
|
+
expect(date_range_between.first.month).to eq(1)
|
39
|
+
|
40
|
+
expect(date_range_between.last.has_month?).to eq(true)
|
41
|
+
expect(date_range_between.last.month).to eq(4)
|
42
|
+
|
43
|
+
expect(date_bc.first.has_month?).to eq(true)
|
44
|
+
expect(date_bc.first.month).to eq(1)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "finds years" do
|
48
|
+
expect(date.first.has_year?).to eq(true)
|
49
|
+
expect(date.first.year).to eq(2008)
|
50
|
+
|
51
|
+
expect(date_range_between.first.has_year?).to eq(true)
|
52
|
+
expect(date_range_between.first.year).to eq(1970)
|
53
|
+
|
54
|
+
expect(date_range_between.last.has_year?).to eq(true)
|
55
|
+
expect(date_range_between.last.year).to eq(2008)
|
56
|
+
|
57
|
+
expect(date_bc.first.has_year?).to eq(true)
|
58
|
+
expect(date_bc.first.year).to eq(1)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "finds the epoch" do
|
62
|
+
expect(date.first.epoch).to eq("AD")
|
63
|
+
expect(date_bc.first.epoch).to eq("BC")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "finds year span" do
|
67
|
+
expect(date_year_span.first.has_year_span?).to eq(true)
|
68
|
+
expect(date.first.has_year_span?).to eq(false)
|
69
|
+
end
|
70
|
+
|
71
|
+
# to_s currently works differently in the Ruby vs. C extension
|
72
|
+
# code, therefore this test is failing (in C)
|
73
|
+
it "converts to string" do
|
74
|
+
expect(date.first.to_s).to eq("1 Apr 2008")
|
75
|
+
|
76
|
+
expect(date_range_from.first.to_s).to eq("Apr 2007")
|
77
|
+
expect(date_range_from.last.to_s).to eq("Jun 2008")
|
78
|
+
|
79
|
+
expect(date_range_between.first.to_s).to eq("1 Jan 1970")
|
80
|
+
expect(date_range_between.last.to_s).to eq("1 Apr 2008")
|
81
|
+
|
82
|
+
expect(date_bc.first.to_s).to eq("25 Jan 1 BC")
|
83
|
+
|
84
|
+
expect(date_year_span.to_s).to eq("1 Apr 2007-8")
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
0 @SUBMITTER@ SUBM
|
2
|
+
1 TEXT This is a really long body of text that should be wrapped in the mid
|
3
|
+
2 CONC dle of a word. The resulting data object (string) should not include th
|
4
|
+
2 CONC at newline, but instead should just concatenate the two pie
|
5
|
+
2 CONC ces of the word together. It should also correctly handle breaks
|
6
|
+
2 CONC on spaces. It should also handle blank lines.
|
7
|
+
2 CONC
|
@@ -0,0 +1,48 @@
|
|
1
|
+
0 HEAD
|
2
|
+
1 CHAR ASCII
|
3
|
+
1 SOUR ID_OF_CREATING_FILE
|
4
|
+
1 GEDC
|
5
|
+
2 VERS 5.5
|
6
|
+
2 FORM Lineage-Linked
|
7
|
+
1 SUBM @SUBMITTER@
|
8
|
+
0 @SUBMITTER@ SUBM
|
9
|
+
1 NAME /Submitter/
|
10
|
+
1 ADDR Submitters address
|
11
|
+
2 CONT address continued here
|
12
|
+
0 @FATHER@ INDI
|
13
|
+
1 NAME /Father/
|
14
|
+
1 SEX M
|
15
|
+
1 BIRT
|
16
|
+
2 PLAC birth place
|
17
|
+
2 DATE 1 JAN 1899
|
18
|
+
1 DEAT
|
19
|
+
2 PLAC death place
|
20
|
+
2 DATE 31 DEC 1990
|
21
|
+
1 FAMS @FAMILY@
|
22
|
+
0 @MOTHER@ INDI
|
23
|
+
1 NAME /Mother/
|
24
|
+
1 SEX F
|
25
|
+
1 BIRT
|
26
|
+
2 PLAC birth place
|
27
|
+
2 DATE 1 JAN 1899
|
28
|
+
1 DEAT
|
29
|
+
2 PLAC death place
|
30
|
+
2 DATE 31 DEC 1990
|
31
|
+
1 FAMS @FAMILY@
|
32
|
+
0 @CHILD@ INDI
|
33
|
+
1 NAME /Child/
|
34
|
+
1 BIRT
|
35
|
+
2 PLAC birth place
|
36
|
+
2 DATE 31 JUL 1950
|
37
|
+
1 DEAT
|
38
|
+
2 PLAC death place
|
39
|
+
2 DATE 29 FEB 2000
|
40
|
+
1 FAMC @FAMILY@
|
41
|
+
0 @FAMILY@ FAM
|
42
|
+
1 MARR
|
43
|
+
2 PLAC marriage place
|
44
|
+
2 DATE 1 APR 1950
|
45
|
+
1 HUSB @FATHER@
|
46
|
+
1 WIFE @MOTHER@
|
47
|
+
1 CHIL @CHILD@
|
48
|
+
0 TRLR
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
describe Parser do
|
2
|
+
GEDCOMS = File.dirname(__FILE__)+"/gedcoms"
|
3
|
+
SIMPLE = "#{GEDCOMS}/simple.ged"
|
4
|
+
|
5
|
+
let(:parser) { GEDCOM::Parser.new }
|
6
|
+
let(:tag_count) { {:all => 0} }
|
7
|
+
|
8
|
+
let(:callback) { lambda{|data| } }
|
9
|
+
|
10
|
+
describe ".new" do
|
11
|
+
it "can be called with block" do
|
12
|
+
parser = GEDCOM::Parser.new do
|
13
|
+
before 'INDI' do
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
describe "#before" do
|
21
|
+
it "adds a callback to the :before stack" do
|
22
|
+
parser.before(:any, callback)
|
23
|
+
expect(parser.callbacks[:before].values.flatten).to include(callback)
|
24
|
+
end
|
25
|
+
describe ":any" do
|
26
|
+
it "is called for each line" do
|
27
|
+
parser.before(:any, callback)
|
28
|
+
expect(callback).to receive(:call).exactly(5).times
|
29
|
+
parser.parse "#{GEDCOMS}/5_lines.ged"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# I have no clue why this isn't working. It puts out the "meh" five times,
|
34
|
+
# but for some reason rspec doesn't think some_method has been called
|
35
|
+
# context "with a custom parser" do
|
36
|
+
# before do
|
37
|
+
# class CustomParser < GEDCOM::Parser
|
38
|
+
# def after_initialize
|
39
|
+
# before(:any, :some_method)
|
40
|
+
# end
|
41
|
+
# def some_method(data)
|
42
|
+
# puts "meh"
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
# let(:parser) { CustomParser.new }
|
47
|
+
#
|
48
|
+
# it "can be called with a method" do
|
49
|
+
# expect(parser).to receive(:some_method).exactly(5).times
|
50
|
+
# parser.parse "#{GEDCOMS}/5_lines.ged"
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#after" do
|
56
|
+
it "adds a callback to the :before stack" do
|
57
|
+
parser.after(:any, callback)
|
58
|
+
expect(parser.callbacks[:after].values.flatten).to include(callback)
|
59
|
+
end
|
60
|
+
|
61
|
+
describe ":any" do
|
62
|
+
it "is called for each line" do
|
63
|
+
parser.after(:any, callback)
|
64
|
+
expect(callback).to receive(:call).exactly(5).times
|
65
|
+
parser.parse "#{GEDCOMS}/5_lines.ged"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
let(:correct_conc) do
|
70
|
+
"This is a really long body of text that should be wrapped in " +
|
71
|
+
"the middle of a word. The resulting data object (string) should " +
|
72
|
+
"not include that newline, but instead should just concatenate the " +
|
73
|
+
"two pieces of the word together. It should also correctly handle " +
|
74
|
+
"breaks on spaces. It should also handle blank lines."
|
75
|
+
end
|
76
|
+
it "handles CONC correctly" do
|
77
|
+
# Continue the text, with no newline or space in between
|
78
|
+
parser.after ['SUBM', 'TEXT'] do |text|
|
79
|
+
expect(text).to eq(correct_conc)
|
80
|
+
end
|
81
|
+
|
82
|
+
parser.parse "#{GEDCOMS}/linewrap_conc.ged"
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
let(:correct_cont) do
|
87
|
+
"This is a formatted attribute\n" +
|
88
|
+
"with a line break in the middle.\n" +
|
89
|
+
"Unlike CONC, the resulting string\n" +
|
90
|
+
"should have newline characters."
|
91
|
+
end
|
92
|
+
it "handles CONT correctly" do
|
93
|
+
# Continue the text, with a newline in the middle
|
94
|
+
|
95
|
+
parser.after ['SUBM', 'TEXT'] do |text|
|
96
|
+
expect(text).to eq(correct_cont)
|
97
|
+
end
|
98
|
+
parser.parse "#{GEDCOMS}/linewrap_cont.ged"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#parse" do
|
103
|
+
it "can count tags, using before" do
|
104
|
+
parser.before(['INDI'], callback)
|
105
|
+
expect(callback).to receive(:call).exactly(3).times
|
106
|
+
parser.parse "#{GEDCOMS}/3_indis.ged"
|
107
|
+
end
|
108
|
+
|
109
|
+
it "can count tags, using after" do
|
110
|
+
parser.after(['INDI'], callback)
|
111
|
+
expect(callback).to receive(:call).exactly(3).times
|
112
|
+
parser.parse "#{GEDCOMS}/3_indis.ged"
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
it "unwinds all the way" do
|
117
|
+
# TRLR indicates the end of a gedcom file
|
118
|
+
parser.after('TRLR', callback)
|
119
|
+
expect(callback).to receive(:call).once
|
120
|
+
parser.parse SIMPLE
|
121
|
+
end
|
122
|
+
|
123
|
+
it "handles empty gedcom" do
|
124
|
+
parser.before(:any, callback)
|
125
|
+
parser.parse "\n"
|
126
|
+
expect(callback).to_not receive(:call)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "handles windows line endings" do
|
130
|
+
parser.before(['INDI'],callback)
|
131
|
+
expect(callback).to receive(:call).with('@I1@')
|
132
|
+
parser.parse "0 @I1@ INDI\r\n"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gedcom_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Kniffin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-09-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -60,6 +60,17 @@ extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
62
|
- lib/gedcom_ruby.rb
|
63
|
+
- lib/gedcom_ruby/date.rb
|
64
|
+
- lib/gedcom_ruby/date_parser.rb
|
65
|
+
- spec/date_spec.rb
|
66
|
+
- spec/datepart_spec.rb
|
67
|
+
- spec/gedcoms/3_indis.ged
|
68
|
+
- spec/gedcoms/5_lines.ged
|
69
|
+
- spec/gedcoms/linewrap_conc.ged
|
70
|
+
- spec/gedcoms/linewrap_cont.ged
|
71
|
+
- spec/gedcoms/simple.ged
|
72
|
+
- spec/parser_spec.rb
|
73
|
+
- spec/spec_helper.rb
|
63
74
|
homepage: https://github.com/dkniffin/gedcom-ruby
|
64
75
|
licenses:
|
65
76
|
- GNU LESSER GENERAL PUBLIC LICENSE
|
@@ -84,4 +95,13 @@ rubygems_version: 2.4.5
|
|
84
95
|
signing_key:
|
85
96
|
specification_version: 4
|
86
97
|
summary: A Ruby library for easily doing custom, callback-based GEDCOM parsing
|
87
|
-
test_files:
|
98
|
+
test_files:
|
99
|
+
- spec/date_spec.rb
|
100
|
+
- spec/datepart_spec.rb
|
101
|
+
- spec/gedcoms/3_indis.ged
|
102
|
+
- spec/gedcoms/5_lines.ged
|
103
|
+
- spec/gedcoms/linewrap_conc.ged
|
104
|
+
- spec/gedcoms/linewrap_cont.ged
|
105
|
+
- spec/gedcoms/simple.ged
|
106
|
+
- spec/parser_spec.rb
|
107
|
+
- spec/spec_helper.rb
|