csl 1.0.2 → 1.1.0
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.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.gitignore +1 -0
- data/.simplecov +3 -1
- data/.travis.yml +4 -10
- data/AGPL +1 -1
- data/BSDL +2 -2
- data/Gemfile +22 -12
- data/README.md +20 -11
- data/Rakefile +6 -1
- data/csl.gemspec +4 -2
- data/features/parser/choose.feature +16 -0
- data/features/step_definitions/parser_steps.rb +10 -0
- data/features/support/env.rb +16 -2
- data/lib/csl.rb +7 -4
- data/lib/csl/compatibility.rb +10 -16
- data/lib/csl/info.rb +3 -2
- data/lib/csl/locale.rb +92 -19
- data/lib/csl/locale/term.rb +41 -2
- data/lib/csl/name_options.rb +44 -0
- data/lib/csl/node.rb +54 -6
- data/lib/csl/parser.rb +17 -17
- data/lib/csl/schema.rb +37 -32
- data/lib/csl/style.rb +32 -8
- data/lib/csl/style/bibliography.rb +46 -9
- data/lib/csl/style/choose.rb +4 -2
- data/lib/csl/style/citation.rb +10 -11
- data/lib/csl/style/group.rb +13 -6
- data/lib/csl/style/label.rb +1 -1
- data/lib/csl/style/layout.rb +4 -4
- data/lib/csl/style/names.rb +161 -22
- data/lib/csl/style/sort.rb +74 -18
- data/lib/csl/style/text.rb +6 -4
- data/lib/csl/treelike.rb +16 -5
- data/lib/csl/version.rb +2 -2
- data/spec/csl/locale/term_spec.rb +70 -70
- data/spec/csl/locale_spec.rb +140 -99
- data/spec/csl/parser_spec.rb +26 -26
- data/spec/csl/schema_spec.rb +15 -15
- data/spec/csl/style/layout_spec.rb +2 -2
- data/spec/csl/style/sort_spec.rb +11 -0
- data/spec/spec_helper.rb +13 -4
- metadata +20 -14
data/lib/csl/style/sort.rb
CHANGED
|
@@ -1,21 +1,77 @@
|
|
|
1
1
|
module CSL
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
class Style
|
|
3
|
+
|
|
4
|
+
class Sort < Node
|
|
5
|
+
|
|
6
|
+
attr_children :key
|
|
7
|
+
|
|
8
|
+
alias keys key
|
|
9
|
+
|
|
10
|
+
def initialize(attributes = {})
|
|
11
|
+
super(attributes)
|
|
12
|
+
children[:key] = []
|
|
13
|
+
|
|
14
|
+
yield self if block_given?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class Key < Node
|
|
18
|
+
|
|
19
|
+
attr_struct :variable, :macro, :sort,
|
|
20
|
+
:'names-use-min', :'names-use-first', :'names-use-last'
|
|
21
|
+
|
|
22
|
+
attr_defaults :sort => 'ascending'
|
|
23
|
+
|
|
24
|
+
has_no_children
|
|
25
|
+
|
|
26
|
+
def name_options
|
|
27
|
+
options = {}
|
|
28
|
+
|
|
29
|
+
options[:'et-al-use-min'] = options[:'et-al-subsequent-use-min'] =
|
|
30
|
+
attributes[:'names-use-min'] if attribute? :'names-use-min'
|
|
31
|
+
|
|
32
|
+
options[:'et-al-use-first'] = options[:'et-al-subsequent-use-first'] =
|
|
33
|
+
attributes[:'names-use-first'] if attribute? :'names-use-first'
|
|
34
|
+
|
|
35
|
+
options[:'et-al-use-last'] = options[:'et-al-subsequent-use-last'] =
|
|
36
|
+
attributes[:'names-use-last'] if attribute? :'names-use-last'
|
|
37
|
+
|
|
38
|
+
options
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def ascending?
|
|
42
|
+
attributes[:sort] =~ /^ascending$/i
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def ascending!
|
|
46
|
+
attributes[:sort] = 'ascending'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def descending?
|
|
50
|
+
!ascending?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def descending!
|
|
54
|
+
attributes[:sort] = 'descending'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def macro?
|
|
58
|
+
attribute? :macro
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def macro
|
|
62
|
+
fail 'cannot resolve macro: not associated with style' unless
|
|
63
|
+
!root? && root.respond_to?(:macros)
|
|
64
|
+
|
|
65
|
+
root.macros[attributes[:macro].to_s]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def variable
|
|
69
|
+
attributes[:variable]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
|
|
17
74
|
end
|
|
18
|
-
|
|
75
|
+
|
|
19
76
|
end
|
|
20
|
-
|
|
21
|
-
end
|
|
77
|
+
end
|
data/lib/csl/style/text.rb
CHANGED
|
@@ -14,7 +14,7 @@ module CSL
|
|
|
14
14
|
def variable
|
|
15
15
|
attributes[:variable]
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
def variable_options
|
|
19
19
|
attributes_for :form
|
|
20
20
|
end
|
|
@@ -25,8 +25,10 @@ module CSL
|
|
|
25
25
|
|
|
26
26
|
# @return [Macro, nil]
|
|
27
27
|
def macro
|
|
28
|
-
raise
|
|
29
|
-
|
|
28
|
+
raise "failed to resolve macro #{attributes[:macro].inspect}" unless
|
|
29
|
+
!root? && root.respond_to?(:macros)
|
|
30
|
+
|
|
31
|
+
root.macros[attributes[:macro]]
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def has_term?
|
|
@@ -43,4 +45,4 @@ module CSL
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
end
|
|
46
|
-
end
|
|
48
|
+
end
|
data/lib/csl/treelike.rb
CHANGED
|
@@ -32,7 +32,7 @@ module CSL
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
alias delete delete_children
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
# Deletes child nodes that are equal to the passed-in node. Returns all
|
|
37
37
|
# deleted children. If no children were deleted, returns nil. If the
|
|
38
38
|
# optional block is given, returns the result block if no children were
|
|
@@ -114,6 +114,17 @@ module CSL
|
|
|
114
114
|
end
|
|
115
115
|
alias >> find_children
|
|
116
116
|
|
|
117
|
+
def closest(name, conditions = {})
|
|
118
|
+
case
|
|
119
|
+
when root?
|
|
120
|
+
nil
|
|
121
|
+
when parent.match?(name, conditions)
|
|
122
|
+
parent
|
|
123
|
+
else
|
|
124
|
+
parent.closest(name, conditions)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
117
128
|
# @return [Boolean] true if this node has child nodes; false otherwise.
|
|
118
129
|
def has_children?
|
|
119
130
|
!empty?
|
|
@@ -287,7 +298,7 @@ module CSL
|
|
|
287
298
|
# standard Array that normally holds the child nodes. The benefit of
|
|
288
299
|
# using the Struct is that all child nodes are accessible by name and
|
|
289
300
|
# need not be looked up; this improves performance, however, note that
|
|
290
|
-
# a node defining
|
|
301
|
+
# a node defining its children that way can only contain nodes of the
|
|
291
302
|
# given types.
|
|
292
303
|
#
|
|
293
304
|
# This method also generates accessors for each child. The writer
|
|
@@ -324,7 +335,7 @@ module CSL
|
|
|
324
335
|
raise ArgumentError, "failed to convert #{value.inspect} to node: #{e.message}"
|
|
325
336
|
end unless value.respond_to?(:nodename)
|
|
326
337
|
|
|
327
|
-
|
|
338
|
+
add_child value
|
|
328
339
|
value
|
|
329
340
|
end
|
|
330
341
|
|
|
@@ -437,7 +448,7 @@ module CSL
|
|
|
437
448
|
private
|
|
438
449
|
|
|
439
450
|
def resolve(nodename)
|
|
440
|
-
keys.include?(nodename.to_sym) &&
|
|
451
|
+
keys.include?(nodename.to_sym) && self[nodename]
|
|
441
452
|
end
|
|
442
453
|
})
|
|
443
454
|
end
|
|
@@ -474,4 +485,4 @@ module CSL
|
|
|
474
485
|
end
|
|
475
486
|
|
|
476
487
|
end
|
|
477
|
-
end
|
|
488
|
+
end
|
data/lib/csl/version.rb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module CSL
|
|
2
|
-
VERSION = '1.0
|
|
1
|
+
module CSL
|
|
2
|
+
VERSION = '1.1.0'.freeze
|
|
3
3
|
end
|
|
@@ -4,13 +4,13 @@ require 'spec_helper'
|
|
|
4
4
|
module CSL
|
|
5
5
|
describe Locale::Terms do
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
it { should_not be nil }
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
describe '#to_xml' do
|
|
10
|
+
it 'returns <terms/> by default' do
|
|
11
|
+
subject.to_xml.should == '<terms/>'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
14
|
|
|
15
15
|
describe '.specialize' do
|
|
16
16
|
it 'filters the passed in hash to contain only match-able entries' do
|
|
@@ -18,40 +18,40 @@ module CSL
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
describe '#ordinalize' do
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
describe "given standard English terms" do
|
|
24
|
+
let(:en) do
|
|
25
|
+
Locale::Terms.parse <<-EOS
|
|
26
|
+
<terms>
|
|
27
|
+
<term name="ordinal">th</term>
|
|
28
28
|
<term name="ordinal-01">st</term>
|
|
29
29
|
<term name="ordinal-02">nd</term>
|
|
30
30
|
<term name="ordinal-03">rd</term>
|
|
31
31
|
<term name="ordinal-11">th</term>
|
|
32
32
|
<term name="ordinal-12">th</term>
|
|
33
33
|
<term name="ordinal-13">th</term>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
</terms>
|
|
35
|
+
EOS
|
|
36
|
+
end
|
|
37
37
|
|
|
38
38
|
%w{
|
|
39
39
|
ordinal ordinal-01 ordinal-02 ordinal-03 ordinal
|
|
40
40
|
}.each_with_index do |ordinal, number|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
it "returns #{ordinal.inspect} for #{number}" do
|
|
42
|
+
en.ordinalize(number)[:name].should == ordinal
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
end
|
|
48
48
|
|
|
49
49
|
describe '#lookup' do
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
describe "given standard English terms" do
|
|
52
|
+
let(:en) do
|
|
53
|
+
Locale::Terms.parse <<-EOS
|
|
54
|
+
<terms>
|
|
55
55
|
<term name="page" form="short">
|
|
56
56
|
<single>p.</single>
|
|
57
57
|
<multiple>pp.</multiple>
|
|
@@ -79,42 +79,42 @@ module CSL
|
|
|
79
79
|
</term>
|
|
80
80
|
<term name="editor" form="verb">edited by</term>
|
|
81
81
|
<term name="editor" form="verb-short">ed.</term>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
</terms>
|
|
83
|
+
EOS
|
|
84
|
+
end
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
it 'returns nil if there is no matching term' do
|
|
87
|
+
en.lookup(:foo).should be_nil
|
|
88
|
+
end
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
it 'returns the long form by default' do
|
|
91
|
+
en.lookup(:page).should be_long
|
|
92
|
+
end
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
it 'returns the term in the passed-in form if available' do
|
|
95
|
+
en.lookup(:section, :form => 'long').should be_long
|
|
96
|
+
en.lookup(:section, :form => 'short').should be_short
|
|
97
|
+
en.lookup(:section, :form => 'symbol').should be_symbol
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
en.lookup(:editor).should be_long
|
|
100
|
+
en.lookup(:editor, :form => 'long').should be_long
|
|
101
|
+
en.lookup(:editor, :form => 'verb').should be_verb
|
|
102
|
+
en.lookup(:editor, :form => 'verb-short').should be_verb_short
|
|
103
|
+
end
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
it 'returns the right fallback form if the passed-in form is not available' do
|
|
106
|
+
en.lookup(:page, :form => 'verb').should be_long
|
|
107
|
+
en.lookup(:page, :form => 'verb-short').should be_long
|
|
108
|
+
en.lookup(:page, :form => 'symbol').should be_short
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
it 'ignores irrelevant options' do
|
|
112
|
+
en.lookup(:page, :plural => true).should_not be_nil
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
115
|
|
|
116
116
|
end
|
|
117
|
-
|
|
117
|
+
end
|
|
118
118
|
|
|
119
119
|
describe Locale::Term do
|
|
120
120
|
|
|
@@ -129,13 +129,13 @@ module CSL
|
|
|
129
129
|
it { should_not be_short_ordinal }
|
|
130
130
|
it { should_not be_long_ordinal }
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
it 'is not a textnode by default' do
|
|
133
|
+
subject.should_not be_textnode
|
|
134
|
+
end
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
it 'is a textnode when the text is "foo"' do
|
|
137
|
+
Locale::Term.new { |t| t.text = 'foo' }.should be_textnode
|
|
138
|
+
end
|
|
139
139
|
|
|
140
140
|
describe 'gender attribute is set' do
|
|
141
141
|
let(:m) { Locale::Term.new(:name => 'month-05') { |t| t.masculine!; t.text = 'Mai' } }
|
|
@@ -237,19 +237,19 @@ module CSL
|
|
|
237
237
|
end
|
|
238
238
|
end
|
|
239
239
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
240
|
+
describe '#to_xml' do
|
|
241
|
+
it 'returns <term/> by default' do
|
|
242
|
+
subject.to_xml.should == '<term/>'
|
|
243
|
+
end
|
|
244
244
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
245
|
+
it 'returns <term>foo</term> when the text is "foo"' do
|
|
246
|
+
Locale::Term.new { |t| t.text = 'foo' }.to_xml.should == '<term>foo</term>'
|
|
247
|
+
end
|
|
248
248
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
249
|
+
it 'returns <term><multiple>foo</multiple></term> when multiple is "foo"' do
|
|
250
|
+
Locale::Term.new { |t| t.multiple = 'foo' }.to_xml.should == '<term><multiple>foo</multiple></term>'
|
|
251
|
+
end
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
end
|
|
254
254
|
end
|
|
255
|
-
end
|
|
255
|
+
end
|
data/spec/csl/locale_spec.rb
CHANGED
|
@@ -4,35 +4,35 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
module CSL
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
describe Locale do
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
let(:locale) { Locale.new }
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
let(:en) { Locale.new('en-US') }
|
|
12
|
+
let(:gb) { Locale.new('en-GB') }
|
|
13
|
+
let(:de) { Locale.new('de-DE') }
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
describe '.regions' do
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
it 'returns the default region when passed a language symbol' do
|
|
18
|
+
Locale.regions[:en].should == :US
|
|
19
|
+
end
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
end
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
describe '.languages' do
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
describe 'the language hash' do
|
|
26
|
+
it 'returns the default language when passed a region string' do
|
|
27
|
+
%w{ US en GB en AT de DE de }.map(&:to_sym).each_slice(2) do |region, language|
|
|
28
|
+
Locale.languages[region].should == language
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
end
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
describe '.normalize' do
|
|
36
36
|
{
|
|
37
37
|
'en' => 'en-US',
|
|
38
38
|
'-GB' => 'en-GB',
|
|
@@ -43,18 +43,18 @@ module CSL
|
|
|
43
43
|
Locale.normalize(tag).should == expected
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
|
-
|
|
46
|
+
end
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
describe '.new' do
|
|
49
|
+
it { should_not be_nil }
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
it 'defaults to default language' do
|
|
52
|
+
Locale.new.language.should == Locale.default.split(/-/)[0].to_sym
|
|
53
|
+
end
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
it 'defaults to default region' do
|
|
56
|
+
Locale.new.region.should == Locale.default.split(/-/)[1].to_sym
|
|
57
|
+
end
|
|
58
58
|
|
|
59
59
|
it 'contains no dates by default' do
|
|
60
60
|
Locale.new.dates.should be_nil
|
|
@@ -64,7 +64,7 @@ module CSL
|
|
|
64
64
|
Locale.new.terms.should be_nil
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
end
|
|
68
68
|
|
|
69
69
|
describe '.load' do
|
|
70
70
|
|
|
@@ -87,80 +87,121 @@ module CSL
|
|
|
87
87
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
describe '#set' do
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
it 'when passed "en-GB" sets language to :en and region to :GB' do
|
|
93
|
+
locale.set('en-GB')
|
|
94
|
+
[locale.language, locale.region].should == [:en, :GB]
|
|
95
|
+
end
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
it 'when passed "de" sets language to :de and region to :DE' do
|
|
98
|
+
locale.set('de')
|
|
99
|
+
[locale.language, locale.region].should == [:de, :DE]
|
|
100
|
+
end
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
it 'when passed "-AT" sets language to :de and region to :AT' do
|
|
103
|
+
locale.set('-AT')
|
|
104
|
+
[locale.language, locale.region].should == [:de, :AT]
|
|
105
|
+
end
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
end
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
describe '#merge!' do
|
|
110
|
+
let(:locale_with_options) { Locale.new('en', :foo => 'bar') }
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
describe 'style options' do
|
|
113
|
+
it 'does not change the options if none are set on either locale' do
|
|
114
|
+
expect { locale.merge!(en) }.not_to change { locale.options }
|
|
115
|
+
end
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
it 'creates a duplicate option element if the first locale has no options' do
|
|
118
|
+
locale.should_not have_options
|
|
119
|
+
locale.merge!(locale_with_options)
|
|
120
|
+
locale.should have_options
|
|
121
|
+
locale.options[:foo].should == 'bar'
|
|
122
122
|
locale.options.should_not equal(locale_with_options.options)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'merges the options if both locales have options' do
|
|
126
|
+
locale << Locale::StyleOptions.new(:bar => 'foo')
|
|
127
|
+
|
|
128
|
+
expect { locale.merge!(locale_with_options) }.not_to change { locale.options.object_id }
|
|
129
|
+
|
|
130
|
+
locale.options[:foo].should == 'bar'
|
|
131
|
+
locale.options[:bar].should == 'foo'
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'overrides the options with those in the other locale' do
|
|
135
|
+
locale << Locale::StyleOptions.new(:bar => 'foo', :foo => 'foo')
|
|
136
|
+
locale.merge!(locale_with_options)
|
|
137
|
+
locale.options[:foo].should == 'bar'
|
|
138
|
+
locale.options[:bar].should == 'foo'
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe 'dates' do
|
|
143
|
+
it 'does not change the dates if none are set on either locale' do
|
|
144
|
+
expect { locale.merge!(en) }.not_to change { locale.dates }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it 'creates duplicate date elements if the first locale has no options' do
|
|
148
|
+
locale.merge!(Locale.load('en-US'))
|
|
149
|
+
locale.should have_dates
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
describe '#legacy?' do
|
|
155
|
+
it 'returns false by default' do
|
|
156
|
+
locale.should_not be_legacy
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it 'returns true if the version is less than 1.0.1' do
|
|
160
|
+
locale.version = '0.8'
|
|
161
|
+
locale.should be_legacy
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
describe '#quote' do
|
|
166
|
+
|
|
167
|
+
it 'quotes the passed-in string' do
|
|
168
|
+
locale.store 'open-quote', '»'
|
|
169
|
+
locale.store 'close-quote', '«'
|
|
170
|
+
|
|
171
|
+
locale.quote('foo').should == '»foo«'
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'does not alter the string if there are no quotes in the locale' do
|
|
175
|
+
locale.quote('foo').should == 'foo'
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it 'adds quotes inside final punctuation if punctuation-in-quote option is set' do
|
|
179
|
+
locale.store 'open-quote', '»'
|
|
180
|
+
locale.store 'close-quote', '«'
|
|
181
|
+
|
|
182
|
+
locale.quote('foo.').should == '»foo«.'
|
|
183
|
+
locale.quote('foo,').should == '»foo«,'
|
|
184
|
+
|
|
185
|
+
locale.quote('foo!').should == '»foo!«'
|
|
186
|
+
locale.quote('foo?').should == '»foo?«'
|
|
187
|
+
|
|
188
|
+
locale.punctuation_in_quotes!
|
|
189
|
+
|
|
190
|
+
locale.quote('foo.').should == '»foo.«'
|
|
191
|
+
locale.quote('foo,').should == '»foo,«'
|
|
192
|
+
|
|
193
|
+
locale.quote('foo!').should == '»foo!«'
|
|
194
|
+
locale.quote('foo?').should == '»foo?«'
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it 'replaces existing quotes with inner quotes' do
|
|
198
|
+
locale.store 'open-quote', '“'
|
|
199
|
+
locale.store 'close-quote', '”'
|
|
200
|
+
locale.store 'open-inner-quote', '‘'
|
|
201
|
+
locale.store 'close-inner-quote', '’'
|
|
202
|
+
|
|
203
|
+
locale.quote('“foo”').should == '“‘foo’”'
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|