squib 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/deck_spec.rb CHANGED
@@ -45,180 +45,16 @@ describe Squib::Deck do
45
45
  end
46
46
  end
47
47
 
48
- context '#load_layout' do
49
-
50
- it 'loads a normal layout with no extends' do
51
- d = Squib::Deck.new(layout: layout_file('no-extends.yml'))
52
- expect(d.layout).to \
53
- eq({'frame' => {
54
- 'x' => 38,
55
- 'valign' => :middle,
56
- 'str' => 'blah',
57
- 'font' => 'Mr. Font',
58
- }
59
- }
60
- )
61
- end
62
-
63
- it 'loads with a single extends' do
64
- d = Squib::Deck.new(layout: layout_file('single-extends.yml'))
65
- expect(d.layout).to \
66
- eq({'frame' => {
67
- 'x' => 38,
68
- 'y' => 38,
69
- },
70
- 'title' => {
71
- 'extends' => 'frame',
72
- 'x' => 38,
73
- 'y' => 50,
74
- 'width' => 100,
75
- }
76
- }
77
- )
78
- end
79
-
80
- it 'applies the extends regardless of order' do
81
- d = Squib::Deck.new(layout: layout_file('pre-extends.yml'))
82
- expect(d.layout).to \
83
- eq({'frame' => {
84
- 'x' => 38,
85
- 'y' => 38,
86
- },
87
- 'title' => {
88
- 'extends' => 'frame',
89
- 'x' => 38,
90
- 'y' => 50,
91
- 'width' => 100,
92
- }
93
- }
94
- )
95
- end
96
-
97
- it 'applies the single-level extends multiple times' do
98
- d = Squib::Deck.new(layout: layout_file('single-level-multi-extends.yml'))
99
- expect(d.layout).to \
100
- eq({'frame' => {
101
- 'x' => 38,
102
- 'y' => 38,
103
- },
104
- 'title' => {
105
- 'extends' => 'frame',
106
- 'x' => 38,
107
- 'y' => 50,
108
- 'width' => 100,
109
- },
110
- 'title2' => {
111
- 'extends' => 'frame',
112
- 'x' => 75,
113
- 'y' => 150,
114
- 'width' => 150,
115
- },
116
- }
117
- )
118
- end
119
-
120
- it 'applies multiple extends in a single rule' do
121
- d = Squib::Deck.new(layout: layout_file('multi-extends-single-entry.yml'))
122
- expect(d.layout).to \
123
- eq({'aunt' => {
124
- 'a' => 101,
125
- 'b' => 102,
126
- 'c' => 103,
127
- },
128
- 'uncle' => {
129
- 'x' => 104,
130
- 'y' => 105,
131
- 'b' => 106,
132
- },
133
- 'child' => {
134
- 'extends' => ['uncle','aunt'],
135
- 'a' => 107, # my own
136
- 'b' => 102, # from the younger aunt
137
- 'c' => 103, # from aunt
138
- 'x' => 108, # my own
139
- 'y' => 105, # from uncle
140
- },
141
- }
142
- )
143
- end
144
-
145
- it 'applies multi-level extends' do
146
- d = Squib::Deck.new(layout: layout_file('multi-level-extends.yml'))
147
- expect(d.layout).to \
148
- eq({'frame' => {
149
- 'x' => 38,
150
- 'y' => 38,
151
- },
152
- 'title' => {
153
- 'extends' => 'frame',
154
- 'x' => 38,
155
- 'y' => 50,
156
- 'width' => 100,
157
- },
158
- 'subtitle' => {
159
- 'extends' => 'title',
160
- 'x' => 38,
161
- 'y' => 150,
162
- 'width' => 100,
163
- },
164
- }
165
- )
166
- end
167
-
168
- it 'fails on a self-circular extends' do
169
- file = layout_file('self-circular-extends.yml')
170
- expect { Squib::Deck.new(layout: file) }.to \
171
- raise_error(RuntimeError, 'Invalid layout: circular extends with \'a\'')
172
- end
173
-
174
- it 'fails on a easy-circular extends' do
175
- file = layout_file('easy-circular-extends.yml')
176
- expect { Squib::Deck.new(layout: file) }.to \
177
- raise_error(RuntimeError, 'Invalid layout: circular extends with \'a\'')
178
- end
179
-
180
- it 'hard on a easy-circular extends' do
181
- file = layout_file('hard-circular-extends.yml')
182
- expect { Squib::Deck.new(layout: file) }.to \
183
- raise_error(RuntimeError, 'Invalid layout: circular extends with \'a\'')
184
- end
185
-
186
- it 'redefines keys on multiple layouts' do
187
- a = layout_file('multifile-a.yml')
188
- b = layout_file('multifile-b.yml')
189
- d = Squib::Deck.new(layout: [a, b])
190
- expect(d.layout).to eq({
191
- 'title' => { 'x' => 300 },
192
- 'subtitle' => { 'x' => 200 },
193
- 'desc' => { 'x' => 400 }
194
- })
195
- end
196
-
197
- it 'evaluates extends on each file first' do
198
- a = layout_file('multifile-extends-a.yml')
199
- b = layout_file('multifile-extends-b.yml')
200
- d = Squib::Deck.new(layout: [a, b])
201
- expect(d.layout).to eq({
202
- 'grandparent' => { 'x' => 100 },
203
- 'parent_a' => { 'x' => 110, 'extends' => 'grandparent' },
204
- 'parent_b' => { 'x' => 130, 'extends' => 'grandparent' },
205
- 'child_a' => { 'x' => 113, 'extends' => 'parent_a' },
206
- 'child_b' => { 'x' => 133, 'extends' => 'parent_b' }
207
- })
208
- end
209
-
210
- it 'loads nothing on an empty layout file' do
211
- d = Squib::Deck.new(layout: layout_file('empty.yml'))
212
- expect(d.layout).to eq({})
213
- end
214
-
215
- it 'handles extends on a rule with no args' do
216
- d = Squib::Deck.new(layout: layout_file('empty-rule.yml'))
217
- expect(d.layout).to eq({
218
- 'empty' => nil
219
- })
220
- end
221
-
48
+ it 'loads a normal layout with no extends' do
49
+ d = Squib::Deck.new(layout: layout_file('no-extends.yml'))
50
+ expect(d.layout).to eq({
51
+ 'frame' => {
52
+ 'x' => 38,
53
+ 'valign' => :middle,
54
+ 'str' => 'blah',
55
+ 'font' => 'Mr. Font',
56
+ }
57
+ })
222
58
  end
