csl 1.0.0.pre1

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.
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,92 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+
5
+ describe Parser do
6
+
7
+ describe '.instance' do
8
+ it 'returns the parser' do
9
+ Parser.instance.should be_instance_of(Parser)
10
+ end
11
+ end
12
+
13
+ Parser.engines.each_pair do |name, parser|
14
+ describe "when using the #{name} parser " do
15
+ before(:all) { Parser.instance.parser = parser }
16
+
17
+ describe '#parse' do
18
+
19
+ describe 'for <foo/>' do
20
+ let(:source) { '<foo/>' }
21
+
22
+ it 'returns a CSL::Node' do
23
+ Parser.instance.parse(source).should be_a(Node)
24
+ end
25
+
26
+ it 'returns a node with nodename "foo"' do
27
+ Parser.instance.parse(source).nodename.should == 'foo'
28
+ end
29
+
30
+ it 'returns a node with no attributes' do
31
+ Parser.instance.parse(source).should_not have_attributes
32
+ end
33
+
34
+ it 'returns a node with no children' do
35
+ Parser.instance.parse(source).should_not have_children
36
+ end
37
+ end
38
+
39
+ describe 'for <foo bar="x"/>' do
40
+ let(:source) { '<foo bar="x"/>' }
41
+
42
+ it 'returns a node with attributes' do
43
+ Parser.instance.parse(source).should have_attributes
44
+ end
45
+
46
+ it 'returns a node with attribute bar' do
47
+ Parser.instance.parse(source).attribute?(:bar).should be
48
+ end
49
+
50
+ it 'bar should be "x"' do
51
+ Parser.instance.parse(source)[:bar].should == 'x'
52
+ end
53
+ end
54
+
55
+ describe 'for <foo>Foo Bar</foo>' do
56
+ let(:source) { '<foo>Foo Bar</foo>' }
57
+
58
+ it 'returns text node' do
59
+ Parser.instance.parse(source).should be_textnode
60
+ end
61
+ end
62
+
63
+ it 'returns a regular node for <x>\n <y/></x>' do
64
+ Parser.instance.parse("<x>\n <y/></x>").should_not be_textnode
65
+ end
66
+
67
+ describe 'xml comments' do
68
+ it 'ignores comment-only documents' do
69
+ Parser.instance.parse("<!--x></x-->").should be_nil
70
+ end
71
+
72
+ it 'ignores comments in normal nodes' do
73
+ Parser.instance.parse("<x><!-- comment --></x>").should_not have_children
74
+ end
75
+
76
+ it 'ignores comments in text nodes' do
77
+ node = Parser.instance.parse("<x>foo<!-- comment --></x>")
78
+ node.should be_textnode
79
+ node.should_not have_children
80
+ node.text.should == 'foo'
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe 'Schema' do
5
+
6
+ describe '.version' do
7
+ it 'returns a version string' do
8
+ Schema.version.should match(/^\d+\.\d+\.\d+/)
9
+ end
10
+
11
+ it 'is greater than 1.0' do
12
+ Schema.version.split(/\./)[0].to_i.should >= 1
13
+ end
14
+ end
15
+
16
+ describe '.variables' do
17
+ it 'contains :names fields' do
18
+ Schema.variables[:names].should_not be_empty
19
+ Schema.variables[:name].should equal Schema.variables[:names]
20
+ end
21
+
22
+ it 'contains :date fields' do
23
+ Schema.variables[:date].should_not be_empty
24
+ Schema.variables[:dates].should equal Schema.variables[:date]
25
+ end
26
+
27
+ it 'contains :text fields' do
28
+ Schema.variables[:text].should_not be_empty
29
+ end
30
+
31
+ it 'contains :number fields' do
32
+ Schema.variables[:numbers].should_not be_empty
33
+ Schema.variables[:number].should_not be_empty
34
+ end
35
+
36
+ it 'accepts either string or symbol input' do
37
+ Schema.variables[:names].should equal Schema.variables['names']
38
+ end
39
+ end
40
+
41
+ describe '.types' do
42
+ it 'returns an array' do
43
+ Schema.types.should be_a(Array)
44
+ end
45
+
46
+ it 'is not empty' do
47
+ Schema.types.should_not be_empty
48
+ end
49
+
50
+ it 'includes :article' do
51
+ Schema.types.should include(:article)
52
+ end
53
+ end
54
+
55
+ describe '.categories' do
56
+ it 'given a field name returns the corresponding type' do
57
+ Schema.categories[:author].should == :names
58
+ Schema.categories[:issued].should == :date
59
+ Schema.categories[:abstract].should == :text
60
+ Schema.categories[:issue].should == :number
61
+ end
62
+
63
+ it 'accepts either string or symbol input' do
64
+ Schema.categories.should have_key(:author)
65
+ Schema.categories['author'].should equal Schema.categories[:author]
66
+ end
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Bibliography do
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Citation do
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Conditional do
5
+
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Date do
5
+
6
+ end
7
+
8
+ describe Style::DatePart do
9
+
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Group do
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Label do
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Layout do
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Macro do
5
+
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Names do
5
+
6
+ end
7
+
8
+ describe Style::Name do
9
+
10
+ end
11
+
12
+ describe Style::NamePart do
13
+
14
+ end
15
+
16
+ describe Style::EtAl do
17
+
18
+ end
19
+
20
+ describe Style::Substitute do
21
+
22
+ end
23
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Number do
5
+
6
+ describe '.new' do
7
+ it 'returns an empty number tag by default' do
8
+ Style::Number.new.should_not have_attributes
9
+ end
10
+
11
+ it 'accepts a form attribute' do
12
+ Style::Number.new(:form => 'roman').should be_roman
13
+ end
14
+ end
15
+
16
+ describe '#numeric?' do
17
+ it 'returns true by default' do
18
+ Style::Number.new.should be_numeric
19
+ end
20
+
21
+ it 'returns false if the form attribute is set to a value other than :numeric' do
22
+ Style::Number.new(:form => 'foo').should_not be_numeric
23
+ end
24
+
25
+ it 'returns false if the form attribute is set to :numeric' do
26
+ Style::Number.new(:form => 'numeric').should be_numeric
27
+ end
28
+ end
29
+
30
+ describe '#roman?' do
31
+ it 'returns false by default' do
32
+ Style::Number.new.should_not be_roman
33
+ end
34
+
35
+ it 'returns false if the form attribute is set to a value other than :numeric' do
36
+ Style::Number.new(:form => 'ordinal').should_not be_roman
37
+ end
38
+
39
+ it 'returns false if the form attribute is set to :roman' do
40
+ Style::Number.new(:form => 'roman').should be_roman
41
+ end
42
+ end
43
+
44
+ describe '#ordinal?' do
45
+ it 'returns false by default' do
46
+ Style::Number.new.should_not be_ordinal
47
+ end
48
+
49
+ it 'returns false if the form attribute is set to a value other than :ordinal' do
50
+ Style::Number.new(:form => 'long-ordinal').should_not be_ordinal
51
+ end
52
+
53
+ it 'returns false if the form attribute is set to :ordinal' do
54
+ Style::Number.new(:form => 'ordinal').should be_ordinal
55
+ end
56
+ end
57
+
58
+ describe '#long_ordinal?' do
59
+ it 'returns false by default' do
60
+ Style::Number.new.should_not be_long_ordinal
61
+ end
62
+
63
+ it 'returns false if the form attribute is set to a value other than :"long-ordinal"' do
64
+ Style::Number.new(:form => 'ordinal').should_not be_long_ordinal
65
+ end
66
+
67
+ it 'returns false if the form attribute is set to :ordinal' do
68
+ Style::Number.new(:form => 'long-ordinal').should be_long_ordinal
69
+ end
70
+ end
71
+
72
+
73
+ describe '#to_xml' do
74
+ it 'returns an empty number tag by default' do
75
+ Style::Number.new.to_xml.should == '<number/>'
76
+ end
77
+
78
+ it 'returns a tag with a all attribute assignments' do
79
+ Style::Number.new(:form => 'roman').to_xml.should == '<number form="roman"/>'
80
+ end
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style::Text do
5
+
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe Style do
5
+
6
+ it { should be }
7
+
8
+ it 'has a 1.x version by default' do
9
+ Style.new[:version].should match(/1\.\d+(\.\d+)?/)
10
+ end
11
+
12
+ describe '#to_xml' do
13
+ it 'returns an empty style' do
14
+ Style.new.to_xml.should match(/<style[^>]*\/>/)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+
3
+ module CSL
4
+ describe 'Treelike' do
5
+
6
+ before(:all) do
7
+ class TestTree
8
+ include Treelike
9
+
10
+ def initialize
11
+ @children = self.class.create_children
12
+ end
13
+ end
14
+ end
15
+
16
+ let(:node) { TestTree.new }
17
+
18
+ let(:lvl1) { TestTree.new.add_child(TestTree.new) }
19
+ let(:lvl2) { TestTree.new.add_child(TestTree.new).add_child(TestTree.new) }
20
+
21
+ it 'has no children by default' do
22
+ node.should_not have_children
23
+ end
24
+
25
+ it 'is empty by default' do
26
+ node.should be_empty
27
+ end
28
+
29
+ describe '#children' do
30
+
31
+ it 'is empty by default' do
32
+ node.children.should be_empty
33
+ end
34
+
35
+ it 'grows when adding child nodes' do
36
+ expect { node << TestTree.new }.to change { node.children.length }.by(1)
37
+ end
38
+
39
+ end
40
+
41
+ describe '#nodename' do
42
+ it 'returns the class name in attribute form by default' do
43
+ node.nodename.should == 'test-tree'
44
+ end
45
+ end
46
+
47
+ describe '#ancestors' do
48
+ it 'returns and empty list by default' do
49
+ node.ancestors.should be_empty
50
+ end
51
+
52
+ it 'returns a list with one ancestor at level 1' do
53
+ lvl1.ancestors.should have(1).element
54
+ end
55
+
56
+ it 'the last ancestor is also the root node at levels 1 and deeper' do
57
+ lvl1.ancestors.last.should be_root
58
+ lvl2.ancestors.last.should be_root
59
+ end
60
+
61
+ it 'returns a list with two ancestors at level 2' do
62
+ lvl2.ancestors.should have(2).elements
63
+ end
64
+ end
65
+
66
+ it 'is a root node by default' do
67
+ node.should be_root
68
+ end
69
+
70
+ describe '#root' do
71
+ it 'returns self at level 0' do
72
+ node.root.should equal(node)
73
+ end
74
+
75
+ it 'returns the parent at level 1' do
76
+ lvl1.root.should == lvl1.parent
77
+ end
78
+
79
+ it 'returns parent.parent at level 2' do
80
+ lvl2.root.should == lvl2.parent.parent
81
+ end
82
+ end
83
+
84
+ describe '#depth' do
85
+ it 'returns 0 by default' do
86
+ node.depth.should == 0
87
+ end
88
+
89
+ it 'returns 1 at level 1' do
90
+ lvl1.depth.should == 1
91
+ end
92
+
93
+ it 'returns 2 at level 2' do
94
+ lvl2.depth.should == 2
95
+ end
96
+
97
+ it 'grows when the node is added to another node' do
98
+ expect { TestTree.new << node }.to change { node.depth }.by(1)
99
+ end
100
+
101
+ end
102
+
103
+ describe 'named children' do
104
+ before(:all) do
105
+ class TestTree
106
+ attr_children :'test-tree'
107
+ end
108
+ class AnotherTree
109
+ include Treelike
110
+ end
111
+ end
112
+
113
+ it 'the class contains a children struct' do
114
+ TestTree.const?(:Children).should be true
115
+ end
116
+
117
+ describe '.create_children' do
118
+ it 'returns the children struct' do
119
+ TestTree.create_children.should be_a(Struct)
120
+ end
121
+ end
122
+
123
+ describe '#children' do
124
+ it 'returns a children struct instance' do
125
+ TestTree.new.children.should be_a(Struct)
126
+ end
127
+ end
128
+
129
+ it 'has no children by default' do
130
+ TestTree.new.should_not have_children
131
+ end
132
+
133
+ it 'has children when adding child nodes' do
134
+ expect { node << TestTree.new }.to change { node.has_children? }.to(true)
135
+ end
136
+
137
+ it 'raises an error when adding a child with an invalid name' do
138
+ expect { node << AnotherTree.new }.to raise_error(ValidationError)
139
+ end
140
+
141
+ it 'accepts multiple nodes of the same name' do
142
+ expect { node << TestTree.new << TestTree.new }.to change {
143
+ node.children.each.to_a.length
144
+ }.from(0).to(2)
145
+ end
146
+
147
+ end
148
+
149
+ end
150
+
151
+ end