vcardigan 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,9 @@ module VCardigan
2
2
 
3
3
  class VCard
4
4
 
5
- VCARD_PATTERN = /BEGIN:VCARD\s+(.*?)VERSION:(.+?)\s+(.+?)END:VCARD/m;
5
+ # A quoted-printable encoded string with a trailing '=', indicating that
6
+ # it's not terminated
7
+ UNTERMINATED_QUOTED_PRINTABLE = /ENCODING=QUOTED-PRINTABLE:.*=$/
6
8
 
7
9
  attr_accessor :version
8
10
  attr_accessor :chars
@@ -23,18 +25,18 @@ module VCardigan
23
25
  end
24
26
 
25
27
  def parse(data)
26
- match = VCARD_PATTERN.match(data)
27
- if match
28
- # Set version number
29
- @version = match[2]
30
- lines = "#{match[1].strip}#{match[3].strip}"
31
-
32
- # Add the parsed properties to this vCard
33
- lines.each_line do |line|
34
- property = VCardigan::Property.parse(self, line)
35
- add_prop(property)
28
+ lines = unfold(data)
29
+
30
+ # Add the parsed properties to this vCard
31
+ lines.each do |line|
32
+ if line =~ /^VERSION:(.+)/
33
+ @version = $1
36
34
  end
35
+
36
+ property = VCardigan::Property.parse(self, line)
37
+ add_prop(property)
37
38
  end
39
+
38
40
  self
39
41
  end
40
42
 
@@ -57,7 +59,7 @@ module VCardigan
57
59
  if @group
58
60
  # If there's a group, add it to the name
59
61
  name = "#{@group}.#{name}"
60
-
62
+
61
63
  # Reset group to nil
62
64
  @group = nil
63
65
  end
@@ -124,6 +126,39 @@ module VCardigan
124
126
  # Private ##########
125
127
  private
126
128
 
129
+ # Split on \r\n or \n to get the lines, unfold continued lines (they
130
+ # start with " " or \t), and return the array of unfolded lines.
131
+ #
132
+ # Strip away BEGIN:VCARD and END:VCARD
133
+ #
134
+ # This also supports the (invalid) encoding convention of allowing empty
135
+ # lines to be inserted for readability - it does this by dropping zero-length
136
+ # lines.
137
+ # Borrowed from https://github.com/qoobaa/vcard
138
+ def unfold(card)
139
+ unfolded = []
140
+
141
+ prior_line = nil
142
+ card.lines do |line|
143
+ line.chomp!
144
+ # If it's a continuation line, add it to the last.
145
+ # If it's an empty line, drop it from the input.
146
+ if line =~ /^[ \t]/
147
+ unfolded[-1] << line[1, line.size-1]
148
+ elsif line =~ /(^BEGIN:VCARD$)|(^END:VCARD$)/
149
+ elsif prior_line && (prior_line =~ UNTERMINATED_QUOTED_PRINTABLE)
150
+ # Strip the trailing = off prior line, then append current line
151
+ unfolded[-1] = prior_line[0, prior_line.length-1] + line
152
+ elsif line =~ /^$/
153
+ else
154
+ unfolded << line
155
+ end
156
+ prior_line = unfolded[-1]
157
+ end
158
+
159
+ unfolded
160
+ end
161
+
127
162
  def build_prop(name, *args)
128
163
  VCardigan::Property.create(self, name, *args)
129
164
  end
@@ -137,7 +172,7 @@ module VCardigan
137
172
  unless @fields.has_key? name
138
173
  @fields[name] = []
139
174
  end
140
-
175
+
141
176
  # Add the property to the field array
142
177
  @fields[name].push(property)
143
178
 
@@ -1,5 +1,5 @@
1
1
  module VCardigan
2
2
 
3
- VERSION = '0.0.2'
3
+ VERSION = '0.0.3'
4
4
 
5
5
  end
@@ -95,6 +95,42 @@ describe VCardigan::Property do
95
95
  it 'should return the property vCard formatted' do
96
96
  prop.to_s.should == "#{group}.#{name.upcase};TYPE=#{params[:type]}:#{value}"
97
97
  end
