bibtex-ruby 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bibtex-ruby might be problematic. Click here for more details.

data/lib/bibtex/lexer.rb CHANGED
@@ -260,27 +260,27 @@ module BibTeX
260
260
  end
261
261
 
262
262
  def error_unbalanced_braces
263
- Log.warn("Lexer: unbalanced braces at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
263
+ BibTeX.log.warn("Lexer: unbalanced braces at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
264
264
  backtrace [:E_UNBALANCED, @scanner.matched]
265
265
  end
266
266
 
267
267
  def error_unterminated_string
268
- Log.warn("Lexer: unterminated string at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
268
+ BibTeX.log.warn("Lexer: unterminated string at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
269
269
  backtrace [:E_UNTERMINATED_STRING, @scanner.matched]
270
270
  end
271
271
 
272
272
  def error_unterminated_content
273
- Log.warn("Lexer: unterminated content at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
273
+ BibTeX.log.warn("Lexer: unterminated content at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
274
274
  backtrace [:E_UNTERMINATED_CONTENT, @scanner.matched]
275
275
  end
276
276
 
277
277
  def error_unexpected_token
278
- Log.warn("Lexer: unexpected token `#{@scanner.matched}' at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
278
+ BibTeX.log.warn("Lexer: unexpected token `#{@scanner.matched}' at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
279
279
  backtrace [:E_UNEXPECTED_TOKEN, @scanner.matched]
280
280
  end
281
281
 
282
282
  def error_unexpected_object
283
- Log.warn("Lexer: unexpected object at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
283
+ BibTeX.log.warn("Lexer: unexpected object at #{@scanner.pos}; brace level #{@brace_level}; mode #{@mode.inspect}.")
284
284
  backtrace [:E_UNEXPECTED_OBJECT, '@']
285
285
  end
286
286
 
data/lib/bibtex/names.rb CHANGED
@@ -109,7 +109,8 @@ module BibTeX
109
109
  :suffix => :lineage
110
110
  }.freeze
111
111
 
112
- def_delegators :to_s, :=~, :===, *(String.instance_methods(false).reject { |m| m =~ /^\W|each|first|last|!$/ })
112
+ def_delegators :to_s, :=~, :===,
113
+ *String.instance_methods(false).reject { |m| m =~ /^\W|to_s|replace|each|first|last|!$/ }
113
114
 
114
115
  class << self
115
116
  def parse(string)
data/lib/bibtex/value.rb CHANGED
@@ -103,7 +103,7 @@ module BibTeX
103
103
  when ::String # simulates Ruby's String#replace
104
104
  @tokens = [argument]
105
105
  when String
106
- @tokens = @tokens.map { |v| argument.key == v ? argument.value.tokens : v }.flatten
106
+ @tokens = @tokens.map { |v| argument.key == v ? argument.value.tokens : v }.flatten
107
107
  when Hash
108
108
  @tokens = @tokens.map { |v| argument[v] || v }
109
109
  end
@@ -112,12 +112,11 @@ module BibTeX
112
112
  end
113
113
 
114
114
 
115
- # Returns the Value instance with all consecutive String tokens joined.
116
- #
117
115
  # call-seq:
118
- # Value.new('foo', 'bar').join #=> <'foobar'>
119
- # Value.new(:foo, 'bar').join #=> <:foo, 'bar'>
116
+ # Value.new('foo', 'bar').join #=> <'foobar'>
117
+ # Value.new(:foo, 'bar').join #=> <:foo, 'bar'>
120
118
  #
119
+ # Returns the Value instance with all consecutive String tokens joined.
121
120
  def join
122
121
  @tokens = @tokens.inject([]) do |a,b|
123
122
  a[-1].is_a?(::String) && b.is_a?(::String) ? a[-1] += b : a << b; a
@@ -125,6 +124,16 @@ module BibTeX
125
124
  self
126
125
  end
127
126
 
127
+ # call-seq:
128
+ # Value.new('foo').to_s #=> "foo"
129
+ # Value.new(:foo).to_s #=> "foo"
130
+ # Value.new('foo').to_s(:quotes => '"') #=> "\"foo\""
131
+ # Value.new('foo').to_s(:quotes => ['"','"']) #=> "\"foo\""
132
+ # Value.new('foo').to_s(:quotes => ['{','}']) #=> "{foo}"
133
+ # Value.new(:foo, 'bar').to_s #=> "foo # \"bar\""
134
+ # Value.new('foo', 'bar').to_s #=> "\"foo\" # \"bar\""
135
+ # Value.new('\"u').to_s(:filter => :latex) #=> "ü"
136
+ #
128
137
  # Returns a the Value as a string. @see #value; the only difference is
129
138
  # that single symbols are returned as String, too.
130
139
  # If the Value is atomic and the option :quotes is given, the string
@@ -132,17 +141,6 @@ module BibTeX
132
141
  #
133
142
  # If the option :filter is given, the Value will be converted using
134
143
  # the filter(s) specified.
135
- #
136
- # call-seq:
137
- # Value.new('foo').to_s #=> "foo"
138
- # Value.new(:foo).to_s #=> "foo"
139
- # Value.new('foo').to_s(:quotes => '"') #=> "\"foo\""
140
- # Value.new('foo').to_s(:quotes => ['"','"']) #=> "\"foo\""
141
- # Value.new('foo').to_s(:quotes => ['{','}']) #=> "{foo}"
142
- # Value.new(:foo, 'bar').to_s #=> "foo # \"bar\""
143
- # Value.new('foo', 'bar').to_s #=> "\"foo\" # \"bar\""
144
- # Value.new('\"u').to_s(:filter => :latex) #=> "ü"
145
- #
146
144
  def to_s(options = {})
147
145
  return convert(options.delete(:filter)).to_s(options) if options.has_key?(:filter)
148
146
  return value.to_s unless options.has_key?(:quotes) && atomic?
@@ -161,7 +159,7 @@ module BibTeX
161
159
  alias :v :value
162
160
 
163
161
  def inspect
164
- '<' + @tokens.map(&:inspect).join(', ') + '>'
162
+ "#<#{self.class} #{tokens.map(&:inspect).join(', ')}>"
165
163
  end
166
164
 
167
165
  # Returns true if the Value is empty or consists of a single token.
@@ -173,7 +171,6 @@ module BibTeX
173
171
  def name?; false; end
174
172
 
175
173
  alias :names? :name?
176
- alias :is_name? :name?
177
174
 
178
175
  def to_name
179
176
  Names.parse(to_s)
@@ -181,24 +178,24 @@ module BibTeX
181
178
 
182
179
  alias to_names to_name
183
180
 
184
- # Returns true if the Value's content looks like a date.
181
+ # Returns true if the Value's content is a date.
185
182
  def date?
183
+ !to_date.nil?
186
184
  end
187
-
188
- alias is_date? date?
189
185
 
190
- # Returns the string as a citeproc date. TODO use edtf format instead.
186
+ # Returns the string as a date.
191
187
  def to_date
192
- numeric? ? { 'date-parts' => [[to_i]] } : { 'literal' => to_s(:quotes => [])}
188
+ require 'date'
189
+ Date.parse(to_s)
190
+ rescue
191
+ nil
193
192
  end
194
-
193
+
195
194
  # Returns true if the Value's content is numeric.
196
195
  def numeric?
197
196
  to_s =~ /^\s*[+-]?\d+[\/\.]?\d*\s*$/
198
197
  end
199
-
200
- alias is_numeric? numeric?
201
-
198
+
202
199
  def to_citeproc (options = {})
203
200
  to_s(options)
204
201
  end
@@ -225,27 +222,27 @@ module BibTeX
225
222
  # Converts all string values according to the given filter.
226
223
  def convert! (filter)
227
224
  if f = Filters.resolve(filter)
228
- tokens.map! { |t| f.apply(t) }
229
- else
230
- raise ArgumentError, "Failed to load filter #{filter.inspect}"
225
+ tokens.map! { |t| f.apply(t) }
226
+ else
227
+ raise ArgumentError, "Failed to load filter #{filter.inspect}"
231
228
  end
232
229
 
233
230
  self
234
231
  end
235
232
 
236
- def method_missing (name, *args)
237
- case
238
- when name.to_s =~ /^(?:convert|from)_([a-z]+)(!)?$/
239
- $2 ? convert!($1) : convert($1)
240
- else
241
- super
242
- end
243
- end
244
-
245
- def respond_to? (method)
246
- method =~ /^(?:convert|from)_([a-z]+)(!)?$/ || super
247
- end
248
-
233
+ def method_missing (name, *args)
234
+ case
235
+ when name.to_s =~ /^(?:convert|from)_([a-z]+)(!)?$/
236
+ $2 ? convert!($1) : convert($1)
237
+ else
238
+ super
239
+ end
240
+ end
241
+
242
+ def respond_to? (method)
243
+ method =~ /^(?:convert|from)_([a-z]+)(!)?$/ || super
244
+ end
245
+
249
246
  def <=> (other)
250
247
  to_s <=> other.to_s
251
248
  end
@@ -18,6 +18,6 @@
18
18
 
19
19
  module BibTeX
20
20
  module Version
21
- STRING = '2.0.1'.freeze
21
+ STRING = '2.0.2'.freeze
22
22
  end
23
23
  end
@@ -30,11 +30,11 @@ module BibTeX
30
30
 
31
31
  end
32
32
 
33
- describe '.parse' do
34
- it 'accepts filters' do
35
- Bibliography.parse("@misc{k, title = {\\''u}}", :filter => 'latex')[0].title.must_be :==, 'ü'
36
- end
37
- end
33
+ describe '.parse' do
34
+ it 'accepts filters' do
35
+ Bibliography.parse("@misc{k, title = {\\''u}}", :filter => 'latex')[0].title.must_be :==, 'ü'
36
+ end
37
+ end
38
38
 
39
39
  describe 'given a populated biliography' do
40
40
  before do
@@ -66,41 +66,41 @@ module BibTeX
66
66
  END
67
67
  end
68
68
 
69
- it 'should support access by index' do
69
+ it 'supports access by index' do
70
70
  assert_equal 'ruby', @bib[1].keywords
71
71
  end
72
72
 
73
- it 'should support access by range' do
73
+ it 'supports access by range' do
74
74
  assert_equal %w{2008 2007}, @bib[1..2].map(&:year)
75
75
  end
76
76
 
77
- it 'should support access by index and offset' do
77
+ it 'supports access by index and offset' do
78
78
  assert_equal %w{2008 2007}, @bib[1,2].map(&:year)
79
79
  end
80
80
 
81
- it 'should support queries by symbol key' do
81
+ it 'supports queries by symbol key' do
82
82
  refute_nil @bib[:rails]
83
83
  assert_nil @bib[:ruby]
84
84
  end
85
85
 
86
- it 'should support queries by symbol key and selector' do
86
+ it 'supports queries by symbol key and selector' do
87
87
  assert_equal 1, @bib.q(:all, :rails).length
88
88
  refute_nil @bib.q(:first, :rails)
89
89
  assert_nil @bib.q(:first, :railss)
90
90
  end
91
91
 
92
- it 'should support queries by string key' do
92
+ it 'supports queries by string key' do
93
93
  refute_nil @bib['rails']
94
94
  assert_nil @bib['ruby']
95
95
  end
96
96
 
97
- it 'should support queries by type string' do
97
+ it 'supports queries by type string' do
98
98
  assert_equal 2, @bib['@book'].length
99
99
  assert_equal 1, @bib['@article'].length
100
100
  assert_equal 0, @bib['@collection'].length
101
101
  end
102
102
 
103
- it 'should support queries by type string and selector' do
103
+ it 'supports queries by type string and selector' do
104
104
  assert_equal 2, @bib.q(:all, '@book').length
105
105
  refute_nil @bib.q(:first, '@book')
106
106
  assert_equal 1, @bib.q(:all, '@article').length
@@ -110,16 +110,16 @@ module BibTeX
110
110
  end
111
111
 
112
112
 
113
- it 'should support queries by pattern' do
113
+ it 'supports queries by pattern' do
114
114
  assert_equal 0, @bib[/reilly/].length
115
115
  assert_equal 2, @bib[/reilly/i].length
116
116
  end
117
117
 
118
- it 'should support queries by type string and conditions' do
118
+ it 'supports queries by type string and conditions' do
119
119
  assert_equal 1, @bib['@book[keywords=ruby]'].length
120
120
  end
121
121
 
122
- it 'should support queries by bibtex element' do
122
+ it 'supports queries by bibtex element' do
123
123
  entry = Entry.parse(<<-END).first
124
124
  @article{segaran2007,
125
125
  title = {{Programming collective intelligence}},
@@ -133,11 +133,11 @@ module BibTeX
133
133
  assert_equal 0, @bib[entry].length
134
134
  end
135
135
 
136
- it 'should support query and additional block' do
136
+ it 'supports query and additional block' do
137
137
  assert_equal 1, @bib.q('@book') { |e| e.keywords.split(/,/).length > 1 }.length
138
138
  end
139
139
 
140
- it 'should support saving the bibliography to a file' do
140
+ it 'supports saving the bibliography to a file' do
141
141
  tmp = Tempfile.new('bibtex')
142
142
  tmp.close
143
143
  @bib.save_to(tmp.path)
@@ -163,38 +163,38 @@ module BibTeX
163
163
 
164
164
  end
165
165
 
166
- describe 'LaTeX filter' do
167
- before do
168
- @bib['rails'].keywords = 'r\\"uby'
169
- end
170
-
171
- it 'converts LaTeX umlauts' do
172
- @bib.convert(:latex)['rails'].keywords.must_be :==, 'rüby'
173
- end
174
-
175
- end
176
-
177
- describe 'BibTeXML export' do
178
- before { @bibtexml = Tempfile.new('bibtexml') }
179
- after { @bibtexml.unlink }
180
-
181
- it 'should support exporting to BibTeXML' do
182
- @bib.to_xml.write(@bibtexml, 2)
183
- @bibtexml.rewind
184
- xml = REXML::Document.new(@bibtexml)
185
- xml.root.namespace.must_be :==, 'http://bibtexml.sf.net/'
186
- xml.root.get_elements('//bibtex:entry').wont_be_empty
187
- end
166
+ describe 'LaTeX filter' do
167
+ before do
168
+ @bib['rails'].keywords = 'r\\"uby'
169
+ end
170
+
171
+ it 'converts LaTeX umlauts' do
172
+ @bib.convert(:latex)['rails'].keywords.must_be :==, 'rüby'
173
+ end
174
+
175
+ end
176
+
177
+ describe 'BibTeXML export' do
178
+ before { @bibtexml = Tempfile.new('bibtexml') }
179
+ after { @bibtexml.unlink }
180
+
181
+ it 'supports exporting to BibTeXML' do
182
+ @bib.to_xml.write(@bibtexml, 2)
183
+ @bibtexml.rewind
184
+ xml = REXML::Document.new(@bibtexml)
185
+ xml.root.namespace.must_be :==, 'http://bibtexml.sf.net/'
186
+ xml.root.get_elements('//bibtex:entry').wont_be_empty
187
+ end
188
188
 
189
- it 'should support exporting to extended BibTeXML' do
190
- @bib.to_xml(:extended => true).write(@bibtexml, 2)
191
- @bibtexml.rewind
192
- xml = REXML::Document.new(@bibtexml)
193
- xml.root.namespace.must_be :==, 'http://bibtexml.sf.net/'
194
- xml.root.get_elements('//bibtex:person').wont_be_empty
195
- end
196
-
197
- end
189
+ it 'supports exporting to extended BibTeXML' do
190
+ @bib.to_xml(:extended => true).write(@bibtexml, 2)
191
+ @bibtexml.rewind
192
+ xml = REXML::Document.new(@bibtexml)
193
+ xml.root.namespace.must_be :==, 'http://bibtexml.sf.net/'
194
+ xml.root.get_elements('//bibtex:person').wont_be_empty
195
+ end
196
+
197
+ end
198
198
  end
199
199
 
200
200
 
@@ -11,140 +11,146 @@ module BibTeX
11
11
  end
12
12
  end
13
13
 
14
- describe 'cross-references' do
15
- it 'has no cross-reference by default' do
16
- assert_equal false, Entry.new.has_cross_reference?
17
- end
18
-
19
- it 'is not cross-referenced by default' do
20
- assert_equal false, Entry.new.cross_referenced?
21
- Entry.new.cross_referenced_by.must_be_empty
22
- end
23
-
24
- describe 'given a bibliography with cross referenced entries' do
25
- before do
26
- @bib = Bibliography.parse <<-END
27
- @book{a, editor = "A", title = "A"}
28
- @incollection{a1, crossref = "a"}
29
- @incollection{b1, crossref = "b"}
30
- END
31
- end
32
-
33
- describe '#has_cross_reference?' do
34
- it 'returns true if the entry has a valid cross-reference' do
35
- assert_equal true, @bib['a1'].has_cross_reference?
36
- end
37
- it 'returns false if the entry has no valid cross-reference' do
38
- assert_equal false, @bib['a'].has_cross_reference?
39
- assert_equal false, @bib['b1'].has_cross_reference?
40
- end
41
- end
42
-
43
- describe '#cross_referemced?' do
44
- it 'returns true if the entry is cross-referenced by another entry' do
45
- assert_equal true, @bib['a'].cross_referenced?
46
- end
47
- it 'returns false if the entry is not cross-referenced' do
48
- assert_equal false, @bib['a1'].cross_referenced?
49
- end
50
- end
51
-
52
- describe '#cross_referenced_by' do
53
- it 'returns a list of all entries that cross-reference this entry' do
54
- @bib['a'].cross_referenced_by.must_include(@bib['a1'])
55
- end
56
-
57
- it 'returns an empty list if there are no cross-references to this entry' do
58
- @bib['a1'].cross_referenced_by.must_be_empty
59
- end
60
- end
61
-
62
- describe 'resolve field values using array accessors #[]' do
63
- describe 'when a "title" is set in the entry itself' do
64
- before { @bib['a1'].title = 'A1' }
65
- it 'returns the title' do
66
- @bib['a1'].title.must_be :==, 'A1'
67
- end
68
- end
69
-
70
- describe 'when "title" is undefined for the entry but defined in the reference' do
71
- it 'returns the referenced title' do
72
- @bib['a1'].title.must_be :==, @bib['a'].title
73
- end
74
- end
75
-
76
- describe 'when "booktitle" is undefined for the entry but defined in the reference' do
77
- before { @bib['a'].booktitle = "A Booktitle" }
78
- it 'returns the referenced booktitle' do
79
- @bib['a1'].booktitle.must_be :==, @bib['a'].booktitle
80
- end
81
- end
14
+ describe 'cross-references' do
15
+ it 'has no cross-reference by default' do
16
+ assert_equal false, Entry.new.has_cross_reference?
17
+ end
18
+
19
+ it 'is not cross-referenced by default' do
20
+ assert_equal false, Entry.new.cross_referenced?
21
+ Entry.new.cross_referenced_by.must_be_empty
22
+ end
23
+
24
+ describe 'given a bibliography with cross referenced entries' do
25
+ before do
26
+ @bib = Bibliography.parse <<-END
27
+ @book{a, editor = "A", title = "A"}
28
+ @incollection{a1, crossref = "a"}
29
+ @incollection{b1, crossref = "b"}
30
+ END
31
+ end
32
+
33
+ describe '#has_cross_reference?' do
34
+ it 'returns true if the entry has a valid cross-reference' do
35
+ assert_equal true, @bib['a1'].has_cross_reference?
36
+ end
37
+ it 'returns false if the entry has no valid cross-reference' do
38
+ assert_equal false, @bib['a'].has_cross_reference?
39
+ assert_equal false, @bib['b1'].has_cross_reference?
40
+ end
41
+ end
42
+
43
+ describe '#cross_referenced?' do
44
+ it 'returns true if the entry is cross-referenced by another entry' do
45
+ assert_equal true, @bib['a'].cross_referenced?
46
+ end
47
+ it 'returns false if the entry is not cross-referenced' do
48
+ assert_equal false, @bib['a1'].cross_referenced?
49
+ end
50
+ end
51
+
52
+ describe '#cross_referenced_by' do
53
+ it 'returns a list of all entries that cross-reference this entry' do
54
+ @bib['a'].cross_referenced_by.must_include(@bib['a1'])
55
+ end
56
+
57
+ it 'returns an empty list if there are no cross-references to this entry' do
58
+ @bib['a1'].cross_referenced_by.must_be_empty
59
+ end
60
+ end
61
+
62
+ describe '#respond_to?' do
63
+ it 'takes into account the inherited attributes' do
64
+ @bib['a1'].respond_to?(:title)
65
+ end
66
+ end
67
+
68
+ describe 'resolve field values using array accessors #[]' do
69
+ describe 'when a "title" is set in the entry itself' do
70
+ before { @bib['a1'].title = 'A1' }
71
+ it 'returns the title' do
72
+ @bib['a1'].title.must_be :==, 'A1'
73
+ end
74
+ end
75
+
76
+ describe 'when "title" is undefined for the entry but defined in the reference' do
77
+ it 'returns the referenced title' do
78
+ @bib['a1'].title.must_be :==, @bib['a'].title
79
+ end
80
+ end
81
+
82
+ describe 'when "booktitle" is undefined for the entry but defined in the reference' do
83
+ before { @bib['a'].booktitle = "A Booktitle" }
84
+ it 'returns the referenced booktitle' do
85
+ @bib['a1'].booktitle.must_be :==, @bib['a'].booktitle
86
+ end
87
+ end
82
88
 
83
- describe 'when "booktitle" is undefined for the entry and the reference but the reference has a "title"' do
84
- it "returns the reference's title" do
85
- @bib['a1'].booktitle.must_be :==, @bib['a'].title
86
- end
87
- end
88
-
89
- it 'does not store referenced values permanently' do
90
- refute_nil @bib['a1'].booktitle
91
- assert_nil @bib['a1'].fields[:booktitle]
92
- end
89
+ describe 'when "booktitle" is undefined for the entry and the reference but the reference has a "title"' do
90
+ it "returns the reference's title" do
91
+ @bib['a1'].booktitle.must_be :==, @bib['a'].title
92
+ end
93
+ end
94
+
95
+ it 'does not store referenced values permanently' do
96
+ refute_nil @bib['a1'].booktitle
97
+ assert_nil @bib['a1'].fields[:booktitle]
98
+ end
93
99
 
94
- describe '#inherited_fields' do
95
- it 'returns an empty list by default' do
96
- Entry.new.inherited_fields.must_be_empty
97
- end
98
-
99
- it 'returns an empty list if this entry has no cross-reference' do
100
- @bib['a'].inherited_fields.must_be_empty
101
- end
102
-
103
- it 'returns an empty list if this entry has a cross-reference but the reference does not exist in the bibliography' do
104
- @bib['b1'].inherited_fields.must_be_empty
105
- end
106
-
107
- it 'returns a list of all fields not set in the field but in the reference' do
108
- @bib['a1'].inherited_fields.must_be :==, [:booktitle, :editor, :title]
109
- end
110
- end
111
-
112
- describe '#save_inherited_fields' do
113
- it 'copies referenced values to the entry' do
114
- @bib['a1'].title = 'a1'
115
- @bib['a1'].save_inherited_fields
116
- @bib['a1'].fields[:booktitle].must_be :==, @bib['a'].title
117
- @bib['a1'].fields[:title].wont_be :==, @bib['a'].title
118
- end
119
- end
120
- end
121
-
122
- end
123
- end
124
-
125
- describe '#names' do
126
- it 'returns an empty list by default' do
127
- Entry.new.names.must_be :==, []
128
- end
129
-
130
- it 'returns the author (if set)' do
131
- Entry.new(:author => 'A').names.must_be :==, %w{ A }
132
- end
100
+ describe '#inherited_fields' do
101
+ it 'returns an empty list by default' do
102
+ Entry.new.inherited_fields.must_be_empty
103
+ end
104
+
105
+ it 'returns an empty list if this entry has no cross-reference' do
106
+ @bib['a'].inherited_fields.must_be_empty
107
+ end
108
+
109
+ it 'returns an empty list if this entry has a cross-reference but the reference does not exist in the bibliography' do
110
+ @bib['b1'].inherited_fields.must_be_empty
111
+ end
112
+
113
+ it 'returns a list of all fields not set in the field but in the reference' do
114
+ @bib['a1'].inherited_fields.must_be :==, [:booktitle, :editor, :title]
115
+ end
116
+ end
117
+
118
+ describe '#save_inherited_fields' do
119
+ it 'copies referenced values to the entry' do
120
+ @bib['a1'].title = 'a1'
121
+ @bib['a1'].save_inherited_fields
122
+ @bib['a1'].fields[:booktitle].must_be :==, @bib['a'].title
123
+ @bib['a1'].fields[:title].wont_be :==, @bib['a'].title
124
+ end
125
+ end
126
+ end
127
+
128
+ end
129
+ end
130
+
131
+ describe '#names' do
132
+ it 'returns an empty list by default' do
133
+ Entry.new.names.must_be :==, []
134
+ end
135
+
136
+ it 'returns the author (if set)' do
137
+ Entry.new(:author => 'A').names.must_be :==, %w{ A }
138
+ end
133
139
 
134
- it 'returns all authors (if set)' do
135
- Entry.new(:author => 'A B and C D').parse_names.names.length.must_be :==, 2
136
- end
137
-
138
- it 'returns the editor (if set)' do
139
- Entry.new(:editor => 'A').names.must_be :==, %w{ A }
140
- end
140
+ it 'returns all authors (if set)' do
141
+ Entry.new(:author => 'A B and C D').parse_names.names.length.must_be :==, 2
142
+ end
143
+
144
+ it 'returns the editor (if set)' do
145
+ Entry.new(:editor => 'A').names.must_be :==, %w{ A }
146
+ end
141
147
 
142
- it 'returns the translator (if set)' do
143
- Entry.new(:translator => 'A').names.must_be :==, %w{ A }
144
- end
145
-
146
- end
147
-
148
+ it 'returns the translator (if set)' do
149
+ Entry.new(:translator => 'A').names.must_be :==, %w{ A }
150
+ end
151
+
152
+ end
153
+
148
154
  describe 'month conversion' do
149
155
  before do
150
156
  @entry = Entry.new
@@ -254,36 +260,36 @@ module BibTeX
254
260
 
255
261
  end
256
262
 
257
- describe 'LaTeX filter' do
258
- before do
259
- @entry.title = 'M\\"{o}by Dick'
260
- end
261
-
262
- describe '#convert' do
263
- it 'converts LaTeX umlauts' do
264
- @entry.convert(:latex).title.must_be :==, 'Möby Dick'
265
- end
266
-
267
- it 'does not change the original entry' do
268
- e = @entry.convert(:latex)
269
- e.wont_be :==, @entry
270
- e.title.to_s.length.must_be :<, @entry.title.to_s.length
271
- end
272
- end
263
+ describe 'LaTeX filter' do
264
+ before do
265
+ @entry.title = 'M\\"{o}by Dick'
266
+ end
267
+
268
+ describe '#convert' do
269
+ it 'converts LaTeX umlauts' do
270
+ @entry.convert(:latex).title.must_be :==, 'Möby Dick'
271
+ end
272
+
273
+ it 'does not change the original entry' do
274
+ e = @entry.convert(:latex)
275
+ e.wont_be :==, @entry
276
+ e.title.to_s.length.must_be :<, @entry.title.to_s.length
277
+ end
278
+ end
273
279
 
274
- describe '#convert!' do
275
- it 'converts LaTeX umlauts' do
276
- @entry.convert!(:latex).title.must_be :==, 'Möby Dick'
277
- end
278
-
279
- it 'changes the original entry in-place' do
280
- e = @entry.convert!(:latex)
281
- e.must_be :equal?, @entry
282
- e.title.to_s.length.must_be :==, @entry.title.to_s.length
283
- end
284
- end
285
-
286
- end
280
+ describe '#convert!' do
281
+ it 'converts LaTeX umlauts' do
282
+ @entry.convert!(:latex).title.must_be :==, 'Möby Dick'
283
+ end
284
+
285
+ it 'changes the original entry in-place' do
286
+ e = @entry.convert!(:latex)
287
+ e.must_be :equal?, @entry
288
+ e.title.to_s.length.must_be :==, @entry.title.to_s.length
289
+ end
290
+ end
291
+
292
+ end
287
293
  end
288
294
 
289
295
  describe 'citeproc export' do
@@ -393,57 +399,57 @@ module BibTeX
393
399
 
394
400
  end
395
401
 
396
- describe 'default keys' do
397
- before {
398
- @e1 = Entry.new(:type => 'book', :author => 'Poe, Edgar A.', :title => 'The Raven', :editor => 'John Hopkins', :year => 1996)
399
- @e2 = Entry.new(:type => 'book', :title => 'The Raven', :editor => 'John Hopkins', :year => 1996)
400
- @e3 = Entry.new(:type => 'book', :author => 'Poe, Edgar A.', :title => 'The Raven', :editor => 'John Hopkins')
401
- }
402
-
403
- it 'should return "unknown-a" for an empty Entry' do
404
- Entry.new.key.must_be :==, 'unknown-a'
405
- end
406
-
407
- it 'should return a key made up of author-year-a if all fields are present' do
408
- @e1.key.must_be :==, 'poe1996a'
409
- end
402
+ describe 'default keys' do
403
+ before {
404
+ @e1 = Entry.new(:type => 'book', :author => 'Poe, Edgar A.', :title => 'The Raven', :editor => 'John Hopkins', :year => 1996)
405
+ @e2 = Entry.new(:type => 'book', :title => 'The Raven', :editor => 'John Hopkins', :year => 1996)
406
+ @e3 = Entry.new(:type => 'book', :author => 'Poe, Edgar A.', :title => 'The Raven', :editor => 'John Hopkins')
407
+ }
408
+
409
+ it 'should return "unknown-a" for an empty Entry' do
410
+ Entry.new.key.must_be :==, 'unknown-a'
411
+ end
412
+
413
+ it 'should return a key made up of author-year-a if all fields are present' do
414
+ @e1.key.must_be :==, 'poe1996a'
415
+ end
410
416
 
411
- it 'should return a key made up of editor-year-a if there is no author' do
412
- @e2.key.must_be :==, 'john1996a'
413
- end
417
+ it 'should return a key made up of editor-year-a if there is no author' do
418
+ @e2.key.must_be :==, 'john1996a'
419
+ end
414
420
 
415
- it 'should return use the last name if the author/editor names have been parsed' do
416
- @e2.parse_names.key.must_be :==, 'hopkins1996a'
417
- end
421
+ it 'should return use the last name if the author/editor names have been parsed' do
422
+ @e2.parse_names.key.must_be :==, 'hopkins1996a'
423
+ end
418
424
 
419
- it 'skips the year if not present' do
420
- @e3.key.must_be :==, 'poe-a'
421
- end
422
- end
423
-
424
- describe 'when the entry is added to a Bibliography' do
425
- before {
426
- @e = Entry.new
427
- @bib = Bibliography.new
428
- }
429
-
430
- it 'should register itself with its key' do
431
- @bib << @e
432
- @bib.entries.keys.must_include @e.key
433
- end
434
-
435
- describe "when there is already an element registered with the entry's key" do
436
- before { @bib << Entry.new }
437
-
438
- it "should find a suitable key" do
439
- k = @e.key
440
- @bib << @e
441
- @bib.entries.keys.must_include @e.key
442
- k.wont_be :==, @e.key
443
- end
444
-
445
- end
446
- end
447
-
425
+ it 'skips the year if not present' do
426
+ @e3.key.must_be :==, 'poe-a'
427
+ end
428
+ end
429
+
430
+ describe 'when the entry is added to a Bibliography' do
431
+ before {
432
+ @e = Entry.new
433
+ @bib = Bibliography.new
434
+ }
435
+
436
+ it 'should register itself with its key' do
437
+ @bib << @e
438
+ @bib.entries.keys.must_include @e.key
439
+ end
440
+
441
+ describe "when there is already an element registered with the entry's key" do
442
+ before { @bib << Entry.new }
443
+
444
+ it "should find a suitable key" do
445
+ k = @e.key
446
+ @bib << @e
447
+ @bib.entries.keys.must_include @e.key
448
+ k.wont_be :==, @e.key
449
+ end
450
+
451
+ end
452
+ end
453
+
448
454
  end
449
455
  end