mork 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/README.md +107 -35
  4. data/lib/mork/coord.rb +1 -1
  5. data/lib/mork/extensions.rb +3 -0
  6. data/lib/mork/grid.rb +13 -6
  7. data/lib/mork/grid_const.rb +11 -9
  8. data/lib/mork/grid_omr.rb +15 -5
  9. data/lib/mork/grid_pdf.rb +1 -0
  10. data/lib/mork/magicko.rb +46 -28
  11. data/lib/mork/mimage.rb +113 -52
  12. data/lib/mork/mimage_list.rb +6 -5
  13. data/lib/mork/npatch.rb +16 -18
  14. data/lib/mork/sheet_omr.rb +210 -125
  15. data/lib/mork/sheet_pdf.rb +15 -8
  16. data/lib/mork/version.rb +1 -1
  17. data/mork.gemspec +2 -0
  18. data/mork.sublime-project +1 -1
  19. data/spec/mork/extensions_spec.rb +3 -3
  20. data/spec/mork/grid_omr_spec.rb +2 -1
  21. data/spec/mork/grid_spec.rb +34 -35
  22. data/spec/mork/magicko_spec.rb +2 -2
  23. data/spec/mork/mimage_spec.rb +22 -63
  24. data/spec/mork/sheet_omr_spec.rb +96 -201
  25. data/spec/mork/sheet_pdf_spec.rb +9 -10
  26. data/spec/out/{.gitignore → barcode/.gitignore} +0 -0
  27. data/spec/out/highlight/.gitignore +4 -0
  28. data/spec/out/mark/.gitignore +4 -0
  29. data/spec/out/outline/.gitignore +4 -0
  30. data/spec/out/pdf/.gitignore +4 -0
  31. data/spec/out/registration/.gitignore +4 -0
  32. data/spec/out/text/.gitignore +4 -0
  33. data/spec/samples/angolo.jpg +0 -0
  34. data/spec/samples/angolo2.jpg +0 -0
  35. data/spec/samples/angolo3.jpg +0 -0
  36. data/spec/samples/boxy.yml +0 -0
  37. data/spec/samples/grid.yml +0 -0
  38. data/spec/samples/grid160.yml +0 -0
  39. data/spec/samples/grid_omr_layout.yml +56 -0
  40. data/spec/samples/info.yml +15 -39
  41. data/spec/samples/jdoe/JohnDoe1.jpeg +0 -0
  42. data/spec/samples/jdoe/JohnDoe2.jpeg +0 -0
  43. data/spec/samples/jdoe/JohnDoe3.jpeg +0 -0
  44. data/spec/samples/jdoe/layout.yml +58 -0
  45. data/spec/samples/layout.yml +2 -2
  46. data/spec/samples/lucrezia/border1.pdf +0 -0
  47. data/spec/samples/lucrezia/border2.pdf +0 -0
  48. data/spec/samples/lucrezia/bw1.pdf +0 -0
  49. data/spec/samples/lucrezia/bw2.pdf +0 -0
  50. data/spec/samples/lucrezia/gray1.pdf +0 -0
  51. data/spec/samples/lucrezia/gray2.pdf +0 -0
  52. data/spec/samples/{syst/IMG_20150104_0004.jpg → marisol/marisol1.jpg} +0 -0
  53. data/spec/samples/{syst/IMG_20150104_0009.jpg → marisol/marisol2.jpg} +0 -0
  54. data/spec/samples/{syst/IMG_20150104_0011.jpg → marisol/marisol3.jpg} +0 -0
  55. data/spec/samples/reg_mark.jpg +0 -0
  56. data/spec/samples/rm00.jpeg +0 -0
  57. data/spec/samples/rm01.jpeg +0 -0
  58. data/spec/samples/rm02.jpeg +0 -0
  59. data/spec/samples/rm03.jpeg +0 -0
  60. data/spec/samples/rm04.jpeg +0 -0
  61. data/spec/samples/rm05.jpeg +0 -0
  62. data/spec/samples/syst/barr0.jpg +0 -0
  63. data/spec/samples/syst/barr1.jpg +0 -0
  64. data/spec/samples/syst/barr2.jpg +0 -0
  65. data/spec/samples/syst/bell0.jpg +0 -0
  66. data/spec/samples/syst/bell1.jpg +0 -0
  67. data/spec/samples/syst/bell2.jpg +0 -0
  68. data/spec/samples/syst/bila0.jpg +0 -0
  69. data/spec/samples/syst/bila1.jpg +0 -0
  70. data/spec/samples/syst/bila2.jpg +0 -0
  71. data/spec/samples/syst/bila3.jpg +0 -0
  72. data/spec/samples/syst/bila4.jpg +0 -0
  73. data/spec/samples/syst/bone0.jpg +0 -0
  74. data/spec/samples/syst/bone1.jpg +0 -0
  75. data/spec/samples/syst/bone2.jpg +0 -0
  76. data/spec/samples/syst/cost0.jpg +0 -0
  77. data/spec/samples/syst/cost1.jpg +0 -0
  78. data/spec/samples/syst/cost2.jpg +0 -0
  79. data/spec/samples/syst/cost3.jpg +0 -0
  80. data/spec/samples/syst/cost4.jpg +0 -0
  81. data/spec/samples/syst/dald0.jpg +0 -0
  82. data/spec/samples/syst/dald1.jpg +0 -0
  83. data/spec/samples/syst/dald2.jpg +0 -0
  84. data/spec/samples/syst/dald3.jpg +0 -0
  85. data/spec/samples/syst/dald4.jpg +0 -0
  86. data/spec/samples/syst/dign0.jpg +0 -0
  87. data/spec/samples/syst/dign1.jpg +0 -0
  88. data/spec/samples/syst/dign2.jpg +0 -0
  89. data/spec/samples/syst/dive0.jpg +0 -0
  90. data/spec/samples/syst/dive1.jpg +0 -0
  91. data/spec/samples/syst/dive2.jpg +0 -0
  92. data/spec/samples/syst/histo.m +0 -0
  93. data/spec/samples/{syst_grid.yml → syst/layout.yml} +0 -0
  94. data/spec/spec_helper.rb +29 -29
  95. metadata +49 -62
  96. data/auto.txt +0 -0
  97. data/spec/samples/out-1.jpg +0 -0
  98. data/spec/samples/qzc013.jpg +0 -0
  99. data/spec/samples/sample02.jpg +0 -0
  100. data/spec/samples/sample_gray.jpg +0 -0
  101. data/spec/samples/sheet.jpg +0 -0
  102. data/spec/samples/sheet666.jpg +0 -0
  103. data/spec/samples/slanted.jpg +0 -0
  104. data/spec/samples/slanted.yml +0 -54
  105. data/spec/samples/syst/IMG_20150104_0004.txt +0 -4955
  106. data/spec/samples/syst/IMG_20150104_0009.txt +0 -4955
  107. data/spec/samples/syst/IMG_20150104_0011.txt +0 -4955
  108. data/spec/samples/syst/SCN_0001.jpg +0 -0
  109. data/spec/samples/syst/SCN_0001.txt +0 -4955
  110. data/spec/samples/syst/barr0.txt +0 -4955
  111. data/spec/samples/syst/barr1.txt +0 -4955
  112. data/spec/samples/syst/barr2.txt +0 -4955
  113. data/spec/samples/syst/bell0.txt +0 -4955
  114. data/spec/samples/syst/bell1.txt +0 -4955
  115. data/spec/samples/syst/bell2.txt +0 -4955
  116. data/spec/samples/syst/bila0.txt +0 -4955
  117. data/spec/samples/syst/bila1.txt +0 -4955
  118. data/spec/samples/syst/bila2.txt +0 -4955
  119. data/spec/samples/syst/bila3.txt +0 -4955
  120. data/spec/samples/syst/bila4.txt +0 -4955
  121. data/spec/samples/syst/bone0.txt +0 -4955
  122. data/spec/samples/syst/bone1.txt +0 -4955
  123. data/spec/samples/syst/bone2.txt +0 -4955
  124. data/spec/samples/syst/cost0.txt +0 -4955
  125. data/spec/samples/syst/cost1.txt +0 -4955
  126. data/spec/samples/syst/cost2.txt +0 -4955
  127. data/spec/samples/syst/cost3.txt +0 -4955
  128. data/spec/samples/syst/cost4.txt +0 -4955
  129. data/spec/samples/syst/dald0.txt +0 -4955
  130. data/spec/samples/syst/dald1.txt +0 -4955
  131. data/spec/samples/syst/dald2.txt +0 -4955
  132. data/spec/samples/syst/dald3.txt +0 -4955
  133. data/spec/samples/syst/dald4.txt +0 -4955
  134. data/spec/samples/syst/dign0.txt +0 -4955
  135. data/spec/samples/syst/dign1.txt +0 -4955
  136. data/spec/samples/syst/dign2.txt +0 -4955
  137. data/spec/samples/syst/dive0.txt +0 -4955
  138. data/spec/samples/syst/dive1.txt +0 -4955
  139. data/spec/samples/syst/dive2.txt +0 -4955
  140. data/spec/samples/syst/out0000.jpg +0 -0
  141. data/spec/samples/syst/out0000.txt +0 -4955
  142. data/spec/samples/syst/out0001.jpg +0 -0
  143. data/spec/samples/syst/out0001.txt +0 -4955
  144. data/spec/samples/syst/out0002.jpg +0 -0
  145. data/spec/samples/syst/out0002.txt +0 -4955
  146. data/spec/samples/syst/qzc013.jpg +0 -0
  147. data/spec/samples/syst/qzc013.txt +0 -4955
  148. data/spec/samples/syst/sample_gray.jpg +0 -0
  149. data/spec/samples/syst/sample_gray.txt +0 -4955
  150. data/spec/samples/two_pages.pdf +0 -0
