smalruby-editor 0.0.8-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of smalruby-editor might be problematic. Click here for more details.

Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +19 -0
  5. data/.ruby-version +1 -0
  6. data/.simplecov +7 -0
  7. data/.travis.yml +23 -0
  8. data/LEGAL +13 -0
  9. data/LICENSE +22 -0
  10. data/Procfile +1 -0
  11. data/README.rdoc +46 -0
  12. data/Rakefile +9 -0
  13. data/app/assets/images/.keep +0 -0
  14. data/app/assets/images/favicon.ico +0 -0
  15. data/app/assets/javascripts/application.js +21 -0
  16. data/app/assets/javascripts/editor.js.coffee.erb +139 -0
  17. data/app/assets/stylesheets/application.css +19 -0
  18. data/app/assets/stylesheets/editor.css.scss +19 -0
  19. data/app/assets/stylesheets/flatstrap-custom.css.scss +2 -0
  20. data/app/controllers/application_controller.rb +5 -0
  21. data/app/controllers/concerns/.keep +0 -0
  22. data/app/controllers/editor_controller.rb +5 -0
  23. data/app/controllers/source_codes_controller.rb +106 -0
  24. data/app/helpers/application_helper.rb +2 -0
  25. data/app/helpers/editor_helper.rb +2 -0
  26. data/app/mailers/.keep +0 -0
  27. data/app/models/.keep +0 -0
  28. data/app/models/concerns/.keep +0 -0
  29. data/app/models/source_code.rb +49 -0
  30. data/app/views/editor/index.html.erb +23 -0
  31. data/app/views/layouts/application.html.erb +15 -0
  32. data/bin/bundle +3 -0
  33. data/bin/rails +4 -0
  34. data/bin/rake +4 -0
  35. data/bin/smalruby-editor +80 -0
  36. data/config/application.rb +16 -0
  37. data/config/boot.rb +17 -0
  38. data/config/database.yml.mysql2 +48 -0
  39. data/config/database.yml.sqlite3 +31 -0
  40. data/config/database.yml.travis +5 -0
  41. data/config/environment.rb +5 -0
  42. data/config/environments/development.rb +30 -0
  43. data/config/environments/production.rb +86 -0
  44. data/config/environments/standalone.rb +16 -0
  45. data/config/environments/test.rb +46 -0
  46. data/config/initializers/backtrace_silencers.rb +9 -0
  47. data/config/initializers/filter_parameter_logging.rb +4 -0
  48. data/config/initializers/inflections.rb +16 -0
  49. data/config/initializers/mime_types.rb +5 -0
  50. data/config/initializers/secret_token.rb +17 -0
  51. data/config/initializers/session_store.rb +4 -0
  52. data/config/initializers/wrap_parameters.rb +15 -0
  53. data/config/locales/en.yml +23 -0
  54. data/config/routes.rb +68 -0
  55. data/config/unicorn.rb +23 -0
  56. data/config.ru +4 -0
  57. data/db/migrate/20131216121603_create_source_codes.rb +9 -0
  58. data/db/migrate/20131219045113_add_filename_to_source_code.rb +5 -0
  59. data/db/schema.rb +23 -0
  60. data/db/seeds.rb +7 -0
  61. data/lib/assets/.keep +0 -0
  62. data/lib/smalruby_editor/version.rb +3 -0
  63. data/lib/smalruby_editor.rb +46 -0
  64. data/lib/tasks/.keep +0 -0
  65. data/lib/tasks/gem.rake +10 -0
  66. data/lib/tasks/rspec.rake +16 -0
  67. data/lib/tasks/rubocop.rake +3 -0
  68. data/log/.keep +0 -0
  69. data/public/404.html +58 -0
  70. data/public/422.html +58 -0
  71. data/public/500.html +57 -0
  72. data/public/assets/application-759ce4d1ac1e0e3991e6d350c8f98fc5.js +5267 -0
  73. data/public/assets/application-759ce4d1ac1e0e3991e6d350c8f98fc5.js.gz +0 -0
  74. data/public/assets/application-f51ea0e777d97f12a8ce84308f31eb57.css +4791 -0
  75. data/public/assets/application-f51ea0e777d97f12a8ce84308f31eb57.css.gz +0 -0
  76. data/public/assets/favicon-c7ae857bb9d06de8742ae2d337157e83.ico +0 -0
  77. data/public/assets/loading-e8e6dd7833131c92a6c3b9c8ccc6a6ac.gif +0 -0
  78. data/public/assets/manifest-f86249f9779f8f4d7c8fc148e4361b4f.json +1 -0
  79. data/public/assets/progressbar-82023a146fba2a0f6d925629ed2b09c5.gif +0 -0
  80. data/public/favicon.ico +0 -0
  81. data/public/fonts/FontAwesome.otf +0 -0
  82. data/public/fonts/fontawesome-webfont.eot +0 -0
  83. data/public/fonts/fontawesome-webfont.ttf +0 -0
  84. data/public/fonts/fontawesome-webfont.woff +0 -0
  85. data/public/robots.txt +5 -0
  86. data/smalruby-editor.gemspec +81 -0
  87. data/spec/acceptance/readme.md +3 -0
  88. data/spec/acceptance/standalone/save.feature +32 -0
  89. data/spec/acceptance/text_editor/base.feature +24 -0
  90. data/spec/acceptance/text_editor/check.feature +25 -0
  91. data/spec/acceptance/text_editor/load.feature +81 -0
  92. data/spec/acceptance/text_editor/save.feature +34 -0
  93. data/spec/controllers/editor_controller_spec.rb +12 -0
  94. data/spec/controllers/source_codes_controller_spec.rb +469 -0
  95. data/spec/fixtures/files/01.rb +57 -0
  96. data/spec/fixtures/files/favicon.ico +0 -0
  97. data/spec/helpers/editor_helper_spec.rb +14 -0
  98. data/spec/lib/smalruby_editor_spec.rb +66 -0
  99. data/spec/models/source_code_spec.rb +55 -0
  100. data/spec/spec_helper.rb +156 -0
  101. data/spec/steps/ace_steps.rb +59 -0
  102. data/spec/steps/global_variable.rb +39 -0
  103. data/spec/steps/text_editor_steps.rb +183 -0
  104. data/spec/support/assets.rb +18 -0
  105. data/spec/support/capybara.rb +17 -0
  106. data/spec/support/env.rb +15 -0
  107. data/spec/turnip_helper.rb +2 -0
  108. data/vendor/assets/javascripts/.keep +0 -0
  109. data/vendor/assets/stylesheets/.keep +0 -0
  110. metadata +407 -0
@@ -0,0 +1,469 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe SourceCodesController do
5
+ describe 'プログラムが正しいかチェックする (XHR POST check)' do
6
+ before do
7
+ params = {
8
+ source_code: {
9
+ data: data,
10
+ }
11
+ }.with_indifferent_access
12
+
13
+ xhr :post, :check, params
14
+ end
15
+
16
+ context 'プログラムが正しい場合' do
17
+ let(:data) { 'puts "Hello, World!"' }
18
+
19
+ it { expect(response).to be_success }
20
+
21
+ it do
22
+ expected = parse_json(SourceCode.new(data: data).check_syntax.to_json)
23
+ expect(parse_json(response.body)).to eq(expected)
24
+ end
25
+ end
26
+
27
+ context 'プログラムが正しくない場合' do
28
+ let(:data) { 'puts Hello, World!"' }
29
+
30
+ it { expect(response).to be_success }
31
+
32
+ it do
33
+ expected = parse_json(SourceCode.new(data: data).check_syntax.to_json)
34
+ expect(parse_json(response.body)).to eq(expected)
35
+ end
36
+ end
37
+ end
38
+
39
+ describe 'プログラムを保存する (XHR POST create)' do
40
+ let(:params) {
41
+ {
42
+ source_code: {
43
+ filename: '01.rb',
44
+ data: 'puts "Hello, World!"',
45
+ }
46
+ }
47
+ }
48
+
49
+ describe 'レスポンス' do
50
+ subject {
51
+ xhr :post, :create, params
52
+ response
53
+ }
54
+
55
+ it { should be_success }
56
+ it {
57
+ ids = SourceCode.all.map(&:id)
58
+ expect(parse_json(subject.body))
59
+ .to eq('source_code' => {
60
+ 'id' => SourceCode.find(SourceCode.all.map(&:id) - ids)
61
+ .first.id
62
+ })
63
+ }
64
+ end
65
+
66
+ it 'アップロードされたプログラムを保存できる' do
67
+ expect {
68
+ xhr :post, :create, params
69
+ }.to change { SourceCode.count }.by(1)
70
+ end
71
+
72
+ describe 'アップロードされたプログラム' do
73
+ subject {
74
+ ids = SourceCode.all.map(&:id)
75
+ xhr :post, :create, params
76
+ SourceCode.find((SourceCode.all.map(&:id) - ids).first)
77
+ }
78
+
79
+ its(:data) { should eq(params[:source_code][:data]) }
80
+ its(:filename) { should eq(params[:source_code][:filename]) }
81
+ end
82
+
83
+ describe 'session' do
84
+ before {
85
+ ids = SourceCode.all.map(&:id)
86
+ xhr :post, :create, params
87
+ @created_source_code =
88
+ SourceCode.find((SourceCode.all.map(&:id) - ids).first)
89
+ }
90
+
91
+ subject { session }
92
+
93
+ it '[:source_code][:id]はアップロードしたプログラムのIDである' do
94
+ expect(subject[:source_code][:id]).to eq(@created_source_code.id)
95
+ end
96
+
97
+ it '[:source_code][:digest]はアップロードしたプログラムのSHA256のハッシュ値である' do
98
+ expect(subject[:source_code][:digest])
99
+ .to eq(@created_source_code.digest)
100
+ end
101
+ end
102
+ end
103
+
104
+ describe 'プログラムをダウンロードしてサーバ上から削除する (DELETE download)' do
105
+ let(:source_code) {
106
+ SourceCode.create!(filename: '01.rb', data: 'puts "Hello, World!"')
107
+ }
108
+
109
+ context 'セッションが正しい場合' do
110
+ let(:_session) {
111
+ {
112
+ source_code: {
113
+ id: source_code.id,
114
+ digest: source_code.digest,
115
+ }
116
+ }
117
+ }
118
+
119
+ context 'ファイル名が半角英数字の場合' do
120
+ before do
121
+ allow(@controller).to receive(:send_data).and_call_original
122
+ delete :download, {}, _session
123
+ end
124
+
125
+ specify 'プログラムをダウンロードする' do
126
+ expect(@controller).to have_received(:send_data)
127
+ .with(source_code.data,
128
+ filename: source_code.filename,
129
+ disposition: 'attachment',
130
+ type: 'text/plain; charset=utf-8')
131
+ .once
132
+ end
133
+
134
+ specify 'プログラムをサーバ上から削除する' do
135
+ expect(SourceCode).to have(0).records
136
+ end
137
+
138
+ specify 'セッションから[:source_code]を削除する' do
139
+ expect(session[:source_code]).to be_nil
140
+ end
141
+ end
142
+
143
+ context 'ファイル名が日本語の場合' do
144
+ # rubocop:disable LineLength
145
+ USER_AGENT = {
146
+ IE11: 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko',
147
+ IE10: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Touch)',
148
+ Chrome20: 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11',
149
+ Firefox14: 'Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1',
150
+ }
151
+ # rubocop:enable LineLength
152
+
153
+ let(:source_code) {
154
+ SourceCode.create!(filename: '日本語.rb', data: 'puts "Hello, World!"')
155
+ }
156
+
157
+ [:IE10, :IE11].each do |browser|
158
+ context "ブラウザが#{browser}の場合" do
159
+ before do
160
+ @request.env['HTTP_USER_AGENT'] = USER_AGENT[browser]
161
+ allow(@controller).to receive(:send_data).and_call_original
162
+ delete :download, {}, _session
163
+ end
164
+
165
+ specify 'プログラムをダウンロードする' do
166
+ expect(@controller).to have_received(:send_data)
167
+ .with(source_code.data,
168
+ filename: ERB::Util.url_encode(source_code.filename),
169
+ disposition: 'attachment',
170
+ type: 'text/plain; charset=utf-8')
171
+ .once
172
+ end
173
+ end
174
+ end
175
+
176
+ [:Chrome20, :Firefox14].each do |browser|
177
+ context "ブラウザが#{browser}の場合" do
178
+ before do
179
+ @request.env['HTTP_USER_AGENT'] = USER_AGENT[browser]
180
+ allow(@controller).to receive(:send_data).and_call_original
181
+ delete :download, {}, _session
182
+ end
183
+
184
+ specify 'プログラムをダウンロードする' do
185
+ expect(@controller).to have_received(:send_data)
186
+ .with(source_code.data,
187
+ filename: source_code.filename,
188
+ disposition: 'attachment',
189
+ type: 'text/plain; charset=utf-8')
190
+ .once
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ context 'セッションが不正な場合' do
198
+ shared_examples 'raise exception' do
199
+ it {
200
+ expect {
201
+ delete :download, {}, _session
202
+ }.to raise_exception
203
+ }
204
+ end
205
+
206
+ context 'セッションに[:source_code]がない場合' do
207
+ let(:_session) { {} }
208
+
209
+ include_examples 'raise exception'
210
+ end
211
+
212
+ context 'セッションに[:source_code][:id]がない場合' do
213
+ let(:_session) {
214
+ {
215
+ source_code: {
216
+ digest: source_code.digest,
217
+ }
218
+ }
219
+ }
220
+
221
+ include_examples 'raise exception'
222
+ end
223
+
224
+ context 'セッションに[:source_code][:digest]がない場合' do
225
+ let(:_session) {
226
+ {
227
+ source_code: {
228
+ id: source_code.id,
229
+ }
230
+ }
231
+ }
232
+
233
+ include_examples 'raise exception'
234
+ end
235
+
236
+ context 'セッションの[:source_code][:digest]が不正な場合' do
237
+ let(:_session) {
238
+ {
239
+ source_code: {
240
+ id: source_code.id,
241
+ digest: 'invalid_digest',
242
+ }
243
+ }
244
+ }
245
+
246
+ include_examples 'raise exception'
247
+ end
248
+ end
249
+ end
250
+
251
+ describe 'プログラムをホームディレクトリに保存してサーバ上から削除する' \
252
+ ' (DELETE write)' do
253
+ let(:source_code) {
254
+ SourceCode.create!(filename: '01.rb', data: 'puts "Hello, World!"')
255
+ }
256
+ let(:params) { {} }
257
+ let(:_session) {
258
+ {
259
+ source_code: {
260
+ id: source_code.id,
261
+ digest: source_code.digest,
262
+ }
263
+ }
264
+ }
265
+
266
+ context 'RAILS_ENVがstandaloneの場合', set_standalone_rails_env: true do
267
+ let(:path) { Pathname("~/#{source_code.filename}").expand_path.to_s }
268
+
269
+ context 'セッションが正しい場合' do
270
+ shared_examples 'success writing' do
271
+ let(:target_file) {
272
+ f = double('File')
273
+ allow(f).to receive(:write)
274
+ f
275
+ }
276
+
277
+ before do
278
+ allow(File).to receive(:open).and_yield(target_file)
279
+ xhr :delete, :write, params, _session
280
+ end
281
+
282
+ specify { expect(response).to be_success }
283
+
284
+ specify 'ホームディレクトリにファイルを保存する' do
285
+ expect(File).to have_received(:open).with(path, 'w').once
286
+ expect(target_file)
287
+ .to have_received(:write).with(source_code.data).once
288
+ end
289
+
290
+ specify 'プログラムをサーバ上から削除する' do
291
+ expect(SourceCode).to have(0).records
292
+ end
293
+
294
+ specify 'セッションから[:source_code]を削除する' do
295
+ expect(session[:source_code]).to be_nil
296
+ end
297
+ end
298
+
299
+ context '同じ名前のファイルが存在しない場合' do
300
+ before do
301
+ allow(File).to receive(:exist?).with(path).and_return(false)
302
+ end
303
+
304
+ context 'ファイル名が半角英数字の場合' do
305
+ include_examples 'success writing'
306
+ end
307
+
308
+ context 'ファイル名が日本語の場合' do
309
+ let(:source_code) {
310
+ SourceCode.create!(filename: '日本語でも表現できる.rb',
311
+ data: 'puts "Hello, World!"')
312
+ }
313
+
314
+ include_examples 'success writing'
315
+ end
316
+ end
317
+
318
+ context '同じ名前のファイルが存在する場合' do
319
+ before do
320
+ allow(File).to receive(:exist?).with(path).and_return(true)
321
+ end
322
+
323
+ context '上書き保存モードの場合' do
324
+ let(:params) { { force: true } }
325
+
326
+ include_examples 'success writing'
327
+ end
328
+
329
+ context '上書き保存モードではない場合' do
330
+ before do
331
+ xhr :delete, :write, params, _session
332
+ end
333
+
334
+ specify 'プログラムをサーバ上から削除しない' do
335
+ expect(SourceCode).to have(1).records
336
+ end
337
+
338
+ specify 'セッションから[:source_code]を削除しない' do
339
+ expect(session[:source_code]).to eq(_session[:source_code])
340
+ end
341
+ end
342
+ end
343
+ end
344
+
345
+ context 'セッションが不正な場合' do
346
+ shared_examples 'raise exception' do
347
+ it {
348
+ expect {
349
+ xhr :delete, :write, params, _session
350
+ }.to raise_exception
351
+ }
352
+ end
353
+
354
+ context 'セッションに[:source_code]がない場合' do
355
+ let(:_session) { {} }
356
+
357
+ include_examples 'raise exception'
358
+ end
359
+
360
+ context 'セッションに[:source_code][:id]がない場合' do
361
+ let(:_session) {
362
+ {
363
+ source_code: {
364
+ digest: source_code.digest,
365
+ }
366
+ }
367
+ }
368
+
369
+ include_examples 'raise exception'
370
+ end
371
+
372
+ context 'セッションに[:source_code][:digest]がない場合' do
373
+ let(:_session) {
374
+ {
375
+ source_code: {
376
+ id: source_code.id,
377
+ }
378
+ }
379
+ }
380
+
381
+ include_examples 'raise exception'
382
+ end
383
+
384
+ context 'セッションの[:source_code][:digest]が不正な場合' do
385
+ let(:_session) {
386
+ {
387
+ source_code: {
388
+ id: source_code.id,
389
+ digest: 'invalid_digest',
390
+ }
391
+ }
392
+ }
393
+
394
+ include_examples 'raise exception'
395
+ end
396
+ end
397
+ end
398
+
399
+ context 'RAILS_ENVがstandalone以外の場合' do
400
+ subject do
401
+ xhr :delete, :write, params, _session
402
+ end
403
+
404
+ it { expect { subject }.to raise_exception }
405
+
406
+ it 'プログラムをサーバ上から削除しない' do
407
+ begin
408
+ subject
409
+ rescue
410
+ expect(SourceCode).to have(1).records
411
+ end
412
+ end
413
+
414
+ it 'セッションから[:source_code]を削除しない' do
415
+ begin
416
+ subject
417
+ rescue
418
+ expect(session[:source_code]).to eq(_session[:source_code])
419
+ end
420
+ end
421
+ end
422
+ end
423
+
424
+ describe 'プログラムを読み込む (POST load)' do
425
+ before do
426
+ post :load, source_code: { file: load_file }
427
+ end
428
+
429
+ describe '正常系' do
430
+ let(:load_file) { fixture_file_upload('files/01.rb', 'text/plain') }
431
+
432
+ it { expect(response).to be_success }
433
+
434
+ it 'アップロードされたプログラムの情報をJSON形式でダウンロードできる' do
435
+ load_file.rewind
436
+ expected = {
437
+ source_code: {
438
+ filename: load_file.original_filename,
439
+ type: load_file.content_type,
440
+ size: load_file.size,
441
+ data: load_file.read.force_encoding('utf-8'),
442
+ }
443
+ }.to_json
444
+ expect(response.body).to be_json_eql(expected)
445
+ end
446
+ end
447
+
448
+ describe '異常系' do
449
+ context '画像をアップロードした場合' do
450
+ let(:load_file) {
451
+ fixture_file_upload('files/favicon.ico', 'application/octet-stream')
452
+ }
453
+
454
+ it { expect(response).to be_success }
455
+
456
+ it 'エラーを返す' do
457
+ info = {
458
+ filename: load_file.original_filename,
459
+ error: 'Rubyのプログラムではありません',
460
+ }
461
+ info.each do |path, value|
462
+ expect(response.body)
463
+ .to include_json(value.to_json).at_path("source_code/#{path}")
464
+ end
465
+ end
466
+ end
467
+ end
468
+ end
469
+ end
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ # 画面をクリックして隠れている車を1台探してみよう
3
+
4
+ require "smalruby"
5
+
6
+ # <プログラム> # <説明>
7
+ canvas1 = Canvas.new # 背景を用意する
8
+ car1 = Character.new(x: 0, y: 148, costume: "car3.png", visible: true)
9
+ # 車を用意する (最初に隠しておく)
10
+
11
+ # <プログラム> # <説明>
12
+ canvas1.on(:start) do # (背景は) 始まったとき
13
+ draw_font(x: 0, y: 0,
14
+ string: "画面をクリックして隠れている車を探してね",
15
+ size: 32) # (0, 0) に (32) の大きさで
16
+ # 「画面をクリックして隠れている車を探してね」の
17
+ # 文章を表示する
18
+ draw_font(x: 0, y: 32,
19
+ string: "ヒント:線の少し上だよ",
20
+ size: 24) # (0, 32) に (24) の大きさで
21
+ # 「ヒント:線の少し上だよ」の
22
+ # 文章を表示する
23
+ box_fill(x1: 0, y1: 200,
24
+ x2: 639, y2: 204,
25
+ color: "red") # (0, 200)-(639, 204) の四角を
26
+ # (white) 色で塗りつぶす
27
+ end
28
+
29
+ # <プログラム> # <説明>
30
+ canvas1.on(:click) do |x, y| # (背景は) クリックしたとき
31
+ canvas2 = Canvas.new(x: x - 9, y: y - 9, width: 20, height: 20)
32
+ # (お絵かき) を用意する
33
+ canvas2.on(:start) do # >> (お絵かきは) 始まったとき
34
+ circle_fill(x: 9, y: 9, r: 9, color: "white")
35
+ # >> (9, 9)、半径9の円をwhite色で塗りつぶす
36
+ sleep(0.5) # >> (0.5) 秒待つ
37
+ vanish # >> (お絵かきを) 取り除く
38
+ end
39
+ end
40
+
41
+ # <プログラム> # <説明>
42
+ car1.on(:start) do # (車は) プログラムが始まったとき
43
+ speed = rand(10..20) # (speed) を (5~10までのランダム) にする
44
+ loop do # ずっと
45
+ move(speed) # >> (speed) 歩動かす
46
+ turn_if_reach_wall # >> もし端に着いたら、跳ね返る
47
+ end
48
+ end
49
+
50
+ # <プログラム> # <説明>
51
+ car1.on(:click) do # (車は) クリックしたとき
52
+ if self.visible == false # もし (隠している) だったら
53
+ self.visible = true # >> 表示する
54
+ else # そうでなければ
55
+ self.visible = false # >> 隠す
56
+ end
57
+ end
Binary file
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ # Specs in this file have access to a helper object that includes
4
+ # the EditorHelper. For example:
5
+ #
6
+ # describe EditorHelper do
7
+ # describe "string concat" do
8
+ # it "concats two strings with spaces" do
9
+ # expect(helper.concat_strings("this","that")).to eq("this that")
10
+ # end
11
+ # end
12
+ # end
13
+ describe EditorHelper do
14
+ end
@@ -0,0 +1,66 @@
1
+ # -*- coding: utf-8 -*-
2
+ require_relative '../spec_helper'
3
+ require 'smalruby_editor'
4
+
5
+ describe SmalrubyEditor do
6
+ describe '.create_home_directory' do
7
+ before(:all) do
8
+ @home_dir = Pathname(Dir.tmpdir).join('.smalruby-editor')
9
+ end
10
+
11
+ shared_examples 'ホームディレクトリを作成する', create_home_directory: true do
12
+ after(:all) do
13
+ FileUtils.rm_rf(@home_dir)
14
+ end
15
+
16
+ it 'ホームディレクトリを作成する' do
17
+ expect(@home_dir).to be_directory
18
+ end
19
+
20
+ describe 'ホームディレクトリ' do
21
+ %w(config db log tmp
22
+ tmp/cache tmp/pids tmp/sessions tmp/sockets).each do |dir|
23
+ it "#{dir}ディレクトリを作成する" do
24
+ expect(@home_dir.join(dir)).to be_directory
25
+ end
26
+ end
27
+
28
+ describe 'configディレクトリ' do
29
+ let(:path) { @home_dir.join('config', 'database.yml') }
30
+
31
+ it 'database.ymlを作成する' do
32
+ expect(path).to be_exist
33
+ end
34
+
35
+ it 'database.ymlの内容が正しい' do
36
+ expect(path.read).to eq(<<-EOS.strip_heredoc)
37
+ standalone:
38
+ adapter: sqlite3
39
+ database: #{@home_dir.join('db', 'standalone.sqlite3')}
40
+ pool: 5
41
+ timeout: 5000
42
+ EOS
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ it '戻り値は作成したホームディレクトリである' do
49
+ expect(SmalrubyEditor.create_home_directory(@home_dir)).to eq(@home_dir)
50
+ end
51
+
52
+ context '引数を指定した場合', create_home_directory: true do
53
+ before(:all) do
54
+ SmalrubyEditor.create_home_directory(@home_dir)
55
+ end
56
+ end
57
+
58
+ describe '引数を指定しない場合は環境変数SMALRUBY_EDITOR_HOMEに従う',
59
+ create_home_directory: true do
60
+ before(:all) do
61
+ ENV['SMALRUBY_EDITOR_HOME'] = @home_dir.to_s
62
+ SmalrubyEditor.create_home_directory
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe SourceCode, 'Rubyのソースコードを表現するモデル' do
5
+ describe 'validation' do
6
+ describe 'filename' do
7
+ specify 'ディレクトリセパレータを含むことはできない' do
8
+ sc = SourceCode.new(filename: '/etc/passwd')
9
+ expect(sc).not_to be_valid
10
+ expect(sc.errors[:filename])
11
+ .to include('includes directory separator(s)')
12
+ end
13
+ end
14
+ end
15
+
16
+ describe '#check_syntax', 'シンタックスをチェックする' do
17
+ let(:source_code) {
18
+ SourceCode.new(data: data)
19
+ }
20
+
21
+ subject { source_code.check_syntax }
22
+
23
+ context 'シンタックスが正しい場合' do
24
+ let(:data) { 'puts "Hello, World!"' }
25
+
26
+ it { should be_empty }
27
+ end
28
+
29
+ context 'シンタックスが正しくない場合' do
30
+ let(:data) { 'puts Hello, World!"' }
31
+
32
+ it { should_not be_empty }
33
+ it {
34
+ should include(row: 1, column: 19,
35
+ message: 'syntax error, unexpected tSTRING_BEG,' \
36
+ " expecting keyword_do or '{' or '('")
37
+ }
38
+ it {
39
+ should include(row: 1, column: 0,
40
+ message: 'unterminated string meets end of file')
41
+ }
42
+ end
43
+ end
44
+
45
+ describe '#digest', 'プログラムのハッシュ値を計算する' do
46
+ let(:data) { 'puts "Hello, World!"' }
47
+ let(:source_code) {
48
+ SourceCode.new(data: data)
49
+ }
50
+
51
+ subject { source_code.digest }
52
+
53
+ it { should eq(Digest::SHA256.hexdigest(data)) }
54
+ end
55
+ end