csl 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/.document +5 -0
  2. data/.gitignore +8 -0
  3. data/.gitmodules +6 -0
  4. data/.rspec +3 -0
  5. data/.simplecov +2 -0
  6. data/.travis.yml +13 -0
  7. data/.yardopts +2 -0
  8. data/AGPL +662 -0
  9. data/BSDL +29 -0
  10. data/Gemfile +24 -0
  11. data/Guardfile +14 -0
  12. data/README.md +39 -0
  13. data/Rakefile +45 -0
  14. data/csl.gemspec +36 -0
  15. data/cucumber.yml +1 -0
  16. data/features/locales/loading.feature +57 -0
  17. data/features/locales/ordinalize.feature +861 -0
  18. data/features/parser/info.feature +27 -0
  19. data/features/parser/localized_dates.feature +35 -0
  20. data/features/parser/terms.feature +28 -0
  21. data/features/step_definitions/locale_steps.rb +34 -0
  22. data/features/step_definitions/parser_steps.rb +28 -0
  23. data/features/step_definitions/style_steps.rb +16 -0
  24. data/features/style/loading.feature +53 -0
  25. data/features/support/env.rb +8 -0
  26. data/lib/csl.rb +54 -0
  27. data/lib/csl/compatibility.rb +19 -0
  28. data/lib/csl/errors.rb +15 -0
  29. data/lib/csl/extensions.rb +63 -0
  30. data/lib/csl/info.rb +40 -0
  31. data/lib/csl/loader.rb +78 -0
  32. data/lib/csl/locale.rb +393 -0
  33. data/lib/csl/locale/date.rb +48 -0
  34. data/lib/csl/locale/style_options.rb +10 -0
  35. data/lib/csl/locale/term.rb +185 -0
  36. data/lib/csl/node.rb +285 -0
  37. data/lib/csl/parser.rb +92 -0
  38. data/lib/csl/pretty_printer.rb +33 -0
  39. data/lib/csl/schema.rb +109 -0
  40. data/lib/csl/style.rb +53 -0
  41. data/lib/csl/style/bibliography.rb +15 -0
  42. data/lib/csl/style/citation.rb +17 -0
  43. data/lib/csl/style/conditional.rb +11 -0
  44. data/lib/csl/style/date.rb +16 -0
  45. data/lib/csl/style/group.rb +9 -0
  46. data/lib/csl/style/label.rb +14 -0
  47. data/lib/csl/style/layout.rb +10 -0
  48. data/lib/csl/style/macro.rb +9 -0
  49. data/lib/csl/style/names.rb +54 -0
  50. data/lib/csl/style/number.rb +33 -0
  51. data/lib/csl/style/sort.rb +21 -0
  52. data/lib/csl/style/text.rb +10 -0
  53. data/lib/csl/treelike.rb +442 -0
  54. data/lib/csl/version.rb +3 -0
  55. data/spec/csl/info_spec.rb +116 -0
  56. data/spec/csl/locale/date_spec.rb +63 -0
  57. data/spec/csl/locale/style_options_spec.rb +19 -0
  58. data/spec/csl/locale/term_spec.rb +96 -0
  59. data/spec/csl/locale_spec.rb +128 -0
  60. data/spec/csl/node_spec.rb +100 -0
  61. data/spec/csl/parser_spec.rb +92 -0
  62. data/spec/csl/schema_spec.rb +70 -0
  63. data/spec/csl/style/bibliography_spec.rb +7 -0
  64. data/spec/csl/style/citation_spec.rb +7 -0
  65. data/spec/csl/style/conditional_spec.rb +7 -0
  66. data/spec/csl/style/date_spec.rb +11 -0
  67. data/spec/csl/style/group_spec.rb +7 -0
  68. data/spec/csl/style/label_spec.rb +7 -0
  69. data/spec/csl/style/layout_spec.rb +7 -0
  70. data/spec/csl/style/macro_spec.rb +7 -0
  71. data/spec/csl/style/names_spec.rb +23 -0
  72. data/spec/csl/style/number_spec.rb +84 -0
  73. data/spec/csl/style/text_spec.rb +7 -0
  74. data/spec/csl/style_spec.rb +19 -0
  75. data/spec/csl/treelike_spec.rb +151 -0
  76. data/spec/spec_helper.rb +30 -0
  77. metadata +192 -0
