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.

Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -0
  3. data/.travis.yml +2 -0
  4. data/LEGAL +32 -0
  5. data/Rakefile +1 -1
  6. data/app/assets/demos/default.xml +126 -0
  7. data/app/assets/demos/rgb_led_anode.xml +83 -0
  8. data/app/assets/images/favicon.ico +0 -0
  9. data/app/assets/javascripts/application.js +18 -1
  10. data/app/assets/javascripts/block_mode.js.coffee.erb +10 -0
  11. data/app/assets/javascripts/blocks/blockly.js.coffee.erb +34 -0
  12. data/app/assets/javascripts/blocks/character.js.coffee.erb +76 -0
  13. data/app/assets/javascripts/blocks/control.js.coffee.erb +180 -0
  14. data/app/assets/javascripts/blocks/data.js.coffee.erb +6 -0
  15. data/app/assets/javascripts/blocks/etc.js.coffee.erb +6 -0
  16. data/app/assets/javascripts/blocks/events.js.coffee.erb +82 -0
  17. data/app/assets/javascripts/blocks/hardware.js.coffee.erb +313 -0
  18. data/app/assets/javascripts/blocks/looks.js.coffee.erb +163 -0
  19. data/app/assets/javascripts/blocks/motion.js.coffee.erb +297 -0
  20. data/app/assets/javascripts/blocks/operators.js.coffee.erb +279 -0
  21. data/app/assets/javascripts/blocks/pen.js.coffee.erb +6 -0
  22. data/app/assets/javascripts/blocks/ruby.js.coffee.erb +74 -0
  23. data/app/assets/javascripts/blocks/sensing.js.coffee.erb +241 -0
  24. data/app/assets/javascripts/blocks/sound.js.coffee.erb +75 -0
  25. data/{public/favicon.ico → app/assets/javascripts/collections/.keep} +0 -0
  26. data/app/assets/javascripts/collections/character_set.js.coffee +12 -0
  27. data/app/assets/javascripts/generators/ruby.js.coffee.erb +188 -0
  28. data/app/assets/javascripts/models/.keep +0 -0
  29. data/app/assets/javascripts/models/character.js.coffee +66 -0
  30. data/app/assets/javascripts/models/scene.js.coffee +5 -0
  31. data/app/assets/javascripts/models/source_code.js.coffee +64 -0
  32. data/app/assets/javascripts/routers/.keep +0 -0
  33. data/app/assets/javascripts/ruby_mode.js.coffee.erb +12 -0
  34. data/app/assets/javascripts/smalruby.js.coffee +97 -0
  35. data/app/assets/javascripts/views/.keep +0 -0
  36. data/app/assets/javascripts/views/character_modal_view.js.coffee +148 -0
  37. data/app/assets/javascripts/views/character_selector_view.js.coffee +109 -0
  38. data/app/assets/javascripts/views/main_menu_view.js.coffee +264 -0
  39. data/app/assets/stylesheets/editor.css.scss +318 -2
  40. data/app/assets/stylesheets/toolbox.css.scss.erb +62 -0
  41. data/app/assets/templates/.keep +0 -0
  42. data/app/controllers/application_controller.rb +19 -0
  43. data/app/controllers/editor_controller.rb +4 -0
  44. data/app/controllers/source_codes_controller.rb +8 -2
  45. data/app/helpers/application_helper.rb +1 -0
  46. data/app/helpers/editor_helper.rb +46 -0
  47. data/app/models/source_code.rb +49 -6
  48. data/app/views/editor/_block_tab.html.haml +53 -0
  49. data/app/views/editor/_character_modal.html.haml +53 -0
  50. data/app/views/editor/_toolbox.html.haml +384 -0
  51. data/app/views/editor/demo.html.erb +16 -0
  52. data/app/views/editor/index.html.haml +60 -0
  53. data/app/views/layouts/application.html.erb +7 -0
  54. data/config/application.rb +1 -0
  55. data/config/initializers/teaspoon.rb +79 -0
  56. data/config/routes.rb +4 -0
  57. data/lib/smalruby_editor/version.rb +1 -1
  58. data/lib/tasks/gem.rake +7 -4
  59. data/lib/tasks/release.rake +43 -0
  60. data/public/apple-touch-icon.png +0 -0
  61. data/public/blockly/media/1x1.gif +0 -0
  62. data/public/blockly/media/click.mp3 +0 -0
  63. data/public/blockly/media/click.ogg +0 -0
  64. data/public/blockly/media/click.wav +0 -0
  65. data/public/blockly/media/delete.mp3 +0 -0
  66. data/public/blockly/media/delete.ogg +0 -0
  67. data/public/blockly/media/delete.wav +0 -0
  68. data/public/blockly/media/handclosed.cur +0 -0
  69. data/public/blockly/media/handopen.cur +0 -0
  70. data/public/blockly/media/quote0.png +0 -0
  71. data/public/blockly/media/quote1.png +0 -0
  72. data/public/blockly/media/trashbody.png +0 -0
  73. data/public/blockly/media/trashlid.png +0 -0
  74. data/public/blockly/media/tree.png +0 -0
  75. data/public/browserconfig.xml +1 -0
  76. data/public/large.png +0 -0
  77. data/public/smalruby/assets/ball1.png +0 -0
  78. data/public/smalruby/assets/ball2.png +0 -0
  79. data/public/smalruby/assets/ball3.png +0 -0
  80. data/public/smalruby/assets/ball4.png +0 -0
  81. data/public/smalruby/assets/ball5.png +0 -0
  82. data/public/smalruby/assets/ball6.png +0 -0
  83. data/public/smalruby/assets/car1.png +0 -0
  84. data/public/smalruby/assets/car2.png +0 -0
  85. data/public/smalruby/assets/car3.png +0 -0
  86. data/public/smalruby/assets/car4.png +0 -0
  87. data/public/smalruby/assets/cat1.png +0 -0
  88. data/public/smalruby/assets/cat2.png +0 -0
  89. data/public/smalruby/assets/cat3.png +0 -0
  90. data/public/smalruby/assets/frog1.png +0 -0
  91. data/public/smalruby/assets/piano_do.wav +0 -0
  92. data/public/smalruby/assets/piano_do_2.wav +0 -0
  93. data/public/smalruby/assets/piano_fa.wav +0 -0
  94. data/public/smalruby/assets/piano_mi.wav +0 -0
  95. data/public/smalruby/assets/piano_ra.wav +0 -0
  96. data/public/smalruby/assets/piano_re.wav +0 -0
  97. data/public/smalruby/assets/piano_si.wav +0 -0
  98. data/public/smalruby/assets/piano_so.wav +0 -0
  99. data/public/square.png +0 -0
  100. data/public/tiny.png +0 -0
  101. data/public/wide.png +0 -0
  102. data/smalruby-editor.gemspec +4 -0
  103. data/spec/acceptance/block_mode/blocks/character/new.feature +136 -0
  104. data/spec/acceptance/block_mode/blocks/control/await.feature +20 -0
  105. data/spec/acceptance/block_mode/blocks/control/await_until.feature +39 -0
  106. data/spec/acceptance/block_mode/blocks/control/break.feature +20 -0
  107. data/spec/acceptance/block_mode/blocks/control/if.feature +68 -0
  108. data/spec/acceptance/block_mode/blocks/control/if_else.feature +78 -0
  109. data/spec/acceptance/block_mode/blocks/control/loop.feature +45 -0
  110. data/spec/acceptance/block_mode/blocks/control/next.feature +20 -0
  111. data/spec/acceptance/block_mode/blocks/control/redo.feature +20 -0
  112. data/spec/acceptance/block_mode/blocks/control/sleep.feature +41 -0
  113. data/spec/acceptance/block_mode/blocks/control/times.feature +72 -0
  114. data/spec/acceptance/block_mode/blocks/control/until.feature +68 -0
  115. data/spec/acceptance/block_mode/blocks/events/on_click.feature +75 -0
  116. data/spec/acceptance/block_mode/blocks/events/on_hit.feature +83 -0
  117. data/spec/acceptance/block_mode/blocks/events/on_key_push_or_down.feature +171 -0
  118. data/spec/acceptance/block_mode/blocks/events/on_start.feature +75 -0
  119. data/spec/acceptance/block_mode/blocks/hardware/init_hardware.feature +44 -0
  120. data/spec/acceptance/block_mode/blocks/hardware/led_off.feature +75 -0
  121. data/spec/acceptance/block_mode/blocks/hardware/led_on.feature +75 -0
  122. data/spec/acceptance/block_mode/blocks/hardware/on_sensor_change.feature +81 -0
  123. data/spec/acceptance/block_mode/blocks/hardware/rgb_led_off.feature +81 -0
  124. data/spec/acceptance/block_mode/blocks/hardware/rgb_led_on.feature +87 -0
  125. data/spec/acceptance/block_mode/blocks/hardware/sensor_value.feature +100 -0
  126. data/spec/acceptance/block_mode/blocks/looks/hide.feature +69 -0
  127. data/spec/acceptance/block_mode/blocks/looks/say.feature +106 -0
  128. data/spec/acceptance/block_mode/blocks/looks/show.feature +69 -0
  129. data/spec/acceptance/block_mode/blocks/looks/vanish.feature +69 -0
  130. data/spec/acceptance/block_mode/blocks/motion/change_x_by.feature +81 -0
  131. data/spec/acceptance/block_mode/blocks/motion/change_y_by.feature +81 -0
  132. data/spec/acceptance/block_mode/blocks/motion/move.feature +81 -0
  133. data/spec/acceptance/block_mode/blocks/motion/reach_wall.feature +98 -0
  134. data/spec/acceptance/block_mode/blocks/motion/rotate_left.feature +81 -0
  135. data/spec/acceptance/block_mode/blocks/motion/rotate_right.feature +81 -0
  136. data/spec/acceptance/block_mode/blocks/motion/self_angle.feature +92 -0
  137. data/spec/acceptance/block_mode/blocks/motion/self_x.feature +92 -0
  138. data/spec/acceptance/block_mode/blocks/motion/self_y.feature +92 -0
  139. data/spec/acceptance/block_mode/blocks/motion/set_angle.feature +81 -0
  140. data/spec/acceptance/block_mode/blocks/motion/set_x.feature +81 -0
  141. data/spec/acceptance/block_mode/blocks/motion/set_x_y.feature +95 -0
  142. data/spec/acceptance/block_mode/blocks/motion/set_y.feature +81 -0
  143. data/spec/acceptance/block_mode/blocks/motion/turn.feature +69 -0
  144. data/spec/acceptance/block_mode/blocks/motion/turn_if_reach_wall.feature +69 -0
  145. data/spec/acceptance/block_mode/blocks/sensing/character_property.feature +114 -0
  146. data/spec/acceptance/block_mode/blocks/sensing/hit.feature +110 -0
  147. data/spec/acceptance/block_mode/blocks/sensing/input_key_push_or_down.feature +91 -0
  148. data/spec/acceptance/block_mode/blocks/sensing/input_mouse_pos_x.feature +39 -0
  149. data/spec/acceptance/block_mode/blocks/sensing/input_mouse_pos_y.feature +39 -0
  150. data/spec/acceptance/block_mode/blocks/sensing/input_mouse_push_or_down.feature +91 -0
  151. data/spec/acceptance/block_mode/blocks/sensing/time_now.feature +43 -0
  152. data/spec/acceptance/block_mode/blocks/sound/play.feature +81 -0
  153. data/spec/acceptance/block_mode/demo.feature +49 -0
  154. data/spec/acceptance/{text_editor → ruby_mode}/base.feature +11 -2
  155. data/spec/acceptance/{standalone → ruby_mode}/check.feature +8 -9
  156. data/spec/acceptance/ruby_mode/download.feature +33 -0
  157. data/spec/acceptance/{text_editor → ruby_mode}/load.feature +13 -13
  158. data/spec/acceptance/standalone/run.feature +17 -0
  159. data/spec/acceptance/standalone/save.feature +6 -6
  160. data/spec/helpers/editor_helper_spec.rb +110 -10
  161. data/spec/javascripts/collections/character_set_spec.coffee +41 -0
  162. data/spec/javascripts/models/character_spec.coffee +146 -0
  163. data/spec/javascripts/models/scene_spec.coffee +15 -0
  164. data/spec/javascripts/spec_helper.js +29 -0
  165. data/spec/spec_helper.rb +3 -8
  166. data/spec/steps/block_mode_steps.rb +37 -0
  167. data/spec/steps/global_variable.rb +30 -6
  168. data/spec/steps/text_editor_steps.rb +20 -2
  169. data/spec/teaspoon_env.rb +46 -0
  170. data/vendor/assets/javascripts/blockly/blockly_compressed.js +992 -0
  171. data/vendor/assets/javascripts/blockly/blocks_compressed.js +129 -0
  172. data/vendor/assets/javascripts/blockly/msg/js/ja.js +377 -0
  173. data/vendor/assets/javascripts/jquery.blockUI.js +619 -0
  174. metadata +290 -23
  175. data/app/assets/javascripts/editor.js.coffee.erb +0 -137
  176. data/app/views/editor/index.html.erb +0 -22
  177. data/spec/acceptance/text_editor/check.feature +0 -29
  178. data/spec/acceptance/text_editor/save.feature +0 -34
  179. 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