Skip to content

Commit

Permalink
Added keyword header field handling and specs
Browse files Browse the repository at this point in the history
  • Loading branch information
mikel committed Aug 5, 2009
1 parent 37a3f95 commit cb1bd5e
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 10 deletions.
13 changes: 7 additions & 6 deletions lib/mail.rb
Expand Up @@ -28,19 +28,20 @@ module Mail
Treetop.load(File.join(dir_name, 'parsers', 'rfc2822_obsolete'))
Treetop.load(File.join(dir_name, 'parsers', 'rfc2822'))
Treetop.load(File.join(dir_name, 'parsers', 'address_lists'))

# Load in all header fields
fields = Dir.glob(File.join(dir_name, 'fields', '*.rb'))
fields.each do |field|
require field
end
Treetop.load(File.join(dir_name, 'parsers', 'phrase_lists'))

# Load in all header field elements
elems = Dir.glob(File.join(dir_name, 'elements', '*.rb'))
elems.each do |elem|
require elem
end

# Load in all header fields
fields = Dir.glob(File.join(dir_name, 'fields', '*.rb'))
fields.each do |field|
require field
end

def Mail.message(*args, &block)
if block_given?
Mail::Message.new(args, &block)
Expand Down
21 changes: 21 additions & 0 deletions lib/mail/elements/phrase_list.rb
@@ -0,0 +1,21 @@
# encoding: utf-8
module Mail
class PhraseList

include Mail::Utilities

def initialize(string)
parser = Mail::PhraseListsParser.new
if tree = parser.parse(string)
@phrases = tree.phrases
else
raise Mail::Field::ParseError, "Can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
end
end

def phrases
@phrases.map { |p| unquote(p.text_value) }
end

end
end
14 changes: 14 additions & 0 deletions lib/mail/fields/keywords_field.rb
Expand Up @@ -4,5 +4,19 @@
module Mail
class KeywordsField < StructuredField

FIELD_NAME = 'keywords'

def initialize(*args)
super(FIELD_NAME, strip_field(FIELD_NAME, args.last))
end

def phrase_list
@phrase_list ||= PhraseList.new(value)
end

def keywords
phrase_list.phrases
end

end
end
2 changes: 1 addition & 1 deletion lib/mail/parsers/address_lists.treetop
Expand Up @@ -3,7 +3,7 @@ module Mail

include RFC2822

rule primary
rule primary_address
address_list {
def addresses
[first_addr] + other_addr.elements.map { |o| o.addr_value }
Expand Down
15 changes: 15 additions & 0 deletions lib/mail/parsers/phrase_lists.treetop
@@ -0,0 +1,15 @@
module Mail
grammar PhraseLists

include RFC2822

rule primary_phrase
phrase_list {
def phrases
[first_phrase] + other_phrases.elements.map { |o| o.phrase_value }
end
}
end

end
end
4 changes: 4 additions & 0 deletions lib/mail/parsers/rfc2822.treetop
Expand Up @@ -124,6 +124,10 @@ module Mail
rule word
atom / quoted_string
end

rule phrase_list
first_phrase:phrase other_phrases:("," FWS* phrase_value:phrase)*
end

rule phrase
word+ / obs_phrase
Expand Down
56 changes: 53 additions & 3 deletions spec/mail/fields/keywords_field_spec.rb
Expand Up @@ -3,8 +3,58 @@

describe Mail::KeywordsField do

it "should initialize" do
doing { Mail::KeywordsField.new("this, is, email") }.should_not raise_error
describe "initializing" do

it "should initialize" do
doing { Mail::KeywordsField.new("this, is, email") }.should_not raise_error
end

it "should accept two strings with the field separate" do
k = Mail::KeywordsField.new('Keywords', 'these are keywords, so there')
k.name.should == 'Keywords'
k.value.should == 'these are keywords, so there'
end

it "should accept a string with the field name" do
k = Mail::KeywordsField.new('Keywords: these are keywords, so there')
k.name.should == 'Keywords'
k.value.should == 'these are keywords, so there'
end

it "should accept a string with the field name" do
k = Mail::KeywordsField.new('these are keywords, so there')
k.name.should == 'Keywords'
k.value.should == 'these are keywords, so there'
end

end


describe "giving a list of keywords" do
it "should return a list of keywords" do
k = Mail::KeywordsField.new('these are keywords, so there')
k.keywords.should == ['these are keywords', 'so there']
end

it "should handle phrases" do
k = Mail::KeywordsField.new('"these, are keywords", so there')
k.keywords.should == ['these, are keywords', 'so there']
end

it "should handle comments" do
k = Mail::KeywordsField.new('"these, are keywords", so there (This is an irrelevant comment)')
k.keywords.should == ['these, are keywords', 'so there (This is an irrelevant comment)']
end

it "should handle comments" do
k = Mail::KeywordsField.new('"these, are keywords", so there (This is an irrelevant comment)')
k.keywords.should == ['these, are keywords', 'so there (This is an irrelevant comment)']
end

it "should handle comments in quotes" do
k = Mail::KeywordsField.new('"these, are keywords (another comment to be ignored)", so there (This is an irrelevant comment)')
k.keywords.should == ['these, are keywords (another comment to be ignored)', 'so there (This is an irrelevant comment)']
end

end

end

0 comments on commit cb1bd5e

Please sign in to comment.