@@ -4,81 +4,40 @@ module Mork
4
4
  describe Mimage do
5
5
  let(:qna) { [5] * 100 }
6
6
 
7
- context 'new age on slanted' do
8
- let(:img) { sample_img 'slanted' }
9
- let(:mim) { Mimage.new img.filename, qna, GridOMR.new(img.grid_file) }
7
+ context 'John Doe' do
8
+ let(:img) { sample_img 'jdoe1' }
9
+ let(:fn) { File.basename(img.image_path) }
10
+ let(:mim) { Mimage.new img.image_path, [img.nchoices]*img.nitems, GridOMR.new(img.grid_path) }
10
11
  describe 'basics' do
11
12
  it 'should be valid' do
12
- mim.highlight_rm_centers
13
- mim.highlight_rm_areas
14
- mim.write 'spec/out/slanted.jpg', false
15
13
  expect(mim.valid?).to be_truthy
16
14
  end
17
15
 
18
16
  it 'should return the correct regmark coordinates' do
19
17
  [:tl, :tr, :br, :bl].each do |corner|
20
18
  crn = mim.rm[corner]
21
- expect(crn[:x]).to be_within(2).of(img.info[corner.to_s][0])
22
-
23
- end
24
- end
25
- end
26
- end
27
-
28
- context 'problematic sheets' do
29
- let(:mim) { Mimage.new 'spec/samples/out-1.jpg', qna, GridOMR.new('spec/samples/grid.yml') }
30
- let(:bila) { Mimage.new 'spec/samples/syst/bila0.jpg', qna, GridOMR.new('spec/samples/grid.yml') }
31
-
32
- it 'writes all cell values to a text file', exclude: true do
33
- d=Dir['spec/samples/syst/*.jpg']
34
- d.each do |f|
35
- fn = File.basename f, '.jpg'
36
- m = Mimage.new "spec/samples/syst/#{fn}.jpg", qna, GridOMR.new('spec/samples/grid.yml')
37
- puts fn
38
- File.open("spec/samples/syst/#{fn}.txt",'w') do |f|
39
- f.puts "ink:#{m.send :ink_black}"
40
- f.puts "drk:#{m.send :darkest_cell_mean}"
41
- f.puts "pap:#{m.send :paper_white}"
42
- f.puts "cal:#{m.send :cal_cell_mean}"
43
- f.puts "cho:#{m.send :choice_threshold}"
44
- 100.times do |q|
45
- 5.times do |c|
46
- f.puts m.send('choice_cell_averages')[q, c]
47
- end
48
- end
19
+ expect(crn[:x]).to be_within(2).of(img.send(corner)[0])
20
+ expect(crn[:x]).to be_within(2).of(img.send(corner)[0])
49
21
  end
