caracal_the_curve 1.4.1

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 (116) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +22 -0
  3. data/.github/workflows/publish_gem.yml +40 -0
  4. data/.gitignore +25 -0
  5. data/.travis.yml +20 -0
  6. data/CHANGELOG.md +141 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +842 -0
  10. data/Rakefile +7 -0
  11. data/caracal.gemspec +28 -0
  12. data/lib/caracal/core/bookmarks.rb +52 -0
  13. data/lib/caracal/core/custom_properties.rb +49 -0
  14. data/lib/caracal/core/file_name.rb +43 -0
  15. data/lib/caracal/core/fonts.rb +75 -0
  16. data/lib/caracal/core/iframes.rb +42 -0
  17. data/lib/caracal/core/ignorables.rb +47 -0
  18. data/lib/caracal/core/images.rb +37 -0
  19. data/lib/caracal/core/list_styles.rb +93 -0
  20. data/lib/caracal/core/lists.rb +57 -0
  21. data/lib/caracal/core/models/base_model.rb +51 -0
  22. data/lib/caracal/core/models/bookmark_model.rb +86 -0
  23. data/lib/caracal/core/models/border_model.rb +120 -0
  24. data/lib/caracal/core/models/custom_property_model.rb +60 -0
  25. data/lib/caracal/core/models/font_model.rb +64 -0
  26. data/lib/caracal/core/models/iframe_model.rb +148 -0
  27. data/lib/caracal/core/models/image_model.rb +133 -0
  28. data/lib/caracal/core/models/line_break_model.rb +15 -0
  29. data/lib/caracal/core/models/link_model.rb +94 -0
  30. data/lib/caracal/core/models/list_item_model.rb +108 -0
  31. data/lib/caracal/core/models/list_model.rb +132 -0
  32. data/lib/caracal/core/models/list_style_model.rb +118 -0
  33. data/lib/caracal/core/models/margin_model.rb +76 -0
  34. data/lib/caracal/core/models/namespace_model.rb +65 -0
  35. data/lib/caracal/core/models/page_break_model.rb +61 -0
  36. data/lib/caracal/core/models/page_number_model.rb +95 -0
  37. data/lib/caracal/core/models/page_size_model.rb +79 -0
  38. data/lib/caracal/core/models/paragraph_model.rb +186 -0
  39. data/lib/caracal/core/models/relationship_model.rb +114 -0
  40. data/lib/caracal/core/models/rule_model.rb +27 -0
  41. data/lib/caracal/core/models/style_model.rb +165 -0
  42. data/lib/caracal/core/models/table_cell_model.rb +176 -0
  43. data/lib/caracal/core/models/table_model.rb +206 -0
  44. data/lib/caracal/core/models/text_model.rb +118 -0
  45. data/lib/caracal/core/namespaces.rb +89 -0
  46. data/lib/caracal/core/page_breaks.rb +29 -0
  47. data/lib/caracal/core/page_numbers.rb +58 -0
  48. data/lib/caracal/core/page_settings.rb +74 -0
  49. data/lib/caracal/core/relationships.rb +90 -0
  50. data/lib/caracal/core/rules.rb +35 -0
  51. data/lib/caracal/core/styles.rb +86 -0
  52. data/lib/caracal/core/tables.rb +42 -0
  53. data/lib/caracal/core/text.rb +75 -0
  54. data/lib/caracal/document.rb +272 -0
  55. data/lib/caracal/errors.rb +23 -0
  56. data/lib/caracal/renderers/app_renderer.rb +41 -0
  57. data/lib/caracal/renderers/content_types_renderer.rb +54 -0
  58. data/lib/caracal/renderers/core_renderer.rb +44 -0
  59. data/lib/caracal/renderers/custom_renderer.rb +64 -0
  60. data/lib/caracal/renderers/document_renderer.rb +427 -0
  61. data/lib/caracal/renderers/fonts_renderer.rb +56 -0
  62. data/lib/caracal/renderers/footer_renderer.rb +90 -0
  63. data/lib/caracal/renderers/numbering_renderer.rb +88 -0
  64. data/lib/caracal/renderers/package_relationships_renderer.rb +51 -0
  65. data/lib/caracal/renderers/relationships_renderer.rb +48 -0
  66. data/lib/caracal/renderers/settings_renderer.rb +58 -0
  67. data/lib/caracal/renderers/styles_renderer.rb +181 -0
  68. data/lib/caracal/renderers/xml_renderer.rb +83 -0
  69. data/lib/caracal/utilities.rb +23 -0
  70. data/lib/caracal/version.rb +3 -0
  71. data/lib/caracal.rb +40 -0
  72. data/lib/tilt/caracal.rb +21 -0
  73. data/spec/lib/caracal/core/bookmarks_spec.rb +35 -0
  74. data/spec/lib/caracal/core/file_name_spec.rb +54 -0
  75. data/spec/lib/caracal/core/fonts_spec.rb +119 -0
  76. data/spec/lib/caracal/core/iframes_spec.rb +29 -0
  77. data/spec/lib/caracal/core/ignorables_spec.rb +79 -0
  78. data/spec/lib/caracal/core/images_spec.rb +25 -0
  79. data/spec/lib/caracal/core/list_styles_spec.rb +121 -0
  80. data/spec/lib/caracal/core/lists_spec.rb +43 -0
  81. data/spec/lib/caracal/core/models/base_model_spec.rb +38 -0
  82. data/spec/lib/caracal/core/models/bookmark_model_spec.rb +135 -0
  83. data/spec/lib/caracal/core/models/border_model_spec.rb +159 -0
  84. data/spec/lib/caracal/core/models/font_model_spec.rb +92 -0
  85. data/spec/lib/caracal/core/models/iframe_model_spec.rb +83 -0
  86. data/spec/lib/caracal/core/models/image_model_spec.rb +225 -0
  87. data/spec/lib/caracal/core/models/line_break_model_spec.rb +21 -0
  88. data/spec/lib/caracal/core/models/link_model_spec.rb +179 -0
  89. data/spec/lib/caracal/core/models/list_item_model_spec.rb +197 -0
  90. data/spec/lib/caracal/core/models/list_model_spec.rb +178 -0
  91. data/spec/lib/caracal/core/models/list_style_model_spec.rb +198 -0
  92. data/spec/lib/caracal/core/models/margin_model_spec.rb +111 -0
  93. data/spec/lib/caracal/core/models/namespace_model_spec.rb +107 -0
  94. data/spec/lib/caracal/core/models/page_break_model_spec.rb +21 -0
  95. data/spec/lib/caracal/core/models/page_number_model_spec.rb +136 -0
  96. data/spec/lib/caracal/core/models/page_size_model_spec.rb +101 -0
  97. data/spec/lib/caracal/core/models/paragraph_model_spec.rb +196 -0
  98. data/spec/lib/caracal/core/models/relationship_model_spec.rb +193 -0
  99. data/spec/lib/caracal/core/models/rule_model_spec.rb +108 -0
  100. data/spec/lib/caracal/core/models/style_model_spec.rb +225 -0
  101. data/spec/lib/caracal/core/models/table_cell_model_spec.rb +230 -0
  102. data/spec/lib/caracal/core/models/table_model_spec.rb +222 -0
  103. data/spec/lib/caracal/core/models/text_model_spec.rb +154 -0
  104. data/spec/lib/caracal/core/namespaces_spec.rb +116 -0
  105. data/spec/lib/caracal/core/page_breaks_spec.rb +25 -0
  106. data/spec/lib/caracal/core/page_numbers_spec.rb +89 -0
  107. data/spec/lib/caracal/core/page_settings_spec.rb +151 -0
  108. data/spec/lib/caracal/core/relationships_spec.rb +119 -0
  109. data/spec/lib/caracal/core/rules_spec.rb +25 -0
  110. data/spec/lib/caracal/core/styles_spec.rb +129 -0
  111. data/spec/lib/caracal/core/tables_spec.rb +25 -0
  112. data/spec/lib/caracal/core/text_spec.rb +52 -0
  113. data/spec/lib/caracal/errors_spec.rb +10 -0
  114. data/spec/spec_helper.rb +8 -0
  115. data/spec/support/_fixtures/snippet.docx +0 -0
  116. metadata +292 -0
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+
3
+ describe Caracal::Core::Models::LinkModel do
4
+ subject do
5
+ described_class.new do
6
+ content 'Link Text'
7
+ href 'http://www.google.com'
8
+ internal false
9
+ font 'Courier New'
10
+ color '666666'
11
+ size 20
12
+ bold false
13
+ italic false
14
+ underline true
15
+ bgcolor 'cccccc'
16
+ highlight_color 'yellow'
17
+ vertical_align :top
18
+ end
19
+ end
20
+
21
+ #-------------------------------------------------------------
22
+ # Configuration
23
+ #-------------------------------------------------------------
24
+
25
+ describe 'configuration tests' do
26
+
27
+ # constants
28
+ describe 'constants' do
29
+ it { expect(described_class::DEFAULT_LINK_COLOR).to eq '1155cc' }
30
+ it { expect(described_class::DEFAULT_LINK_UNDERLINE).to eq true }
31
+ end
32
+
33
+ # accessors
34
+ describe 'accessors' do
35
+ it { expect(subject.link_content).to eq 'Link Text' }
36
+ it { expect(subject.link_href).to eq 'http://www.google.com' }
37
+ it { expect(subject.link_internal).to eq false }
38
+ it { expect(subject.link_font).to eq 'Courier New' }
39
+ it { expect(subject.link_color).to eq '666666' }
40
+ it { expect(subject.link_size).to eq 20 }
41
+ it { expect(subject.link_bold).to eq false }
42
+ it { expect(subject.link_italic).to eq false }
43
+ it { expect(subject.link_underline).to eq true }
44
+ it { expect(subject.link_bgcolor).to eq 'cccccc' }
45
+ it { expect(subject.link_highlight_color).to eq 'yellow' }
46
+ it { expect(subject.link_vertical_align).to eq :top }
47
+ end
48
+
49
+ end
50
+
51
+
52
+ #-------------------------------------------------------------
53
+ # Public Methods
54
+ #-------------------------------------------------------------
55
+
56
+ describe 'public method tests' do
57
+
58
+ #=============== GETTERS ==========================
59
+
60
+ # .run_attributes
61
+ describe '.run_attributes' do
62
+ let(:expected) { { style: nil, font: 'Courier New', color: '666666', size: 20, bold: false, italic: false, underline: true, bgcolor: 'cccccc', highlight_color: 'yellow', vertical_align: :top } }
63
+
64
+ it { expect(subject.run_attributes).to eq expected }
65
+ end
66
+
67
+
68
+ #=============== SETTERS ==========================
69
+
70
+ # booleans
71
+ describe '.bold' do
72
+ before { subject.bold(true) }
73
+
74
+ it { expect(subject.link_bold).to eq true }
75
+ end
76
+ describe '.internal' do
77
+ before { subject.internal(true) }
78
+
79
+ it { expect(subject.link_internal).to eq true }
80
+ end
81
+ describe '.italic' do
82
+ before { subject.italic(true) }
83
+
84
+ it { expect(subject.link_italic).to eq true }
85
+ end
86
+ describe '.underline' do
87
+ before { subject.underline(true) }
88
+
89
+ it { expect(subject.link_underline).to eq true }
90
+ end
91
+
92
+ # integers
93
+ describe '.size' do
94
+ before { subject.size(24) }
95
+
96
+ it { expect(subject.link_size).to eq 24 }
97
+ end
98
+
99
+ # strings
100
+ describe '.bgcolor' do
101
+ before { subject.bgcolor('dddddd') }
102
+
103
+ it { expect(subject.link_bgcolor).to eq 'dddddd' }
104
+ end
105
+ describe '.color' do
106
+ before { subject.color('999999') }
107
+
108
+ it { expect(subject.link_color).to eq '999999' }
109
+ end
110
+ describe '.content' do
111
+ before { subject.content('Something Else') }
112
+
113
+ it { expect(subject.link_content).to eq 'Something Else' }
114
+ end
115
+ describe '.font' do
116
+ before { subject.font('Palantino') }
117
+
118
+ it { expect(subject.link_font).to eq 'Palantino' }
119
+ end
120
+ describe '.href' do
121
+ before { subject.href('http://www.google.com') }
122
+
123
+ it { expect(subject.link_href).to eq 'http://www.google.com' }
124
+ end
125
+
126
+
127
+ #=============== STATE HELPERS ========================
128
+
129
+ describe '.external?' do
130
+ describe 'when internal is true' do
131
+ before { subject.internal(true) }
132
+
133
+ it { expect(subject.external?).to eq false }
134
+ end
135
+ describe 'when internal is false' do
136
+ before { subject.internal(false) }
137
+
138
+ it { expect(subject.external?).to eq true }
139
+ end
140
+ end
141
+
142
+
143
+ #=============== VALIDATION ===========================
144
+
145
+ describe '.valid?' do
146
+ describe 'when required attributes provided' do
147
+ it { expect(subject.valid?).to eq true }
148
+ end
149
+ [:content, :href].each do |prop|
150
+ describe "when #{ prop } nil" do
151
+ before do
152
+ allow(subject).to receive("link_#{ prop }").and_return(nil)
153
+ end
154
+
155
+ it { expect(subject.valid?).to eq false }
156
+ end
157
+ end
158
+ end
159
+
160
+ end
161
+
162
+
163
+ #-------------------------------------------------------------
164
+ # Private Methods
165
+ #-------------------------------------------------------------
166
+
167
+ describe 'private method tests' do
168
+
169
+ # .option_keys
170
+ describe '.option_keys' do
171
+ let(:actual) { subject.send(:option_keys).sort }
172
+ let(:expected) { [:content, :href, :internal, :style, :font, :color, :size, :bold, :highlight_color, :italic, :underline, :bgcolor, :vertical_align].sort }
173
+
174
+ it { expect(actual).to eq expected }
175
+ end
176
+
177
+ end
178
+
179
+ end
@@ -0,0 +1,197 @@
1
+ require 'spec_helper'
2
+
3
+ describe Caracal::Core::Models::ListItemModel do
4
+ subject do
5
+ described_class.new content: 'Lorem ipsum dolor....' do
6
+ type :ordered
7
+ level 2
8
+ style 'Fancy'
9
+ color '666666'
10
+ size 20
11
+ bold false
12
+ italic false
13
+ underline true
14
+ bgcolor 'cccccc'
15
+ end
16
+ end
17
+
18
+ #-------------------------------------------------------------
19
+ # Configuration
20
+ #-------------------------------------------------------------
21
+
22
+ describe 'configuration tests' do
23
+
24
+ # accessors
25
+ describe 'accessors' do
26
+ it { expect(subject.respond_to? :nested_list).to eq true }
27
+ it { expect(subject.respond_to? :nested_list=).to eq true }
28
+ it { expect(subject.list_item_type).to eq :ordered }
29
+ it { expect(subject.list_item_level).to eq 2 }
30
+ it { expect(subject.list_item_style).to eq 'Fancy' }
31
+ it { expect(subject.list_item_color).to eq '666666' }
32
+ it { expect(subject.list_item_size).to eq 20 }
33
+ it { expect(subject.list_item_bold).to eq false }
34
+ it { expect(subject.list_item_italic).to eq false }
35
+ it { expect(subject.list_item_underline).to eq true }
36
+ it { expect(subject.list_item_bgcolor).to eq 'cccccc' }
37
+ end
38
+
39
+ end
40
+
41
+
42
+ #-------------------------------------------------------------
43
+ # Public Methods
44
+ #-------------------------------------------------------------
45
+
46
+ describe 'public method tests' do
47
+
48
+ #=============== GETTERS ==========================
49
+
50
+ # .runs
51
+ describe '.runs' do
52
+ it { expect(subject.runs).to be_a(Array) }
53
+ end
54
+
55
+
56
+ #=============== SETTERS ==========================
57
+
58
+ # booleans
59
+ describe '.bold' do
60
+ before { subject.bold(true) }
61
+
62
+ it { expect(subject.list_item_bold).to eq true }
63
+ end
64
+ describe '.italic' do
65
+ before { subject.italic(true) }
66
+
67
+ it { expect(subject.list_item_italic).to eq true }
68
+ end
69
+ describe '.underline' do
70
+ before { subject.underline(true) }
71
+
72
+ it { expect(subject.list_item_underline).to eq true }
73
+ end
74
+
75
+ # integers
76
+ describe '.level' do
77
+ before { subject.level(3) }
78
+
79
+ it { expect(subject.list_item_level).to eq 3 }
80
+ end
81
+ describe '.size' do
82
+ before { subject.size(24) }
83
+
84
+ it { expect(subject.list_item_size).to eq 24 }
85
+ end
86
+
87
+ # strings
88
+ describe '.bgcolor' do
89
+ before { subject.bgcolor('dddddd') }
90
+
91
+ it { expect(subject.list_item_bgcolor).to eq 'dddddd' }
92
+ end
93
+ describe '.color' do
94
+ before { subject.color('999999') }
95
+
96
+ it { expect(subject.list_item_color).to eq '999999' }
97
+ end
98
+ describe '.style' do
99
+ before { subject.style('Dummy') }
100
+
101
+ it { expect(subject.list_item_style).to eq 'Dummy' }
102
+ end
103
+
104
+ # symbols
105
+ describe '.type' do
106
+ before { subject.type(:ordered) }
107
+
108
+ it { expect(subject.list_item_type).to eq :ordered }
109
+ end
110
+
111
+
112
+ #=============== SUB-METHODS ==========================
113
+
114
+ # .link
115
+ describe '.link' do
116
+ let!(:length) { subject.runs.length }
117
+
118
+ before { subject.link 'Text', 'http://www.google.com' }
119
+
120
+ it { expect(subject.runs.size).to eq length + 1 }
121
+ end
122
+
123
+ # .text
124
+ describe '.text' do
125
+ let!(:length) { subject.runs.length }
126
+
127
+ before { subject.text 'Text' }
128
+
129
+ it { expect(subject.runs.size).to eq length + 1 }
130
+ end
131
+
132
+ # .ol
133
+ describe '.ol' do
134
+ describe 'when no nested list provided' do
135
+ subject do
136
+ described_class.new type: :ordered, level: 0 do
137
+ text 'Item text.'
138
+ end
139
+ end
140
+
141
+ it { expect(subject.nested_list).to eq nil }
142
+ end
143
+ describe 'when nested list provided' do
144
+ subject do
145
+ described_class.new type: :ordered, level: 0 do
146
+ text 'Item text.'
147
+ ol do
148
+ li 'Nested item text.'
149
+ end
150
+ end
151
+ end
152
+
153
+ it { expect(subject.nested_list).to be_a(Caracal::Core::Models::ListModel) }
154
+ end
155
+ end
156
+
157
+
158
+
159
+ #=============== VALIDATION ===========================
160
+
161
+ describe '.valid?' do
162
+ describe 'when at least one run exists' do
163
+ before do
164
+ allow(subject).to receive(:runs).and_return(['a'])
165
+ end
166
+
167
+ it { expect(subject.valid?).to eq true }
168
+ end
169
+ describe 'when no runs exist' do
170
+ before do
171
+ allow(subject).to receive(:runs).and_return([])
172
+ end
173
+
174
+ it { expect(subject.valid?).to eq false }
175
+ end
176
+ end
177
+
178
+ end
179
+
180
+
181
+ #-------------------------------------------------------------
182
+ # Private Methods
183
+ #-------------------------------------------------------------
184
+
185
+ describe 'private method tests' do
186
+
187
+ # .option_keys
188
+ describe '.option_keys' do
189
+ let(:actual) { subject.send(:option_keys).sort }
190
+ let(:expected) { [:type, :level, :content, :style, :color, :size, :bold, :italic, :underline, :bgcolor].sort }
191
+
192
+ it { expect(actual).to eq expected }
193
+ end
194
+
195
+ end
196
+
197
+ end
@@ -0,0 +1,178 @@
1
+ require 'spec_helper'
2
+
3
+ describe Caracal::Core::Models::ListModel do
4
+ subject do
5
+ described_class.new do
6
+ type :ordered
7
+ level 1
8
+ li 'Item 1'
9
+ end
10
+ end
11
+
12
+ #-------------------------------------------------------------
13
+ # Configuration
14
+ #-------------------------------------------------------------
15
+
16
+ describe 'configuration tests' do
17
+
18
+ # constants
19
+ describe 'constants' do
20
+ it { expect(described_class::DEFAULT_LIST_TYPE).to eq :unordered }
21
+ it { expect(described_class::DEFAULT_LIST_LEVEL).to eq 0 }
22
+ end
23
+
24
+ # accessors
25
+ describe 'accessors' do
26
+ it { expect(subject.list_type).to eq :ordered }
27
+ it { expect(subject.list_level).to eq 1 }
28
+ end
29
+
30
+ end
31
+
32
+
33
+ #-------------------------------------------------------------
34
+ # Public Methods
35
+ #-------------------------------------------------------------
36
+
37
+ describe 'public method tests' do
38
+
39
+ #=============== GETTERS ==========================
40
+
41
+ # .items
42
+ describe '.items' do
43
+ it { expect(subject.items).to be_a(Array) }
44
+ end
45
+
46
+ # .recursive_items
47
+ describe '.recursive_items' do
48
+ describe 'when no nested lists provided' do
49
+ subject do
50
+ described_class.new type: :ordered, level: 0 do
51
+ li 'Item 1'
52
+ li 'Item 2'
53
+ end
54
+ end
55
+
56
+ it { expect(subject.recursive_items.size).to eq 2 }
57
+ it { expect(subject.recursive_items[0].list_item_level).to eq 0 }
58
+ end
59
+ describe 'when one nested list provided' do
60
+ subject do
61
+ described_class.new type: :ordered, level: 0 do
62
+ li 'Item 1'
63
+ li 'Item 2' do
64
+ ol do
65
+ li 'SubItem 1'
66
+ li 'SubItem 2'
67
+ end
68
+ end
69
+ li 'Item 3'
70
+ end
71
+ end
72
+
73
+ it { expect(subject.recursive_items.size).to eq 5 }
74
+ it { expect(subject.recursive_items[0].list_item_level).to eq 0 }
75
+ it { expect(subject.recursive_items[2].list_item_level).to eq 1 }
76
+ it { expect(subject.recursive_items[4].list_item_level).to eq 0 }
77
+ end
78
+ describe 'when more than one nested list provided' do
79
+ subject do
80
+ described_class.new type: :ordered, level: 0 do
81
+ li 'Item 1'
82
+ li 'Item 2' do
83
+ ol do
84
+ li 'SubItem 1' do
85
+ ul do
86
+ li 'NestedItem 1'
87
+ end
88
+ end
89
+ li 'SubItem 2'
90
+ end
91
+ end
92
+ li 'Item 3'
93
+ end
94
+ end
95
+
96
+ it { expect(subject.recursive_items.size).to eq 6 }
97
+ it { expect(subject.recursive_items[0].list_item_level).to eq 0 }
98
+ it { expect(subject.recursive_items[2].list_item_level).to eq 1 }
99
+ it { expect(subject.recursive_items[3].list_item_level).to eq 2 }
100
+ it { expect(subject.recursive_items[4].list_item_level).to eq 1 }
101
+ it { expect(subject.recursive_items[5].list_item_level).to eq 0 }
102
+ end
103
+ end
104
+
105
+
106
+ #=============== SETTERS ==========================
107
+
108
+ # .type
109
+ describe '.type' do
110
+ before { subject.type(:dummy) }
111
+
112
+ it { expect(subject.list_type).to eq :dummy }
113
+ end
114
+
115
+ # .level
116
+ describe '.level' do
117
+ before { subject.level(2) }
118
+
119
+ it { expect(subject.list_level).to eq 2 }
120
+ end
121
+
122
+
123
+ #=============== SUB-METHODS ==========================
124
+
125
+ # .li
126
+ describe '.li' do
127
+ let!(:length) { subject.items.length }
128
+
129
+ before { subject.li 'Text' }
130
+
131
+ it { expect(subject.items.size).to eq length + 1 }
132
+ end
133
+
134
+
135
+ #=============== VALIDATION ===========================
136
+
137
+ describe '.valid?' do
138
+ describe 'when all required attributes provides' do
139
+ it { expect(subject.valid?).to eq true }
140
+ end
141
+ [:type, :level].each do |attr|
142
+ describe "when #{ attr } nil" do
143
+ before do
144
+ allow(subject).to receive("list_#{ attr }").and_return(nil)
145
+ end
146
+
147
+ it { expect(subject.valid?).to eq false }
148
+ end
149
+ end
150
+ describe 'when items empty' do
151
+ before do
152
+ allow(subject).to receive(:items).and_return([])
153
+ end
154
+
155
+ it { expect(subject.valid?).to eq false }
156
+ end
157
+ end
158
+
159
+ end
160
+
161
+
162
+ #-------------------------------------------------------------
163
+ # Private Methods
164
+ #-------------------------------------------------------------
165
+
166
+ describe 'private method tests' do
167
+
168
+ # .option_keys
169
+ describe '.option_keys' do
170
+ let(:actual) { subject.send(:option_keys).sort }
171
+ let(:expected) { [:type, :level].sort }
172
+
173
+ it { expect(actual).to eq expected }
174
+ end
175
+
176
+ end
177
+
178
+ end