bibtex-ruby 2.0.1 → 2.0.2

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.

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