50
22
  end
51
- end
52
- end
53
-
54
- context 'Old specs' do
55
- let(:sgi) { sample_img 'sample-gray' }
56
- let(:sg) { Mimage.new sgi.filename, qna, GridOMR.new(sgi.grid_file) }
57
-
58
- describe 'basics' do
59
- it 'returns the pixels as an array' do
60
- expect(sg.send :reg_pixels).to be_a NPatch
61
- end
62
-
63
- it 'returns the correct number of pixels' do
64
- expect(sg.send(:reg_pixels).length).to eq sgi.width * sgi.height
65
- end
66
-
67
- it 'returns the stretched array' do
68
- expect(sg.send(:reg_pixels).length).to eq sgi.width * sgi.height
69
- end
70
- end
71
23
 
72
- describe 'inspecting' do
73
- xit 'writes out average whiteness of choice cells' do
74
- qz = sample_img 'silvia'
75
- s = Mimage.new qz.filename, [5] * 5, GridOMR.new(qz.grid_file)
76
- File.open('spec/out/choices.txt', 'w') do |f|
77
- 5.times do |q|
78
- t = (0..4).collect do |c|
79
- s.send(:shade_of, q, c).round
24
+ xit 'writes all cell values to a text file' do
25
+ d=Dir['spec/samples/syst/*.jpg']
26
+ d.each do |f|
27
+ fname = File.basename f, '.jpg'
28
+ m = Mimage.new "spec/samples/syst/#{fname}.jpg", qna, GridOMR.new('spec/samples/grid.yml')
29
+ puts fname
30
+ File.open("spec/out/text/#{fname}.txt",'w') do |f|
31
+ f.puts "ink:#{m.send :ink_black}"
32
+ f.puts "drk:#{m.send :darkest_cell_mean}"
33
+ f.puts "pap:#{m.send :paper_white}"
34
+ f.puts "cal:#{m.send :cal_cell_mean}"
35
+ f.puts "cho:#{m.send :choice_threshold}"
36
+ 100.times do |q|
37
+ 5.times do |c|
38
+ f.puts m.send('choice_cell_averages')[q, c]
39
+ end
80
40
  end
