smalruby-editor 0.0.12 → 0.1.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -0
- data/.travis.yml +2 -0
- data/LEGAL +32 -0
- data/Rakefile +1 -1
- data/app/assets/demos/default.xml +126 -0
- data/app/assets/demos/rgb_led_anode.xml +83 -0
- data/app/assets/images/favicon.ico +0 -0
- data/app/assets/javascripts/application.js +18 -1
- data/app/assets/javascripts/block_mode.js.coffee.erb +10 -0
- data/app/assets/javascripts/blocks/blockly.js.coffee.erb +34 -0
- data/app/assets/javascripts/blocks/character.js.coffee.erb +76 -0
- data/app/assets/javascripts/blocks/control.js.coffee.erb +180 -0
- data/app/assets/javascripts/blocks/data.js.coffee.erb +6 -0
- data/app/assets/javascripts/blocks/etc.js.coffee.erb +6 -0
- data/app/assets/javascripts/blocks/events.js.coffee.erb +82 -0
- data/app/assets/javascripts/blocks/hardware.js.coffee.erb +313 -0
- data/app/assets/javascripts/blocks/looks.js.coffee.erb +163 -0
- data/app/assets/javascripts/blocks/motion.js.coffee.erb +297 -0
- data/app/assets/javascripts/blocks/operators.js.coffee.erb +279 -0
- data/app/assets/javascripts/blocks/pen.js.coffee.erb +6 -0
- data/app/assets/javascripts/blocks/ruby.js.coffee.erb +74 -0
- data/app/assets/javascripts/blocks/sensing.js.coffee.erb +241 -0
- data/app/assets/javascripts/blocks/sound.js.coffee.erb +75 -0
- data/{public/favicon.ico → app/assets/javascripts/collections/.keep} +0 -0
- data/app/assets/javascripts/collections/character_set.js.coffee +12 -0
- data/app/assets/javascripts/generators/ruby.js.coffee.erb +188 -0
- data/app/assets/javascripts/models/.keep +0 -0
- data/app/assets/javascripts/models/character.js.coffee +66 -0
- data/app/assets/javascripts/models/scene.js.coffee +5 -0
- data/app/assets/javascripts/models/source_code.js.coffee +64 -0
- data/app/assets/javascripts/routers/.keep +0 -0
- data/app/assets/javascripts/ruby_mode.js.coffee.erb +12 -0
- data/app/assets/javascripts/smalruby.js.coffee +97 -0
- data/app/assets/javascripts/views/.keep +0 -0
- data/app/assets/javascripts/views/character_modal_view.js.coffee +148 -0
- data/app/assets/javascripts/views/character_selector_view.js.coffee +109 -0
- data/app/assets/javascripts/views/main_menu_view.js.coffee +264 -0
- data/app/assets/stylesheets/editor.css.scss +318 -2
- data/app/assets/stylesheets/toolbox.css.scss.erb +62 -0
- data/app/assets/templates/.keep +0 -0
- data/app/controllers/application_controller.rb +19 -0
- data/app/controllers/editor_controller.rb +4 -0
- data/app/controllers/source_codes_controller.rb +8 -2
- data/app/helpers/application_helper.rb +1 -0
- data/app/helpers/editor_helper.rb +46 -0
- data/app/models/source_code.rb +49 -6
- data/app/views/editor/_block_tab.html.haml +53 -0
- data/app/views/editor/_character_modal.html.haml +53 -0
- data/app/views/editor/_toolbox.html.haml +384 -0
- data/app/views/editor/demo.html.erb +16 -0
- data/app/views/editor/index.html.haml +60 -0
- data/app/views/layouts/application.html.erb +7 -0
- data/config/application.rb +1 -0
- data/config/initializers/teaspoon.rb +79 -0
- data/config/routes.rb +4 -0
- data/lib/smalruby_editor/version.rb +1 -1
- data/lib/tasks/gem.rake +7 -4
- data/lib/tasks/release.rake +43 -0
- data/public/apple-touch-icon.png +0 -0
- data/public/blockly/media/1x1.gif +0 -0
- data/public/blockly/media/click.mp3 +0 -0
- data/public/blockly/media/click.ogg +0 -0
- data/public/blockly/media/click.wav +0 -0
- data/public/blockly/media/delete.mp3 +0 -0
- data/public/blockly/media/delete.ogg +0 -0
- data/public/blockly/media/delete.wav +0 -0
- data/public/blockly/media/handclosed.cur +0 -0
- data/public/blockly/media/handopen.cur +0 -0
- data/public/blockly/media/quote0.png +0 -0
- data/public/blockly/media/quote1.png +0 -0
- data/public/blockly/media/trashbody.png +0 -0
- data/public/blockly/media/trashlid.png +0 -0
- data/public/blockly/media/tree.png +0 -0
- data/public/browserconfig.xml +1 -0
- data/public/large.png +0 -0
- data/public/smalruby/assets/ball1.png +0 -0
- data/public/smalruby/assets/ball2.png +0 -0
- data/public/smalruby/assets/ball3.png +0 -0
- data/public/smalruby/assets/ball4.png +0 -0
- data/public/smalruby/assets/ball5.png +0 -0
- data/public/smalruby/assets/ball6.png +0 -0
- data/public/smalruby/assets/car1.png +0 -0
- data/public/smalruby/assets/car2.png +0 -0
- data/public/smalruby/assets/car3.png +0 -0
- data/public/smalruby/assets/car4.png +0 -0
- data/public/smalruby/assets/cat1.png +0 -0
- data/public/smalruby/assets/cat2.png +0 -0
- data/public/smalruby/assets/cat3.png +0 -0
- data/public/smalruby/assets/frog1.png +0 -0
- data/public/smalruby/assets/piano_do.wav +0 -0
- data/public/smalruby/assets/piano_do_2.wav +0 -0
- data/public/smalruby/assets/piano_fa.wav +0 -0
- data/public/smalruby/assets/piano_mi.wav +0 -0
- data/public/smalruby/assets/piano_ra.wav +0 -0
- data/public/smalruby/assets/piano_re.wav +0 -0
- data/public/smalruby/assets/piano_si.wav +0 -0
- data/public/smalruby/assets/piano_so.wav +0 -0
- data/public/square.png +0 -0
- data/public/tiny.png +0 -0
- data/public/wide.png +0 -0
- data/smalruby-editor.gemspec +4 -0
- data/spec/acceptance/block_mode/blocks/character/new.feature +136 -0
- data/spec/acceptance/block_mode/blocks/control/await.feature +20 -0
- data/spec/acceptance/block_mode/blocks/control/await_until.feature +39 -0
- data/spec/acceptance/block_mode/blocks/control/break.feature +20 -0
- data/spec/acceptance/block_mode/blocks/control/if.feature +68 -0
- data/spec/acceptance/block_mode/blocks/control/if_else.feature +78 -0
- data/spec/acceptance/block_mode/blocks/control/loop.feature +45 -0
- data/spec/acceptance/block_mode/blocks/control/next.feature +20 -0
- data/spec/acceptance/block_mode/blocks/control/redo.feature +20 -0
- data/spec/acceptance/block_mode/blocks/control/sleep.feature +41 -0
- data/spec/acceptance/block_mode/blocks/control/times.feature +72 -0
- data/spec/acceptance/block_mode/blocks/control/until.feature +68 -0
- data/spec/acceptance/block_mode/blocks/events/on_click.feature +75 -0
- data/spec/acceptance/block_mode/blocks/events/on_hit.feature +83 -0
- data/spec/acceptance/block_mode/blocks/events/on_key_push_or_down.feature +171 -0
- data/spec/acceptance/block_mode/blocks/events/on_start.feature +75 -0
- data/spec/acceptance/block_mode/blocks/hardware/init_hardware.feature +44 -0
- data/spec/acceptance/block_mode/blocks/hardware/led_off.feature +75 -0
- data/spec/acceptance/block_mode/blocks/hardware/led_on.feature +75 -0
- data/spec/acceptance/block_mode/blocks/hardware/on_sensor_change.feature +81 -0
- data/spec/acceptance/block_mode/blocks/hardware/rgb_led_off.feature +81 -0
- data/spec/acceptance/block_mode/blocks/hardware/rgb_led_on.feature +87 -0
- data/spec/acceptance/block_mode/blocks/hardware/sensor_value.feature +100 -0
- data/spec/acceptance/block_mode/blocks/looks/hide.feature +69 -0
- data/spec/acceptance/block_mode/blocks/looks/say.feature +106 -0
- data/spec/acceptance/block_mode/blocks/looks/show.feature +69 -0
- data/spec/acceptance/block_mode/blocks/looks/vanish.feature +69 -0
- data/spec/acceptance/block_mode/blocks/motion/change_x_by.feature +81 -0
- data/spec/acceptance/block_mode/blocks/motion/change_y_by.feature +81 -0
- data/spec/acceptance/block_mode/blocks/motion/move.feature +81 -0
- data/spec/acceptance/block_mode/blocks/motion/reach_wall.feature +98 -0
- data/spec/acceptance/block_mode/blocks/motion/rotate_left.feature +81 -0
- data/spec/acceptance/block_mode/blocks/motion/rotate_right.feature +81 -0
- data/spec/acceptance/block_mode/blocks/motion/self_angle.feature +92 -0
- data/spec/acceptance/block_mode/blocks/motion/self_x.feature +92 -0
- data/spec/acceptance/block_mode/blocks/motion/self_y.feature +92 -0
- data/spec/acceptance/block_mode/blocks/motion/set_angle.feature +81 -0
- data/spec/acceptance/block_mode/blocks/motion/set_x.feature +81 -0
- data/spec/acceptance/block_mode/blocks/motion/set_x_y.feature +95 -0
- data/spec/acceptance/block_mode/blocks/motion/set_y.feature +81 -0
- data/spec/acceptance/block_mode/blocks/motion/turn.feature +69 -0
- data/spec/acceptance/block_mode/blocks/motion/turn_if_reach_wall.feature +69 -0
- data/spec/acceptance/block_mode/blocks/sensing/character_property.feature +114 -0
- data/spec/acceptance/block_mode/blocks/sensing/hit.feature +110 -0
- data/spec/acceptance/block_mode/blocks/sensing/input_key_push_or_down.feature +91 -0
- data/spec/acceptance/block_mode/blocks/sensing/input_mouse_pos_x.feature +39 -0
- data/spec/acceptance/block_mode/blocks/sensing/input_mouse_pos_y.feature +39 -0
- data/spec/acceptance/block_mode/blocks/sensing/input_mouse_push_or_down.feature +91 -0
- data/spec/acceptance/block_mode/blocks/sensing/time_now.feature +43 -0
- data/spec/acceptance/block_mode/blocks/sound/play.feature +81 -0
- data/spec/acceptance/block_mode/demo.feature +49 -0
- data/spec/acceptance/{text_editor → ruby_mode}/base.feature +11 -2
- data/spec/acceptance/{standalone → ruby_mode}/check.feature +8 -9
- data/spec/acceptance/ruby_mode/download.feature +33 -0
- data/spec/acceptance/{text_editor → ruby_mode}/load.feature +13 -13
- data/spec/acceptance/standalone/run.feature +17 -0
- data/spec/acceptance/standalone/save.feature +6 -6
- data/spec/helpers/editor_helper_spec.rb +110 -10
- data/spec/javascripts/collections/character_set_spec.coffee +41 -0
- data/spec/javascripts/models/character_spec.coffee +146 -0
- data/spec/javascripts/models/scene_spec.coffee +15 -0
- data/spec/javascripts/spec_helper.js +29 -0
- data/spec/spec_helper.rb +3 -8
- data/spec/steps/block_mode_steps.rb +37 -0
- data/spec/steps/global_variable.rb +30 -6
- data/spec/steps/text_editor_steps.rb +20 -2
- data/spec/teaspoon_env.rb +46 -0
- data/vendor/assets/javascripts/blockly/blockly_compressed.js +992 -0
- data/vendor/assets/javascripts/blockly/blocks_compressed.js +129 -0
- data/vendor/assets/javascripts/blockly/msg/js/ja.js +377 -0
- data/vendor/assets/javascripts/jquery.blockUI.js +619 -0
- metadata +290 -23
- data/app/assets/javascripts/editor.js.coffee.erb +0 -137
- data/app/views/editor/index.html.erb +0 -22
- data/spec/acceptance/text_editor/check.feature +0 -29
- data/spec/acceptance/text_editor/save.feature +0 -34
- data/spec/support/assets.rb +0 -18
@@ -4,11 +4,11 @@
|
|
4
4
|
@standalone
|
5
5
|
機能: Save - プログラムのセーブ(standaloneモード)
|
6
6
|
シナリオ: セーブボタンを押してローカルマシンにプログラムを保存できる
|
7
|
-
前提 "
|
7
|
+
前提 "Ruby" タブを表示する
|
8
8
|
かつ テキストエディタに "puts 'Hello, World!'" を入力済みである
|
9
9
|
かつ プログラムの名前に "01.rb" を指定する
|
10
10
|
|
11
|
-
もし "セーブボタン" をクリックする
|
11
|
+
もし サブメニューの "セーブボタン" をクリックする
|
12
12
|
かつ JavaScriptによるリクエストが終わるまで待つ
|
13
13
|
|
14
14
|
ならば ホームディレクトリに "01.rb" が存在すること
|
@@ -16,12 +16,12 @@
|
|
16
16
|
かつ "メッセージ" に "セーブしました" を含むこと
|
17
17
|
|
18
18
|
シナリオ: ローカルマシンに同じ名前のプログラムがある状態でセーブボタンを押して上書き保存する
|
19
|
-
前提 "
|
19
|
+
前提 "Ruby" タブを表示する
|
20
20
|
かつ ホームディレクトリに "puts 'Hello, World!'" という内容の "01.rb" が存在する
|
21
21
|
かつ テキストエディタに "n = 0" を入力済みである
|
22
22
|
かつ プログラムの名前に "01.rb" を指定する
|
23
23
|
|
24
|
-
もし "セーブボタン" をクリックする
|
24
|
+
もし サブメニューの "セーブボタン" をクリックする
|
25
25
|
かつ JavaScriptによるリクエストが終わるまで待つ
|
26
26
|
かつ JavaScriptによるリクエストが終わるまで待つ
|
27
27
|
|
@@ -30,13 +30,13 @@
|
|
30
30
|
かつ ホームディレクトリの "01.rb" の内容が "n = 0" であること
|
31
31
|
|
32
32
|
シナリオ: ローカルマシンに同じ名前のプログラムがある状態でセーブボタンを押すが、キャンセルして上書き保存をしない
|
33
|
-
前提 "
|
33
|
+
前提 "Ruby" タブを表示する
|
34
34
|
かつ ホームディレクトリに "puts 'Hello, World!'" という内容の "01.rb" が存在する
|
35
35
|
かつ テキストエディタに "n = 0" を入力済みである
|
36
36
|
かつ プログラムの名前に "01.rb" を指定する
|
37
37
|
かつ 確認ダイアログをキャンセルするようにしておく
|
38
38
|
|
39
|
-
もし "セーブボタン" をクリックする
|
39
|
+
もし サブメニューの "セーブボタン" をクリックする
|
40
40
|
かつ JavaScriptによるリクエストが終わるまで待つ
|
41
41
|
かつ JavaScriptによるリクエストが終わるまで待つ
|
42
42
|
|
@@ -1,14 +1,114 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require 'spec_helper'
|
2
3
|
|
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
4
|
describe EditorHelper do
|
5
|
+
INCLUDED_HTML_STRING = '"><script>alert("hello")</script><"'
|
6
|
+
|
7
|
+
shared_context 'name include html', name_include_html: true do
|
8
|
+
let(:name) { INCLUDED_HTML_STRING }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#toolbox_character_field' do
|
12
|
+
subject { toolbox_character_field(name) }
|
13
|
+
|
14
|
+
let(:name) { 'VAR' }
|
15
|
+
|
16
|
+
it { should be_html_safe }
|
17
|
+
it { should include(%(<field name="#{h name}">char1</field>)) }
|
18
|
+
|
19
|
+
context '名前にタグを含む場合', name_include_html: true do
|
20
|
+
it { should include(%(<field name="#{h name}">char1</field>)) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#toolbox_key_field' do
|
25
|
+
subject { toolbox_key_field(name, value) }
|
26
|
+
|
27
|
+
let(:name) { 'KEY' }
|
28
|
+
let(:value) { 'K_A' }
|
29
|
+
|
30
|
+
it { should be_html_safe }
|
31
|
+
it { should include(%(<field name="#{h name}">#{h value}</field>)) }
|
32
|
+
|
33
|
+
context '名前にタグを含む場合', name_include_html: true do
|
34
|
+
it { should include(%(<field name="#{h name}">#{h value}</field>)) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context '値を省略した場合' do
|
38
|
+
subject { toolbox_key_field(name) }
|
39
|
+
|
40
|
+
it { should include(%(<field name="#{h name}">K_SPACE</field>)) }
|
41
|
+
end
|
42
|
+
|
43
|
+
context '名前と値を省略した場合' do
|
44
|
+
subject { toolbox_key_field }
|
45
|
+
|
46
|
+
it { should include('<field name="KEY">K_SPACE</field>') }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#toolbox_number_value' do
|
51
|
+
subject { toolbox_number_value(name, value) }
|
52
|
+
|
53
|
+
let(:name) { 'ANGLE' }
|
54
|
+
let(:value) { 90 }
|
55
|
+
|
56
|
+
it { should be_html_safe }
|
57
|
+
it { should include(%(<value name="#{h name}">)) }
|
58
|
+
it { should include(%(<field name="NUM">#{h value.to_i}</field>)) }
|
59
|
+
|
60
|
+
context '入力値の名前にタグを含む場合', name_include_html: true do
|
61
|
+
it { should include(%(<value name="#{h name}">)) }
|
62
|
+
end
|
63
|
+
|
64
|
+
shared_examples 'NUM is 0' do
|
65
|
+
it { should include('<field name="NUM">0</field>') }
|
66
|
+
end
|
67
|
+
|
68
|
+
context '数値に文字列を指定した場合' do
|
69
|
+
let(:value) { 'invalid' }
|
70
|
+
|
71
|
+
include_examples 'NUM is 0'
|
72
|
+
end
|
73
|
+
|
74
|
+
context '数値を指定しない場合' do
|
75
|
+
subject { toolbox_number_value(name) }
|
76
|
+
|
77
|
+
include_examples 'NUM is 0'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#toolbox_text_value' do
|
82
|
+
subject { toolbox_text_value(name, value) }
|
83
|
+
|
84
|
+
let(:name) { 'TEXT' }
|
85
|
+
let(:value) { 'こんにちは!' }
|
86
|
+
|
87
|
+
it { should be_html_safe }
|
88
|
+
it { should include(%(<value name="#{h name}">)) }
|
89
|
+
it { should include(%(<field name="TEXT">#{h value}</field>)) }
|
90
|
+
|
91
|
+
context '入力値の名前にタグを含む場合', name_include_html: true do
|
92
|
+
it { should include(%(<value name="#{h name}">)) }
|
93
|
+
end
|
94
|
+
|
95
|
+
context '文字列にタグを含む場合' do
|
96
|
+
let(:value) { INCLUDED_HTML_STRING }
|
97
|
+
|
98
|
+
it { should include(%(<field name="TEXT">#{h value}</field>)) }
|
99
|
+
end
|
100
|
+
|
101
|
+
context '入力値の名前と文字列を指定しない場合' do
|
102
|
+
subject { toolbox_text_value }
|
103
|
+
|
104
|
+
it { should include('<value name="TEXT">') }
|
105
|
+
it { should include('<field name="TEXT"></field>') }
|
106
|
+
end
|
107
|
+
|
108
|
+
context '文字列を指定しない場合' do
|
109
|
+
subject { toolbox_text_value(name) }
|
110
|
+
|
111
|
+
it { should include('<field name="TEXT"></field>') }
|
112
|
+
end
|
113
|
+
end
|
14
114
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
describe 'Smalruby.CharacterSet', ->
|
2
|
+
klass = Smalruby.CharacterSet
|
3
|
+
self = null
|
4
|
+
|
5
|
+
beforeEach ->
|
6
|
+
self = new klass()
|
7
|
+
|
8
|
+
describe '#uniqueName', ->
|
9
|
+
describe 'costumeを省略した場合', ->
|
10
|
+
it 'プリセットコスチュームの最初の要素名からユニークな名前を求めること', ->
|
11
|
+
expect(self.uniqueName()).to.equal('car1')
|
12
|
+
|
13
|
+
describe 'キャラクターが1つもない場合', ->
|
14
|
+
it 'car1を返すこと', ->
|
15
|
+
expect(self.uniqueName('car1.png')).to.equal('car1')
|
16
|
+
|
17
|
+
it '2回以降の呼び出しでもcar1を返すこと', ->
|
18
|
+
num = 5
|
19
|
+
while num -= 1
|
20
|
+
expect(self.uniqueName('car1.png')).to.equal('car1')
|
21
|
+
|
22
|
+
describe 'キャラクターが複数ある場合', ->
|
23
|
+
beforeEach ->
|
24
|
+
self.add(new Smalruby.Character({ name: 'car1' }))
|
25
|
+
self.add(new Smalruby.Character({ name: 'car3' }))
|
26
|
+
self.add(new Smalruby.Character({ name: 'ball4' }))
|
27
|
+
self.add(new Smalruby.Character({ name: 'cat1' }))
|
28
|
+
|
29
|
+
it '添え字が最大となるものを返す', ->
|
30
|
+
expect(self.uniqueName('car1.png')).to.equal('car4')
|
31
|
+
expect(self.uniqueName('car4.png')).to.equal('car4')
|
32
|
+
expect(self.uniqueName('car5.png')).to.equal('car4')
|
33
|
+
expect(self.uniqueName('ball1.png')).to.equal('ball5')
|
34
|
+
expect(self.uniqueName('ball5.png')).to.equal('ball5')
|
35
|
+
expect(self.uniqueName('ball6.png')).to.equal('ball5')
|
36
|
+
expect(self.uniqueName('cat1.png')).to.equal('cat2')
|
37
|
+
expect(self.uniqueName('cat3.png')).to.equal('cat2')
|
38
|
+
|
39
|
+
expect(self.uniqueName('http://example.com/cat3.png')).to.equal('cat2')
|
40
|
+
expect(self.uniqueName('http://example.com/cat3')).to.equal('cat2')
|
41
|
+
expect(self.uniqueName('cat3')).to.equal('cat2')
|
@@ -0,0 +1,146 @@
|
|
1
|
+
describe 'Smalruby.Character', ->
|
2
|
+
klass = Smalruby.Character
|
3
|
+
self = null
|
4
|
+
|
5
|
+
beforeEach ->
|
6
|
+
self = new klass
|
7
|
+
name: 'car1'
|
8
|
+
costumes: [
|
9
|
+
'car1.png'
|
10
|
+
'car2.png'
|
11
|
+
]
|
12
|
+
|
13
|
+
describe 'プロパティのデフォルト値', ->
|
14
|
+
beforeEach ->
|
15
|
+
self = new klass()
|
16
|
+
|
17
|
+
it 'name: null', ->
|
18
|
+
expect(self.get('name')).to.be(null)
|
19
|
+
|
20
|
+
it 'costumes: PRESET_COSTUMESの1番目の要素のみの配列', ->
|
21
|
+
expect(_.isEqual(self.get('costumes'), [klass.PRESET_COSTUMES[0]])).to.be(true)
|
22
|
+
|
23
|
+
it 'costumeIndex: 0', ->
|
24
|
+
expect(self.get('costumeIndex')).to.equal(0)
|
25
|
+
|
26
|
+
it 'x: 0', ->
|
27
|
+
expect(self.get('x')).to.equal(0)
|
28
|
+
|
29
|
+
it 'y: 0', ->
|
30
|
+
expect(self.get('y')).to.equal(0)
|
31
|
+
|
32
|
+
it 'angle: 0', ->
|
33
|
+
expect(self.get('angle')).to.equal(0)
|
34
|
+
|
35
|
+
it 'visible: true', ->
|
36
|
+
expect(self.get('visible')).to.be(true)
|
37
|
+
|
38
|
+
it 'using: false', ->
|
39
|
+
expect(self.get('using')).to.be(false)
|
40
|
+
|
41
|
+
describe '#initialize', ->
|
42
|
+
describe 'costumesを指定した場合', ->
|
43
|
+
it 'costumesが指定したものになる', ->
|
44
|
+
expect(_.isEqual(self.get('costumes'), ['car1.png', 'car2.png'])).to.be(true)
|
45
|
+
|
46
|
+
describe '#namePrefix', ->
|
47
|
+
it 'car', ->
|
48
|
+
expect(self.namePrefix()).to.equal('car')
|
49
|
+
|
50
|
+
describe '#costume', ->
|
51
|
+
it 'car1.pngであること', ->
|
52
|
+
expect(self.costume()).to.equal('car1.png')
|
53
|
+
|
54
|
+
describe '#costumeUrl', ->
|
55
|
+
describe 'プリセットの場合', ->
|
56
|
+
it 'プレフィックスが/smalruby/assets/であること', ->
|
57
|
+
expect(self.costumeUrl()).to.equal('/smalruby/assets/car1.png')
|
58
|
+
|
59
|
+
describe 'プリセットではない場合', ->
|
60
|
+
beforeEach ->
|
61
|
+
self = new klass
|
62
|
+
costumes: [
|
63
|
+
'http://example.com/car1.png'
|
64
|
+
'http://example.com/car2.png'
|
65
|
+
]
|
66
|
+
|
67
|
+
it 'costumeの値であること', ->
|
68
|
+
expect(self.costumeUrl()).to.equal(self.costume())
|
69
|
+
|
70
|
+
describe '#nextCostume', ->
|
71
|
+
it 'costumeIndexをインクリメントすること', ->
|
72
|
+
expect(self.get('costumeIndex')).to.equal(0)
|
73
|
+
self.nextCostume()
|
74
|
+
expect(self.get('costumeIndex')).to.equal(1)
|
75
|
+
|
76
|
+
it 'コスチュームの最大値までいったら0に戻ること', ->
|
77
|
+
self.set({ costumeIndex: 1 })
|
78
|
+
self.nextCostume()
|
79
|
+
expect(self.get('costumeIndex')).to.equal(0)
|
80
|
+
|
81
|
+
it '次のコスチューム番号を返すこと', ->
|
82
|
+
expect(self.nextCostume()).to.equal(1)
|
83
|
+
|
84
|
+
describe '#link', ->
|
85
|
+
linkObject = null
|
86
|
+
|
87
|
+
beforeEach ->
|
88
|
+
linkObject =
|
89
|
+
name: 'any object'
|
90
|
+
|
91
|
+
it '任意のオブジェクトと結びつきusingプロパティをtrueにできること', ->
|
92
|
+
self.link(linkObject)
|
93
|
+
expect(self.get('using')).to.be.ok
|
94
|
+
|
95
|
+
it '自分自身を返すこと', ->
|
96
|
+
expect(self.link(linkObject)).to.be(self)
|
97
|
+
|
98
|
+
describe '#unlink', ->
|
99
|
+
linkedObjects = null
|
100
|
+
|
101
|
+
beforeEach ->
|
102
|
+
linkedObjects = [
|
103
|
+
{ name: 'any object 1' }
|
104
|
+
{ name: 'any object 2' }
|
105
|
+
{ name: 'any object 3' }
|
106
|
+
]
|
107
|
+
self.link(o) for o in linkedObjects
|
108
|
+
|
109
|
+
it '任意のオブジェクトとの結びつきを解除してusingプロパティをfalseにできること', ->
|
110
|
+
self.unlink(o) for o in linkedObjects
|
111
|
+
expect(self.get('using')).to.not.be.ok
|
112
|
+
|
113
|
+
it 'すべてのオブジェクトとの結びつきを解除するまではusingプロパティがtrueのままであること', ->
|
114
|
+
self.unlink(linkedObjects[0])
|
115
|
+
expect(self.get('using')).to.be.ok
|
116
|
+
self.unlink(linkedObjects[1])
|
117
|
+
expect(self.get('using')).to.be.ok
|
118
|
+
self.unlink(linkedObjects[2])
|
119
|
+
expect(self.get('using')).to.not.be.ok
|
120
|
+
|
121
|
+
it '解除済みのオブジェクトを指定しても例外が発生しないこと', ->
|
122
|
+
self.unlink(linkedObjects[0])
|
123
|
+
expect(-> self.unlink(linkedObjects[0])).to.not.throwException()
|
124
|
+
|
125
|
+
it '自分自身を返すこと', ->
|
126
|
+
expect(self.unlink(linkedObjects[0]))
|
127
|
+
|
128
|
+
describe '.PRESET_COSTUMES', ->
|
129
|
+
it '文字列の配列であること', ->
|
130
|
+
expect(klass.PRESET_COSTUMES).to.be.a('array')
|
131
|
+
expect(klass.PRESET_COSTUMES[0]).to.be.a('string')
|
132
|
+
|
133
|
+
describe '.costumeToNamePrefix', ->
|
134
|
+
args = [
|
135
|
+
'car1.png'
|
136
|
+
'car1'
|
137
|
+
'car'
|
138
|
+
'http://example.com/car1.png'
|
139
|
+
'http://example.com/car1'
|
140
|
+
'http://example.com/car'
|
141
|
+
]
|
142
|
+
for arg in args
|
143
|
+
do (arg) ->
|
144
|
+
describe arg, ->
|
145
|
+
it 'car', ->
|
146
|
+
expect(klass.costumeToNamePrefix(arg)).to.equal('car')
|
@@ -0,0 +1,15 @@
|
|
1
|
+
describe 'Smalruby.Scene', ->
|
2
|
+
self = null
|
3
|
+
|
4
|
+
beforeEach ->
|
5
|
+
self = new Smalruby.Scene
|
6
|
+
|
7
|
+
describe 'プロパティのデフォルト値', ->
|
8
|
+
it 'width: 640', ->
|
9
|
+
expect(self.get('width')).to.equal(640)
|
10
|
+
|
11
|
+
it 'height: 480', ->
|
12
|
+
expect(self.get('height')).to.equal(480)
|
13
|
+
|
14
|
+
it "color: 'black'", ->
|
15
|
+
expect(self.get('color')).to.equal('black')
|
@@ -0,0 +1,29 @@
|
|
1
|
+
// Teaspoon includes some support files, but you can use anything from your own support path too.
|
2
|
+
//= require support/sinon
|
3
|
+
//= require support/expect
|
4
|
+
//= require support/jasmine-jquery
|
5
|
+
//
|
6
|
+
// PhantomJS (Teaspoons default driver) doesn't have support for Function.prototype.bind, which has caused confusion. Use
|
7
|
+
// this polyfill to avoid the confusion.
|
8
|
+
//= require support/bind-poly
|
9
|
+
//
|
10
|
+
// Deferring execution
|
11
|
+
// If you're using CommonJS, RequireJS or some other asynchronous library you can defer execution. Call Teaspoon.execute()
|
12
|
+
// after everything has been loaded. Simple example of a timeout:
|
13
|
+
//
|
14
|
+
// Teaspoon.defer = true
|
15
|
+
// setTimeout(Teaspoon.execute, 1000)
|
16
|
+
//
|
17
|
+
// Matching files
|
18
|
+
// By default Teaspoon will look for files that match _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your
|
19
|
+
// spec path and it'll be included in the default suite automatically. If you want to customize suites, check out the
|
20
|
+
// configuration in config/initializers/teaspoon.rb
|
21
|
+
//
|
22
|
+
// Manifest
|
23
|
+
// If you'd rather require your spec files manually (to control order for instance) you can disable the suite matcher in
|
24
|
+
// the configuration and use this file as a manifest.
|
25
|
+
//
|
26
|
+
// For more information: http://github.com/modeset/teaspoon
|
27
|
+
//
|
28
|
+
// You can require javascript files here. A good place to start is by requiring your application.js.
|
29
|
+
//= require application
|
data/spec/spec_helper.rb
CHANGED
@@ -100,20 +100,15 @@ Spork.prefork do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
config.include JsonSpec::Helpers
|
103
|
+
config.include ERB::Util, type: :helper
|
104
|
+
config.include ERB::Util, type: :feature
|
105
|
+
config.include ActionView::Helpers::JavaScriptHelper, type: :feature
|
103
106
|
|
104
107
|
config.after(javascript: true) do
|
105
108
|
page.execute_script('window.onbeforeunload = null')
|
106
109
|
FileUtils.rm_rf(downloads_dir) if selenium?
|
107
110
|
end
|
108
111
|
|
109
|
-
config.before(:all, javascript: true, standalone: true) do
|
110
|
-
expire_assets_cache
|
111
|
-
end
|
112
|
-
|
113
|
-
config.after(:all, javascript: true, standalone: true) do
|
114
|
-
expire_assets_cache
|
115
|
-
end
|
116
|
-
|
117
112
|
config.before(javascript: true, standalone: true) do
|
118
113
|
page.driver.restart
|
119
114
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
step '次のブロックを配置する:' do |haml|
|
4
|
+
haml = %(%xml{:xmlns => "http://www.w3.org/1999/xhtml"}\n) +
|
5
|
+
haml.lines.map { |s| " #{s}" }.join
|
6
|
+
engine = Haml::Engine.new(haml)
|
7
|
+
xml = engine.render
|
8
|
+
page.execute_script(<<-JS)
|
9
|
+
do {
|
10
|
+
var dom = Blockly.Xml.textToDom('#{escape_javascript(xml)}');
|
11
|
+
Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, dom);
|
12
|
+
} while (false);
|
13
|
+
JS
|
14
|
+
end
|
15
|
+
|
16
|
+
step 'すべてのブロックをクリアする' do
|
17
|
+
page.execute_script('Blockly.mainWorkspace.clear()')
|
18
|
+
end
|
19
|
+
|
20
|
+
step 'ブロックからソースコードを生成する' do
|
21
|
+
step '"Rubyタブ" にタブを切り替える'
|
22
|
+
end
|
23
|
+
|
24
|
+
step '次のキャラクターを追加する:' do |table|
|
25
|
+
table.hashes.each do |h|
|
26
|
+
costumes = h['costumes'].split(',').map { |s| "'#{s}'" }.join(', ')
|
27
|
+
page.execute_script(<<-JS)
|
28
|
+
Smalruby.Collections.CharacterSet.add(new Smalruby.Character({
|
29
|
+
name: '#{h['name']}',
|
30
|
+
costumes: [#{costumes}],
|
31
|
+
x: #{h['x']},
|
32
|
+
y: #{h['y']},
|
33
|
+
angle: #{h['angle']}
|
34
|
+
}))
|
35
|
+
JS
|
36
|
+
end
|
37
|
+
end
|