squib 0.11.0 → 0.12.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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +5 -3
  4. data/CHANGELOG.md +24 -2
  5. data/README.md +2 -4
  6. data/RELEASE TODO.md +1 -0
  7. data/Rakefile +1 -1
  8. data/docs/arrays.rst +5 -2
  9. data/docs/build_groups.rst +15 -17
  10. data/docs/colors.rst +29 -3
  11. data/docs/conf.py +3 -3
  12. data/docs/config.rst +14 -1
  13. data/docs/data.rst +8 -4
  14. data/docs/dsl/configure.rst +18 -0
  15. data/docs/dsl/csv.rst +19 -0
  16. data/docs/dsl/data_frame.rst +85 -0
  17. data/docs/dsl/disable_build.rst +1 -4
  18. data/docs/dsl/disable_build_globally.rst +46 -0
  19. data/docs/dsl/enable_build.rst +1 -1
  20. data/docs/dsl/enable_build_globally.rst +44 -0
  21. data/docs/dsl/save_pdf.rst +44 -3
  22. data/docs/dsl/showcase.rst +11 -0
  23. data/docs/dsl/text.rst +3 -5
  24. data/docs/dsl/xlsx.rst +6 -0
  25. data/docs/guides/game_icons.rst +124 -4
  26. data/docs/guides/getting-started/part_1_zero_to_game.rst +4 -3
  27. data/docs/guides/getting-started/part_2_iconography.rst +92 -16
  28. data/docs/guides/getting-started/part_3_workflows.rst +43 -1
  29. data/docs/guides/getting-started/part_4_ruby_power.rst +18 -0
  30. data/docs/guides/git.rst +2 -1
  31. data/docs/guides/guard.rst +84 -0
  32. data/docs/guides/hello_world.rst +63 -4
  33. data/docs/guides/projects.rst +35 -0
  34. data/docs/install.rst +3 -1
  35. data/docs/layouts.rst +3 -3
  36. data/docs/learning.rst +3 -1
  37. data/docs/parameters.rst +14 -6
  38. data/docs/text_feature.rst +42 -13
  39. data/docs/units.rst +9 -1
  40. data/lib/squib/api/data.rb +6 -5
  41. data/lib/squib/api/groups.rb +14 -7
  42. data/lib/squib/api/save.rb +2 -1
  43. data/lib/squib/args/sheet.rb +57 -2
  44. data/lib/squib/card.rb +8 -0
  45. data/lib/squib/conf.rb +9 -1
  46. data/lib/squib/deck.rb +2 -1
  47. data/lib/squib/graphics/save_doc.rb +0 -45
  48. data/lib/squib/graphics/save_pdf.rb +85 -0
  49. data/lib/squib/graphics/showcase.rb +1 -1
  50. data/lib/squib/import/data_frame.rb +108 -0
  51. data/lib/squib/version.rb +1 -1
  52. data/samples/autoscale_font/.gitignore +2 -0
  53. data/samples/autoscale_font/card_00_expected.png +0 -0
  54. data/samples/backend/.gitignore +1 -0
  55. data/samples/backend/_backend-config.yml +5 -0
  56. data/samples/backend/_backend.rb +2 -9
  57. data/samples/backend/backend_00_expected.png +0 -0
  58. data/samples/backend/backend_01_expected.png +0 -0
  59. data/samples/backend/backend_vectorized_expected.pdf +0 -0
  60. data/samples/backend/backend_vectors_00_expected.svg +84 -0
  61. data/samples/backend/backend_vectors_01_expected.svg +84 -0
  62. data/samples/backend/shiny-purse.png +0 -0
  63. data/samples/backend/showcase_expected.png +0 -0
  64. data/samples/backend/spanner.svg +91 -0
  65. data/samples/build_groups/.gitignore +1 -0
  66. data/samples/build_groups/Rakefile +25 -0
  67. data/samples/colors/.gitignore +1 -0
  68. data/samples/colors/color_constants_00_expected.png +0 -0
  69. data/samples/colors/colors_00_expected.png +0 -0
  70. data/samples/colors/gradient_00_expected.png +0 -0
  71. data/samples/data/.gitignore +1 -0
  72. data/samples/data/explode_quantities.xlsx +0 -0
  73. data/samples/data/quantity_explosion.csv +3 -0
  74. data/samples/data/sample.csv +3 -0
  75. data/samples/data/sample.xlsx +0 -0
  76. data/samples/data/sample_csv_00_expected.png +0 -0
  77. data/samples/data/sample_csv_01_expected.png +0 -0
  78. data/samples/data/sample_csv_qty_00_expected.png +0 -0
  79. data/samples/data/sample_excel_00_expected.png +0 -0
  80. data/samples/data/sample_excel_01_expected.png +0 -0
  81. data/samples/data/sample_excel_02_expected.png +0 -0
  82. data/samples/data/sample_excel_resources_00_expected.png +0 -0
  83. data/samples/data/sample_excel_resources_01_expected.png +0 -0
  84. data/samples/data/sample_xlsx_qty_00_expected.png +0 -0
  85. data/samples/images/.gitignore +8 -0
  86. data/samples/images/_images_00_expected.png +0 -0
  87. data/samples/images/angler-fish.png +0 -0
  88. data/samples/images/ball.png +0 -0
  89. data/samples/images/glass-heart.svg +52 -0
  90. data/samples/images/grit.png +0 -0
  91. data/samples/images/offset.svg +85 -0
  92. data/samples/images/robot-golem.svg +1 -0
  93. data/samples/images/shiny-purse.png +0 -0
  94. data/samples/images/spanner.svg +91 -0
  95. data/samples/images/sprites.png +0 -0
  96. data/samples/images/with-alpha.png +0 -0
  97. data/samples/intro/.gitignore +2 -0
  98. data/samples/intro/auto-repair.svg +1 -0
  99. data/samples/intro/crawling.svg +1 -0
  100. data/samples/intro/data.xlsx +0 -0
  101. data/samples/intro/humans.svg +1 -0
  102. data/samples/intro/ninja-mask.svg +1 -0
  103. data/samples/intro/part1_00_expected.png +0 -0
  104. data/samples/intro/part2_00_expected.png +0 -0
  105. data/samples/intro/part3_00_expected.png +0 -0
  106. data/samples/intro/part3_layout.yml +34 -0
  107. data/samples/intro/part4_00_expected.png +0 -0
  108. data/samples/intro/part4_01_expected.png +0 -0
  109. data/samples/intro/part5_00_expected.png +0 -0
  110. data/samples/intro/part5_01_expected.png +0 -0
  111. data/samples/intro/part5_02_expected.png +0 -0
  112. data/samples/intro/part5_03_expected.png +0 -0
  113. data/samples/intro/part5_hand_expected.png +0 -0
  114. data/samples/intro/part5_showcase_expected.png +0 -0
  115. data/samples/intro/pirate-skull.svg +1 -0
  116. data/samples/intro/robot-golem.svg +1 -0
  117. data/samples/project/Gemfile +6 -0
  118. data/samples/project/Guardfile +18 -0
  119. data/samples/project/Rakefile +25 -0
  120. data/samples/project/bw/robot-golem.svg +53 -0
  121. data/samples/project/color/robot-golem.svg +1 -0
  122. data/samples/project/config.yml +2 -0
  123. data/samples/project/layouts/characters.yml +3 -0
  124. data/samples/project/layouts/skills.yml +3 -0
  125. data/samples/project/src/characters.rb +8 -0
  126. data/samples/project/src/skills.rb +7 -0
  127. data/samples/{ranges.rb → ranges/_ranges.rb} +0 -0
  128. data/samples/ranges/glass-heart.svg +52 -0
  129. data/samples/ranges/ranges_00_expected.png +0 -0
  130. data/samples/saves/.gitignore +1 -0
  131. data/samples/saves/_save_pdf.rb +18 -0
  132. data/samples/saves/hand_expected.png +0 -0
  133. data/samples/saves/hand_pretty_expected.png +0 -0
  134. data/samples/saves/save-pdf-small_expected.pdf +0 -0
  135. data/samples/saves/save-pdf_expected.pdf +0 -0
  136. data/samples/saves/save_png_00_expected.png +0 -0
  137. data/samples/saves/save_png_trimmed_00_expected.png +0 -0
  138. data/samples/saves/save_sheet_00_expected.png +0 -0
  139. data/samples/saves/save_sheet_01_expected.png +0 -0
  140. data/samples/saves/save_sheet_range_00_expected.png +0 -0
  141. data/samples/saves/save_sheet_range_01_expected.png +0 -0
  142. data/samples/saves/save_single_sheet_00_expected.png +0 -0
  143. data/samples/saves/saves_notrim_01_expected.png +0 -0
  144. data/samples/saves/showcase2_expected.png +0 -0
  145. data/samples/saves/showcase_expected.png +0 -0
  146. data/samples/saves/showcase_individual_00_expected.png +0 -0
  147. data/samples/saves/showcase_individual_01_expected.png +0 -0
  148. data/samples/saves/showcase_individual_02_expected.png +0 -0
  149. data/samples/saves/showcase_individual_03_expected.png +0 -0
  150. data/samples/saves/spanner.svg +91 -0
  151. data/samples/shapes/.gitignore +1 -0
  152. data/samples/shapes/shape_00_expected.png +0 -0
  153. data/samples/text/.gitignore +2 -0
  154. data/samples/text/README.md +1 -0
  155. data/samples/text/_text_00_expected.png +0 -0
  156. data/samples/text/config.yml +2 -0
  157. data/samples/units/_units.rb +32 -0
  158. data/samples/units/units_00_expected.png +0 -0
  159. data/samples/units/using_units.yml +10 -0
  160. data/spec/api/api_data_spec.rb +18 -18
  161. data/spec/api/api_groups_spec.rb +49 -0
  162. data/spec/args/sheet_spec.rb +24 -2
  163. data/spec/conf_spec.rb +8 -0
  164. data/spec/data/conf/basic.yml +1 -0
  165. data/spec/data/samples/autoscale_font/_autoscale_font.rb.txt +3 -0
  166. data/spec/data/samples/basic.rb.txt +3 -0
  167. data/spec/data/samples/cairo_access.rb.txt +2 -0
  168. data/spec/data/samples/colors/_gradients.rb.txt +1 -0
  169. data/spec/data/samples/config_text_markup.rb.txt +2 -0
  170. data/spec/data/samples/custom_config.rb.txt +1 -0
  171. data/spec/data/samples/data/_csv.rb.txt +6 -0
  172. data/spec/data/samples/data/_excel.rb.txt +13 -0
  173. data/spec/data/samples/embed_text.rb.txt +4 -0
  174. data/spec/data/samples/hello_world.rb.txt +2 -0
  175. data/spec/data/samples/images/_more_load_images.rb.txt +1 -0
  176. data/spec/data/samples/{ranges.rb.txt → ranges/_ranges.rb.txt} +3 -0
  177. data/spec/data/samples/saves/_hand.rb.txt +8 -0
  178. data/spec/data/samples/saves/_portrait_landscape.rb.txt +2 -0
  179. data/spec/data/samples/saves/_save_pdf.rb.txt +1505 -449
  180. data/spec/data/samples/saves/_saves.rb.txt +16 -0
  181. data/spec/data/samples/saves/_showcase.rb.txt +4 -0
  182. data/spec/data/samples/shapes/_draw_shapes.rb.txt +1 -0
  183. data/spec/data/samples/text_options.rb.txt +3 -0
  184. data/spec/data/samples/tgc_proofs.rb.txt +1 -0
  185. data/spec/data/samples/{units.rb.txt → units/_units.rb.txt} +20 -15
  186. data/spec/deck_spec.rb +7 -0
  187. data/spec/graphics/graphics_save_doc_spec.rb +2 -1
  188. data/spec/import/data_frame_spec.rb +251 -0
  189. data/spec/samples/run_samples_spec.rb +1 -1
  190. data/spec/samples/samples_regression_spec.rb +3 -2
  191. data/squib.gemspec +6 -6
  192. metadata +144 -24
  193. data/.gitmodules +0 -36
  194. data/samples/units.rb +0 -28