81
- f.puts "#{q+1}: #{t.join(' ')}"
82
41
  end
83
42
  end
84
43
  end
@@ -3,258 +3,153 @@ require 'fileutils'
3
3
 
4
4
  module Mork
5
5
  describe SheetOMR do
6
- context 'basic object generation' do
7
- let(:img) { sample_img 'slanted' }
8
- let(:omr) { SheetOMR.new img.filename, [5] * 120, img.grid_file }
6
+ context 'with a valid response sheet' do
7
+ let(:img) { sample_img 'jdoe1' }
8
+ let(:fn) { File.basename(img.image_path) }
9
+ let(:omr) { SheetOMR.new img.image_path, choices: [img.nchoices]*img.nitems, layout: img.grid_path }
9
10
  describe '#new' do
10
- it 'raises an error if the provided path is invalid' do
11
- expect { SheetOMR.new 'non_existing_file.jpg'}.to raise_error IOError
12
- end
13
-
14
11
  it 'creates a SheetOMR object' do
15
12
  expect(omr).to be_a SheetOMR
16
13
  end
17
14
 
18
- it 'registers correctly' do
19
- expect(omr.valid?).to be_truthy
20
- end
21
-
22
- it 'writes out the registration' do
23
- omr.write_registration 'spec/out/slanted2.jpg'
15
+ it 'raises an error if the provided path is invalid' do
16
+ expect { SheetOMR.new 'non_existing_file.jpg'}.to raise_error IOError
24
17
  end
25
18
  end
26
- end
27
- # context 'problematic' do
28
- # let(:shinfo) { sample_img 'bianchi' }
29
- # let(:sheet) { SheetOMR.new shinfo.filename, shinfo.grid_file }
30
- #
31
- # it 'has a status' do
32
- # sheet.status.should == {:tl=>:ok, :tr=>:ok, :br=>:ok, :bl=>:ok, :write=>nil}
33
- # end
34
- #
35
- # it 'has a barcode' do
36
- # sheet.barcode.should == shinfo.barcode_int
37
- # end
38
- #
39
- # it 'writes the registered and marked image' do
40
- # sheet.cross_marked
41
- # sheet.write 'spec/out/bianchi.jpg'
42
- # sheet.status[:write].should == :fail
43
- # end
44
- #
45
- # it 'writes the registration areas' do
46
- # sheet.highlight_registration
47
- # sheet.write_raw 'spec/out/reg_bianchi.jpg'
48
- # end
49
- #
50
- # end
51
- #
52
- context 'slanted' do
53
- let(:sh) { sample_img 'slanted' }
54
- let(:sheet) { SheetOMR.new sh.filename, [5]*120, sh.grid_file }
55
-
56
- it 'gets in trouble' do
57
- sheet.write_registration 'spec/out/laurout.jpg'
58
- end
59
-
60
- it 'gets more in trouble' do
61
- sheet.highlight_marked
62
- sheet.write 'spec/out/lauraout2.jpg'
63
- end
64
-
65
- it 'should be valid' do
66
- expect(sheet.valid?).to be_truthy
67
- end
68
- end
69
-
70
- context 'highlighting' do
71
- # since these specs change the @crop, they must be run in isolation
72
- # with the SheetOMR rebuilt each time, even though it is time consuming!
73
- let(:shinfo) { sample_img 'sample-gray' }
74
- let(:sheet) { SheetOMR.new shinfo.filename, [5]*120, shinfo.grid_file }
75
-
76
- it 'writes the sheet with registrations highlighted' do
77
- sheet.write_registration 'spec/out/sample_gray_registered.jpg'
78
- end
79
-
80
- it 'highlights all choice cells' do
81
- sheet.highlight_all_choices
82
- sheet.write 'spec/out/all_highlights.jpg'
83
- end
84
-
85
- it 'highlights marked cells' do
86
- sheet.highlight_marked
87
- sheet.write 'spec/out/marked_highlights.jpg'
88
- end
89
-
90
- it 'crossed marked cells' do
91
- sheet.cross_marked
92
- sheet.write 'spec/out/marked_crosses.jpg'
93
- end
94
19
 
95
- it 'outlines some responses' do
96
- sheet.outline [[1],[1],[2],[2],[3,4],[],[0,1,2,3,4], [],[1],[2],[2],[3,4],[],[0,1,2,3,4]]
97
- sheet.write 'spec/out/outlines.jpg'
20
+ describe '#valid?' do
21
+ it 'registers correctly' do
22
+ expect(omr.valid?).to be_truthy
23
+ end
98
24
  end
99
25
 