98
+
99
+ context 'with properties that return long strings' do
100
+ let(:value) { 'qwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwertqwert' }
101
+ let(:prop) { VCardigan::Property.create(vcard, "#{group}.#{name}", value, params) }
102
+
103
+ it 'should line fold at 75 chars' do
104
+ prop.to_s.split("\n").each do |line|
105
+ line.length.should <= 75
106
+ end
107
+ end
108
+
109
+ context 'when chars option is set to 50' do
110
+ let(:chars) { 50 }
111
+ let(:vcard) { VCardigan.create(:chars => chars) }
112
+ let(:prop) { VCardigan::Property.create(vcard, "#{group}.#{name}", value, params) }
113
+
114
+ it 'should line fold at 50 chars' do
115
+ prop.to_s.split("\n").each do |line|
116
+ line.length.should <= 50
117
+ end
118
+ end
119
+ end
120
+
121
+ context 'when chars option is set to 0' do
122
+ let(:chars) { 0 }
123
+ let(:vcard) { VCardigan.create(:chars => chars) }
124
+ let(:prop) { VCardigan::Property.create(vcard, "#{group}.#{name}", value, params) }
125
+
126
+ it 'should not line fold' do
127
+ ret = "#{group}.#{name.upcase};TYPE=#{params[:type]}:#{value}"
128
+ prop.to_s.split("\n").length.should == 1
129
+ prop.to_s.length.should == ret.length
130
+ end
131
+ end
132
+ end
133
+
98
134
  end
99
135
 
100
136
  describe '#parse' do
@@ -245,6 +245,22 @@ describe VCardigan::VCard do
245
245
  fields.should have_key('fn')
246
246
  end
247
247
  end
248
- end
249
248
 
249
+ context 'google 3.0 vCard' do
250
+ let(:data) { File.read(File.dirname(__FILE__) + '/../helpers/google.vcf') }
251
+ let(:vcard) { VCardigan.parse(data) }
252
+ let(:fields) { vcard.instance_variable_get(:@fields) }
253
+
254
+ it 'should set the version' do
255
+ vcard.version.should == '3.0'
256
+ end
257
+
258
+ it 'should add the properties to the fields array' do
259
+ fields.should have_key('n')
260
+ fields.should have_key('fn')
261
+ fields.should have_key('photo')
262
+ fields.should have_key('x-socialprofile')
263
+ end
264
+ end
265
+ end
250
266
  end
metadata CHANGED
@@ -1,74 +1,93 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: vcardigan
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 3
9
+ version: 0.0.3
6
10
  platform: ruby
7
- authors:
11
+ authors:
8
12
  - Matt Morgan
9
13
  autorequire:
10
14
  bindir: bin
11
15
  cert_chain: []
12
- date: 2013-01-24 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
16
+
17
+ date: 2014-02-07 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: rspec
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
19
25
  - - ~>
20
- - !ruby/object:Gem::Version
21
- version: '2.0'
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 0
30
+ version: "2.0"
22
31
  type: :development
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: pry
23
35
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: '2.0'
30
- description: vCardigan is a ruby library for building and parsing vCards that supports
31
- both v3.0 and v4.0.
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 0
42
+ version: "0"
43
+ type: :development
44
+ version_requirements: *id002
45
+ description: vCardigan is a ruby library for building and parsing vCards that supports both v3.0 and v4.0.
32
46
  email: matt@mlmorg.com
33
47
  executables: []
48
+
34
49
  extensions: []
50
+
35
51
  extra_rdoc_files: []
36
- files:
52
+
53
+ files:
37
54
  - lib/vcardigan/errors.rb
38
55
  - lib/vcardigan/properties/name_property.rb
39
56
  - lib/vcardigan/property.rb
40
57
  - lib/vcardigan/vcard.rb
41
58
  - lib/vcardigan/version.rb
42
59
  - lib/vcardigan.rb
43
- - spec/examples/property_spec.rb
44
- - spec/examples/vcard_spec.rb
45
- - spec/spec_helper.rb
60
+ has_rdoc: true
46
61
  homepage: http://github.com/brewster/vcardigan
47
- licenses:
62
+ licenses:
48
63
  - MIT
49
64
  post_install_message:
50
65
  rdoc_options: []
51
- require_paths:
66
+
67
+ require_paths:
52
68
  - lib
53
- required_ruby_version: !ruby/object:Gem::Requirement
54
- none: false
55
- requirements:
56
- - - ! '>='
57
- - !ruby/object:Gem::Version
58
- version: '0'
59
- required_rubygems_version: !ruby/object:Gem::Requirement
60
- none: false
61
- requirements:
62
- - - ! '>='
63
- - !ruby/object:Gem::Version
64
- version: '0'
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
65
83
  requirements: []
84
+
66
85
  rubyforge_project:
67
- rubygems_version: 1.8.24
86
+ rubygems_version: 1.3.6
68
87
  signing_key:
69
88
  specification_version: 3
70
89
  summary: Ruby vCard Builder/Parser
71
- test_files:
90
+ test_files:
72
91
  - spec/examples/property_spec.rb
73
92
  - spec/examples/vcard_spec.rb
74
93
  - spec/spec_helper.rb