@@ -855,3 +855,19 @@ cairo: paint([])
855
855
  cairo: set_source([MockDouble, 180, 75])
856
856
  cairo: paint([])
857
857
  surface: write_to_png(["_output/save_sheet_range_01.png"])
858
+ surface: finish([])
859
+ surface: finish([])
860
+ surface: finish([])
861
+ surface: finish([])
862
+ surface: finish([])
863
+ surface: finish([])
864
+ surface: finish([])
865
+ surface: finish([])
866
+ surface: finish([])
867
+ surface: finish([])
868
+ surface: finish([])
869
+ surface: finish([])
870
+ surface: finish([])
871
+ surface: finish([])
872
+ surface: finish([])
873
+ surface: finish([])
@@ -5936,3 +5936,7 @@ surface: write_to_png(["_output/showcase_individual_00.png"])
5936
5936
  surface: write_to_png(["_output/showcase_individual_01.png"])
5937
5937
  surface: write_to_png(["_output/showcase_individual_02.png"])
5938
5938
  surface: write_to_png(["_output/showcase_individual_03.png"])
5939
+ surface: finish([])
5940
+ surface: finish([])
5941
+ surface: finish([])
5942
+ surface: finish([])
@@ -754,3 +754,4 @@ cairo: set_dash([[]])
754
754
  cairo: stroke([])