100
- it 'cross some responses' do
101
- sheet.cross [[1],[1],[2],[2],[3,4],[],[0,1,2,3,4], [],[1],[2],[2],[3,4],[],[0,1,2,3,4]]
102
- sheet.write 'spec/out/crosses.jpg'
26
+ describe '#status' do
27
+ it 'returns the registration status for each of the four corners' do
28
+ expect(omr.status).to eq({ tl: :ok, tr: :ok, br: :ok, bl: :ok })
29
+ end
103
30
  end
104
31
 
105
- it 'outlines some responses in-place (rewriting the source image)' do
106
- FileUtils.cp shinfo.filename, 'spec/out/inplace.jpg'
107
- tsheet = SheetOMR.new 'spec/out/inplace.jpg', [5]*100, shinfo.grid_file
108
- tsheet.outline [[1],[1],[2],[2],[3,4],[],[0,1,2,3,4], [],[1],[2],[2],[3,4],[],[0,1,2,3,4]]
109
- tsheet.write
32
+ describe '#barcode' do
33
+ it 'returns the integer form of the barcode' do
34
+ expect(omr.barcode).to eq img.barcode_int
35
+ end
110
36
  end
111
37
 
112
- it 'highlights marked cells and outline correct responses' do
113
- sheet.highlight_marked
114
- sheet.outline [[1],[1],[2],[2],[3,4],[],[0,1,2,3,4], [],[1],[2],[2],[3,4],[],[0,1,2,3,4]]
115
- sheet.write 'spec/out/marks_and_outs.jpg'
38
+ describe '#barcode_string' do
39
+ it 'returns the binary string version of the barcode' do
40
+ expect(omr.barcode_string).to eq img.barcode_str
41
+ end
116
42
  end
117
43
 
118
- it 'highlights marked cells of a problematic one' do
119
- si = sample_img 'silvia'
120
- s = SheetOMR.new si.filename, [5]*100, si.grid_file
121
- s.highlight_marked
122
- s.write 'spec/out/problem.jpg'
44
+ describe '#marked?' do
45
+ it 'returns true if the given cell was marked, false otherwise' do
46
+ expect(omr.marked? 0, 0).to be_truthy
47
+ expect(omr.marked? 0, 1).to be_falsy
48
+ expect(omr.marked? 119, 4).to be_truthy
49
+ expect(omr.marked? 119, 3).to be_falsy
50
+ end
123
51
  end
124
52
 
125
- it 'highlights the barcode' do
126
- si = sample_img 'sample-gray'
127
- s = SheetOMR.new si.filename, [5]*100, si.grid_file
128
- s.highlight_barcode
129
- s.write 'spec/out/code_bits.jpg'
53
+ describe '#marked_choices' do
54
+ it 'returns an array of marked choices as position indices' do
55
+ expect(omr.marked_choices).to eq standard_mark_array(24)
56
+ end
130
57
  end
131
- end
132
58
 
133
- context 'marking a nicely printed and scanned sheet' do
134
- before(:all) do
135
- @shinfo = sample_img 'sample-gray'
136
- @sheet = SheetOMR.new @shinfo.filename, [5]*120, @shinfo.grid_file
137
- end
59
+ describe '#marked_choices' do
60
+ it 'returns an array of marked choices as position indexes' do
61
+ expect(omr.marked_choices ).to eq standard_mark_array(24)
62
+ end
138
63
 
139
- describe '#valid?' do
140
- it 'returns true' do
141
- @sheet.valid?.should be_truthy
64
+ let(:om2) { SheetOMR.new img.image_path, choices: [5, 4, 3, 2, 1], layout: img.grid_path }
65
+ it 'returns marked choices only for existing choice cells' do
66
+ expect(om2.marked_choices).to eq [[0], [1], [2], [], []]
142
67
  end
143
68
  end
144
69
 
145
- describe '#marked?' do
146
- it 'returns true for some darkened choices' do
147
- expect(@sheet.marked?(0,0)).to be_truthy
148
- expect(@sheet.marked?(1,1)).to be_truthy
149
- expect(@sheet.marked?(2,2)).to be_truthy
70
+ describe '#marked_logicals' do
71
+ it 'returns an array of logicals for the marked choices' do
72
+ expect(omr.marked_logicals).to eq standard_mark_logical_array(24)
150
73
  end
74
+ end
151
75
 
152
- it 'return false for some blank choices' do
153
- expect(@sheet.marked?(0,1)).to be_falsy
154
- expect(@sheet.marked?(1,0)).to be_falsy
155
- expect(@sheet.marked?(2,3)).to be_falsy
76
+ describe '#marked_letters' do
77
+ it 'returns an array of characters for the marked choices' do
78
+ expect(omr.marked_letters).to eq standard_mark_char_array(24)
156
79
  end
80
+ end
157
81
 
