citeproc-ruby 0.0.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.document +4 -0
  4. data/.gitignore +10 -0
  5. data/.rspec +3 -0
  6. data/.simplecov +4 -0
  7. data/.travis.yml +17 -0
  8. data/.yardopts +2 -0
  9. data/AGPL +662 -0
  10. data/BSDL +29 -0
  11. data/Gemfile +42 -0
  12. data/Guardfile +14 -0
  13. data/README.md +32 -76
  14. data/Rakefile +60 -0
  15. data/citeproc-ruby.gemspec +46 -0
  16. data/cucumber.yml +1 -0
  17. data/features/bibliography.feature +25 -0
  18. data/features/name_options.feature +37 -0
  19. data/features/names.feature +192 -0
  20. data/features/renderer.feature +74 -0
  21. data/features/sort.feature +50 -0
  22. data/features/step_definitions/renderer.rb +80 -0
  23. data/features/support/env.rb +33 -0
  24. data/features/support/hooks.rb +10 -0
  25. data/lib/citeproc/ruby.rb +32 -0
  26. data/lib/citeproc/ruby/engine.rb +122 -0
  27. data/lib/citeproc/ruby/format.rb +303 -0
  28. data/lib/citeproc/ruby/formats/default.rb +25 -0
  29. data/lib/citeproc/ruby/formats/html.rb +221 -0
  30. data/lib/citeproc/ruby/renderer.rb +140 -0
  31. data/lib/citeproc/ruby/renderer/choose.rb +106 -0
  32. data/lib/citeproc/ruby/renderer/date.rb +90 -0
  33. data/lib/citeproc/ruby/renderer/format.rb +129 -0
  34. data/lib/citeproc/ruby/renderer/group.rb +34 -0
  35. data/lib/citeproc/ruby/renderer/history.rb +40 -0
  36. data/lib/citeproc/ruby/renderer/label.rb +66 -0
  37. data/lib/citeproc/ruby/renderer/layout.rb +20 -0
  38. data/lib/citeproc/ruby/renderer/locale.rb +26 -0
  39. data/lib/citeproc/ruby/renderer/macro.rb +20 -0
  40. data/lib/citeproc/ruby/renderer/names.rb +401 -0
  41. data/lib/citeproc/ruby/renderer/number.rb +41 -0
  42. data/lib/citeproc/ruby/renderer/observer.rb +44 -0
  43. data/lib/citeproc/ruby/renderer/state.rb +96 -0
  44. data/lib/citeproc/ruby/renderer/text.rb +62 -0
  45. data/lib/citeproc/ruby/sort.rb +82 -0
  46. data/lib/citeproc/ruby/version.rb +5 -0
  47. data/spec/citeproc/ruby/engine_spec.rb +94 -0
  48. data/spec/citeproc/ruby/formats/default_spec.rb +159 -0
  49. data/spec/citeproc/ruby/formats/html_spec.rb +162 -0
  50. data/spec/citeproc/ruby/renderer/choose_spec.rb +293 -0
  51. data/spec/citeproc/ruby/renderer/date_spec.rb +173 -0
  52. data/spec/citeproc/ruby/renderer/group_spec.rb +88 -0
  53. data/spec/citeproc/ruby/renderer/history_spec.rb +38 -0
  54. data/spec/citeproc/ruby/renderer/label_spec.rb +225 -0
  55. data/spec/citeproc/ruby/renderer/layout_spec.rb +41 -0
  56. data/spec/citeproc/ruby/renderer/macro_spec.rb +31 -0
  57. data/spec/citeproc/ruby/renderer/names_spec.rb +396 -0
  58. data/spec/citeproc/ruby/renderer/number_spec.rb +120 -0
  59. data/spec/citeproc/ruby/renderer/text_spec.rb +120 -0
  60. data/spec/citeproc/ruby/renderer_spec.rb +65 -0
  61. data/spec/fixtures/items.rb +80 -0
  62. data/{resource/locale → spec/fixtures/locales}/locales-en-US.xml +2 -11
  63. data/{resource/locale → spec/fixtures/locales}/locales-fr-FR.xml +77 -66
  64. data/{resource/style → spec/fixtures/styles}/apa.csl +5 -5
  65. data/spec/spec_helper.rb +67 -14
  66. metadata +121 -211
  67. data/lib/citeproc.rb +0 -100
  68. data/lib/citeproc/bibliography.rb +0 -57
  69. data/lib/citeproc/data.rb +0 -149
  70. data/lib/citeproc/date.rb +0 -133
  71. data/lib/citeproc/formatter.rb +0 -38
  72. data/lib/citeproc/item.rb +0 -53
  73. data/lib/citeproc/name.rb +0 -284
  74. data/lib/citeproc/processor.rb +0 -166
  75. data/lib/citeproc/selector.rb +0 -61
  76. data/lib/citeproc/variable.rb +0 -82
  77. data/lib/citeproc/version.rb +0 -3
  78. data/lib/csl/locale.rb +0 -223
  79. data/lib/csl/node.rb +0 -72
  80. data/lib/csl/nodes.rb +0 -1418
  81. data/lib/csl/renderer.rb +0 -88
  82. data/lib/csl/sort.rb +0 -61
  83. data/lib/csl/style.rb +0 -110
  84. data/lib/csl/term.rb +0 -124
  85. data/lib/extensions/core.rb +0 -43
  86. data/lib/plugins/filters/bibtex.rb +0 -12
  87. data/lib/plugins/formats/default.rb +0 -134
  88. data/lib/plugins/formats/html.rb +0 -67
  89. data/lib/support/attributes.rb +0 -99
  90. data/lib/support/compatibility.rb +0 -83
  91. data/lib/support/tree.rb +0 -80
  92. data/resource/locale/locales-af-ZA.xml +0 -305
  93. data/resource/locale/locales-ar-AR.xml +0 -306
  94. data/resource/locale/locales-bg-BG.xml +0 -305
  95. data/resource/locale/locales-ca-AD.xml +0 -305
  96. data/resource/locale/locales-cs-CZ.xml +0 -305
  97. data/resource/locale/locales-da-DK.xml +0 -305
  98. data/resource/locale/locales-de-AT.xml +0 -304
  99. data/resource/locale/locales-de-CH.xml +0 -304
  100. data/resource/locale/locales-de-DE.xml +0 -332
  101. data/resource/locale/locales-el-GR.xml +0 -305
  102. data/resource/locale/locales-en-GB.xml +0 -304
  103. data/resource/locale/locales-es-ES.xml +0 -305
  104. data/resource/locale/locales-et-EE.xml +0 -304
  105. data/resource/locale/locales-eu.xml +0 -305
  106. data/resource/locale/locales-fa-IR.xml +0 -304
  107. data/resource/locale/locales-fi-FI.xml +0 -304
  108. data/resource/locale/locales-fr-CA.xml +0 -306
  109. data/resource/locale/locales-he-IL.xml +0 -304
  110. data/resource/locale/locales-hu-HU.xml +0 -305
  111. data/resource/locale/locales-is-IS.xml +0 -304
  112. data/resource/locale/locales-it-IT.xml +0 -305
  113. data/resource/locale/locales-ja-JP.xml +0 -305
  114. data/resource/locale/locales-kh-KH.xml +0 -303
  115. data/resource/locale/locales-km-KH.xml +0 -304
  116. data/resource/locale/locales-ko-KR.xml +0 -305
  117. data/resource/locale/locales-mn-MN.xml +0 -306
  118. data/resource/locale/locales-nb-NO.xml +0 -304
  119. data/resource/locale/locales-nl-NL.xml +0 -304
  120. data/resource/locale/locales-nn-NO.xml +0 -304
  121. data/resource/locale/locales-pl-PL.xml +0 -305
  122. data/resource/locale/locales-pt-BR.xml +0 -304
  123. data/resource/locale/locales-pt-PT.xml +0 -305
  124. data/resource/locale/locales-ro-RO.xml +0 -305
  125. data/resource/locale/locales-ru-RU.xml +0 -306
  126. data/resource/locale/locales-sk-SK.xml +0 -304
  127. data/resource/locale/locales-sl-SI.xml +0 -305
  128. data/resource/locale/locales-sr-RS.xml +0 -305
  129. data/resource/locale/locales-sv-SE.xml +0 -305
  130. data/resource/locale/locales-th-TH.xml +0 -304
  131. data/resource/locale/locales-tr-TR.xml +0 -305
  132. data/resource/locale/locales-uk-UA.xml +0 -306
  133. data/resource/locale/locales-vi-VN.xml +0 -305
  134. data/resource/locale/locales-zh-CN.xml +0 -304
  135. data/resource/locale/locales-zh-TW.xml +0 -305
  136. data/resource/schema/csl-categories.rnc +0 -39
  137. data/resource/schema/csl-data.rnc +0 -98
  138. data/resource/schema/csl-terms.rnc +0 -106
  139. data/resource/schema/csl-types.rnc +0 -39
  140. data/resource/schema/csl-variables.rnc +0 -182
  141. data/resource/schema/csl.rnc +0 -941
  142. data/resource/style/bibtex.csl +0 -177
  143. data/resource/style/chicago-annotated-bibliography.csl +0 -513
  144. data/resource/style/chicago-author-date-basque.csl +0 -707
  145. data/resource/style/chicago-author-date-de.csl +0 -394
  146. data/resource/style/chicago-author-date-listing.csl +0 -434
  147. data/resource/style/chicago-author-date.csl +0 -425
  148. data/resource/style/chicago-dated-note-biblio-no-ibid.csl +0 -472
  149. data/resource/style/chicago-fullnote-bibliography-bb.csl +0 -928
  150. data/resource/style/chicago-fullnote-bibliography-delimiter-fixes.csl +0 -972
  151. data/resource/style/chicago-fullnote-bibliography-no-ibid-delimiter-fixes.csl +0 -963
  152. data/resource/style/chicago-fullnote-bibliography-no-ibid.csl +0 -785
  153. data/resource/style/chicago-fullnote-bibliography.csl +0 -803
  154. data/resource/style/chicago-library-list.csl +0 -511
  155. data/resource/style/chicago-note-biblio-no-ibid.csl +0 -514
  156. data/resource/style/chicago-note-bibliography.csl +0 -530
  157. data/resource/style/chicago-note.csl +0 -388
  158. data/resource/style/chicago-quick-copy.csl +0 -685
  159. data/resource/style/ieee.csl +0 -299
  160. data/resource/style/mla-notes.csl +0 -796
  161. data/resource/style/mla-underline.csl +0 -175
  162. data/resource/style/mla-url.csl +0 -214
  163. data/resource/style/mla.csl +0 -394
  164. data/resource/style/vancouver-brackets.csl +0 -256
  165. data/resource/style/vancouver-superscript-bracket-only-year.csl +0 -165
  166. data/resource/style/vancouver-superscript.csl +0 -256
  167. data/resource/style/vancouver.csl +0 -256
  168. data/spec/citeproc/bibliography_spec.rb +0 -45
  169. data/spec/citeproc/citeproc_spec.rb +0 -80
  170. data/spec/citeproc/date_spec.rb +0 -89
  171. data/spec/citeproc/formatter_spec.rb +0 -101
  172. data/spec/citeproc/item_spec.rb +0 -71
  173. data/spec/citeproc/name_spec.rb +0 -30
  174. data/spec/citeproc/processor_spec.rb +0 -61
  175. data/spec/citeproc/selector_spec.rb +0 -82
  176. data/spec/citeproc/variable_spec.rb +0 -69
  177. data/spec/csl/locale_spec.rb +0 -208
  178. data/spec/csl/node_spec.rb +0 -25
  179. data/spec/csl/nodes_spec.rb +0 -145
  180. data/spec/csl/style_spec.rb +0 -62
  181. data/spec/csl/term_spec.rb +0 -56
  182. data/spec/fixtures/dates.yaml +0 -80
  183. data/spec/fixtures/names.yaml +0 -115
  184. data/spec/fixtures/nodes.yaml +0 -245
  185. data/spec/support/attributes_spec.rb +0 -39
  186. data/spec/support/tree_spec.rb +0 -163