755
755
  cairo: restore([])
756
756
  surface: write_to_png(["_output/shape_00.png"])
757
+ surface: finish([])
@@ -1153,3 +1153,6 @@ cairo: restore([])
1153
1153
  surface: write_to_png(["_output/text_00.png"])
1154
1154
  surface: write_to_png(["_output/text_01.png"])
1155
1155
  surface: write_to_png(["_output/text_02.png"])
1156
+ surface: finish([])
1157
+ surface: finish([])
1158
+ surface: finish([])
@@ -99,3 +99,4 @@ cairo: set_source([ImageSurface, 0, 0])
99
99
  cairo: paint([0.5])
100
100
  cairo: restore([])
101
101
  surface: write_to_png(["_output/tgc_sample_00.png"])
102
+ surface: finish([])
@@ -1,27 +1,27 @@
1
1
  cairo: antialias=(["subpixel"])
2
2
  cairo: save([])
3
- cairo: set_source_color(["#ddd"])
3
+ cairo: set_source_color(["white"])
4
4
  cairo: paint([])
5
5
  cairo: restore([])
6
6
  cairo: save([])
7
7
  cairo: translate([37.5, 37.5])
8
8
  cairo: rotate([0])
9
9
  cairo: translate([-37.5, -37.5])
10
- cairo: rounded_rectangle([37.5, 37.5, 750.0, 1050.0, 25, 25])
10
+ cairo: rounded_rectangle([37.5, 37.5, 375.0, 375.0, 0, 0])
11
11
  cairo: set_source_color(["#0000"])
12
12
  cairo: fill_preserve([])
13
13
  cairo: set_source_color(["black"])
14
14
  cairo: set_line_width([2.0])
15
15
  cairo: set_line_join([0])
16
16
  cairo: set_line_cap([0])
17
- cairo: set_dash([[]])
17
+ cairo: set_dash([[5.905511805, 5.905511805]])
18
18
  cairo: stroke([])
19
19
  cairo: restore([])
20
20
  cairo: save([])
21
21
  cairo: translate([75.0, 75.0])
22
22
  cairo: rotate([0])
23
23
  cairo: translate([-75.0, -75.0])
24
- cairo: rounded_rectangle([75.0, 75.0, 675.0, 975.0, 25, 25])
24
+ cairo: rounded_rectangle([75.0, 75.0, 300.0, 300.0, 23.62204722, 23.62204722])
25
25
  cairo: set_source_color(["#0000"])
26
26
  cairo: fill_preserve([])
27
27
  cairo: set_source_color(["black"])
@@ -32,17 +32,22 @@ cairo: set_dash([[]])
32
32
  cairo: stroke([])
33
33
  cairo: restore([])
34
34
  cairo: save([])
35
- cairo: translate([472.4409444, 472.4409444])
36
- cairo: rotate([0])
37
- cairo: translate([-472.4409444, -472.4409444])
38
- cairo: rounded_rectangle([472.4409444, 472.4409444, 100, 100, 0, 0])
39
- cairo: set_source_color(["#0000"])
40
- cairo: fill_preserve([])
41
35
  cairo: set_source_color(["black"])