@@ -0,0 +1,3 @@
1
+ module CSL
2
+ VERSION = '1.0.0.pre1'.freeze
3
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+
5
+ describe Info do
6
+
7
+ it { should_not be_nil }
8
+ it { should_not have_children }
9
+
10
+ describe '#nodename' do
11
+ it 'returns "info"' do
12
+ subject.nodename.should == 'info'
13
+ end
14
+ end
15
+
16
+ describe '#children' do
17
+ it 'returns a Info::Children instance' do
18
+ Info.new.children.should be_a(Info::Children)
19
+ end
20
+
21
+ it 'allows to set the id by writer method' do
22
+ lambda { Info.new.children.id = 'foo' }.should_not raise_error
23
+ end
24
+
25
+ it 'allows to set the id by array accessor' do
26
+ lambda { Info.new.children[:id] = 'foo' }.should_not raise_error
27
+ end
28
+ end
29
+
30
+ describe '#category' do
31
+ it 'returns nil by default' do
32
+ Info.new.category.should be nil
33
+ end
34
+ end
35
+
36
+ describe '#to_xml' do
37
+ it 'returns an empty info element by default' do
38
+ subject.to_xml.should == '<info/>'
39
+ end
40
+
41
+ it 'prints the id if present' do
42
+ Info.new { |i| i.set_child_id 'apa' }.to_xml.should == '<info><id>apa</id></info>'
43
+ end
44
+
45
+ it 'prints the category if present' do
46
+ Info.new { |i| i.category = 'author' }.to_xml.should == '<info><category>author</category></info>'
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ describe Info::Author do
54
+ it { should_not be_nil }
55
+
56
+ let(:poe) {
57
+ Info::Author.new { |a|
58
+ a.email = 'poe@baltimore.com'
59
+ a.name = 'E. A. Poe'
60
+ }
61
+ }
62
+
63
+ describe '#name' do
64
+ it 'returns nil by default' do
65
+ subject.name.should be nil
66
+ end
67
+
68
+ it 'returns the name if set' do
69
+ poe.name.to_s.should == 'E. A. Poe'
70
+ end
71
+ end
72
+
73
+ describe '#email' do
74
+ it 'returns the email' do
75
+ poe.email.to_s.should == 'poe@baltimore.com'
76
+ end
77
+ end
78
+
79
+ describe '#to_xml' do
80
+ it 'returns an empty author by default' do
81
+ subject.to_xml.should == '<author/>'
82
+ end
83
+
84
+ it 'prints all children' do
85
+ poe.to_xml.should == '<author><name>E. A. Poe</name><email>poe@baltimore.com</email></author>'
86
+ end
87
+ end
88
+
89
+ end
90
+
91
+ describe Info::Contributor do
92
+
93
+ it { should_not be_nil }
94
+
95
+ let(:bruce) { Info::Contributor.new { |c| c.name = "Bruce D'Arcus" } }
96
+
97
+ describe '#name' do
98
+ it 'returns the name' do
99
+ bruce.name.to_s.should == "Bruce D'Arcus"
100
+ end
101
+ end
102
+
103
+
104
+ describe '#to_xml' do
105
+ it 'returns an empty contributor by default' do
106
+ subject.to_xml.should == '<contributor/>'
107
+ end
108
+
109
+ it 'prints the name tag if present' do
110
+ bruce.to_xml.should == "<contributor><name>Bruce D'Arcus</name></contributor>"
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+
5
+ describe Locale::Date do
6
+
7
+ let(:date) { Locale::Date.new }
8
+
9
+ it { should_not be_nil }
10
+
11
+ it { should_not be_text }
12
+ it { should_not be_numeric }
13
+
14
+ describe '#parts' do
15
+
16
+ it 'returns nil by default' do
17
+ date.parts.should be_empty
18
+ end
19
+
20
+ end
21
+
22
+ describe '#to_xml' do
23
+
24
+ it 'returns <date/> by default' do
25
+ Locale::Date.new.to_xml.should == '<date/>'
26
+ end
27
+
28
+ it 'returns <date form="numeric"/> for an empty numeric date' do
29
+ Locale::Date.new(:form => 'numeric').to_xml.should == '<date form="numeric"/>'
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ describe Locale::DatePart do
37
+
38
+ it { should_not be_nil }
39
+
40
+ it { should_not be_day }
41
+ it { should_not be_month }
42
+ it { should_not be_year }
43
+
44
+ describe '#to_xml' do
45
+
46
+ it 'returns <date-part/> by default' do
47
+ Locale::DatePart.new.to_xml.should == "<date-part/>"
48
+ end
49
+
50
+ it 'returns <date-part name="year"/> when the name is "year"' do
51
+ Locale::DatePart.new(:name => 'year').to_xml.should == '<date-part name="year"/>'
52
+ end
53
+
54
+ it 'returns <date-part name="month" form="numeric" prefix="-"/> for a numeric month with prefix "-"' do
55
+ Locale::DatePart.new(:name => 'month', :form => 'numeric', :prefix => '-').to_xml.should match(/(\s(name|form|prefix)="[^"]+"){3}/)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+
63
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Locale::StyleOptions do
5
+
6
+ it { should_not be nil }
7
+
8
+ it 'punctuation-in-quote is false by default' do
9
+ subject[:'punctuation-in-quote'].should be false
10
+ end
11
+
12
+ describe '#to_xml' do
13
+ it 'returns <style-options punctuation-in-quote="false"/> by default' do
14
+ subject.to_xml.should == '<style-options punctuation-in-quote="false"/>'
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Locale::Terms do
5
+
6
+ it { should_not be nil }
7
+
8
+ describe '#to_xml' do
9
+ it 'returns <terms/> by default' do
10
+ subject.to_xml.should == '<terms/>'
11
+ end
12
+ end
13
+
14
+ end
15
+
16
+ describe Locale::Term do
17
+
18
+ it { should_not be_nil }
19
+
20
+ it { should_not be_gendered }
21
+
22
+ it { should be_neutral }
23
+
24
+ it 'is not a textnode by default' do
25
+ subject.should_not be_textnode
26
+ end
27
+
28
+ it 'is a textnode when the text is "foo"' do
29
+ Locale::Term.new { |t| t.text = 'foo' }.should be_textnode
30
+ end
31
+
32
+ describe 'gender attribute is set' do
33
+ let(:m) { Locale::Term.new(:name => 'month-05') { |t| t.masculine!; t.text = 'Mai' } }
34
+ let(:f) { Locale::Term.new(:name => 'edition') { |t| t.feminine!; t.text = 'Ausgabe' } }
35
+
36
+ it 'is gendered' do
37
+ m.should be_gendered
38
+ f.should be_gendered
39
+ end
40
+
41
+ it 'is feminine or masculine' do
42
+ m.should be_masculine
43
+ f.should be_feminine
44
+ end
45
+
46
+ it 'is not neutral' do
47
+ m.should_not be_neutral
48
+ f.should_not be_neutral
49
+ end
50
+
51
+ describe '#to_xml' do
52
+ it 'contains the correct gender' do
53
+ m.to_xml.should =~ /gender="masculine"/
54
+ f.to_xml.should =~ /gender="feminine"/
55
+ end
56
+ end
57
+
58
+ describe '#match?' do
59
+ it 'matches the name when passed a string' do
60
+ m.matches?('month-05').should be_true
61
+ end
62
+
63
+ it 'matches the name when passed a pattern' do
64
+ m.matches?(/month-\d\d/).should be_true
65
+ end
66
+
67
+ it 'does not match when passed a matching hash without gender' do
68
+ f.matches?(:name => 'edition').should_not be_true
69
+ end
70
+
71
+ it 'does not match when passed a matching hash with wrong gender' do
72
+ f.matches?(:name => 'edition', :gender => 'masculine').should_not be_true
73
+ end
74
+
75
+ it 'matches when passed a matching hash with matching gender' do
76
+ f.matches?(:name => 'edition', :gender => 'feminine').should be_true
77
+ end
78
+ end
79
+ end
80
+
81
+ describe '#to_xml' do
82
+ it 'returns <term/> by default' do
83
+ subject.to_xml.should == '<term/>'
84
+ end
85
+
86
+ it 'returns <term>foo</term> when the text is "foo"' do
87
+ Locale::Term.new { |t| t.text = 'foo' }.to_xml.should == '<term>foo</term>'
88
+ end
89
+
90
+ it 'returns <term><multiple>foo</multiple></term> when multiple is "foo"' do
91
+ Locale::Term.new { |t| t.multiple = 'foo' }.to_xml.should == '<term><multiple>foo</multiple></term>'
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,128 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+
5
+ module CSL
6
+
7
+ describe Locale do
8
+
9
+ let(:locale) { Locale.new }
10
+
11
+ let(:en) { Locale.new('en-US') }
12
+ let(:de) { Locale.new('de-DE') }
13
+ let(:fr) { Locale.new('fr-FR') }
14
+
15
+ describe '.regions' do
16
+
17
+ it 'returns the default region when passed a language symbol' do
18
+ Locale.regions[:en].should == :US
19
+ end
20
+
21
+ end
22
+
23
+ describe '.languages' do
24
+
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
+
33
+ end
34
+
35
+ describe '.new' do
36
+ it { should_not be_nil }
37
+
38
+ it 'defaults to default language' do
39
+ Locale.new.language.should == Locale.default.split(/-/)[0].to_sym
40
+ end
41
+
42
+ it 'defaults to default region' do
43
+ Locale.new.region.should == Locale.default.split(/-/)[1].to_sym
44
+ end
45
+
46
+ it 'contains no dates by default' do
47
+ Locale.new.dates.should be_nil
48
+ end
49
+
50
+ it 'contains no terms by default' do
51
+ Locale.new.terms.should be_nil
52
+ end
53
+
54
+ end
55
+
56
+ describe '.load' do
57
+
58
+ describe 'when called with "en-GB" ' do
59
+ let(:locale) { Locale.load('en-GB') }
60
+
61
+ it 'the returned locale has the correct IETF tag' do
62
+ locale.to_s.should == 'en-GB'
63
+ end
64
+
65
+ it 'the locale has language :en' do
66
+ locale.language.should == :en
67
+ end
68
+
69
+ it 'the locale has region :GB' do
70
+ locale.region.should == :GB
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+
77
+ describe '#set' do
78
+
79
+ it 'when passed "en-GB" sets language to :en and region to :GB' do
80
+ locale.set('en-GB')
81
+ [locale.language, locale.region].should == [:en, :GB]
82
+ end
83
+
84
+ it 'when passed "de" sets language to :de and region to :DE' do
85
+ locale.set('de')
86
+ [locale.language, locale.region].should == [:de, :DE]
87
+ end
88
+
89
+ it 'when passed "-AT" sets language to :de and region to :AT' do
90
+ locale.set('-AT')
91
+ [locale.language, locale.region].should == [:de, :AT]
92
+ end
93
+
94
+ end
95
+
96
+ describe '#legacy?' do
97
+ it 'returns false by default' do
98
+ locale.should_not be_legacy
99
+ end
100
+
101
+ it 'returns true if the version is less than 1.0.1' do
102
+ locale.version = '1.0'
103
+ locale.should be_legacy
104
+ end
105
+ end
106
+
107
+ describe '#ordinalize_query_for' do
108
+
109
+ it 'returns { :name => "ordinal-%02d" } by default' do
110
+ locale.send(:ordinalize_query_for, nil).should == { :name => "ordinal-%02d" }
111
+ end
112
+
113
+ it 'returns { :name => "ordinal-%02d" } for { :form => :short }' do
114
+ locale.send(:ordinalize_query_for, { :form => :short }).should == { :name => "ordinal-%02d" }
115
+ end
116
+
117
+ it 'returns { :name => "long-ordinal-%02d" } for { :form => :long }' do
118
+ locale.send(:ordinalize_query_for, { :form => :long }).should == { :name => "long-ordinal-%02d" }
119
+ end
120
+
121
+ it 'returns { :name => "ordinal-%02d", :"gender-form" => "feminine" } for { :gender => :feminine }' do
122
+ locale.send(:ordinalize_query_for, { :gender => :feminine }).should == { :name => "ordinal-%02d", :'gender-form' => 'feminine' }
123
+ end
124
+
125
+ end
126
+
127
+ end
128
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+
5
+ describe Node do
6
+
7
+ it { should_not be nil }
8
+ it { should_not have_children }
9
+ it { should_not have_attributes }
10
+
11
+ describe 'given a FooBarNode with attributes :foo and :bar and a TestNode without defined attributes' do
12
+ before(:all) do
13
+ class FooBarNode < Node
14
+ attr_struct :foo, :bar
15
+ end
16
+ class TestNode < Node
17
+ end
18
+ end
19
+
20
+ it 'creates FooBarNode::Attributes' do
21
+ FooBarNode.const_defined?(:Attributes).should be_true
22
+ end
23
+
24
+ it 'does not create TestNode::Attributes' do
25
+ TestNode.const_defined?(:Attributes).should_not be_true
26
+ end
27
+
28
+ it 'TestNode attributes are a regular Hash' do
29
+ TestNode.new.attributes.should be_a(Hash)
30
+ end
31
+
32
+ it 'FooBarNode attributes are a Struct' do
33
+ FooBarNode.new.attributes.should be_a(Struct)
34
+ end
35
+
36
+ describe '#values_at' do
37
+ it 'FooBarNode accepts attribute names' do
38
+ FooBarNode.new(:foo => 'Foo', :bar => 'Bar').values_at(:bar, :foo).should == %w{ Bar Foo }
39
+ end
40
+
41
+ it 'TestNode accepts attribute names' do
42
+ TestNode.new(:foo => 'Foo', :bar => 'Bar').values_at(:bar, :foo).should == %w{ Bar Foo }
43
+ end
44
+ end
45
+
46
+ describe '#to_a' do
47
+ it 'returns an empty list by default' do
48
+ Node.new.attributes.to_a.should == []
49
+ end
50
+
51
+ it 'TestNode returns an empty list by default' do
52
+ TestNode.new.attributes.to_a.should == []
53
+ end
54
+
55
+ # it 'TestNode returns a list of all key/value pairs' do
56
+ # TestNode.new(:foo => 'Foo', :bar => 'Bar').attributes.to_a.map(&:last).sort.should == %w{ Bar Foo }
57
+ # end
58
+
59
+ # it 'FooBarNode returns an empty list by default' do
60
+ # FooBarNode.new.attributes.to_a.should == []
61
+ # end
62
+
63
+ # it 'FooBarNode returns a list of all key/value pairs' do
64
+ # FooBarNode.new(:foo => 'Foo', :bar => 'Bar').attributes.to_a.map(&:last).sort.should == %w{ Bar Foo }
65
+ # end
66
+ end
67
+
68
+ describe 'attributes.keys' do
69
+ it 'returns all attribute names as symbols' do
70
+ TestNode.new.attributes.keys.should be_empty
71
+ FooBarNode.new.attributes.keys.should == [:foo, :bar]
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ describe TextNode do
78
+
79
+ it { should_not be nil }
80
+ it { should_not have_children }
81
+ it { should_not have_attributes }
82
+
83
+ describe '.new' do
84
+ it 'accepts a hash of attributes' do
85
+ TextNode.new(:foo => 'bar').should have_attributes
86
+ end
87
+
88
+ it 'yields itself to the optional block' do
89
+ TextNode.new { |n| n.text = 'foo' }.text.should == 'foo'
90
+ end
91
+
92
+ it 'accepts hash and yields itself to the optional block' do
93
+ TextNode.new(:foo => 'bar') { |n| n.text = 'foo' }.to_xml.should == '<text-node foo="bar">foo</text-node>'
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ end