smalruby-editor 0.0.5 → 0.0.6

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.

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