158
- it 'writes out markedness' do
159
- mf = File.open('spec/out/marked.txt', 'w')
160
- 120.times do |q|
161
- x = 5.times.collect do |c|
162
- @sheet.marked?(q,c) ? '1' : '0'
163
- end
164
- mf.puts x.join(' ')
82
+ it 'writes out markedness' do
83
+ mf = File.open('spec/out/text/marked.txt', 'w')
84
+ img.nitems.times do |q|
85
+ x = 5.times.collect do |c|
86
+ omr.marked?(q,c) ? '1' : '0'
165
87
  end
166
- mf.close
88
+ mf.puts x.join(' ')
167
89
  end
90
+ mf.close
168
91
  end
169
92
 
170
- describe '#mark_array' do
171
- it 'should return an array of marked choices for each of the first 5 questions' do
172
- @sheet.mark_array(5).should == [[0], [1], [2], [3], [4]]
173
- end
174
-
175
- it 'should return an array of marked choices for the specified question set' do
176
- @sheet.mark_array([0, 1, 13, 16, 31, 104, 21]).should == [[0], [1], [3,4], [2], [1], [], [0,1,2,3,4]]
93
+ context 'creating overlays' do
94
+ it 'registration highlighted' do
95
+ omr.save_registration "spec/out/registration/#{fn}"
177
96
  end
178
97
 
179
- it 'should return an array of @grid.max_questions length if called without arguments' do
180
- @sheet.mark_array.length.should == 120
98
+ it 'highlights all choice cells' do
99
+ omr.overlay :highlight, :all
100
+ omr.save "spec/out/highlight/#{fn}"
181
101
  end
182
- end
183
102
 
184
- describe '#mark_logical_array' do
185
- it 'should return an array of booleans for each of the first questions' do
186
- @sheet.mark_logical_array(5).should == [
187
- [true, false, false, false, false],
188
- [false, true, false, false, false],
189
- [false, false, true, false, false],
190
- [false, false, false, true, false],
191
- [false, false, false, false, true],
192
- ]
103
+ it 'highlights marked cells' do
104
+ omr.overlay :highlight, :marked
105
+ omr.save "spec/out/highlight/marked-#{fn}"
193
106
  end
194
- end
195
107
 
196
- describe 'barcodes' do
197
- it 'should read the bit string as all ones' do
198
- @sheet.barcode_string.should == '1111111111111111111111111111111111111111'
199
- @sheet.barcode.should == 1099511627775
108
+ it 'checks marked cells' do
109
+ omr.overlay :check, :marked
110
+ omr.save "spec/out/mark/#{fn}"
200
111
  end
201
112
 
202
- it 'should read another bit string' do
203
- barcode_string = '0000000000000000000000000010000110100000'
204
- s2 = SheetOMR.new('spec/samples/sample02.jpg', [5]*100)
205
- s2.barcode_string.should == barcode_string
206
- s2.barcode.should == 8608
113
+ it 'outlines and crosses marked cells' do
114
+ omr.overlay :outline, standard_mark_array(24)
115
+ omr.overlay :check
116
+ omr.save "spec/out/outline/#{fn}"
207
117
  end
208
118
 
209
- it 'should read the 666 bit string' do
210
- sh = sample_img 'code666'
211
- s2 = SheetOMR.new sh.filename, [5]*100, sh.grid_file
212
- s2.barcode.should == sh.barcode_int
119
+ it 'highlights the barcode' do
120
+ omr.overlay :outline, :barcode
121
+ omr.save "spec/out/barcode/#{fn}"
213
122
  end
214
123
  end
215
-
216
- end
217
-
218
- context 'marking a problematic sheet' do
219
- let(:sheet) { SheetOMR.new 'spec/samples/out-1.jpg', [5]*100, 'spec/samples/grid.yml' }
220
-
221
- it 'highlights the registration' do
222
- sheet.write_registration 'spec/out/problematic.jpg'
223
- end
224
-
225
- it 'highlights the barcode' do
226
- sheet.highlight_barcode
227
- sheet.write 'spec/out/barcode.jpg'
228
- end
229
124
  end
230
125
 
231
- context 'systematic tests' do
126
+ context 'systematic tests', exclude: true do
232
127
  let(:bila) { 'CCEBEBCEEACCDCABDBEBCADEADDCCCACCACDBBDAECDDABDEEBCEEDCBAAADEEEEDCADEABCBDECCCCDDDCABBECAADADBBEEABA'.split '' }
233
- let(:bila0) { SheetOMR.new 'spec/samples/syst/bila0.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
234
- let(:bila1) { SheetOMR.new 'spec/samples/syst/bila1.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
235
- let(:bila2) { SheetOMR.new 'spec/samples/syst/bila2.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
236
- let(:bila3) { SheetOMR.new 'spec/samples/syst/bila3.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
237
- let(:bila4) { SheetOMR.new 'spec/samples/syst/bila4.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
128
+ let(:bila0) { SheetOMR.new 'spec/samples/syst/bila0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
129
+ let(:bila1) { SheetOMR.new 'spec/samples/syst/bila1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
130
+ let(:bila2) { SheetOMR.new 'spec/samples/syst/bila2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
131
+ let(:bila3) { SheetOMR.new 'spec/samples/syst/bila3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
132
+ let(:bila4) { SheetOMR.new 'spec/samples/syst/bila4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
238
133
  let(:dald) { 'DDDBECAAADBAEEEAEEEBAACAEDBDECDBDCDCDDEDCCDCDBDCADEEDBCCBEBBAADDCDBBECBBBDEABADABADADBABAEABACBDADDA'.split '' }
239
- let(:dald0) { SheetOMR.new 'spec/samples/syst/dald0.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
240
- let(:dald1) { SheetOMR.new 'spec/samples/syst/dald1.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
241
- let(:dald2) { SheetOMR.new 'spec/samples/syst/dald2.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
242
- let(:dald3) { SheetOMR.new 'spec/samples/syst/dald3.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
243
- let(:dald4) { SheetOMR.new 'spec/samples/syst/dald4.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
134
+ let(:dald0) { SheetOMR.new 'spec/samples/syst/dald0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
135
+ let(:dald1) { SheetOMR.new 'spec/samples/syst/dald1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
136
+ let(:dald2) { SheetOMR.new 'spec/samples/syst/dald2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
137
+ let(:dald3) { SheetOMR.new 'spec/samples/syst/dald3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
138
+ let(:dald4) { SheetOMR.new 'spec/samples/syst/dald4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
244
139
  let(:cost) { 'ABBDDBAEAEBAADEAAECBCDBBDABABADEECCACBCAEDDAEBEABBCDABECAACEEEBADECBBEAADBBBEABDAEBDEEABBABEBEDDAEEC'.split '' }
245
- let(:cost0) { SheetOMR.new 'spec/samples/syst/cost0.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
246
- let(:cost1) { SheetOMR.new 'spec/samples/syst/cost1.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
247
- let(:cost2) { SheetOMR.new 'spec/samples/syst/cost2.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
248
- let(:cost3) { SheetOMR.new 'spec/samples/syst/cost3.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
249
- let(:cost4) { SheetOMR.new 'spec/samples/syst/cost4.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
140
+ let(:cost0) { SheetOMR.new 'spec/samples/syst/cost0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
141
+ let(:cost1) { SheetOMR.new 'spec/samples/syst/cost1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
142
+ let(:cost2) { SheetOMR.new 'spec/samples/syst/cost2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
143
+ let(:cost3) { SheetOMR.new 'spec/samples/syst/cost3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
144
+ let(:cost4) { SheetOMR.new 'spec/samples/syst/cost4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
250
145
  let(:bone) { 'CECBBABAECADEDCACBBDEECBADBECDCEDECABCAADCBDEDACAEEDCCADBEDCEBCCBBDCCACDEDDAAECEBDBADCBAAEBAEDABCBDC'.split '' }
251
- let(:bone0) { SheetOMR.new 'spec/samples/syst/bone0.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
252
- let(:bone1) { SheetOMR.new 'spec/samples/syst/bone1.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
253
- let(:bone2) { SheetOMR.new 'spec/samples/syst/bone2.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
146
+ let(:bone0) { SheetOMR.new 'spec/samples/syst/bone0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
147
+ let(:bone1) { SheetOMR.new 'spec/samples/syst/bone1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
148
+ let(:bone2) { SheetOMR.new 'spec/samples/syst/bone2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
254
149
  let(:barr) { 'ACECAAADDBCECCCDBEBECDEDAECEDDEEDCDEADDCCBCCCBBEACBCAEDEEDDDABBBBABEBDCEADEEDEBCBADBCEDCDBACEBCBDCDA'.split '' }
255
- let(:barr0) { SheetOMR.new 'spec/samples/syst/barr0.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
256
- let(:barr1) { SheetOMR.new 'spec/samples/syst/barr1.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
257
- let(:barr2) { SheetOMR.new 'spec/samples/syst/barr2.jpg', [5]*100, 'spec/samples/syst_grid.yml'}
150
+ let(:barr0) { SheetOMR.new 'spec/samples/syst/barr0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
151
+ let(:barr1) { SheetOMR.new 'spec/samples/syst/barr1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
152
+ let(:barr2) { SheetOMR.new 'spec/samples/syst/barr2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
258
153
 
259
154
  it 'checks bila' do
260
155
  expect(bila0.mark_char_array.flatten).to eq(bila)
@@ -40,8 +40,8 @@ module Mork
40
40
  end
41
41
 
42
42
  it 'creates a basic PDF sheet' do
43
- s = SheetPDF.new(content, 'spec/samples/layout.yml')
44
- s.save('spec/out/sheet.pdf')
43
+ s = SheetPDF.new(content)
44
+ s.save('spec/out/pdf/sheet.pdf')
45
45
  end
46
46
 
47
47
  it 'creates a boxed PDF sheet' do
@@ -52,39 +52,38 @@ module Mork
52
52
  signature: 'Signature'
53
53
  }
54
54
  s = SheetPDF.new(content.merge({header: h}), 'spec/samples/boxy.yml')
55
- s.save('spec/out/boxy.pdf')
55
+ s.save('spec/out/pdf/boxy.pdf')
56
56
  end
57
57
 
58
58
  it 'creates a basic PDF sheet with a code of 15' do
59
59
  s = SheetPDF.new(content.merge({barcode: 15}))
60
- s.save('spec/out/sheet16.pdf')
60
+ s.save('spec/out/pdf/sheet16.pdf')
61
61
  end
62
62
 
63
63
  it 'creates a basic PDF sheet with a code of 666666666666' do
64
64
  s = SheetPDF.new(content.merge({barcode: 666666666666}))
65
- s.save('spec/out/sheet666.pdf')
65
+ s.save('spec/out/pdf/sheet666.pdf')
66
66
  end
67
67
 
68
68
  it 'creates a PDF sheet with the maximum possible barcode' do
69
69
  s = SheetPDF.new(content.merge({barcode: 1099511627775}))
70
- s.save('spec/out/maxcode.pdf')
70
+ s.save('spec/out/pdf/maxcode.pdf')
71
71
  end
72
72
 
73
73
  it 'creates a PDF sheet with 160 items' do
74
74
  s = SheetPDF.new(content.merge({choices: [5] * 160}), 'spec/samples/grid160.yml')
75
- s.save('spec/out/i160.pdf')
76
- # system 'open spec/out/i160.pdf'
75
+ s.save('spec/out/pdf/i160.pdf')
77
76
  end
78
77
 
79
78
  it 'creates a PDF sheet with unequal choices per item' do
80
79
  s = SheetPDF.new(content.merge({choices: [5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]}), 'spec/samples/layout.yml')
81
- s.save('spec/out/uneq.pdf')
80
+ s.save('spec/out/pdf/uneq.pdf')
82
81
  end
83
82
 
84
83
  it 'creates 20 PDF sheets' do
85
84
  c = content
86
85
  s = SheetPDF.new([c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c])
87
- s.save('spec/out/p20.pdf')
86
+ s.save('spec/out/pdf/p20.pdf')
88
87
  end
89
88
  end
90
89
  end
File without changes
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
File without changes
Binary file
Binary file
File without changes
File without changes
File without changes
@@ -0,0 +1,56 @@
1
+ page_size: # all measurements in mm
2
+ width: 210 # width of the paper sheet
3
+ height: 297 # height of the paper sheet
4
+ reg_marks:
5
+ margin: 10 # distance from each page border to registration mark center
6
+ radius: 2.5 # registration mark radius
7
+ offset: 2 # distance between the search area and each page border (*)
8
+ crop: 20
9
+ blur: 2
10
+ dilate: 5
11
+ header:
12
+ name: # ‘name’ is just a label; you can add arbitrary header elements
13
+ top: 5 # margin relative to registration frame top side
14
+ left: 15 # margin relative to registration frame left side
15
+ width: 170 # text will be fitted to this width
16
+ height: 7 # text will be fitted to this height
17
+ size: 14 # font size
18
+ title:
19
+ top: 15
20
+ left: 15
21
+ width: 180
22
+ height: 12
23
+ size: 12
24
+ code:
25
+ top: 5
26
+ left: 165
27
+ width: 20
28
+ height: 10
29
+ size: 14
30
+ signature:
31
+ top: 30
32
+ left: 7.5
33
+ width: 120
34
+ height: 15
35
+ size: 7
36
+ box: true # header element will be enclosed in a box
37
+ items:
38
+ top: 55.5 # response area margin, relative to reg frame
39
+ left: 10.5 # response area margin, relative to reg frame
40
+ rows: 30 # number of items per column
41
+ columns: 4 # number of columns
42
+ column_width: 44 #
43
+ x_spacing: 7 # horizontal distance between ajacent cell centers
44
+ y_spacing: 7 # vertical distance between ajacent cell centers
45
+ cell_width: 6 # width of each choice and calibration cell
46
+ cell_height: 5 # height of each choice and calibration cell
47
+ max_cells: 5 # maximum number of choices per item
48
+ font_size: 9 # size of both the item number and choice cell letter
49
+ number_width: 8 #
50
+ number_margin: 2 # margin between
51
+ barcode:
52
+ bits: 40 # the maximum sheet identifier is 2 to the power or bits
53
+ left: 15 # distance between registration frame side and the first barcode bit
54
+ width: 3 # width of each barcode bit
55
+ height: 2.5 # height of each barcode bit from the registration frame bottom side
56
+ spacing: 4 # horizontal distance between adjacent barcode bit centers