42
- cairo: set_line_width([2.0])
43
- cairo: set_line_join([0])
44
- cairo: set_line_cap([0])
45
- cairo: set_dash([[]])
46
- cairo: stroke([])
36
+ cairo: translate([134.05511805, 166.24488195])
37
+ cairo: rotate([0])
38
+ cairo: move_to([0, 0])
39
+ pango: font_description=([MockDouble])
40
+ pango: text=(["Hello."])
41
+ pango: width=([384000.0])
42
+ pango: height=([307200])
43
+ pango: wrap=([#<Pango::Layout::WrapMode word-char>])
44
+ pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
45
+ pango: alignment=([#<Pango::Layout::Alignment left>])
46
+ pango: justify=([false])
47
+ cairo: move_to([0, 0])
48
+ cairo: move_to([0, 0])
49
+ cairo: show_pango_layout([MockDouble])
50
+ pango: ellipsized?([])
47
51
  cairo: restore([])
48
52
  surface: write_to_png(["_output/units_00.png"])
53
+ surface: finish([])
@@ -22,6 +22,8 @@ describe Squib::Deck do
22
22
  card2 = instance_double(Squib::Card)
23
23
  expect(card1).to receive(:text).once
24
24
  expect(card2).to receive(:text).once
25
+ expect(card1).to receive(:finish!).once
26
+ expect(card2).to receive(:finish!).once
25
27
  Squib::Deck.new do
26
28
  @cards = [card1, card2]
27
29
  text str: 'blah'
@@ -31,7 +33,9 @@ describe Squib::Deck do
31
33
  it 'calls text on some cards with an integer' do
32
34
  card1 = instance_double(Squib::Card)
33
35
  card2 = instance_double(Squib::Card)
36
+ expect(card1).to receive(:finish!).once
34
37
  expect(card2).to receive(:text).once
38
+ expect(card2).to receive(:finish!).once
35
39
  Squib::Deck.new do
36
40
  @cards = [card1, card2]
37
41
  text range: 1, str: 'blah'
@@ -43,7 +47,10 @@ describe Squib::Deck do
43
47
  card2 = instance_double(Squib::Card)
44
48
  card3 = instance_double(Squib::Card)
45
49
  expect(card1).to receive(:text).once
50
+ expect(card1).to receive(:finish!).once
46
51
  expect(card2).to receive(:text).once
52
+ expect(card2).to receive(:finish!).once
53
+ expect(card3).to receive(:finish!).once
47
54
  Squib::Deck.new do
48
55
  @cards = [card1, card2, card3]
49
56
  text range: 0..1, str: 'blah'
@@ -45,7 +45,8 @@ describe Squib::Deck, '#save_pdf' do
45
45
  expect(cxt).to receive(:target).and_return(target)
46
46
  expect(target).to receive(:finish).once
47
47
 
48
- args = { file: 'foo.pdf', dir: '_out', margin: 75, gap: 5, trim: 37 }
48
+ args = { file: 'foo.pdf', dir: '_out', crop_marks: false,
49
+ margin: 75, gap: 5, trim: 37 }
49
50
  deck.save_pdf(args)
50
51
  end
51
52
 
@@ -0,0 +1,251 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+ require 'squib/import/data_frame'
5
+
6
+ describe Squib::DataFrame do
7
+ let(:basic) do
8
+ {
9
+ 'Name' => ['Mage', 'Rogue', 'Warrior'],
10
+ 'Cost' => [1, 2, 3],
11
+ }
12
+ end
13
+
14
+ let(:uneven) do
15
+ {
16
+ 'Name' => ['Mage', 'Rogue', 'Warrior'],
17
+ 'Cost' => [1, 2],
18
+ }
19
+ end
20
+
21
+ let(:whitespace) do
22
+ {
23
+ 'Name \n\r\t' => [' Mage \t\r\n'],
24
+ }
25
+ end
26
+
27
+ let(:defined) do
28
+ {
29
+ 'nrows' => [1,2,3],
30
+ }
31
+ end
32
+
33
+ context 'is Enumerable and like a hash, so it' do
34
+ it 'responds to each' do
35
+ expect(subject).to respond_to(:each)
36
+ end
37
+
38
+ it 'responds to any?' do
39
+ expect(subject.any?).to be false
40
+ end
41
+
42
+ it 'responds to []' do
43
+ data = Squib::DataFrame.new basic
44
+ expect(data['Cost']).to eq([1, 2, 3])
45
+ end
46
+
47
+ it 'responds to []=' do
48
+ data = Squib::DataFrame.new basic
49
+ data[:a] = 2
50
+ expect(data[:a]).to eq(2)
51
+ end
52
+ end
53
+
54
+ context :columns do
55
+ it 'provides a list of columns' do
56
+ data = Squib::DataFrame.new basic
57
+ expect(data.columns).to eq %w(Name Cost)
58
+ end
59
+ end
60
+
61
+ context :ncolumns do
62
+ it 'provides column count' do
63
+ data = Squib::DataFrame.new basic
64
+ expect(data.ncolumns).to eq 2
65
+ end
66
+ end
67
+
68
+ context :row do
69
+ it 'returns a hash of each row' do
70
+ data = Squib::DataFrame.new basic
71
+ expect(data.row(0)).to eq ({'Name' => 'Mage', 'Cost' => 1})
72
+ expect(data.row(1)).to eq ({'Name' => 'Rogue', 'Cost' => 2})
73
+ end
74
+
75
+ it 'returns nil for uneven data' do
76
+ data = Squib::DataFrame.new uneven
77
+ expect(data.row(2)).to eq ({'Name' => 'Warrior', 'Cost' => nil})
78
+ end
79
+ end
80
+
81
+ context :nrows do
82
+ it 'returns a row count on even data' do
83
+ data = Squib::DataFrame.new basic
84
+ expect(data.nrows).to eq 3
85
+ end
86
+
87
+ it 'returns largest row count on uneven data' do
88
+ data = Squib::DataFrame.new basic
89
+ expect(data.nrows).to eq 3
90
+ end
91
+ end
92
+
93
+ context :json do
94
+ it 'returns quoty json' do
95
+ data = Squib::DataFrame.new basic
96
+ expect(data.to_json).to eq "{\"Name\":[\"Mage\",\"Rogue\",\"Warrior\"],\"Cost\":[1,2,3]}"
97
+ end
98
+
99
+ it 'returns pretty json' do
100
+ data = Squib::DataFrame.new basic
101
+ str = <<-EOS
102
+ {
103
+ "Name": [
104
+ "Mage",
105
+ "Rogue",
106
+ "Warrior"
107
+ ],
108
+ "Cost": [
109
+ 1,
110
+ 2,
111
+ 3
112
+ ]
113
+ }
114
+ EOS
115
+ expect(data.to_pretty_json).to eq str.chomp
116
+ end
117
+ end
118
+
119
+ context :def_column do
120
+ it 'creates name for Name column' do
121
+ data = Squib::DataFrame.new basic
122
+ expect(data).to respond_to(:name)
123
+ expect(data.name).to eq %w(Mage Rogue Warrior)
124
+ expect(data.cost).to eq [1, 2, 3]
125
+ end
126
+
127
+ it 'does not redefine methods' do
128
+ data = Squib::DataFrame.new defined
129
+ expect(data).to respond_to(:nrows)
130
+ expect(data.nrows).to eq 3
131
+ end
132
+
133
+ it 'defines a new column from empty data frame' do
134
+ data = Squib::DataFrame.new
135
+ expect(data).not_to respond_to(:snark)
136
+ data['snark'] = [1,2,3]
137
+ expect(data.snark).to eq [1,2,3]
138
+ end
139
+ end
140
+
141
+ context :snake_case do
142
+ subject { Squib::DataFrame.new }
143
+ it 'strips leading & trailing whitespace' do
144
+ expect(subject.send(:snake_case, ' A ')).to eq :a
145
+ end
146
+
147
+ it 'converts space to _' do
148
+ expect(subject.send(:snake_case, 'A b')).to eq :a_b
149
+ end
150
+
151
+ it 'handles multiwhitespace' do
152
+ expect(subject.send(:snake_case, 'A b')).to eq :a_b
153
+ end
154
+
155
+ it 'handles camelcase' do
156
+ expect(subject.send(:snake_case, 'fooBar')).to eq :foo_bar
157
+ end
158
+
159
+ it 'handles camelcase with multiple capitals' do
160
+ expect(subject.send(:snake_case, 'FOOBar')).to eq :foo_bar
161
+ end
162
+ end
163
+
164
+ context :col? do
165
+ it 'returns true if a column exists' do
166
+ data = Squib::DataFrame.new basic
167
+ expect(data.col? 'Name').to be true
168
+ end
169
+
170
+ it 'returns false if a column does not exist' do
171
+ data = Squib::DataFrame.new basic
172
+ expect(data.col? 'ROUS').to be false
173
+ end
174
+ end
175
+
176
+ context :wrap_n_pad do
177
+ subject { Squib::DataFrame.new basic }
178
+
179
+ it 'returns a handles a single line' do
180
+ expect(subject.send(:wrap_n_pad, 'a', 3)).
181
+ to eq "| a |\n"
182
+ end
183
+
184
+ it 'wraps multiple a lines at 34 characters' do
185
+ expect(subject.send(:wrap_n_pad, 'a' * 40, 3)).
186
+ to eq <<-EOS
187
+ | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
188
+ | aaaaaa |
189
+ EOS
190
+ end
191
+ end
192
+
193
+ context :to_pretty_text do
194
+
195
+ let(:verbose) do
196
+ {
197
+ 'Name' => ['Mage', 'Rogue', 'Warrior'],
198
+ 'Cost' => [1, 2, 3],
199
+ 'Description' => [
200
+ 'Magic, dude.',
201
+ 'I like to be sneaky',
202
+ 'I have a long story to tell to test the word-wrapping ability of pretty text formatting.'
203
+ ],
204
+ 'Snark' => [nil, '', ' ']
205
+ }
206
+ end
207
+
208
+ it 'returns fun ascii art of the card' do
209
+ data = Squib::DataFrame.new verbose
210
+ expect(data.to_pretty_text).to eq <<-EOS
211
+ ╭------------------------------------╮
212
+ Name | Mage |
213
+ Cost | 1 |
214
+ Description | Magic, dude. |
215
+ Snark | |
216
+ ╰------------------------------------╯
217
+ ╭------------------------------------╮
218
+ Name | Rogue |
219
+ Cost | 2 |
220
+ Description | I like to be sneaky |
221
+ Snark | |
222
+ ╰------------------------------------╯
223
+ ╭------------------------------------╮
224
+ Name | Warrior |
225
+ Cost | 3 |
226
+ Description | I have a long story to tell to tes |
227
+ | t the word-wrapping ability of pre |
228
+ | tty text formatting. |
229
+ Snark | |
230
+ ╰------------------------------------╯
231
+ EOS
232
+ end
233
+
234
+ let(:utf8_fun) do
235
+ {
236
+ 'Fun with UTF8!' => ['👊'],
237
+ }
238
+ end
239
+
240
+ it 'is admittedly janky with multibyte chars' do
241
+ # I hate how Ruby handles multibyte chars. Blech!
242
+ data = Squib::DataFrame.new utf8_fun
243
+ expect(data.to_pretty_text).to eq <<-EOS
244
+ ╭------------------------------------╮
245
+ Fun with UTF8! | 👊 |
246
+ ╰------------------------------------╯
247
+ EOS
248
+ end
249
+ end
250
+
251
+ end
@@ -11,7 +11,7 @@ describe 'Squib samples' do
11
11
  Dir.chdir(File.dirname(sample)) do
12
12
  load sample
13
13
  end
14
- end
14
+ end unless sample =~ /project/ # ignore our project sample, run it below
15
15
  end
16
16
 
17
17
  end
@@ -44,15 +44,16 @@ describe 'Squib samples' do
44
44
  embed_text.rb
45
45
  hello_world.rb
46
46
  images/_more_load_images.rb
47
- ranges.rb
47
+ ranges/_ranges.rb
48
48
  saves/_hand.rb
49
49
  saves/_portrait_landscape.rb
50
50
  saves/_saves.rb
51
+ saves/_save_pdf.rb
51
52
  saves/_showcase.rb
52
53
  shapes/_draw_shapes.rb
53
54
  text_options.rb
54
55
  tgc_proofs.rb
55
- units.rb
56
+ units/_units.rb
56
57
  ).each do |sample|
57
58
  it "has not changed for #{sample}", slow: true do
58
59
  log = StringIO.new
@@ -27,15 +27,15 @@ Gem::Specification.new do |spec|
27
27
  spec.test_files = spec.files.grep(/^(test|spec|features)\//)
28
28
  spec.require_paths = ['lib']
29
29
 
30
- spec.add_runtime_dependency 'cairo', '~> 1.15.2'
31
- spec.add_runtime_dependency 'pango', '~> 3.0.9'
30
+ spec.add_runtime_dependency 'cairo', '~> 1.15.3'
31
+ spec.add_runtime_dependency 'pango', '~> 3.1.0'
32
32
  spec.add_runtime_dependency 'nokogiri', '~> 1.6.7'
33
- spec.add_runtime_dependency 'roo', '~> 2.4.0'
34
- spec.add_runtime_dependency 'rsvg2', '~> 3.0.9'
33
+ spec.add_runtime_dependency 'roo', '~> 2.5.1'
34
+ spec.add_runtime_dependency 'rsvg2', '~> 3.1.0'
35
35
  spec.add_runtime_dependency 'mercenary', '~> 0.3.4'
36
36
  spec.add_runtime_dependency 'ruby-progressbar', '~> 1.8'
37
- spec.add_runtime_dependency 'gobject-introspection', '~> 3.0.9' # for bug 172
38
- spec.add_runtime_dependency 'gio2', '~> 3.0.9' # for bug 172
37
+ spec.add_runtime_dependency 'gobject-introspection', '~> 3.1.0' # for bug 172
38
+ spec.add_runtime_dependency 'gio2', '~> 3.1.0' # for bug 172
39
39
 
40
40
  spec.add_development_dependency 'bundler', '~> 1.6'
41
41
  spec.add_development_dependency 'rake'