smalruby-editor 0.0.5 → 0.0.6

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +2 -1
  4. data/.rubocop.yml +18 -0
  5. data/.travis.yml +24 -23
  6. data/LEGAL +13 -0
  7. data/README.rdoc +1 -0
  8. data/Rakefile +3 -0
  9. data/app/assets/javascripts/application.js +1 -1
  10. data/app/assets/javascripts/editor.js.coffee +60 -15
  11. data/app/assets/stylesheets/application.css +1 -2
  12. data/app/assets/stylesheets/flatstrap-custom.css.scss +2 -0
  13. data/app/controllers/editor_controller.rb +0 -24
  14. data/app/controllers/source_codes_controller.rb +67 -0
  15. data/app/models/source_code.rb +42 -0
  16. data/app/views/editor/index.html.erb +5 -3
  17. data/bin/smalruby-editor +11 -0
  18. data/config/application.rb +8 -20
  19. data/config/boot.rb +3 -0
  20. data/config/environments/development.rb +2 -1
  21. data/config/environments/production.rb +12 -6
  22. data/config/environments/standalone.rb +3 -2
  23. data/config/environments/test.rb +14 -4
  24. data/config/initializers/backtrace_silencers.rb +4 -2
  25. data/config/initializers/session_store.rb +2 -1
  26. data/config/initializers/wrap_parameters.rb +2 -1
  27. data/config/routes.rb +10 -6
  28. data/config/unicorn.rb +7 -6
  29. data/db/migrate/20131216121603_create_source_codes.rb +9 -0
  30. data/db/migrate/20131219045113_add_filename_to_source_code.rb +5 -0
  31. data/db/schema.rb +8 -1
  32. data/lib/smalruby_editor.rb +29 -15
  33. data/lib/smalruby_editor/version.rb +1 -1
  34. data/lib/tasks/rspec.rake +2 -2
  35. data/lib/tasks/rubocop.rake +3 -0
  36. data/public/fonts/FontAwesome.otf +0 -0
  37. data/public/fonts/fontawesome-webfont.eot +0 -0
  38. data/public/fonts/fontawesome-webfont.ttf +0 -0
  39. data/public/fonts/fontawesome-webfont.woff +0 -0
  40. data/smalruby-editor.gemspec +3 -3
  41. data/spec/acceptance/readme.md +3 -0
  42. data/spec/acceptance/text_editor/base.feature +24 -0
  43. data/spec/acceptance/text_editor/check.feature +20 -0
  44. data/spec/acceptance/text_editor/load.feature +74 -0
  45. data/spec/acceptance/text_editor/save.feature +31 -0
  46. data/spec/controllers/editor_controller_spec.rb +2 -63
  47. data/spec/controllers/source_codes_controller_spec.rb +296 -0
  48. data/spec/models/source_code_spec.rb +44 -0
  49. data/spec/spec_helper.rb +123 -65
  50. data/spec/steps/ace_steps.rb +60 -0
  51. data/spec/steps/global_variable.rb +39 -0
  52. data/spec/steps/text_editor_steps.rb +160 -0
  53. data/spec/support/capybara.rb +17 -0
  54. metadata +49 -19
  55. data/spec/acceptance/editor.feature +0 -68
  56. data/spec/steps/editor_steps.rb +0 -123
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2620d7583988f8aefecfcc4f43372e8004f857b0
4
- data.tar.gz: 4f036dff3d6161cba3afeb944f6b01bd1c56aac1
3
+ metadata.gz: d71a9e4754ddc023b99130576187b13e97cca3ce
4
+ data.tar.gz: 4ed1b62b217727d2a96bfa9c337049a8850e2684
5
5
  SHA512:
6
- metadata.gz: 08e39ce807c337397b59f6545dd9a61a435c67df594b14803520f38ac2edf19010d8c76ee53b925e592bf1f0beaf82b15cc713de292843aa5ad484855cb4c13f
7
- data.tar.gz: 54a24bf5fb9714e12ef9721dd5ce0079470758f6774c3591a4459814608084df3215e575541bd317dae91f11dbcb1529ed874dca25e46d3d056259aa623e8237
6
+ metadata.gz: bb60b2b55e43a4403b29441647b3eae78b6ae563be42d2b84c5c6f4971eccd10875fe131bac0013042d641a0aa5165b564472cf1cc3db5039fadb54ac688e9f5
7
+ data.tar.gz: 77272e287ef54a97a9c8fdf70e9da1c02a7a62eee9cf5e05df6413b0ae4285b6686616aa35020ebe64735e1ead930cb80e1d00840f193c4a24250bc49661f237
data/.gitignore CHANGED
@@ -22,3 +22,4 @@
22
22
  /.env
23
23
  /coverage
24
24
  /pkg
25
+ /features
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --color
2
2
  --format documentation
3
- -r turnip/rspec
3
+ --drb
4
+ -r turnip/rspec
data/.rubocop.yml ADDED
@@ -0,0 +1,18 @@
1
+ AllCops:
2
+ Excludes:
3
+ - db/seeds.rb
4
+
5
+ AsciiComments:
6
+ Enabled: false
7
+
8
+ # メソッドの戻り値としてブロックの値を使う場合にもエラーになるため無効
9
+ # にしている
10
+ Blocks:
11
+ Enabled: false
12
+
13
+ Documentation:
14
+ Enabled: false
15
+
16
+ # WindowsだとEndOfLine copが動作しないため無効にしている
17
+ EndOfLine:
18
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,23 +1,24 @@
1
- language: ruby
2
-
3
- rvm:
4
- - 2.0.0
5
-
6
- before_script:
7
- - cp config/database.yml.travis config/database.yml
8
- - mysql -e 'create database myapp_test;'
9
-
10
- script:
11
- - export SECRET_KEY_BASE='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
12
- - export COVERALLS='1'
13
- - RAILS_ENV=test bundle exec rake db:migrate --trace
14
- - bundle exec rake db:test:prepare
15
- - bundle exec rake
16
-
17
- deploy:
18
- provider: heroku
19
- api_key:
20
- secure: HqZ7FylThjaB3XguCZJbccu7dB8CvWIWFlZpWLLfJwfUkjvoEC1F6VPFakFbwjLXLsvaKlYLakzL+bhaLnxu+HyeNmCrvpIRR2j8EuHmSkxdWrlxAZRV2ojHuDpZuVNaEzd7YtcBCoPiTvqnxWzhAfzZWbPrZfCdA1f+5t5/So0=
21
- app: smalruby
22
- on:
23
- repo: smalruby/smalruby-editor
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.0.0
5
+
6
+ before_script:
7
+ - cp config/database.yml.travis config/database.yml
8
+ - mysql -e 'create database myapp_test;'
9
+
10
+ script:
11
+ - export SECRET_KEY_BASE='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
12
+ - export COVERALLS='1'
13
+ - RAILS_ENV=test bundle exec rake db:migrate --trace
14
+ - bundle exec rake db:test:prepare
15
+ - bundle exec rake
16
+
17
+ deploy:
18
+ provider: heroku
19
+ api_key:
20
+ secure: HqZ7FylThjaB3XguCZJbccu7dB8CvWIWFlZpWLLfJwfUkjvoEC1F6VPFakFbwjLXLsvaKlYLakzL+bhaLnxu+HyeNmCrvpIRR2j8EuHmSkxdWrlxAZRV2ojHuDpZuVNaEzd7YtcBCoPiTvqnxWzhAfzZWbPrZfCdA1f+5t5/So0=
21
+ app: smalruby
22
+ on:
23
+ repo: smalruby/smalruby-editor
24
+ run: "rake db:migrate"
data/LEGAL ADDED
@@ -0,0 +1,13 @@
1
+ LEGAL NOTICE INFORMATION
2
+ ------------------------
3
+
4
+ All the files in this distribution are covered under either the
5
+ smalruby-editor's license (see the file LICENSE) except some files
6
+ mentioned below.
7
+
8
+ public/fonts/FontAwesome.otf, public/fonts/fontawesome-webfont.eot,
9
+ public/fonts/fontawesome-webfont.ttf,
10
+ public/fonts/fontawesome-webfont.woff:
11
+
12
+ These's license is SIL Open Font License (OFL) 1.1:
13
+ http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL .
data/README.rdoc CHANGED
@@ -1,5 +1,6 @@
1
1
  == smalruby-editor
2
2
 
3
+ {<img src="https://badge.fury.io/rb/smalruby-editor.png" alt="Gem Version" />}[http://badge.fury.io/rb/smalruby-editor]
3
4
  {<img src="https://travis-ci.org/smalruby/smalruby-editor.png?branch=master" alt="Build Status" />}[https://travis-ci.org/smalruby/smalruby-editor]
4
5
  {<img src="https://coveralls.io/repos/smalruby/smalruby-editor/badge.png?branch=master" alt="Coverage Status" />}[https://coveralls.io/r/smalruby/smalruby-editor?branch=master]
5
6
  {<img src="https://codeclimate.com/github/smalruby/smalruby-editor.png" />}[https://codeclimate.com/github/smalruby/smalruby-editor]
data/Rakefile CHANGED
@@ -4,3 +4,6 @@
4
4
  require File.expand_path('../config/application', __FILE__)
5
5
 
6
6
  SmalrubyEditor::Application.load_tasks
7
+
8
+ task(:default).clear
9
+ task default: [:rubocop, :spec]
@@ -14,7 +14,7 @@
14
14
  //= require jquery_ujs
15
15
  //= require turbolinks
16
16
  //= require ace/ace
17
- //= require ace/theme-clouds.js
17
+ //= require ace/theme-github.js
18
18
  //= require ace/mode-ruby.js
19
19
  //= require bootstrap.js
20
20
  //= require jquery-fileupload/basic
@@ -2,11 +2,22 @@
2
2
  # All this logic will automatically be available in application.js.
3
3
  # You can use CoffeeScript in this file: http://coffeescript.org/
4
4
 
5
+ changed = false
6
+
5
7
  $ ->
8
+ saving = false
9
+
6
10
  textEditor = ace.edit('text-editor')
7
- textEditor.setTheme('ace/theme/clouds')
11
+ textEditor.setTheme('ace/theme/github')
8
12
  textEditor.setShowInvisibles(true)
9
13
 
14
+ textEditor.focus()
15
+ textEditor.gotoLine(0, 0)
16
+
17
+ textEditor.on('change', (e) ->
18
+ changed = true
19
+ )
20
+
10
21
  session = textEditor.getSession()
11
22
  session.setMode('ace/mode/ruby')
12
23
  session.setTabSize(2)
@@ -20,18 +31,40 @@ $ ->
20
31
  e.preventDefault()
21
32
  false
22
33
 
23
- $('#save-button').click ->
34
+ $('#check-button').click (e) ->
35
+ e.preventDefault()
36
+ data =
37
+ source_code:
38
+ data: session.getDocument().getValue()
39
+ success = (data, textStatus, jqXHR) ->
40
+ for errorInfo in data
41
+ do (errorInfo) ->
42
+ msg = $('<div class="alert alert-error" style="display: none">')
43
+ .append('<button type="button" class="close" data-dismiss="alert">×</button>')
44
+ .append('<h4><i class="icon-exclamation-sign"></i>エラー</h4>')
45
+ .append("#{errorInfo.row}行")
46
+ if errorInfo.column > 0
47
+ msg.append("、#{errorInfo.column}文字")
48
+ msg.append(": #{errorInfo.message}")
49
+ $('#messages').append(msg)
50
+ msg.fadeIn('slow')
51
+ $.post('/source_codes/check', data, success, 'json')
52
+
53
+ $('#save-button').click (e) ->
54
+ e.preventDefault()
24
55
  filename = $.trim($('#filename').val())
25
56
  if filename.length <= 0
26
57
  $('#filename').focus()
27
58
  else
28
59
  data =
29
- filename: filename
30
- source: session.getDocument().getValue()
31
- location.href = '/editor/save_file?' + $.param(data)
32
-
33
- $('#load-button').click ->
34
- $(@).parent().find('input[name="load_file"]').click()
60
+ source_code:
61
+ filename: filename
62
+ data: session.getDocument().getValue()
63
+ success = (data, textStatus, jqXHR) ->
64
+ saving = true
65
+ changed = false
66
+ $('#download-link').click()
67
+ $.post('/source_codes/', data, success, 'json')
35
68
 
36
69
  $('#filename').keypress (e) ->
37
70
  e = window.event if !e
@@ -41,20 +74,32 @@ $ ->
41
74
  else
42
75
  true
43
76
 
77
+ $('#load-button').click (e) ->
78
+ e.preventDefault()
79
+ if changed
80
+ return unless confirm('まだセーブしていないのでロードするとプログラムが消えてしまうよ!それでもロードしますか?')
81
+ $(@).parent().find('input[name="source_code[file]"]').click()
82
+
44
83
  $('#file-form').fileupload(
45
84
  dataType: 'json'
46
- add: (e, data) ->
47
- data.submit()
48
85
  done: (e, data) ->
49
- file = data.result
50
- if file.error
86
+ info = data.result.source_code
87
+ if info.error
51
88
  msg = $('<div class="alert alert-error" style="display: none">')
52
89
  .append('<button type="button" class="close" data-dismiss="alert">×</button>')
53
90
  .append('<h4><i class="icon-exclamation-sign"></i>エラー</h4>')
54
- .append(file.name + 'は' + file.error)
91
+ .append(info.filename + 'は' + info.error)
55
92
  $('#messages').append(msg)
56
93
  msg.fadeIn('slow').delay(5000).fadeOut('slow')
57
94
  else
58
- $('#filename').val(file.name)
59
- session.getDocument().setValue(file.source)
95
+ $('#filename').val(info.filename)
96
+ session.getDocument().setValue(info.data)
97
+ changed = false
60
98
  )
99
+
100
+ window.onbeforeunload = (event) ->
101
+ if !saving && session.getDocument().getValue().length > 0
102
+ return '作成中のプログラムが消えてしまいます。'
103
+ else
104
+ saving = false
105
+ return
@@ -8,8 +8,7 @@
8
8
  * You're free to add application-wide styles to this file and they'll appear at the top of the
9
9
  * compiled file, but it's generally better to create a new file per style scope.
10
10
  *
11
- *= require flatstrap
12
- *= require font-awesome
11
+ *= require flatstrap-custom
13
12
  *= require_self
14
13
  *= require_tree .
15
14
  */
@@ -0,0 +1,2 @@
1
+ $fontAwesomePath: "/fonts";
2
+ @import "flatstrap";
@@ -1,29 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- require 'nkf'
3
-
4
2
  class EditorController < ApplicationController
5
3
  def index
6
4
  end
7
-
8
- def save_file
9
- send_data(params[:source], filename: params[:filename],
10
- disposition: 'attachment', type: 'text/plain; charset=utf-8')
11
- end
12
-
13
- def load_file
14
- f = params['load_file']
15
- mime_type = MIME.check(f.path)
16
- content_type = mime_type.try(:content_type) || f.content_type
17
- res = {
18
- name: f.original_filename,
19
- type: content_type,
20
- size: f.size,
21
- }
22
- if /\Atext\/plain/ =~ content_type
23
- res[:source] = NKF.nkf('-w', f.read)
24
- else
25
- res[:error] = 'Rubyのプログラムではありません'
26
- end
27
- render json: res, content_type: request.format
28
- end
29
5
  end
@@ -0,0 +1,67 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'nkf'
3
+
4
+ class SourceCodesController < ApplicationController
5
+ def check
6
+ render json: SourceCode.new(source_code_params).check_syntax
7
+ end
8
+
9
+ def create
10
+ source_code = SourceCode.create!(source_code_params)
11
+ session[:source_code] = {
12
+ id: source_code.id,
13
+ digest: source_code.digest,
14
+ }
15
+ render json: { source_code: { id: source_code.id } }
16
+ end
17
+
18
+ def download
19
+ source_code = SourceCode.find(session[:source_code][:id])
20
+ unless source_code.digest == session[:source_code][:digest]
21
+ fail ActiveRecord::RecordNotFound
22
+ end
23
+
24
+ send_data(source_code.data,
25
+ filename: encode_filename(source_code.filename),
26
+ disposition: 'attachment',
27
+ type: 'text/plain; charset=utf-8')
28
+
29
+ source_code.destroy
30
+
31
+ session[:source_code] = nil
32
+ end
33
+
34
+ def load
35
+ f = params[:source_code][:file]
36
+ info = get_file_info(f)
37
+ if /\Atext\/plain/ =~ info[:type]
38
+ info[:data] = NKF.nkf('-w', f.read)
39
+ else
40
+ info[:error] = 'Rubyのプログラムではありません'
41
+ end
42
+
43
+ render json: { source_code: info }, content_type: request.format
44
+ end
45
+
46
+ private
47
+
48
+ def source_code_params
49
+ params.require(:source_code).permit(:data, :filename)
50
+ end
51
+
52
+ def get_file_info(file)
53
+ {
54
+ filename: file.original_filename,
55
+ type: MIME.check(file.path).try(:content_type) || file.content_type,
56
+ size: file.size,
57
+ }
58
+ end
59
+
60
+ def encode_filename(filename)
61
+ if request.env['HTTP_USER_AGENT'] =~ /MSIE|Trident/
62
+ return ERB::Util.url_encode(filename)
63
+ else
64
+ filename
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'tempfile'
4
+ require 'open3'
5
+ require 'digest/sha2'
6
+
7
+ # ソースコードを表現するモデル
8
+ class SourceCode < ActiveRecord::Base
9
+ validates :filename, presence: true
10
+ validates :data, presence: true, allow_blank: true
11
+
12
+ # シンタックスをチェックする
13
+ def check_syntax
14
+ _, stderr_str, status = *open3_capture3_ruby_c
15
+ return [] if status.success?
16
+
17
+ stderr_str.lines.each.with_object([]) { |line, res|
18
+ if (md = /^.*:(\d+): (.*)$/.match(line))
19
+ res << { row: md[1].to_i, column: 0, message: md[2] }
20
+ elsif (md = /( +)\^$/.match(line))
21
+ res[-1][:column] = md[1].length
22
+ end
23
+ }
24
+ end
25
+
26
+ # ハッシュ値を計算する
27
+ def digest
28
+ Digest::SHA256.hexdigest(data)
29
+ end
30
+
31
+ private
32
+
33
+ def open3_capture3_ruby_c
34
+ tempfile = Tempfile.new('smalruby-editor')
35
+ tempfile.write(data)
36
+ path = tempfile.path
37
+ tempfile.close
38
+ ruby_cmd = File.join(RbConfig::CONFIG['bindir'],
39
+ RbConfig::CONFIG['RUBY_INSTALL_NAME'])
40
+ Open3.capture3("#{ruby_cmd} -c #{path}")
41
+ end
42
+ end
@@ -4,11 +4,13 @@
4
4
  <li class="active"><a id="ruby-tab" href="#">Ruby</a></li>
5
5
  </ul>
6
6
 
7
- <%= form_tag(editor_load_file_path, id: "file-form", class: "navbar-form pull-right", method: "post", multipart: true) do %>
7
+ <%= form_tag(source_codes_load_path, id: "file-form", class: "navbar-form pull-right", method: "post", multipart: true) do %>
8
+ <button id="check-button" type="button" class="btn btn-primary">チェック</button>
8
9
  <input id="filename" type="text" class="span4" placeholder="プログラムの名前を入れてね(例:01.rb)">
9
10
  <button id="save-button" type="button" class="btn btn-primary">セーブ</button>
10
- <a id="load-button" class="btn btn-primary">ロード</a>
11
- <input id="load-file" type="file" name="load_file" style="display: none">
11
+ <%= link_to '', source_codes_download_path, id: 'download-link', style: 'display: none', 'data-method' => 'delete' %>
12
+ <button id="load-button" class="btn btn-primary">ロード</button>
13
+ <input id="load-file" type="file" name="source_code[file]" style="display: none">
12
14
  <% end %>
13
15
  </div>
14
16
  </div>
data/bin/smalruby-editor CHANGED
@@ -17,6 +17,7 @@ require 'smalruby_editor'
17
17
  Dir.chdir(File.expand_path('../../', APP_PATH))
18
18
  require 'rails/commands/server'
19
19
 
20
+ # rubocop:disable all
20
21
  module Rails
21
22
  class Server < ::Rack::Server
22
23
  def start
@@ -35,6 +36,15 @@ module Rails
35
36
  console.level = Rails.logger.level
36
37
 
37
38
  Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
39
+
40
+ if ActiveRecord::Migrator.needs_migration?
41
+ ActiveRecord::Migration.verbose = true
42
+ begin
43
+ ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths)
44
+ ensure
45
+ ActiveRecord::Migration.verbose = false
46
+ end
47
+ end
38
48
  end
39
49
 
40
50
  uri = "http://localhost:#{options[:Port]}"
@@ -71,3 +81,4 @@ Rails::Server.new.tap do |server|
71
81
  Dir.chdir(Rails.application.root)
72
82
  server.start
73
83
  end
84
+ # rubocop:enable all