citeproc-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +78 -0
- data/lib/citeproc.rb +100 -0
- data/lib/citeproc/bibliography.rb +57 -0
- data/lib/citeproc/data.rb +149 -0
- data/lib/citeproc/date.rb +133 -0
- data/lib/citeproc/formatter.rb +38 -0
- data/lib/citeproc/item.rb +53 -0
- data/lib/citeproc/name.rb +284 -0
- data/lib/citeproc/processor.rb +166 -0
- data/lib/citeproc/selector.rb +61 -0
- data/lib/citeproc/variable.rb +82 -0
- data/lib/citeproc/version.rb +3 -0
- data/lib/csl/locale.rb +223 -0
- data/lib/csl/node.rb +72 -0
- data/lib/csl/nodes.rb +1364 -0
- data/lib/csl/renderer.rb +88 -0
- data/lib/csl/sort.rb +53 -0
- data/lib/csl/style.rb +110 -0
- data/lib/csl/term.rb +124 -0
- data/lib/extensions/core.rb +43 -0
- data/lib/plugins/filters/bibtex.rb +12 -0
- data/lib/plugins/formats/default.rb +134 -0
- data/lib/plugins/formats/html.rb +67 -0
- data/lib/support/attributes.rb +99 -0
- data/lib/support/tree.rb +80 -0
- data/resource/locale/locales-af-ZA.xml +304 -0
- data/resource/locale/locales-ar-AR.xml +304 -0
- data/resource/locale/locales-bg-BG.xml +304 -0
- data/resource/locale/locales-ca-AD.xml +304 -0
- data/resource/locale/locales-cs-CZ.xml +304 -0
- data/resource/locale/locales-da-DK.xml +304 -0
- data/resource/locale/locales-de-AT.xml +304 -0
- data/resource/locale/locales-de-CH.xml +304 -0
- data/resource/locale/locales-de-DE.xml +332 -0
- data/resource/locale/locales-el-GR.xml +303 -0
- data/resource/locale/locales-en-US.xml +313 -0
- data/resource/locale/locales-es-ES.xml +304 -0
- data/resource/locale/locales-et-EE.xml +304 -0
- data/resource/locale/locales-fr-FR.xml +304 -0
- data/resource/locale/locales-he-IL.xml +304 -0
- data/resource/locale/locales-hu-HU.xml +304 -0
- data/resource/locale/locales-is-IS.xml +304 -0
- data/resource/locale/locales-it-IT.xml +304 -0
- data/resource/locale/locales-ja-JP.xml +304 -0
- data/resource/locale/locales-kh-KH.xml +303 -0
- data/resource/locale/locales-ko-KR.xml +304 -0
- data/resource/locale/locales-mn-MN.xml +304 -0
- data/resource/locale/locales-nb-NO.xml +304 -0
- data/resource/locale/locales-nl-NL.xml +304 -0
- data/resource/locale/locales-nn-NO.xml +304 -0
- data/resource/locale/locales-pl-PL.xml +304 -0
- data/resource/locale/locales-pt-BR.xml +304 -0
- data/resource/locale/locales-pt-PT.xml +304 -0
- data/resource/locale/locales-ro-RO.xml +304 -0
- data/resource/locale/locales-ru-RU.xml +304 -0
- data/resource/locale/locales-sk-SK.xml +304 -0
- data/resource/locale/locales-sl-SI.xml +304 -0
- data/resource/locale/locales-sr-RS.xml +304 -0
- data/resource/locale/locales-sv-SE.xml +304 -0
- data/resource/locale/locales-th-TH.xml +304 -0
- data/resource/locale/locales-tr-TR.xml +304 -0
- data/resource/locale/locales-uk-UA.xml +304 -0
- data/resource/locale/locales-vi-VN.xml +304 -0
- data/resource/locale/locales-zh-CN.xml +304 -0
- data/resource/locale/locales-zh-TW.xml +304 -0
- data/resource/schema/csl-categories.rnc +39 -0
- data/resource/schema/csl-data.rnc +98 -0
- data/resource/schema/csl-terms.rnc +106 -0
- data/resource/schema/csl-types.rnc +39 -0
- data/resource/schema/csl-variables.rnc +182 -0
- data/resource/schema/csl.rnc +941 -0
- data/resource/style/acta-materialia-x.csl +128 -0
- data/resource/style/advanced-engineering-materials-x.csl +121 -0
- data/resource/style/ama.csl +185 -0
- data/resource/style/ama2-x.csl +179 -0
- data/resource/style/apa-x.csl +324 -0
- data/resource/style/apa.csl +254 -0
- data/resource/style/apsa-x.csl +163 -0
- data/resource/style/apsa.csl +176 -0
- data/resource/style/asa-x.csl +203 -0
- data/resource/style/asa.csl +216 -0
- data/resource/style/asm-journals-x.csl +131 -0
- data/resource/style/bibtex-x2.csl +175 -0
- data/resource/style/bluebook-demo-x.csl +392 -0
- data/resource/style/bluebook-demo.csl +942 -0
- data/resource/style/chicago-author-date-listing.csl +434 -0
- data/resource/style/chicago-author-date.csl +369 -0
- data/resource/style/chicago-fullnote-bibliography-bb.csl +928 -0
- data/resource/style/chicago-fullnote-bibliography.csl +695 -0
- data/resource/style/chicago-note-bibliography.csl +446 -0
- data/resource/style/chicago-note.csl +388 -0
- data/resource/style/greek-chicago-x.csl +1182 -0
- data/resource/style/harvard1-institution-italic.csl +190 -0
- data/resource/style/harvard1.csl +181 -0
- data/resource/style/ieee.csl +129 -0
- data/resource/style/mhra-x.csl +312 -0
- data/resource/style/mhra.csl +390 -0
- data/resource/style/mhra_note_without_bibliography-x.csl +330 -0
- data/resource/style/mhra_note_without_bibliography.csl +338 -0
- data/resource/style/mla-x.csl +178 -0
- data/resource/style/mla.csl +189 -0
- data/resource/style/nature-x.csl +81 -0
- data/resource/style/nature.csl +88 -0
- data/resource/style/nlm.csl +117 -0
- data/spec/citeproc/bibliography_spec.rb +45 -0
- data/spec/citeproc/citeproc_spec.rb +76 -0
- data/spec/citeproc/date_spec.rb +85 -0
- data/spec/citeproc/formatter_spec.rb +101 -0
- data/spec/citeproc/item_spec.rb +71 -0
- data/spec/citeproc/name_spec.rb +30 -0
- data/spec/citeproc/processor_spec.rb +61 -0
- data/spec/citeproc/selector_spec.rb +82 -0
- data/spec/citeproc/variable_spec.rb +69 -0
- data/spec/csl/locale_spec.rb +208 -0
- data/spec/csl/node_spec.rb +25 -0
- data/spec/csl/nodes_spec.rb +140 -0
- data/spec/csl/style_spec.rb +62 -0
- data/spec/csl/term_spec.rb +56 -0
- data/spec/fixtures/dates.yaml +80 -0
- data/spec/fixtures/names.yaml +115 -0
- data/spec/fixtures/nodes.yaml +245 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/attributes_spec.rb +39 -0
- data/spec/support/tree_spec.rb +163 -0
- metadata +264 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
<style
|
2
|
+
xmlns="http://purl.org/net/xbiblio/csl"
|
3
|
+
class="in-text"
|
4
|
+
xml:lang="en">
|
5
|
+
<info>
|
6
|
+
<title>National Library of Medicine</title>
|
7
|
+
<id>http://www.zotero.org/styles/nlm</id>
|
8
|
+
<link href="http://www.zotero.org/styles/nlm" />
|
9
|
+
<author>
|
10
|
+
<name>Michael Berkowitz</name>
|
11
|
+
<email>mberkowi@gmu.edu</email>
|
12
|
+
</author>
|
13
|
+
<category term="generic-base" />
|
14
|
+
<category term="numeric" />
|
15
|
+
<updated />
|
16
|
+
</info>
|
17
|
+
<macro name="author">
|
18
|
+
<names suffix=". " variable="author">
|
19
|
+
<name delimiter=", " delimiter-precedes-last="always" initialize-with="" name-as-sort-order="all" sort-separator=" " />
|
20
|
+
</names>
|
21
|
+
</macro>
|
22
|
+
<macro name="editor">
|
23
|
+
<names suffix=", editor(s). " variable="editor">
|
24
|
+
<name delimiter=", " delimiter-precedes-last="always" initialize-with="" name-as-sort-order="all" sort-separator=" " />
|
25
|
+
</names>
|
26
|
+
</macro>
|
27
|
+
<macro name="publisher">
|
28
|
+
<text suffix=": " variable="publisher-place" />
|
29
|
+
<text suffix="; " variable="publisher" />
|
30
|
+
<date variable="issued">
|
31
|
+
<date-part name="year" suffix=". " />
|
32
|
+
</date>
|
33
|
+
</macro>
|
34
|
+
<macro name="access">
|
35
|
+
<group delimiter=" ">
|
36
|
+
<group delimiter=" " prefix="[" suffix="]">
|
37
|
+
<text term="cited" text-case="lowercase" />
|
38
|
+
<date suffix=" " variable="accessed">
|
39
|
+
<date-part name="year" />
|
40
|
+
<date-part form="short" name="month" prefix=" " />
|
41
|
+
<date-part name="day" prefix=" " />
|
42
|
+
</date>
|
43
|
+
</group>
|
44
|
+
<group>
|
45
|
+
<text value="Available from: " />
|
46
|
+
<text variable="URL" />
|
47
|
+
</group>
|
48
|
+
</group>
|
49
|
+
</macro>
|
50
|
+
<macro name="title">
|
51
|
+
<group delimiter=" ">
|
52
|
+
<text variable="title" />
|
53
|
+
<choose>
|
54
|
+
<if variable="URL">
|
55
|
+
<text prefix="[" suffix="]" term="internet" text-case="capitalize-first" />
|
56
|
+
</if>
|
57
|
+
</choose>
|
58
|
+
</group>
|
59
|
+
</macro>
|
60
|
+
<macro name="edition">
|
61
|
+
<choose>
|
62
|
+
<if is-numeric="edition">
|
63
|
+
<group delimiter=" ">
|
64
|
+
<number form="ordinal" variable="edition" />
|
65
|
+
<text form="short" suffix="." term="edition" />
|
66
|
+
</group>
|
67
|
+
</if>
|
68
|
+
<else>
|
69
|
+
<text suffix="." variable="edition" />
|
70
|
+
</else>
|
71
|
+
</choose>
|
72
|
+
</macro>
|
73
|
+
<citation
|
74
|
+
collapse="citation-number">
|
75
|
+
<sort>
|
76
|
+
<key variable="citation-number" />
|
77
|
+
</sort>
|
78
|
+
<layout delimiter="; " prefix="(" suffix=")">
|
79
|
+
<text variable="citation-number" />
|
80
|
+
</layout>
|
81
|
+
</citation>
|
82
|
+
<bibliography
|
83
|
+
second-field-align="true">
|
84
|
+
<layout>
|
85
|
+
<text suffix=". " variable="citation-number" />
|
86
|
+
<text macro="author" />
|
87
|
+
<text macro="title" suffix=". " />
|
88
|
+
<choose>
|
89
|
+
<if type="book">
|
90
|
+
<text macro="edition" prefix=" " suffix=" " />
|
91
|
+
<text macro="publisher" prefix=" " />
|
92
|
+
</if>
|
93
|
+
<else-if type="chapter">
|
94
|
+
<group prefix=" " suffix=". ">
|
95
|
+
<text suffix=": " term="in" text-case="capitalize-first" />
|
96
|
+
<text macro="editor" />
|
97
|
+
<text variable="container-title" />
|
98
|
+
</group>
|
99
|
+
<text macro="publisher" prefix=" " />
|
100
|
+
<text prefix=" p. " suffix="." variable="page" />
|
101
|
+
</else-if>
|
102
|
+
<else>
|
103
|
+
<text form="short" suffix=". " variable="container-title" />
|
104
|
+
<date suffix=";" variable="issued">
|
105
|
+
<date-part name="year" suffix=" " />
|
106
|
+
<date-part form="short" name="month" suffix=" " />
|
107
|
+
<date-part name="day" />
|
108
|
+
</date>
|
109
|
+
<text variable="volume" />
|
110
|
+
<text prefix="(" suffix="):" variable="issue" />
|
111
|
+
<text suffix="." variable="page" />
|
112
|
+
</else>
|
113
|
+
</choose>
|
114
|
+
<text macro="access" />
|
115
|
+
</layout>
|
116
|
+
</bibliography>
|
117
|
+
</style>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module CiteProc
|
2
|
+
describe Bibliography do
|
3
|
+
|
4
|
+
let(:json) {'[{"test":"test","bibliography-errors":[]},["1","2"]]'}
|
5
|
+
|
6
|
+
describe '#new' do
|
7
|
+
it { should_not be_nil }
|
8
|
+
|
9
|
+
it 'accepts a JSON string' do
|
10
|
+
Bibliography.new(json).should_not be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'accepts a data array' do
|
14
|
+
Bibliography.new([1,2,3]).data.should == [1,2,3]
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'accepts an options hash' do
|
18
|
+
Bibliography.new('test'=>'test').options['test'].should == 'test'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'accepts an options hash with errors' do
|
22
|
+
Bibliography.new('bibliography-errors'=>[1,2,3]).errors.should == [1,2,3]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#to_json' do
|
27
|
+
it 'returns valid JSON when empty' do
|
28
|
+
JSON.parse(Bibliography.new.to_json).should_not be_nil
|
29
|
+
end
|
30
|
+
it 'returns valid JSON with data' do
|
31
|
+
JSON.parse(Bibliography.new([1,2,3]).to_json).should_not be_nil
|
32
|
+
end
|
33
|
+
it 'returns valid JSON with options' do
|
34
|
+
JSON.parse(Bibliography.new({'test'=>'test'}).to_json).should_not be_nil
|
35
|
+
end
|
36
|
+
it 'returns valid JSON with options and data' do
|
37
|
+
JSON.parse(Bibliography.new([{'test'=>'test'}, [1,2]]).to_json).should_not be_nil
|
38
|
+
end
|
39
|
+
it 'supports round-trips' do
|
40
|
+
Bibliography.new(json).to_json.should == json
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#
|
2
|
+
# This generates RSpec tests from the JSON test cases of the citeproc-tests
|
3
|
+
# suite.
|
4
|
+
#
|
5
|
+
|
6
|
+
|
7
|
+
#
|
8
|
+
# Filter applied to each test to decide whether we should run it. Use this
|
9
|
+
# to stay sane while the Processor is not feature-complete!
|
10
|
+
#
|
11
|
+
def filter(file, fixture)
|
12
|
+
# return ['affix_InterveningEmpty.json'].include?(File.basename(file))
|
13
|
+
# File.basename(file) =~ /bugreports_greek/i
|
14
|
+
# File.basename(file) =~ /sort_stripmark/i
|
15
|
+
# return File.basename(file) =~ /^date_rawparsesimpledate/i
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
module CiteProc
|
20
|
+
|
21
|
+
describe 'citeproc' do
|
22
|
+
|
23
|
+
let(:proc) { Processor.new }
|
24
|
+
|
25
|
+
Test::Fixtures::Processor.each_pair do |file, fixture|
|
26
|
+
|
27
|
+
tokens = File.basename(file).split(/_|\.json/)
|
28
|
+
|
29
|
+
describe tokens[0].downcase do
|
30
|
+
|
31
|
+
name = tokens[1].gsub(/([[:lower:]])([[:upper:]])/, '\1 \2').downcase
|
32
|
+
|
33
|
+
it name do
|
34
|
+
pending if tokens[0] =~ /^(position|disambiguate|integration|flipflop|collapse|parallel)/
|
35
|
+
|
36
|
+
proc.style = fixture['csl']
|
37
|
+
proc.import(fixture['input'])
|
38
|
+
proc.format = :html
|
39
|
+
|
40
|
+
proc.add_abbreviations(fixture['abbreviations']) if fixture['abbreviations']
|
41
|
+
|
42
|
+
case fixture['mode']
|
43
|
+
|
44
|
+
when 'citation'
|
45
|
+
# citations => process_citation_cluster
|
46
|
+
# citation_items || :all => make_citation_cluster
|
47
|
+
data = fixture['citation_items']
|
48
|
+
|
49
|
+
unless data
|
50
|
+
result = proc.cite((fixture['bibentries'] && fixture['bibentries'].last) || :all).map { |d| d[1] }.join
|
51
|
+
else
|
52
|
+
result = data.map { |d| proc.cite(d).map { |c| c[1] }.join }.join("\n")
|
53
|
+
end
|
54
|
+
|
55
|
+
when 'bibliography'
|
56
|
+
result = proc.bibliography(fixture['bibsection'] || :all).to_s
|
57
|
+
|
58
|
+
when 'bibliography-header'
|
59
|
+
pending('not yet implemented')
|
60
|
+
|
61
|
+
when 'bibliography-nosort'
|
62
|
+
pending('not yet implemented')
|
63
|
+
|
64
|
+
else
|
65
|
+
CiteProc.log.warn "unkown processor mode: #{fixture['mode']}"
|
66
|
+
pending('not yet implemented')
|
67
|
+
end
|
68
|
+
|
69
|
+
result.should == fixture['result']
|
70
|
+
|
71
|
+
end
|
72
|
+
end if filter(file, fixture)
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module CiteProc
|
4
|
+
|
5
|
+
describe Date do
|
6
|
+
|
7
|
+
describe '#new' do
|
8
|
+
it { should_not be_nil }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.create' do
|
12
|
+
it 'should accept parameters and return a new instance' do
|
13
|
+
Date.create('date-parts' => [[2001, 1]]).year.should == 2001
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#sort' do
|
18
|
+
|
19
|
+
let(:ad2k) { Date.create('date-parts' => [[2000]])}
|
20
|
+
let(:may) { Date.create('date-parts' => [[2000, 5]])}
|
21
|
+
let(:first_of_may) { Date.create('date-parts' => [[2000, 5, 1]])}
|
22
|
+
|
23
|
+
let(:bc100) { Date.create('date-parts' => [[-100]]) }
|
24
|
+
let(:bc50) { Date.create('date-parts' => [[-50]]) }
|
25
|
+
let(:ad50) { Date.create('date-parts' => [[50]]) }
|
26
|
+
let(:ad100) { Date.create('date-parts' => [[100]]) }
|
27
|
+
|
28
|
+
it 'dates with more date-parts will come after those with fewer parts' do
|
29
|
+
(ad2k < may && may < first_of_may).should be true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'negative years are sorted inversely' do
|
33
|
+
[ad50, bc100, bc50, ad100].sort.map(&:year).should == [-100, -50, 50, 100]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Test::Fixtures::Dates.keys.each do |feature|
|
38
|
+
describe feature do
|
39
|
+
Test::Fixtures::Dates[feature].each do |example|
|
40
|
+
|
41
|
+
it example['it'] do
|
42
|
+
dates = example['dates'].map { |date| Date.new(date) }
|
43
|
+
expected = example['expected']
|
44
|
+
options = example['options']
|
45
|
+
|
46
|
+
result = case feature
|
47
|
+
when 'display'
|
48
|
+
dates.map { |date| date.display(options) }
|
49
|
+
when 'json-api'
|
50
|
+
dates.map(&:to_json)
|
51
|
+
end
|
52
|
+
|
53
|
+
result.should == expected
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'literal dates' do
|
61
|
+
|
62
|
+
it 'is not literal by default' do
|
63
|
+
Date.new.should_not be_literal
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'is literal if it contains only a literal field' do
|
67
|
+
Date.create(:literal => 'foo').should be_literal
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'is literal if it contains a literal field' do
|
71
|
+
Date.create('date-parts' => [[2000]], :literal => 'foo').should be_literal
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'uncertain dates' do
|
76
|
+
it 'are uncertain' do
|
77
|
+
Date.new({ 'date-parts' => [[-225]], 'circa' => '1' }).should be_uncertain
|
78
|
+
Date.new { |d| d.parts = [[-225]]; d.circa = true }.should be_uncertain
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module CiteProc
|
2
|
+
describe Formatter do
|
3
|
+
|
4
|
+
it { should_not be_nil }
|
5
|
+
|
6
|
+
describe '#format' do
|
7
|
+
it 'returns the current format by default' do
|
8
|
+
Formatter.new.format.should be_a_kind_of(Format::Default)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'applies the current format if arguments are given' do
|
12
|
+
Formatter.new.format('foo').should == 'foo'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#apply' do
|
17
|
+
|
18
|
+
it 'returns an empty string by default' do
|
19
|
+
Formatter.new.apply.should == ''
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'using the default style' do
|
23
|
+
|
24
|
+
let(:format) { Formatter.new }
|
25
|
+
|
26
|
+
it 'returns the given string if there are no attributes' do
|
27
|
+
format.apply('foo') == 'foo'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns the formatted string (prefix)' do
|
31
|
+
format.apply('foo', 'prefix' => '@').should == '@foo'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns the formatted string (suffix)' do
|
35
|
+
format.apply('foo', 'suffix' => '@').should == 'foo@'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns the formatted string (affixes)' do
|
39
|
+
format.apply('foo', 'prefix' => '@', 'suffix' => '@').should == '@foo@'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns the formatted string (display)' do
|
43
|
+
format.apply('foo', 'display' => 'block').should == 'foo'
|
44
|
+
format.apply('foo', 'display' => 'inline').should == 'foo'
|
45
|
+
format.apply('foo', 'display' => 'right-inline').should == 'foo'
|
46
|
+
format.apply('foo', 'display' => 'left-margin').should == 'foo'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns the formatted string (strip periods)' do
|
50
|
+
format.apply('foo', 'strip-periods' => 'true').should == 'foo'
|
51
|
+
format.apply('foo.', 'strip-periods' => 'true').should == 'foo'
|
52
|
+
format.apply('f.oo.', 'strip-periods' => 'true').should == 'f oo'
|
53
|
+
format.apply('.foo.', 'strip-periods' => 'true').should == 'foo'
|
54
|
+
format.apply('foo...', 'strip-periods' => 'true').should == 'foo'
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns the formatted string (font-style)' do
|
58
|
+
format.apply('foo', 'font-style' => 'normal').should == 'foo'
|
59
|
+
format.apply('foo', 'font-style' => 'italic').should == 'foo'
|
60
|
+
format.apply('foo', 'font-style' => 'italics').should == 'foo'
|
61
|
+
format.apply('foo', 'font-style' => 'oblique').should == 'foo'
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns the formatted string (font-variant)' do
|
65
|
+
format.apply('foo', 'font-variant' => 'normal').should == 'foo'
|
66
|
+
format.apply('foo', 'font-variant' => 'small-caps').should == 'foo'
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns the formatted string (font-weight)' do
|
70
|
+
format.apply('foo', 'font-weight' => 'normal').should == 'foo'
|
71
|
+
format.apply('foo', 'font-weight' => 'bold').should == 'foo'
|
72
|
+
format.apply('foo', 'font-weight' => 'light').should == 'foo'
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns the formatted string (text-decoration)' do
|
76
|
+
format.apply('foo', 'text-decoration' => 'none').should == 'foo'
|
77
|
+
format.apply('foo', 'text-decoration' => 'underline').should == 'foo'
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'returns the formatted string (vertical-align)' do
|
81
|
+
format.apply('foo', 'vertical-align' => 'baseline').should == 'foo'
|
82
|
+
format.apply('foo', 'vertical-align' => 'sub').should == 'foo'
|
83
|
+
format.apply('foo', 'vertical-align' => 'sup').should == 'foo'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns the formatted string (text-case)' do
|
87
|
+
format.apply('foo', 'text-case' => 'none').should == 'foo'
|
88
|
+
format.apply('foo Foo FOO', 'text-case' => 'lowercase').should == 'foo foo foo'
|
89
|
+
format.apply('foo Foo FoO', 'text-case' => 'uppercase').should == 'FOO FOO FOO'
|
90
|
+
format.apply('foo foo foo', 'text-case' => 'capitalize-first').should == 'Foo foo foo'
|
91
|
+
format.apply('foo FOO fOo', 'text-case' => 'capitalize-all').should == 'Foo Foo Foo'
|
92
|
+
format.apply('the short story of foo and bar', 'text-case' => 'title').should == 'The Short Story of Foo and Bar'
|
93
|
+
format.apply('the short story of FOO and BAR', 'text-case' => 'title').should == 'The Short Story of FOO and BAR'
|
94
|
+
format.apply('the short story of foo and bar', 'text-case' => 'sentence').should == 'The short story of foo and bar'
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module CiteProc
|
4
|
+
describe Item do
|
5
|
+
|
6
|
+
let(:item) { Item.new }
|
7
|
+
|
8
|
+
describe '#new' do
|
9
|
+
it { should_not be_nil }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.create' do
|
13
|
+
it 'accepts parameters and returns a new item containing the parameters' do
|
14
|
+
pending #Item.new(:author => 'Poe, Edgar A.').author.family == 'Poe'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#add_observers' do
|
19
|
+
it 'adds a new observer to the empty list of observers' do
|
20
|
+
expect {
|
21
|
+
item.add_observer(stub('observer', :update => nil))
|
22
|
+
}.to change { item.count_observers }.from(0).to(1)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'adds a new observers to the internal list of observers' do
|
26
|
+
expect {
|
27
|
+
item.add_observer(stub('observer1', :update => nil))
|
28
|
+
item.add_observer(stub('observer2', :update => nil))
|
29
|
+
item.add_observer(stub('observer3', :update => nil))
|
30
|
+
}.to change { item.count_observers }.from(0).to(3)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#delete_observers' do
|
35
|
+
let(:observer) { stub('observer', :update => nil) }
|
36
|
+
|
37
|
+
it 'raises no error if the list of observers is empty' do
|
38
|
+
item.delete_observer(observer)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'does not alter the list of observers if the given observer is not currently observing the item' do
|
42
|
+
item.add_observer(observer)
|
43
|
+
item.count_observers.should == 1
|
44
|
+
item.delete_observer(stub('observer2'))
|
45
|
+
item.count_observers.should == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'removes the given observer from the list of observers' do
|
49
|
+
item.add_observer(observer)
|
50
|
+
expect {
|
51
|
+
item.delete_observer(observer)
|
52
|
+
}.to change { item.count_observers }.from(1).to(0)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#[]' do
|
57
|
+
it 'returns the value for the given key' do
|
58
|
+
item['foo'] = 'foo'
|
59
|
+
item['foo'].should == 'foo'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'notifies observers on every variable access' do
|
63
|
+
observer = stub('observer')
|
64
|
+
observer.should_receive(:update).once
|
65
|
+
item.add_observer(observer)
|
66
|
+
item['foo']
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|