squib 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +14 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +201 -175
  5. data/Gemfile +2 -4
  6. data/README.md +650 -645
  7. data/RELEASE TODO.md +18 -18
  8. data/Rakefile +106 -99
  9. data/appveyor.yml +29 -0
  10. data/lib/squib.rb +32 -32
  11. data/lib/squib/api/background.rb +20 -20
  12. data/lib/squib/api/data.rb +131 -131
  13. data/lib/squib/api/image.rb +108 -90
  14. data/lib/squib/api/save.rb +151 -149
  15. data/lib/squib/api/settings.rb +35 -35
  16. data/lib/squib/api/shapes.rb +255 -230
  17. data/lib/squib/api/text.rb +65 -65
  18. data/lib/squib/api/text_embed.rb +96 -96
  19. data/lib/squib/args/arg_loader.rb +138 -138
  20. data/lib/squib/args/box.rb +54 -54
  21. data/lib/squib/args/card_range.rb +32 -32
  22. data/lib/squib/args/color_validator.rb +11 -11
  23. data/lib/squib/args/coords.rb +32 -32
  24. data/lib/squib/args/dir_validator.rb +16 -16
  25. data/lib/squib/args/draw.rb +92 -92
  26. data/lib/squib/args/embed_adjust.rb +25 -25
  27. data/lib/squib/args/embed_key.rb +17 -17
  28. data/lib/squib/args/hand_special.rb +37 -37
  29. data/lib/squib/args/import.rb +39 -39
  30. data/lib/squib/args/input_file.rb +37 -37
  31. data/lib/squib/args/paint.rb +43 -43
  32. data/lib/squib/args/paragraph.rb +116 -115
  33. data/lib/squib/args/save_batch.rb +63 -60
  34. data/lib/squib/args/scale_box.rb +53 -53
  35. data/lib/squib/args/sheet.rb +72 -72
  36. data/lib/squib/args/showcase_special.rb +38 -38
  37. data/lib/squib/args/svg_special.rb +37 -37
  38. data/lib/squib/args/transform.rb +60 -24
  39. data/lib/squib/args/typographer.rb +117 -117
  40. data/lib/squib/card.rb +66 -67
  41. data/lib/squib/conf.rb +131 -117
  42. data/lib/squib/constants.rb +12 -178
  43. data/lib/squib/deck.rb +113 -113
  44. data/lib/squib/graphics/cairo_context_wrapper.rb +113 -99
  45. data/lib/squib/graphics/gradient_regex.rb +46 -46
  46. data/lib/squib/graphics/hand.rb +42 -42
  47. data/lib/squib/graphics/image.rb +103 -76
  48. data/lib/squib/graphics/save_doc.rb +103 -103
  49. data/lib/squib/graphics/save_images.rb +39 -33
  50. data/lib/squib/graphics/shapes.rb +135 -119
  51. data/lib/squib/graphics/showcase.rb +85 -85
  52. data/lib/squib/graphics/text.rb +176 -176
  53. data/lib/squib/layout_parser.rb +91 -91
  54. data/lib/squib/layouts/economy.yml +85 -85
  55. data/lib/squib/layouts/fantasy.yml +101 -101
  56. data/lib/squib/layouts/hand.yml +62 -62
  57. data/lib/squib/layouts/playing-card.yml +35 -35
  58. data/lib/squib/layouts/tuck_box.yml +45 -45
  59. data/lib/squib/project_template/IDEAS.md +22 -0
  60. data/lib/squib/project_template/PLAYTESTING.md +26 -0
  61. data/lib/squib/project_template/RULES.md +21 -0
  62. data/lib/squib/project_template/config.yml +49 -45
  63. data/lib/squib/sample_helpers.rb +34 -0
  64. data/lib/squib/version.rb +10 -10
  65. data/samples/autoscale_font/_autoscale_font.rb +29 -0
  66. data/samples/color_shortcuts.rb +6 -6
  67. data/samples/csv_import.rb +26 -26
  68. data/samples/custom-config.yml +5 -5
  69. data/samples/custom_config.rb +18 -18
  70. data/samples/draw_shapes.rb +48 -45
  71. data/samples/embed_text.rb +88 -88
  72. data/samples/excel.rb +55 -55
  73. data/samples/hand.rb +24 -24
  74. data/samples/images/_images.rb +104 -0
  75. data/samples/intro/01_hello.rb +9 -0
  76. data/samples/intro/02_options.rb +15 -0
  77. data/samples/intro/03_layout.rb +12 -0
  78. data/samples/intro/04_arrays.rb +16 -0
  79. data/samples/intro/05_excel.rb +15 -0
  80. data/samples/layouts.rb +62 -62
  81. data/samples/layouts_builtin.rb +51 -51
  82. data/samples/load_images.rb +99 -78
  83. data/samples/load_images_config.yml +1 -0
  84. data/samples/quantity_explosion.csv +2 -2
  85. data/samples/ranges.rb +64 -64
  86. data/samples/sample.csv +2 -2
  87. data/samples/saves.rb +9 -1
  88. data/samples/sprites.png +0 -0
  89. data/samples/text/_text.rb +46 -0
  90. data/samples/text_options.rb +102 -102
  91. data/spec/api/api_data_spec.rb +117 -117
  92. data/spec/api/api_settings_spec.rb +37 -37
  93. data/spec/args/box_spec.rb +127 -127
  94. data/spec/args/draw_spec.rb +101 -95
  95. data/spec/args/embed_key_spec.rb +13 -13
  96. data/spec/args/input_file_spec.rb +21 -21
  97. data/spec/args/paint_spec.rb +21 -21
  98. data/spec/args/paragraph_spec.rb +152 -152
  99. data/spec/args/range_spec.rb +40 -40
  100. data/spec/args/save_batch_spec.rb +51 -51
  101. data/spec/args/scale_box_spec.rb +71 -71
  102. data/spec/args/sheet_spec.rb +58 -58
  103. data/spec/args/showcase_special_spec.rb +15 -15
  104. data/spec/args/transform_spec.rb +25 -0
  105. data/spec/card_spec.rb +11 -0
  106. data/spec/conf_spec.rb +13 -3
  107. data/spec/data/conf/unrecognized.yml +4 -0
  108. data/spec/data/csv/qty.csv +2 -2
  109. data/spec/data/csv/qty_named.csv +2 -2
  110. data/spec/data/csv/with_spaces.csv +2 -2
  111. data/spec/data/samples/autoscale_font.rb.txt +84 -84
  112. data/spec/data/samples/basic.rb.txt +227 -209
  113. data/spec/data/samples/config_text_markup.rb.txt +72 -72
  114. data/spec/data/samples/csv_import.rb.txt +213 -213
  115. data/spec/data/samples/custom_config.rb.txt +57 -48
  116. data/spec/data/samples/draw_shapes.rb.txt +555 -3
  117. data/spec/data/samples/embed_text.rb.txt +283 -283
  118. data/spec/data/samples/excel.rb.txt +661 -661
  119. data/spec/data/samples/gradients.rb.txt +77 -79
  120. data/spec/data/samples/hand.rb.txt +538 -538
  121. data/spec/data/samples/hello_world.rb.txt +36 -36
  122. data/spec/data/samples/load_images.rb.txt +170 -0
  123. data/spec/data/samples/portrait-landscape.rb.txt +51 -49
  124. data/spec/data/samples/ranges.rb.txt +472 -460
  125. data/spec/data/samples/saves.rb.txt +810 -801
  126. data/spec/data/samples/showcase.rb.txt +5926 -5910
  127. data/spec/data/samples/text_options.rb.txt +1125 -1125
  128. data/spec/data/samples/tgc_proofs.rb.txt +95 -81
  129. data/spec/graphics/cairo_context_wrapper_spec.rb +104 -84
  130. data/spec/graphics/graphics_save_doc_spec.rb +67 -67
  131. data/spec/samples/diff-with-css.example.html +39 -0
  132. data/spec/samples/expected/load_images_00.png +0 -0
  133. data/spec/samples/expected/shape_00.png +0 -0
  134. data/spec/samples/run_samples_spec.rb +17 -0
  135. data/spec/samples/samples_regression_spec.rb +72 -82
  136. data/spec/spec_helper.rb +9 -1
  137. data/squib.gemspec +49 -48
  138. data/squib.sublime-project +42 -42
  139. metadata +94 -48
  140. data/spec/graphics/graphics_images_spec.rb +0 -94
@@ -1,102 +1,102 @@
1
- # encoding: UTF-8
2
- require 'squib'
3
-
4
- data = {'name' => ['Thief', 'Grifter', 'Mastermind'],
5
- 'level' => [1,2,3]}
6
- longtext = "This is left-justified text, with newlines.\nWhat do you know about tweetle beetles? well... When tweetle beetles fight, it's called a tweetle beetle battle. And when they battle in a puddle, it's a tweetle beetle puddle battle. AND when tweetle beetles battle with paddles in a puddle, they call it a tweetle beetle puddle paddle battle. AND... When beetles battle beetles in a puddle paddle battle and the beetle battle puddle is a puddle in a bottle... ..they call this a tweetle beetle bottle puddle paddle battle muddle."
7
-
8
- Squib::Deck.new(width: 825, height: 1125, cards: 3) do
9
- background color: :white
10
- rect x: 15, y: 15, width: 795, height: 1095, x_radius: 50, y_radius: 50
11
- rect x: 30, y: 30, width: 128, height: 128, x_radius: 25, y_radius: 25
12
-
13
- # Arrays are rendered over each card
14
- text str: data['name'], x: 250, y: 55, font: 'Arial weight=900 54'
15
- text str: data['level'], x: 65, y: 40, font: 'Arial 72', color: :burnt_orange
16
-
17
- text str: 'Font strings are expressive!', x:65, y: 200,
18
- font: 'Impact bold italic 36'
19
-
20
- text str: 'Font strings are expressive!', x:65, y: 300,
21
- font: 'Arial,Verdana weight=900 style=oblique 36'
22
-
23
- text str: 'Font string sizes can be overridden per card.', x: 65, y: 350,
24
- font: 'Impact 36', font_size: [16, 20, 24]
25
-
26
- text str: 'This text has fixed width, fixed height, center-aligned, middle-valigned, and has a red hint',
27
- hint: :red,
28
- x: 65, y: 400,
29
- width: 300, height: 125,
30
- align: :center, valign: 'MIDDLE', # these can be specified with case-insenstive strings too
31
- font: 'Serif 16'
32
-
33
- extents = text str: 'Ink extent return value',
34
- x: 65, y: 550,
35
- font: 'Sans Bold', font_size: [16, 20, 24]
36
- margin = 10
37
- # Extents come back as an array of hashes, which can get split out like this
38
- ws = extents.inject([]) { |arr, ext| arr << ext[:width] + 10; arr }
39
- hs = extents.inject([]) { |arr, ext| arr << ext[:height] + 10; arr }
40
- rect x: 65 - margin/2, y: 550 - margin/2,
41
- width: ws, height: hs,
42
- radius: 10, stroke_color: :black
43
-
44
- # If width & height are defined and the text will overflow the box, we can ellipsize.
45
- text str: "Ellipsization!\nThe ultimate question of life, the universe, and everything to life and everything is 42",
46
- hint: :green, font: 'Arial 22',
47
- x: 450, y: 400,
48
- width: 280, height: 180,
49
- ellipsize: true
50
-
51
- # Text hints are guides for showing you how your text boxes are laid out exactly
52
- hint text: :cyan
53
- set font: 'Serif 20' # Impacts all future text calls (unless they specify differently)
54
- text str: 'Text hints & fonts are globally togglable!', x: 65, y: 625
55
- set font: :default # back to Squib-wide default
56
- hint text: :off
57
- text str: 'See? No hint here.',
58
- x: 565, y: 625,
59
- font: 'Arial 22'
60
-
61
- # Text can be rotated, in radians, about the upper-left corner of the text box.
62
- text str: 'Rotated',
63
- x: 565, y: 675, angle: 0.2,
64
- font: 'Arial 18', hint: :red
65
-
66
- # Text can be justified, and have newlines
67
- text str: longtext, font: 'Arial 16',
68
- x: 65, y: 700,
69
- width: '1.5in', height: inches(1),
70
- justify: true, spacing: -6
71
-
72
- # Here's how you embed images into text.
73
- # Pass a block to the method call and use the given context
74
- embed_text = 'Embedded icons! Take 1 :tool: and gain 2:health:. If Level 2, take 2 :tool:'
75
- text(str: embed_text, font: 'Sans 18',
76
- x: '1.8in', y: '2.5in', width: '0.85in',
77
- align: :left, ellipsize: false) do |embed|
78
- embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
79
- embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
80
- end
81
-
82
- text str: "Fill n <span fgcolor=\"\#ff0000\">stroke</span>",
83
- color: :green, stroke_width: 2.0, stroke_color: :blue,
84
- x: '1.8in', y: '2.9in', width: '0.85in', font: 'Sans Bold 26', markup: true
85
-
86
- text str: "Stroke n <span fgcolor=\"\#ff0000\">fill</span>",
87
- color: :green, stroke_width: 2.0, stroke_color: :blue, stroke_strategy: :stroke_first,
88
- x: '1.8in', y: '3.0in', width: '0.85in', font: 'Sans Bold 26', markup: true
89
-
90
- text str: "Dotted",
91
- color: :white, stroke_width: 2.0, dash: '4 2', stroke_color: :black,
92
- x: '1.8in', y: '3.1in', width: '0.85in', font: 'Sans Bold 26', markup: true
93
- #
94
- text str: "<b>Markup</b> is <i>quite</i> <s>'easy'</s> <span fgcolor=\"\#ff0000\">awesome</span>. Can't beat those \"smart\" 'quotes', now with 10--20% more en-dashes --- and em-dashes --- with explicit ellipses too...",
95
- markup: true,
96
- x: 50, y: 1000,
97
- width: 750, height: 100,
98
- valign: :bottom,
99
- font: 'Serif 18', hint: :cyan
100
-
101
- save prefix: 'text_', format: :png
102
- end
1
+ # encoding: UTF-8
2
+ require 'squib'
3
+
4
+ data = {'name' => ['Thief', 'Grifter', 'Mastermind'],
5
+ 'level' => [1,2,3]}
6
+ longtext = "This is left-justified text, with newlines.\nWhat do you know about tweetle beetles? well... When tweetle beetles fight, it's called a tweetle beetle battle. And when they battle in a puddle, it's a tweetle beetle puddle battle. AND when tweetle beetles battle with paddles in a puddle, they call it a tweetle beetle puddle paddle battle. AND... When beetles battle beetles in a puddle paddle battle and the beetle battle puddle is a puddle in a bottle... ..they call this a tweetle beetle bottle puddle paddle battle muddle."
7
+
8
+ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
9
+ background color: :white
10
+ rect x: 15, y: 15, width: 795, height: 1095, x_radius: 50, y_radius: 50
11
+ rect x: 30, y: 30, width: 128, height: 128, x_radius: 25, y_radius: 25
12
+
13
+ # Arrays are rendered over each card
14
+ text str: data['name'], x: 250, y: 55, font: 'Arial weight=900 54'
15
+ text str: data['level'], x: 65, y: 40, font: 'Arial 72', color: :burnt_orange
16
+
17
+ text str: 'Font strings are expressive!', x:65, y: 200,
18
+ font: 'Impact bold italic 36'
19
+
20
+ text str: 'Font strings are expressive!', x:65, y: 300,
21
+ font: 'Arial,Verdana weight=900 style=oblique 36'
22
+
23
+ text str: 'Font string sizes can be overridden per card.', x: 65, y: 350,
24
+ font: 'Impact 36', font_size: [16, 20, 24]
25
+
26
+ text str: 'This text has fixed width, fixed height, center-aligned, middle-valigned, and has a red hint',
27
+ hint: :red,
28
+ x: 65, y: 400,
29
+ width: 300, height: 125,
30
+ align: :center, valign: 'MIDDLE', # these can be specified with case-insenstive strings too
31
+ font: 'Serif 16'
32
+
33
+ extents = text str: 'Ink extent return value',
34
+ x: 65, y: 550,
35
+ font: 'Sans Bold', font_size: [16, 20, 24]
36
+ margin = 10
37
+ # Extents come back as an array of hashes, which can get split out like this
38
+ ws = extents.inject([]) { |arr, ext| arr << ext[:width] + 10; arr }
39
+ hs = extents.inject([]) { |arr, ext| arr << ext[:height] + 10; arr }
40
+ rect x: 65 - margin/2, y: 550 - margin/2,
41
+ width: ws, height: hs,
42
+ radius: 10, stroke_color: :black
43
+
44
+ # If width & height are defined and the text will overflow the box, we can ellipsize.
45
+ text str: "Ellipsization!\nThe ultimate question of life, the universe, and everything to life and everything is 42",
46
+ hint: :green, font: 'Arial 22',
47
+ x: 450, y: 400,
48
+ width: 280, height: 180,
49
+ ellipsize: true
50
+
51
+ # Text hints are guides for showing you how your text boxes are laid out exactly
52
+ hint text: :cyan
53
+ set font: 'Serif 20' # Impacts all future text calls (unless they specify differently)
54
+ text str: 'Text hints & fonts are globally togglable!', x: 65, y: 625
55
+ set font: :default # back to Squib-wide default
56
+ hint text: :off
57
+ text str: 'See? No hint here.',
58
+ x: 565, y: 625,
59
+ font: 'Arial 22'
60
+
61
+ # Text can be rotated, in radians, about the upper-left corner of the text box.
62
+ text str: 'Rotated',
63
+ x: 565, y: 675, angle: 0.2,
64
+ font: 'Arial 18', hint: :red
65
+
66
+ # Text can be justified, and have newlines
67
+ text str: longtext, font: 'Arial 16',
68
+ x: 65, y: 700,
69
+ width: '1.5in', height: inches(1),
70
+ justify: true, spacing: -6
71
+
72
+ # Here's how you embed images into text.
73
+ # Pass a block to the method call and use the given context
74
+ embed_text = 'Embedded icons! Take 1 :tool: and gain 2:health:. If Level 2, take 2 :tool:'
75
+ text(str: embed_text, font: 'Sans 18',
76
+ x: '1.8in', y: '2.5in', width: '0.85in',
77
+ align: :left, ellipsize: false) do |embed|
78
+ embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
79
+ embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
80
+ end
81
+
82
+ text str: "Fill n <span fgcolor=\"\#ff0000\">stroke</span>",
83
+ color: :green, stroke_width: 2.0, stroke_color: :blue,
84
+ x: '1.8in', y: '2.9in', width: '0.85in', font: 'Sans Bold 26', markup: true
85
+
86
+ text str: "Stroke n <span fgcolor=\"\#ff0000\">fill</span>",
87
+ color: :green, stroke_width: 2.0, stroke_color: :blue, stroke_strategy: :stroke_first,
88
+ x: '1.8in', y: '3.0in', width: '0.85in', font: 'Sans Bold 26', markup: true
89
+
90
+ text str: "Dotted",
91
+ color: :white, stroke_width: 2.0, dash: '4 2', stroke_color: :black,
92
+ x: '1.8in', y: '3.1in', width: '0.85in', font: 'Sans Bold 26', markup: true
93
+ #
94
+ text str: "<b>Markup</b> is <i>quite</i> <s>'easy'</s> <span fgcolor=\"\#ff0000\">awesome</span>. Can't beat those \"smart\" 'quotes', now with 10--20% more en-dashes --- and em-dashes --- with explicit ellipses too...",
95
+ markup: true,
96
+ x: 50, y: 1000,
97
+ width: 750, height: 100,
98
+ valign: :bottom,
99
+ font: 'Serif 18', hint: :cyan
100
+
101
+ save prefix: 'text_', format: :png
102
+ end
@@ -1,117 +1,117 @@
1
- require 'spec_helper'
2
-
3
- describe Squib::Deck do
4
- context '#csv' do
5
- it 'loads basic csv data' do
6
- expect(Squib.csv(file: csv_file('basic.csv'))).to eq({
7
- 'h1' => [1, 3],
8
- 'h2' => [2, 4]
9
- })
10
- end
11
-
12
- it 'collapses duplicate columns and warns' do
13
- expect(Squib.logger).to receive(:warn)
14
- .with('CSV duplicated the following column keys: h1,h1')
15
- expect(Squib.csv(file: csv_file('dup_cols.csv'))).to eq({
16
- 'h1' => [1, 3],
17
- 'h2' => [5, 7],
18
- 'H2' => [6, 8],
19
- 'h3' => [9, 10],
20
- })
21
- end
22
-
23
- it 'strips spaces by default' do
24
- expect(Squib.csv(file: csv_file('with_spaces.csv'))).to eq({
25
- 'With Spaces' => ['a b c', 3],
26
- 'h2' => [2, 4],
27
- 'h3' => [3, nil]
28
- })
29
- end
30
-
31
- it 'skips space stripping if told to' do
32
- expect(Squib.csv(strip: false, file: csv_file('with_spaces.csv'))).to eq({
33
- ' With Spaces ' => ['a b c ', 3],
34
- 'h2' => [2, 4],
35
- 'h3' => [3, nil]
36
- })
37
- end
38
-
39
- it 'explodes quantities' do
40
- expect(Squib.csv(file: csv_file('qty.csv'))).to eq({
41
- 'Name' => %w(Ha Ha Ha Ho),
42
- 'Qty' => [3, 3, 3, 1],
43
- })
44
- end
45
-
46
- it 'explodes quantities on specified header' do
47
- expect(Squib.csv(explode: 'Quantity', file: csv_file('qty_named.csv'))).to eq({
48
- 'Name' => %w(Ha Ha Ha Ho),
49
- 'Quantity' => [3, 3, 3, 1],
50
- })
51
- end
52
-
53
- end
54
-
55
- context '#xlsx' do
56
- it 'loads basic xlsx data' do
57
- expect(Squib.xlsx(file: xlsx_file('basic.xlsx'))).to eq({
58
- 'Name' => %w(Larry Curly Mo),
59
- 'General Number' => %w(1 2 3), #general types always get loaded as strings with no conversion
60
- 'Actual Number' => [4.0, 5.0, 6.0], #numbers get auto-converted to integers
61
- })
62
- end
63
-
64
- it 'loads xlsx with formulas' do
65
- expect(Squib.xlsx(file: xlsx_file('formulas.xlsx'))).to eq({
66
- 'A' => %w(1 2),
67
- 'B' => %w(3 4),
68
- 'Sum' => %w(4 6),
69
- })
70
- end
71
-
72
- it 'loads xlsm files with macros' do
73
- expect(Squib.xlsx(file: xlsx_file('with_macros.xlsm'))).to eq({
74
- 'foo' => %w(8 10),
75
- 'bar' => %w(9 11),
76
- })
77
- end
78
-
79
- it 'strips whitespace by default' do
80
- expect(Squib.xlsx(file: xlsx_file('whitespace.xlsx'))).to eq({
81
- 'With Whitespace' => ['foo', 'bar', 'baz'],
82
- })
83
- end
84
-
85
- it 'does not strip whitespace when specified' do
86
- expect(Squib.xlsx(file: xlsx_file('whitespace.xlsx'), strip: false)).to eq({
87
- ' With Whitespace ' => ['foo ', ' bar', ' baz '],
88
- })
89
- end
90
-
91
- it 'yields to block when given' do
92
- data = Squib.xlsx(file: xlsx_file('basic.xlsx')) do |header, value|
93
- case header
94
- when 'Name'
95
- 'he'
96
- when 'Actual Number'
97
- value * 2
98
- else
99
- 'ha'
100
- end
101
- end
102
- expect(data).to eq({
103
- 'Name' => %w(he he he),
104
- 'General Number' => %w(ha ha ha),
105
- 'Actual Number' => [8.0, 10.0, 12.0],
106
- })
107
- end
108
-
109
- it 'explodes quantities' do
110
- expect(Squib.xlsx(explode: 'Qty', file: xlsx_file('explode_quantities.xlsx'))).to eq({
111
- 'Name' => ['Zergling', 'Zergling', 'Zergling', 'High Templar'],
112
- 'Qty' => %w(3 3 3 1),
113
- })
114
- end
115
-
116
- end
117
- end
1
+ require 'spec_helper'
2
+
3
+ describe Squib::Deck do
4
+ context '#csv' do
5
+ it 'loads basic csv data' do
6
+ expect(Squib.csv(file: csv_file('basic.csv'))).to eq({
7
+ 'h1' => [1, 3],
8
+ 'h2' => [2, 4]
9
+ })
10
+ end
11
+
12
+ it 'collapses duplicate columns and warns' do
13
+ expect(Squib.logger).to receive(:warn)
14
+ .with('CSV duplicated the following column keys: h1,h1')
15
+ expect(Squib.csv(file: csv_file('dup_cols.csv'))).to eq({
16
+ 'h1' => [1, 3],
17
+ 'h2' => [5, 7],
18
+ 'H2' => [6, 8],
19
+ 'h3' => [9, 10],
20
+ })
21
+ end
22
+
23
+ it 'strips spaces by default' do
24
+ expect(Squib.csv(file: csv_file('with_spaces.csv'))).to eq({
25
+ 'With Spaces' => ['a b c', 3],
26
+ 'h2' => [2, 4],
27
+ 'h3' => [3, nil]
28
+ })
29
+ end
30
+
31
+ it 'skips space stripping if told to' do
32
+ expect(Squib.csv(strip: false, file: csv_file('with_spaces.csv'))).to eq({
33
+ ' With Spaces ' => ['a b c ', 3],
34
+ 'h2' => [2, 4],
35
+ 'h3' => [3, nil]
36
+ })
37
+ end
38
+
39
+ it 'explodes quantities' do
40
+ expect(Squib.csv(file: csv_file('qty.csv'))).to eq({
41
+ 'Name' => %w(Ha Ha Ha Ho),
42
+ 'Qty' => [3, 3, 3, 1],
43
+ })
44
+ end
45
+
46
+ it 'explodes quantities on specified header' do
47
+ expect(Squib.csv(explode: 'Quantity', file: csv_file('qty_named.csv'))).to eq({
48
+ 'Name' => %w(Ha Ha Ha Ho),
49
+ 'Quantity' => [3, 3, 3, 1],
50
+ })
51
+ end
52
+
53
+ end
54
+
55
+ context '#xlsx' do
56
+ it 'loads basic xlsx data' do
57
+ expect(Squib.xlsx(file: xlsx_file('basic.xlsx'))).to eq({
58
+ 'Name' => %w(Larry Curly Mo),
59
+ 'General Number' => %w(1 2 3), #general types always get loaded as strings with no conversion
60
+ 'Actual Number' => [4.0, 5.0, 6.0], #numbers get auto-converted to integers
61
+ })
62
+ end
63
+
64
+ it 'loads xlsx with formulas' do
65
+ expect(Squib.xlsx(file: xlsx_file('formulas.xlsx'))).to eq({
66
+ 'A' => %w(1 2),
67
+ 'B' => %w(3 4),
68
+ 'Sum' => %w(4 6),
69
+ })
70
+ end
71
+
72
+ it 'loads xlsm files with macros' do
73
+ expect(Squib.xlsx(file: xlsx_file('with_macros.xlsm'))).to eq({
74
+ 'foo' => %w(8 10),
75
+ 'bar' => %w(9 11),
76
+ })
77
+ end
78
+
79
+ it 'strips whitespace by default' do
80
+ expect(Squib.xlsx(file: xlsx_file('whitespace.xlsx'))).to eq({
81
+ 'With Whitespace' => ['foo', 'bar', 'baz'],
82
+ })
83
+ end
84
+
85
+ it 'does not strip whitespace when specified' do
86
+ expect(Squib.xlsx(file: xlsx_file('whitespace.xlsx'), strip: false)).to eq({
87
+ ' With Whitespace ' => ['foo ', ' bar', ' baz '],
88
+ })
89
+ end
90
+
91
+ it 'yields to block when given' do
92
+ data = Squib.xlsx(file: xlsx_file('basic.xlsx')) do |header, value|
93
+ case header
94
+ when 'Name'
95
+ 'he'
96
+ when 'Actual Number'
97
+ value * 2
98
+ else
99
+ 'ha'
100
+ end
101
+ end
102
+ expect(data).to eq({
103
+ 'Name' => %w(he he he),
104
+ 'General Number' => %w(ha ha ha),
105
+ 'Actual Number' => [8.0, 10.0, 12.0],
106
+ })
107
+ end
108
+
109
+ it 'explodes quantities' do
110
+ expect(Squib.xlsx(explode: 'Qty', file: xlsx_file('explode_quantities.xlsx'))).to eq({
111
+ 'Name' => ['Zergling', 'Zergling', 'Zergling', 'High Templar'],
112
+ 'Qty' => %w(3 3 3 1),
113
+ })
114
+ end
115
+
116
+ end
117
+ end
@@ -1,38 +1,38 @@
1
- require 'spec_helper'
2
-
3
- describe Squib::Deck do
4
-
5
- context '#hint' do
6
-
7
- it 'sets hinting to conf' do
8
- mock_conf = double(Squib::Conf)
9
- expect(mock_conf).to receive(:text_hint=).with(:cyan).once
10
- Squib::Deck.new do
11
- @conf = mock_conf
12
- hint text: :cyan
13
- end
14
- end
15
-
16
- end
17
-
18
- context '#set' do
19
-
20
- it 'puts font in @font' do
21
- deck = Squib::Deck.new do
22
- set font: 'foo'
23
- end
24
- expect(deck.font).to eq ('foo')
25
- end
26
-
27
- it 'raises deprecation errors on img_dir' do
28
- set_img_dir = Proc.new do
29
- Squib::Deck.new do
30
- set img_dir: 'foo'
31
- end
32
- end
33
- expect { set_img_dir.call }.to raise_error('DEPRECATED: As of v0.7 img_dir is no longer supported in "set". Use config.yml instead.')
34
- end
35
-
36
- end
37
-
1
+ require 'spec_helper'
2
+
3
+ describe Squib::Deck do
4
+
5
+ context '#hint' do
6
+
7
+ it 'sets hinting to conf' do
8
+ mock_conf = double(Squib::Conf)
9
+ expect(mock_conf).to receive(:text_hint=).with(:cyan).once
10
+ Squib::Deck.new do
11
+ @conf = mock_conf
12
+ hint text: :cyan
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ context '#set' do
19
+
20
+ it 'puts font in @font' do
21
+ deck = Squib::Deck.new do
22
+ set font: 'foo'
23
+ end
24
+ expect(deck.font).to eq ('foo')
25
+ end
26
+
27
+ it 'raises deprecation errors on img_dir' do
28
+ set_img_dir = Proc.new do
29
+ Squib::Deck.new do
30
+ set img_dir: 'foo'
31
+ end
32
+ end
33
+ expect { set_img_dir.call }.to raise_error('DEPRECATED: As of v0.7 img_dir is no longer supported in "set". Use config.yml instead.')
34
+ end
35
+
36
+ end
37
+
38
38
  end