223
59
 
224
60
  end
@@ -199,4 +199,21 @@ describe Squib::InputHelpers do
199
199
  end
200
200
  end
201
201
 
202
+ context '#faceify' do
203
+ it 'is false on left' do
204
+ opts = @deck.send(:faceify, {face: :left})
205
+ expect(opts).to eq({ face: false })
206
+ end
207
+
208
+ it 'is true on right' do
209
+ opts = @deck.send(:faceify, {face: 'Right'})
210
+ expect(opts).to eq({ face: true })
211
+ end
212
+
213
+ it 'is false on anything else' do
214
+ opts = @deck.send(:faceify, {face: 'flugelhorn'})
215
+ expect(opts).to eq({ face: false })
216
+ end
217
+ end
218
+
202
219
  end
@@ -0,0 +1,189 @@
1
+ require 'spec_helper'
2
+
3
+ describe Squib::LayoutParser do
4
+
5
+ it 'loads a normal layout with no extends' do
6
+ layout = Squib::LayoutParser.load_layout(layout_file('no-extends.yml'))
7
+ expect(layout).to eq({'frame' => {
8
+ 'x' => 38,
9
+ 'valign' => :middle,
10
+ 'str' => 'blah',
11
+ 'font' => 'Mr. Font',
12
+ }
13
+ }
14
+ )
15
+ end
16
+
17
+ it 'loads with a single extends' do
18
+ layout = Squib::LayoutParser.load_layout(layout_file('single-extends.yml'))
19
+ expect(layout).to eq({'frame' => {
20
+ 'x' => 38,
21
+ 'y' => 38,
22
+ },
23
+ 'title' => {
24
+ 'extends' => 'frame',
25
+ 'x' => 38,
26
+ 'y' => 50,
27
+ 'width' => 100,
28
+ }
29
+ }
30
+ )
31
+ end
32
+
33
+ it 'applies the extends regardless of order' do
34
+ layout = Squib::LayoutParser.load_layout(layout_file('pre-extends.yml'))
35
+ expect(layout).to eq({'frame' => {
36
+ 'x' => 38,
37
+ 'y' => 38,
38
+ },
39
+ 'title' => {
40
+ 'extends' => 'frame',
41
+ 'x' => 38,
42
+ 'y' => 50,
43
+ 'width' => 100,
44
+ }
45
+ }
46
+ )
47
+ end
48
+
49
+ it 'applies the single-level extends multiple times' do
50
+ layout = Squib::LayoutParser.load_layout(layout_file('single-level-multi-extends.yml'))
51
+ expect(layout).to eq({'frame' => {
52
+ 'x' => 38,
53
+ 'y' => 38,
54
+ },
55
+ 'title' => {
56
+ 'extends' => 'frame',
57
+ 'x' => 38,
58
+ 'y' => 50,
59
+ 'width' => 100,
60
+ },
61
+ 'title2' => {
62
+ 'extends' => 'frame',
63
+ 'x' => 75,
64
+ 'y' => 150,
65
+ 'width' => 150,
66
+ },
67
+ }
68
+ )
69
+ end
70
+
71
+ it 'applies multiple extends in a single rule' do
72
+ layout = Squib::LayoutParser.load_layout(layout_file('multi-extends-single-entry.yml'))
73
+ expect(layout).to eq({'aunt' => {
74
+ 'a' => 101,
75
+ 'b' => 102,
76
+ 'c' => 103,
77
+ },
78
+ 'uncle' => {
79
+ 'x' => 104,
80
+ 'y' => 105,
81
+ 'b' => 106,
82
+ },
83
+ 'child' => {
84
+ 'extends' => ['uncle','aunt'],
85
+ 'a' => 107, # my own
86
+ 'b' => 102, # from the younger aunt
87
+ 'c' => 103, # from aunt
88
+ 'x' => 108, # my own
89
+ 'y' => 105, # from uncle
90
+ },
91
+ }
92
+ )
93
+ end
94
+
95
+ it 'applies multi-level extends' do
96
+ layout = Squib::LayoutParser.load_layout(layout_file('multi-level-extends.yml'))
97
+ expect(layout).to eq({'frame' => {
98
+ 'x' => 38,
99
+ 'y' => 38,
100
+ },
101
+ 'title' => {
102
+ 'extends' => 'frame',
103
+ 'x' => 38,
104
+ 'y' => 50,
105
+ 'width' => 100,
106
+ },
107
+ 'subtitle' => {
108
+ 'extends' => 'title',
109
+ 'x' => 38,
110
+ 'y' => 150,
111
+ 'width' => 100,
112
+ },
113
+ }
114
+ )
115
+ end
116
+
117
+ it 'fails on a self-circular extends' do
118
+ file = layout_file('self-circular-extends.yml')
119
+ expect { Squib::LayoutParser.load_layout(file) }
120
+ .to raise_error(RuntimeError, 'Invalid layout: circular extends with \'a\'')
121
+ end
122
+
123
+ it 'fails on a easy-circular extends' do
124
+ file = layout_file('easy-circular-extends.yml')
125
+ expect { Squib::LayoutParser.load_layout(file) }
126
+ .to raise_error(RuntimeError, 'Invalid layout: circular extends with \'a\'')
127
+ end
128
+
129
+ it 'hard on a easy-circular extends' do
130
+ file = layout_file('hard-circular-extends.yml')
131
+ expect { Squib::LayoutParser.load_layout(file) }
132
+ .to raise_error(RuntimeError, 'Invalid layout: circular extends with \'a\'')
133
+ end
134
+
135
+ it 'redefines keys on multiple layouts' do
136
+ a = layout_file('multifile-a.yml')
137
+ b = layout_file('multifile-b.yml')
138
+ layout = Squib::LayoutParser.load_layout([a, b])
139
+ expect(layout).to eq({
140
+ 'title' => { 'x' => 300 },
141
+ 'subtitle' => { 'x' => 200 },
142
+ 'desc' => { 'x' => 400 }
143
+ })
144
+ end
145
+
146
+ it 'evaluates extends on each file first' do
147
+ a = layout_file('multifile-extends-a.yml')
148
+ b = layout_file('multifile-extends-b.yml')
149
+ layout = Squib::LayoutParser.load_layout([a, b])
150
+ expect(layout).to eq({
151
+ 'grandparent' => { 'x' => 100 },
152
+ 'parent_a' => { 'x' => 110, 'extends' => 'grandparent' },
153
+ 'parent_b' => { 'x' => 130, 'extends' => 'grandparent' },
154
+ 'child_a' => { 'x' => 113, 'extends' => 'parent_a' },
155
+ 'child_b' => { 'x' => 133, 'extends' => 'parent_b' }
156
+ })
157
+ end
158
+
159
+ it 'loads nothing on an empty layout file' do
160
+ layout = Squib::LayoutParser.load_layout(layout_file('empty.yml'))
161
+ expect(layout).to eq({})
162
+ end
163
+
164
+ it 'handles extends on a rule with no args' do
165
+ layout = Squib::LayoutParser.load_layout(layout_file('empty-rule.yml'))
166
+ expect(layout).to eq({
167
+ 'empty' => nil
168
+ })
169
+ end
170
+
171
+ it 'logs an error when a file is not found' do
172
+ expect(Squib.logger).to receive(:error).once
173
+ Squib::LayoutParser.load_layout('yeti')
174
+ end
175
+
176
+ it 'freaks out if you extend something doesn\'t exist' do
177
+ expect(Squib.logger)
178
+ .to receive(:error)
179
+ .with("Processing layout: 'verbal' attempts to extend a missing 'kaisersoze'")
180
+ layout = Squib::LayoutParser.load_layout(layout_file('extends-nonexists.yml'))
181
+ expect(layout).to eq({
182
+ 'verbal' => {
183
+ 'font_size' => 25,
184
+ 'extends' => 'kaisersoze'
185
+ }
186
+ })
187
+ end
188
+
189
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Squib.logger do
4
+ it 'uses the custom format' do
5
+ Squib.logger = nil
6
+ oldstdout = $stdout
7
+ $stdout = StringIO.new
8
+ Squib::logger.warn "Test warn"
9
+ expect($stdout.string).to match /WARN: Test warn/
10
+ $stdout = oldstdout
11
+ end
12
+ end
@@ -58,6 +58,7 @@ describe "Squib samples" do
58
58
  portrait-landscape.rb