@@ -0,0 +1,173 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ module Ruby
5
+
6
+ describe 'Renderer#render_date' do
7
+ let(:renderer) { Renderer.new }
8
+
9
+ let(:item) {
10
+ i = CiteProc::CitationItem.new(:id => 'ID-1')
11
+ i.data = CiteProc::Item.new(:id => 'ID-1')
12
+ i
13
+ }
14
+
15
+ describe 'localized rendering' do
16
+ let(:node) { CSL::Style::Date.new(:variable => 'issued', :form => 'numeric') }
17
+
18
+ describe 'given an item issued on January 27th, 2012' do
19
+ before(:each) { item.data[:issued] = '2012-01-27' }
20
+
21
+ it "uses the locale's date parts to render the date" do
22
+ renderer.render(item, node).should == '01/27/2012'
23
+ end
24
+ end
25
+ end
26
+
27
+ describe 'static rendering' do
28
+ let(:node) { CSL::Style::Date.new(:variable => 'issued') }
29
+
30
+ describe 'given an item issued on January 27th, 2012' do
31
+ before(:each) { item.data[:issued] = '2012-01-27' }
32
+
33
+ it 'returns an empty string by default' do
34
+ renderer.render_date(item, node).should == ''
35
+ end
36
+
37
+ describe 'and given a node with a year part' do
38
+ before(:each) { node << CSL::Style::DatePart.new(:name => 'year') }
39
+
40
+ it 'returns the year as "2012"' do
41
+ renderer.render_date(item, node).should == '2012'
42
+ end
43
+
44
+ describe 'and a day part' do
45
+ before(:each) { node << CSL::Style::DatePart.new(:name => 'day') }
46
+
47
+ it 'returns "201227"' do
48
+ renderer.render_date(item, node).should == '201227'
49
+ end
50
+
51
+ it 'applies delimiters when set on the node' do
52
+ node[:delimiter] = '/'
53
+ renderer.render_date(item, node).should == '2012/27'
54
+ end
55
+
56
+ describe 'and a month part' do
57
+ before(:each) { node << CSL::Style::DatePart.new(:name => 'month') }
58
+
59
+ it 'returns "201227January"' do
60
+ renderer.render_date(item, node).should == '201227January'
61
+ end
62
+
63
+ it 'returns "2012/27/01" when the month form set to "numeric-leading-zeros" and the node has a delimiter "/"' do
64
+ node.parts.last[:form] = 'numeric-leading-zeros'
65
+ node[:delimiter] = '/'
66
+ renderer.render_date(item, node).should == '2012/27/01'
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ describe 'Renderer#render_date_part' do
77
+ let(:renderer) { Renderer.new }
78
+ let(:node) { CSL::Style::DatePart.new }
79
+
80
+ let(:today) { CiteProc::Date.today }
81
+
82
+ let(:january) { CiteProc::Date.new([2012, 1]) }
83
+ let(:december) { CiteProc::Date.new([2012, 12]) }
84
+ let(:independence) { CiteProc::Date.new([1776, 7, 4]) }
85
+
86
+ it 'returns an empty string by default' do
87
+ renderer.render_date_part(CiteProc::Date.today, node).should == ''
88
+ end
89
+
90
+ describe 'when the name is set to "day"' do
91
+ before(:each) { node[:name] = 'day' }
92
+
93
+ it 'renders the day as number by default' do
94
+ renderer.render_date_part(today, node).should == today.day.to_s
95
+ end
96
+
97
+ it 'renders the day as an ordinal number when the form is set to "ordinal"' do
98
+ node[:form] = 'ordinal'
99
+ renderer.render_date_part(independence, node).should == '4th'
100
+
101
+ renderer.locale.limit_day_ordinals!
102
+ renderer.render_date_part(independence, node).should == '4'
103
+
104
+ independence.day = 1
105
+ renderer.render_date_part(independence, node).should == '1st'
106
+ end
107
+ end
108
+
109
+ describe 'when the name is set to "month"' do
110
+ before(:each) { node[:name] = 'month' }
111
+
112
+ it "renders the month's full name by default" do
113
+ renderer.render_date_part(january, node).should == 'January'
114
+ renderer.render_date_part(december, node).should == 'December'
115
+ end
116
+
117
+ it "renders the month's full name as the long form" do
118
+ node[:form] = 'long'
119
+ renderer.render_date_part(january, node).should == 'January'
120
+ end
121
+
122
+ it "renders the month's short name as the short form" do
123
+ node[:form] = 'short'
124
+ renderer.render_date_part(january, node).should == 'Jan.'
125
+ end
126
+
127
+ it 'renders the month as number as the numeric form' do
128
+ node[:form] = 'numeric'
129
+ renderer.render_date_part(january, node).should == '1'
130
+ end
131
+
132
+ it 'renders the month as number with a leading zero when form is set to numeric-leading-zeros' do
133
+ node[:form] = 'numeric-leading-zeros'
134
+ renderer.render_date_part(january, node).should == '01'
135
+ renderer.render_date_part(december, node).should == '12'
136
+ end
137
+
138
+ it 'renders the name of the season when a season is set' do
139
+ january.season = 4
140
+ renderer.render_date_part(january, node).should == 'Winter'
141
+ end
142
+ end
143
+
144
+ describe 'when the name is set to "year"' do
145
+ before(:each) { node[:name] = 'year' }
146
+
147
+ it 'renders the full year by default' do
148
+ renderer.render_date_part(today, node).should == today.year.to_s
149
+ end
150
+
151
+ it 'renders the full year when form is set to long' do
152
+ node[:form] = 'long'
153
+ renderer.render_date_part(january, node).should == '2012'
154
+ end
155
+
156
+ it 'renders the short year when form is set to short' do
157
+ node[:form] = 'short'
158
+ renderer.render_date_part(january, node).should == '12'
159
+ end
160
+
161
+ it 'adds AD if applicable' do
162
+ renderer.render_date_part(CiteProc::Date.new([200]), node) == '200AD'
163
+ end
164
+
165
+ it 'adds BC if applicable' do
166
+ renderer.render_date_part(CiteProc::Date.new([-200]), node) == '200BC'
167
+ end
168
+ end
169
+
170
+ end
171
+
172
+ end
173
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ module Ruby
5
+ describe 'Renderer#render_group' do
6
+ let(:renderer) { Renderer.new }
7
+
8
+ let(:item) {
9
+ i = CiteProc::CitationItem.new(:id => 'ID-1')
10
+ i.data = CiteProc::Item.new(:id => 'ID-1')
11
+ i
12
+ }
13
+
14
+ let(:node) { CSL::Style::Group.new }
15
+
16
+ it 'returns an empty string by default' do
17
+ renderer.render(item, node).should == ''
18
+
19
+ node[:prefix] = '!'
20
+ renderer.render(item, node).should == ''
21
+ end
22
+
23
+ describe 'when there is a text node in the group' do
24
+ before(:each) { node << CSL::Style::Text.new( :term => 'retrieved') }
25
+
26
+ it 'returns the content of the nested node' do
27
+ renderer.render_group(item, node).should == 'retrieved'
28
+ end
29
+
30
+ it 'applies formatting options to the nested node' do
31
+ node[:'text-case'] = 'uppercase'
32
+ renderer.render(item, node).should == 'RETRIEVED'
33
+ end
34
+
35
+ describe 'when there is a second text node in the group' do
36
+ before(:each) { node << CSL::Style::Text.new( :term => 'from') }
37
+
38
+ it 'returns the content of both nested nodes' do
39
+ renderer.render_group(item, node).should == 'retrievedfrom'
40
+ end
41
+
42
+ describe 'when there is a delimter set on the group node' do
43
+ before(:each) { node[:delimiter] = ' ' }
44
+
45
+ it 'applies the delimiter to the output' do
46
+ renderer.render_group(item, node).should == 'retrieved from'
47
+ end
48
+
49
+ it 'applies formatting options to the nested nodes only' do
50
+ node[:'text-case'] = 'uppercase'
51
+ node[:delimiter] = ' foo '
52
+ node[:prefix] = '('
53
+ node[:suffix] = ')'
54
+ renderer.render(item, node).should == '(RETRIEVED foo FROM)'
55
+ end
56
+
57
+ describe 'when a nested node produces no output' do
58
+ before(:each) do
59
+ node << CSL::Style::Text.new( :term => 'fooo')
60
+ node << CSL::Style::Text.new( :term => 'from')
61
+ end
62
+
63
+ it 'the delimiter does not apply to it' do
64
+ renderer.render_group(item, node).should == 'retrieved from from'
65
+ end
66
+ end
67
+
68
+ describe 'when there is a variable-based node in the group' do
69
+ before(:each) { node << CSL::Style::Text.new( :variable => 'URL') }
70
+
71
+ it 'returns the empty string when the variable is not present in the item' do
72
+ renderer.render_group(item, node).should == ''
73
+ end
74
+
75
+ describe 'when the variable is present' do
76
+ before(:each) { item.data[:URL] = 'http://example.org' };
77
+
78
+ it 'returns all nested renditions' do
79
+ renderer.render_group(item, node).should == 'retrieved from http://example.org'
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ module Ruby
5
+
6
+ describe Renderer::History do
7
+ let(:state) { Renderer::State.new }
8
+ let(:history) { state.history }
9
+
10
+ it 'has an empty citation history' do
11
+ history.memory['citation'].should == []
12
+ end
13
+
14
+ it 'has an empty bibliography history' do
15
+ history.memory['bibliogrpahy'].should == []
16
+ end
17
+
18
+ describe '#update' do
19
+ it 'saves the passed in items for :store!' do
20
+ lambda {
21
+ history.update :store!, 'citation', { :x => 1 }
22
+ }.should change { history.citation }.to([{ :x => 1 }])
23
+ end
24
+
25
+ it 'drops remembered items when they are too old' do
26
+ lambda {
27
+ history.update :store!, 'citation', { :x => 1 }
28
+ history.update :store!, 'citation', { :x => 1 }
29
+ history.update :store!, 'citation', { :x => 1 }
30
+ history.update :store!, 'citation', { :x => 1 }
31
+ history.update :store!, 'citation', { :x => 1 }
32
+ }.should change { history.citation.length }.to(3)
33
+ end
34
+ end
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,225 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ module Ruby
5
+
6
+ describe "Renderer#render_label" do
7
+ let(:renderer) { Renderer.new }
8
+
9
+ let(:node) { CSL::Style::Label.new }
10
+
11
+ let(:item) {
12
+ i = CiteProc::CitationItem.new(:id => 'ID-1')
13
+ i.data = CiteProc::Item.new(:id => 'ID-1')
14
+ i
15
+ }
16
+
17
+ describe 'given an empty node' do
18
+ it 'returns an empty string for an empty item' do
19
+ renderer.render_label(item, node).should == ''
20
+ end
21
+
22
+ it 'returns an empty string for an item with variables' do
23
+ item.data.edition = 'foo'
24
+ renderer.render_label(item, node).should == ''
25
+ end
26
+ end
27
+
28
+
29
+ # page
30
+
31
+ describe "when the node's variable is set to :page" do
32
+ before(:each) { node[:variable] = :page }
33
+
34
+ describe "for an item with no page value" do
35
+ it 'returns an empty string' do
36
+ renderer.render_label(item, node).should == ''
37
+ end
38
+ end
39
+
40
+ describe 'for an item with a page value' do
41
+ it 'returns the singular label for a number' do
42
+ item.write_attribute :page, '23'
43
+ renderer.render_label(item, node).should == 'page'
44
+ end
45
+
46
+ it 'returns the plural label for a page-range' do
47
+ item.write_attribute :page, '23-24'
48
+ renderer.render_label(item, node).should == 'pages'
49
+ end
50
+
51
+ it 'returns the plural label for multiple pages' do
52
+ item.write_attribute :page, '23 & 24'
53
+ renderer.render_label(item, node).should == 'pages'
54
+
55
+ item.write_attribute :page, '23, 24, 25'
56
+ renderer.render_label(item, node).should == 'pages'
57
+ end
58
+
59
+ describe 'when pluralization is contextual' do
60
+ before(:each) { node[:plural] = 'contextual' }
61
+
62
+ it 'returns the singular label for a number' do
63
+ item.write_attribute :page, '23'
64
+ renderer.render_label(item, node).should == 'page'
65
+ end
66
+
67
+ it 'returns the plural label for a page-range' do
68
+ item.write_attribute :page, '23-24'
69
+ renderer.render_label(item, node).should == 'pages'
70
+ end
71
+ end
72
+
73
+ describe 'when pluralization is set to "always"' do
74
+ before(:each) { node[:plural] = 'always' }
75
+
76
+ it 'returns the singular label for a number' do
77
+ item.write_attribute :page, '1'
78
+ renderer.render_label(item, node).should == 'pages'
79
+ end
80
+
81
+ it 'returns the plural label for a page-range' do
82
+ item.write_attribute :page, '1-3'
83
+ renderer.render_label(item, node).should == 'pages'
84
+ end
85
+ end
86
+
87
+ describe 'when pluralization is set to "never"' do
88
+ before(:each) { node[:plural] = 'never' }
89
+
90
+ it 'returns the singular label for a number' do
91
+ item.write_attribute :page, '1'
92
+ renderer.render_label(item, node).should == 'page'
93
+ end
94
+
95
+ it 'returns the plural label for a page-range' do
96
+ item.write_attribute :page, '1-3'
97
+ renderer.render_label(item, node).should == 'page'
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+
104
+ # number-of-pages variable
105
+
106
+ describe "when the node's variable is set to :'number-of-pages'" do
107
+ before(:each) { node[:variable] = 'number-of-pages' }
108
+
109
+ describe "for an item with no 'number-of-pages' value" do
110
+ it 'returns an empty string' do
111
+ renderer.render_label(item, node).should == ''
112
+ end
113
+ end
114
+
115
+ describe "for an item with a 'number-of-pages' value" do
116
+ it 'returns the singular label for number 1' do
117
+ item.data[:'number-of-pages'] = 1
118
+ renderer.render_label(item, node).should == 'page'
119
+ end
120
+
121
+ it 'returns the plural label for numbers higher than 1' do
122
+ item.data[:'number-of-pages'] = '2'
123
+ renderer.render_label(item, node).should == 'pages'
124
+
125
+ item.data[:'number-of-pages'] = 42
126
+ renderer.render_label(item, node).should == 'pages'
127
+ end
128
+
129
+ describe 'when pluralization is set to "contextual"' do
130
+ before(:each) { node[:plural] = 'contextual' }
131
+
132
+ it 'returns the singular label for number 1' do
133
+ item.data[:'number-of-pages'] = '1'
134
+ renderer.render_label(item, node).should == 'page'
135
+ end
136
+
137
+ it 'returns the plural label for numbers higher than 1' do
138
+ item.data[:'number-of-pages'] = '2'
139
+ renderer.render_label(item, node).should == 'pages'
140
+
141
+ item.data[:'number-of-pages'] = 42
142
+ renderer.render_label(item, node).should == 'pages'
143
+ end
144
+ end
145
+
146
+ describe 'when pluralization is set to "always"' do
147
+ before(:each) { node[:plural] = 'always' }
148
+
149
+ it 'returns the singular label for number 1' do
150
+ item.data[:'number-of-pages'] = 1
151
+ renderer.render_label(item, node).should == 'pages'
152
+ end
153
+
154
+ it 'returns the plural label for numbers higher than 1' do
155
+ item.data[:'number-of-pages'] = '2'
156
+ renderer.render_label(item, node).should == 'pages'
157
+
158
+ item.data[:'number-of-pages'] = 42
159
+ renderer.render_label(item, node).should == 'pages'
160
+ end
161
+ end
162
+
163
+ describe 'when pluralization is set to "never"' do
164
+ before(:each) { node[:plural] = 'never' }
165
+
166
+ it 'returns the singular label for number 1' do
167
+ item.data[:'number-of-pages'] = 1
168
+ renderer.render_label(item, node).should == 'page'
169
+ end
170
+
171
+ it 'returns the plural label for numbers higher than 1' do
172
+ item.data[:'number-of-pages'] = '2'
173
+ renderer.render_label(item, node).should == 'page'
174
+
175
+ item.data[:'number-of-pages'] = 42
176
+ renderer.render_label(item, node).should == 'page'
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ # number-of-volumes variable
183
+
184
+ describe "when the node's variable is set to :'number-of-volumes'" do
185
+ before(:each) { node[:variable] = 'number-of-volumes' }
186
+
187
+ describe "for an item with a 'number-of-volumes' value" do
188
+ it 'returns the singular label for number 1' do
189
+ item.data[:'number-of-volumes'] = 1
190
+ renderer.render_label(item, node).should == 'volume'
191
+ end
192
+
193
+ it 'returns the plural label for numbers higher than 1' do
194
+ item.data[:'number-of-volumes'] = '2'
195
+ renderer.render_label(item, node).should == 'volumes'
196
+
197
+ item.data[:'number-of-volumes'] = 42
198
+ renderer.render_label(item, node).should == 'volumes'
199
+ end
200
+ end
201
+ end
202
+
203
+ # locators
204
+
205
+ describe "when the node's variable is set to another locator" do
206
+ before(:each) { node[:variable] = 'locator' }
207
+
208
+ describe "for an item with a locator and label" do
209
+ it "returns the singular label for a single number" do
210
+ item.locator = 2
211
+ item.label = 'book'
212
+ renderer.render_label(item, node).should == 'book'
213
+ end
214
+
215
+ it "returns the plural label for multiple numbers" do
216
+ item.locator = '23 & 4'
217
+ item.label = 'book'
218
+ renderer.render_label(item, node).should == 'books'
219
+ end
220
+ end
221
+ end
222
+
223
+ end # render_label
224
+ end
225
+ end