squib 0.8.0 → 0.9.0

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 (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