59
59
  ranges.rb
60
60
  saves.rb
61
+ showcase.rb
61
62
  text_options.rb
62
63
  tgc_proofs.rb
63
64
  units.rb
data/spec/spec_helper.rb CHANGED
@@ -43,6 +43,8 @@ def scrub_hex(str)
43
43
  .gsub(/ptr=\w{1,8}/,'')
44
44
  .gsub(/#<Pango::FontDescription:.*>/,'')
45
45
  .gsub(/#<Cairo::ImageSurface:.*>/,'ImageSurface')
46
+ .gsub(/#<Cairo::LinearPattern:.*>/,'LinearPattern')
47
+ .gsub(/#<Cairo::Matrix:.*>/,'Matrix')
46
48
  .gsub(/#<RSVG::Handle.*>/,'RSVG::Handle')
47
49
  .gsub(/#<RSpec::Mocks::Double:.*>/,'MockDouble')
48
50
  .gsub(/RGB:\w{1,8}/,'RGB:')
@@ -69,7 +71,7 @@ def mock_cairo(strio)
69
71
  %w(save set_source_color paint restore translate rotate move_to
70
72
  update_pango_layout width height show_pango_layout rounded_rectangle
71
73
  set_line_width stroke fill set_source scale render_rsvg_handle circle
72
- triangle line_to operator= show_page).each do |m|
74
+ triangle line_to operator= show_page clip transform mask).each do |m|
73
75
  allow(cxt).to receive(m) { |*args| strio << scrub_hex("cairo: #{m}(#{args})\n") }
74
76
  end
75
77
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Meneely
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-31 00:00:00.000000000 Z
11
+ date: 2015-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cairo
@@ -227,6 +227,7 @@ extra_rdoc_files:
227
227
  - samples/portrait-landscape.rb
228
228
  - samples/ranges.rb
229
229
  - samples/saves.rb
230
+ - samples/showcase.rb
230
231
  - samples/text_options.rb
231
232
  - samples/tgc_proofs.rb
232
233
  - samples/unicode.rb
@@ -260,8 +261,10 @@ files:
260
261
  - lib/squib/graphics/save_doc.rb
261
262
  - lib/squib/graphics/save_images.rb
262
263
  - lib/squib/graphics/shapes.rb
264
+ - lib/squib/graphics/showcase.rb
263
265
  - lib/squib/graphics/text.rb
264
266
  - lib/squib/input_helpers.rb
267
+ - lib/squib/layout_parser.rb
265
268
  - lib/squib/layouts/hand.yml
266
269
  - lib/squib/layouts/playing-card.yml
267
270
  - lib/squib/progress.rb
@@ -269,6 +272,7 @@ files:
269
272
  - lib/squib/project_template/ABOUT.md
270
273
  - lib/squib/project_template/Gemfile
271
274
  - lib/squib/project_template/PNP NOTES.md
275
+ - lib/squib/project_template/Rakefile
272
276
  - lib/squib/project_template/_output/gitkeep.txt
273
277
  - lib/squib/project_template/config.yml
274
278
  - lib/squib/project_template/deck.rb
@@ -301,6 +305,7 @@ files:
301
305
  - samples/sample.xlsx
302
306
  - samples/saves.rb
303
307
  - samples/shiny-purse.png
308
+ - samples/showcase.rb
304
309
  - samples/spanner.svg
305
310
  - samples/text_options.rb
306
311
  - samples/tgc_proofs.rb
@@ -316,6 +321,7 @@ files:
316
321
  - spec/data/layouts/easy-circular-extends.yml
317
322
  - spec/data/layouts/empty-rule.yml
318
323
  - spec/data/layouts/empty.yml
324
+ - spec/data/layouts/extends-nonexists.yml
319
325
  - spec/data/layouts/hard-circular-extends.yml
320
326
  - spec/data/layouts/multi-extends-single-entry.yml
321
327
  - spec/data/layouts/multi-level-extends.yml
@@ -343,6 +349,7 @@ files:
343
349
  - spec/data/samples/ranges.rb.txt
344
350
  - spec/data/samples/save_pdf.rb.txt
345
351
  - spec/data/samples/saves.rb.txt
352
+ - spec/data/samples/showcase.rb.txt
346
353
  - spec/data/samples/text_options.rb.txt
347
354
  - spec/data/samples/tgc_proofs.rb.txt
348
355
  - spec/data/samples/units.rb.txt
@@ -352,6 +359,8 @@ files:
352
359
  - spec/graphics/graphics_shapes_spec.rb
353
360
  - spec/graphics/graphics_text_spec.rb
354
361
  - spec/input_helpers_spec.rb
362
+ - spec/layout_parser_spec.rb
363
+ - spec/logger_spec.rb
355
364
  - spec/samples/samples_regression_spec.rb
356
365
  - spec/spec_helper.rb
357
366
  - squib.gemspec
@@ -391,6 +400,7 @@ test_files:
391
400
  - spec/data/layouts/easy-circular-extends.yml
392
401
  - spec/data/layouts/empty-rule.yml
393
402
  - spec/data/layouts/empty.yml
403
+ - spec/data/layouts/extends-nonexists.yml
394
404
  - spec/data/layouts/hard-circular-extends.yml
395
405
  - spec/data/layouts/multi-extends-single-entry.yml
396
406
  - spec/data/layouts/multi-level-extends.yml
@@ -418,6 +428,7 @@ test_files:
418
428
  - spec/data/samples/ranges.rb.txt
419
429
  - spec/data/samples/save_pdf.rb.txt
420
430
  - spec/data/samples/saves.rb.txt
431
+ - spec/data/samples/showcase.rb.txt
421
432
  - spec/data/samples/text_options.rb.txt
422
433
  - spec/data/samples/tgc_proofs.rb.txt
423
434
  - spec/data/samples/units.rb.txt
@@ -427,6 +438,8 @@ test_files:
427
438
  - spec/graphics/graphics_shapes_spec.rb
428
439
  - spec/graphics/graphics_text_spec.rb
429
440
  - spec/input_helpers_spec.rb
441
+ - spec/layout_parser_spec.rb
442
+ - spec/logger_spec.rb
430
443
  - spec/samples/samples_regression_spec.rb
431
444
  - spec/spec_helper.rb
432
445
  has_rdoc: