smalruby-editor 0.1.1 → 0.1.2

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/demos/default.xml +1 -1
  3. data/app/assets/javascripts/application.js +1 -0
  4. data/app/assets/javascripts/blocks/blockly.js.coffee.erb +1 -1
  5. data/app/assets/javascripts/blocks/events.js.coffee.erb +2 -3
  6. data/app/assets/javascripts/blocks/field_character.js.coffee.erb +108 -0
  7. data/app/assets/javascripts/blocks/hardware.js.coffee.erb +35 -2
  8. data/app/assets/javascripts/blocks/motion.js.coffee.erb +4 -4
  9. data/app/assets/javascripts/blocks/operators.js.coffee.erb +27 -29
  10. data/app/assets/javascripts/blocks/sensing.js.coffee.erb +4 -6
  11. data/app/assets/javascripts/generators/ruby.js.coffee.erb +21 -19
  12. data/app/assets/javascripts/models/character.js.coffee +21 -0
  13. data/app/assets/javascripts/views/character_modal_view.js.coffee +24 -3
  14. data/app/views/editor/_character_modal.html.haml +1 -1
  15. data/app/views/editor/_toolbox.html.haml +7 -3
  16. data/lib/smalruby_editor/version.rb +1 -1
  17. data/public/assets/{application-0c2ae32cd8822cec7ba6e445e2501010.js → application-735e172a0df828da16d22f5d3c26671f.js} +294 -59
  18. data/public/assets/{application-0c2ae32cd8822cec7ba6e445e2501010.js.gz → application-735e172a0df828da16d22f5d3c26671f.js.gz} +0 -0
  19. data/public/assets/{default-7f438ebd7f8ab6ef65c5b9744786e57f.xml → default-5d1886100d7c8961e9962bbc4bb0c714.xml} +1 -1
  20. data/public/assets/manifest-1f254fa92a71ba4faad0f99136daeed8.json +1 -1
  21. data/spec/acceptance/block_mode/blocks/hardware/servo_set_position.feature +104 -0
  22. data/spec/acceptance/block_mode/blocks/operators/and_or.feature +61 -0
  23. data/spec/acceptance/block_mode/blocks/operators/four_arithmetic_and_compares.feature +85 -0
  24. data/spec/acceptance/block_mode/blocks/operators/index_of.feature +60 -0
  25. data/spec/acceptance/block_mode/blocks/operators/length.feature +52 -0
  26. data/spec/acceptance/block_mode/blocks/operators/math_method.feature +109 -0
  27. data/spec/acceptance/block_mode/blocks/operators/negate.feature +47 -0
  28. data/spec/acceptance/block_mode/blocks/operators/rand.feature +60 -0
  29. data/spec/acceptance/block_mode/blocks/operators/round.feature +52 -0
  30. data/spec/acceptance/block_mode/blocks/operators/true_false.feature +36 -0
  31. data/spec/acceptance/block_mode/blocks/ruby/expression.feature +36 -0
  32. data/spec/acceptance/block_mode/blocks/ruby/p.feature +34 -0
  33. data/spec/acceptance/block_mode/blocks/ruby/statement_comment.feature +25 -0
  34. data/spec/javascripts/models/character_spec.coffee +44 -5
  35. data/spec/steps/ace_steps.rb +9 -0
  36. data/spec/steps/block_mode_steps.rb +14 -0
  37. data/spec/steps/fix_turnip.rb +35 -0
  38. data/spec/steps/text_editor_steps.rb +1 -0
  39. data/spec/teaspoon_env.rb +1 -1
  40. data/spec/turnip_helper.rb +1 -0
  41. metadata +34 -5
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ # language: ja
3
+ @javascript
4
+ 機能: operators_negate - 「条件:< >ではない」ブロック
5
+ 背景:
6
+ 前提 "ブロック" タブを表示する
7
+
8
+ シナリオ: ブロックのみ配置する
9
+ もし 次のブロック("operators_negate")を配置する:
10
+ """
11
+ %block{:type => "operators_negate", :x => "0", :y => "0", :inline => "true"}
12
+ """
13
+ かつ ブロックからソースコードを生成する
14
+
15
+ ならば テキストエディタのプログラムは以下を含むこと:
16
+ """
17
+ !true
18
+ """
19
+
20
+ シナリオ: 値を設定したブロックを配置する
21
+ もし 次のブロック("operators_negate")を配置する:
22
+ """
23
+ %block{:type => "operators_negate", :x => "0", :y => "0", :inline => "true"}
24
+ %value{:name => "A"}
25
+ %block{:type => "operators_false"}
26
+ """
27
+ かつ ブロックからソースコードを生成する
28
+
29
+ ならば テキストエディタのプログラムは以下を含むこと:
30
+ """
31
+ !false
32
+ """
33
+
34
+ もし 次のブロック("operators_negate")を配置する:
35
+ """
36
+ %block{:type => "ruby_p", :x => "0", :y => "0", :inline => "true"}
37
+ %value{:name => "ARG"}
38
+ %block{:type => "operators_negate"}
39
+ %value{:name => "A"}
40
+ %block{:type => "operators_false"}
41
+ """
42
+ かつ ブロックからソースコードを生成する
43
+
44
+ ならば テキストエディタのプログラムは以下を含むこと:
45
+ """
46
+ p(!false)
47
+ """
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ # language: ja
3
+ @javascript
4
+ 機能: operators_rand - 「変数:( )から( )までの乱数」ブロック
5
+ 背景:
6
+ 前提 "ブロック" タブを表示する
7
+
8
+ シナリオ: ブロックのみ配置する
9
+ もし 次のブロックを配置する:
10
+ """
11
+ %block{:type => "operators_rand", :x => "0", :y => "0"}
12
+ """
13
+ かつ ブロックからソースコードを生成する
14
+
15
+ ならば テキストエディタのプログラムは以下を含むこと:
16
+ """
17
+ rand(0..0)
18
+ """
19
+
20
+ シナリオ: 値を設定したブロックを配置する
21
+ もし 次のブロックを配置する:
22
+ """
23
+ %block{:type => "operators_rand", :x => "0", :y => "0"}
24
+ %value{:name => "A"}
25
+ %block{:type => "math_number"}
26
+ %field{:name => "NUM"}<
27
+ 1
28
+ %value{:name => "B"}
29
+ %block{:type => "math_number"}
30
+ %field{:name => "NUM"}<
31
+ 10
32
+ """
33
+ かつ ブロックからソースコードを生成する
34
+
35
+ ならば テキストエディタのプログラムは以下を含むこと:
36
+ """
37
+ rand(1..10)
38
+ """
39
+
40
+ シナリオ: 文と値を設定したブロックを配置する
41
+ もし 次のブロックを配置する:
42
+ """
43
+ %block{:type => "ruby_p", :x => "0", :y => "0", :inline => "true"}
44
+ %value{:name => "ARG"}
45
+ %block{:type => "operators_rand"}
46
+ %value{:name => "A"}
47
+ %block{:type => "math_number"}
48
+ %field{:name => "NUM"}<
49
+ 1
50
+ %value{:name => "B"}
51
+ %block{:type => "math_number"}
52
+ %field{:name => "NUM"}<
53
+ 10
54
+ """
55
+ かつ ブロックからソースコードを生成する
56
+
57
+ ならば テキストエディタのプログラムは以下を含むこと:
58
+ """
59
+ p(rand(1..10))
60
+ """
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ # language: ja
3
+ @javascript
4
+ 機能: operators_round - 「変数:( )を丸める」ブロック
5
+ 背景:
6
+ 前提 "ブロック" タブを表示する
7
+
8
+ シナリオ: ブロックのみ配置する
9
+ もし 次のブロックを配置する:
10
+ """
11
+ %block{:type => "operators_round", :x => "0", :y => "0"}
12
+ """
13
+ かつ ブロックからソースコードを生成する
14
+
15
+ ならば テキストエディタのプログラムは以下を含むこと:
16
+ """
17
+ 0.round
18
+ """
19
+
20
+ シナリオ: 値を設定したブロックを配置する
21
+ もし 次のブロックを配置する:
22
+ """
23
+ %block{:type => "operators_round", :x => "0", :y => "0"}
24
+ %value{:name => "A"}
25
+ %block{:type => "math_number"}
26
+ %field{:name => "NUM"}<
27
+ 0.5
28
+ """
29
+ かつ ブロックからソースコードを生成する
30
+
31
+ ならば テキストエディタのプログラムは以下を含むこと:
32
+ """
33
+ 0.5.round
34
+ """
35
+
36
+ シナリオ: 文と値を設定したブロックを配置する
37
+ もし 次のブロックを配置する:
38
+ """
39
+ %block{:type => "ruby_p", :x => "0", :y => "0", :inline => "true"}
40
+ %value{:name => "ARG"}
41
+ %block{:type => "operators_round"}
42
+ %value{:name => "A"}
43
+ %block{:type => "math_number"}
44
+ %field{:name => "NUM"}<
45
+ 0.5
46
+ """
47
+ かつ ブロックからソースコードを生成する
48
+
49
+ ならば テキストエディタのプログラムは以下を含むこと:
50
+ """
51
+ p(0.5.round)
52
+ """
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ # language: ja
3
+ @javascript
4
+ 機能: operators_{true,false} - 「条件:{真,偽}」ブロック
5
+ 背景:
6
+ 前提 "ブロック" タブを表示する
7
+
8
+ シナリオテンプレート: ブロックを配置する
9
+ もし 次のブロック("operators_<ブロック名のサフィックス>")を配置する:
10
+ """
11
+ %block{:type => "operators_<ブロック名のサフィックス>", :x => "0", :y => "0", :inline => "true"}
12
+ """
13
+ かつ ブロックからソースコードを生成する
14
+
15
+ ならば テキストエディタのプログラムは以下を含むこと:
16
+ """
17
+ <Ruby>
18
+ """
19
+
20
+ もし 次のブロック("operators_<ブロック名のサフィックス>")を配置する:
21
+ """
22
+ %block{:type => "ruby_p", :x => "0", :y => "0", :inline => "true"}
23
+ %value{:name => "ARG"}
24
+ %block{:type => "operators_<ブロック名のサフィックス>"}
25
+ """
26
+ かつ ブロックからソースコードを生成する
27
+
28
+ ならば テキストエディタのプログラムは以下を含むこと:
29
+ """
30
+ p(<Ruby>)
31
+ """
32
+
33
+ 例:
34
+ | ブロック名のサフィックス | Ruby |
35
+ | true | true |
36
+ | false | false |
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ # language: ja
3
+ @javascript
4
+ 機能: ruby_expression - 「式」ブロック
5
+ 背景:
6
+ 前提 "ブロック" タブを表示する
7
+
8
+ シナリオ: ブロックのみ配置する
9
+ もし 次のブロック("ruby_expression")を配置する:
10
+ """
11
+ %block{:type => "ruby_expression", :x => "0", :y => "0", :inline => "true"}
12
+ %field{:name => "EXP"}<
13
+ stage1 = Stage.new(color: "white")
14
+ """
15
+ かつ ブロックからソースコードを生成する
16
+
17
+ ならば テキストエディタのプログラムは以下を含むこと:
18
+ """
19
+ (stage1 = Stage.new(color: "white"))
20
+ """
21
+
22
+ シナリオ: 文とブロックを配置する
23
+ もし 次のブロック("ruby_expression")を配置する:
24
+ """
25
+ %block{:type => "ruby_p", :x => "0", :y => "0", :inline => "true"}
26
+ %value{:name => "ARG"}
27
+ %block{:type => "ruby_expression", :x => "0", :y => "0", :inline => "true"}
28
+ %field{:name => "EXP"}<
29
+ stage1 = Stage.new(color: "white")
30
+ """
31
+ かつ ブロックからソースコードを生成する
32
+
33
+ ならば テキストエディタのプログラムは以下を含むこと:
34
+ """
35
+ p((stage1 = Stage.new(color: "white")))
36
+ """
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ # language: ja
3
+ @javascript
4
+ 機能: ruby_p - 「p」ブロック
5
+ 背景:
6
+ 前提 "ブロック" タブを表示する
7
+
8
+ シナリオ: ブロックのみ配置する
9
+ もし 次のブロック("ruby_p")を配置する:
10
+ """
11
+ %block{:type => "ruby_p", :x => "0", :y => "0", :inline => "true"}
12
+ """
13
+ かつ ブロックからソースコードを生成する
14
+
15
+ ならば テキストエディタのプログラムは以下を含むこと:
16
+ """
17
+ p("")
18
+ """
19
+
20
+ シナリオ: 式を設定したブロックを配置する
21
+ もし 次のブロック("ruby_p")を配置する:
22
+ """
23
+ %block{:type => "ruby_p", :x => "0", :y => "0", :inline => "true"}
24
+ %value{:name => "ARG"}
25
+ %block{:type => "text"}
26
+ %field{:name => "TEXT"}<
27
+ こんにちは
28
+ """
29
+ かつ ブロックからソースコードを生成する
30
+
31
+ ならば テキストエディタのプログラムは以下を含むこと:
32
+ """
33
+ p("こんにちは")
34
+ """
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ # language: ja
3
+ @javascript
4
+ 機能: ruby_{statement,comment} - 「{文,コメント}」ブロック
5
+ 背景:
6
+ 前提 "ブロック" タブを表示する
7
+
8
+ シナリオテンプレート: ブロックのみ配置する
9
+ もし 次のブロック("ruby_<ブロック名のサフィックス>")を配置する:
10
+ """
11
+ %block{:type => "ruby_<ブロック名のサフィックス>", :x => "0", :y => "0", :inline => "true"}
12
+ %field{:name => "<フィールド名>"}<
13
+ stage1 = Stage.new(color: "white")
14
+ """
15
+ かつ ブロックからソースコードを生成する
16
+
17
+ ならば テキストエディタのプログラムは以下を含むこと:
18
+ """
19
+ <Ruby>
20
+ """
21
+
22
+ 例:
23
+ | ブロック名のサフィックス | フィールド名 | Ruby |
24
+ | statement | STATEMENT | stage1 = Stage.new(color: "white") |
25
+ | comment | COMMENT | # stage1 = Stage.new(color: "white") |
@@ -43,6 +43,45 @@ describe 'Smalruby.Character', ->
43
43
  it 'costumesが指定したものになる', ->
44
44
  expect(_.isEqual(self.get('costumes'), ['car1.png', 'car2.png'])).to.be(true)
45
45
 
46
+ describe '#validate', ->
47
+ it 'nameは指定しなければいけない', ->
48
+ self.set({ name: '' })
49
+ expect(self.isValid()).to.not.be.ok()
50
+ self.set({ name: null })
51
+ expect(self.isValid()).to.not.be.ok()
52
+ self.set({ name: undefined })
53
+ expect(self.isValid()).to.not.be.ok()
54
+
55
+ describe 'nameはRubyの変数名として正しくなければいけない', ->
56
+ invalidNames = [
57
+ '1'
58
+ 'CONSTANT'
59
+ '-abc'
60
+ '[1, 2, 3]'
61
+ '{ a: 1, b: 2}'
62
+ ':symbol'
63
+ 'abc{'
64
+ 'abc['
65
+ 'abc:def'
66
+ ]
67
+ for name in invalidNames
68
+ do (name) ->
69
+ it "#{name}は不正であること", ->
70
+ self.set({ name: name })
71
+ expect(self.isValid()).to.not.be.ok()
72
+
73
+ invalidNames = [
74
+ 'one'
75
+ 'constant'
76
+ 'o1e'
77
+ 'あいうえお'
78
+ ]
79
+ for name in invalidNames
80
+ do (name) ->
81
+ it "#{name}は正しいこと", ->
82
+ self.set({ name: name })
83
+ expect(self.isValid()).to.be.ok()
84
+
46
85
  describe '#namePrefix', ->
47
86
  it 'car', ->
48
87
  expect(self.namePrefix()).to.equal('car')
@@ -90,7 +129,7 @@ describe 'Smalruby.Character', ->
90
129
 
91
130
  it '任意のオブジェクトと結びつきusingプロパティをtrueにできること', ->
92
131
  self.link(linkObject)
93
- expect(self.get('using')).to.be.ok
132
+ expect(self.get('using')).to.be.ok()
94
133
 
95
134
  it '自分自身を返すこと', ->
96
135
  expect(self.link(linkObject)).to.be(self)
@@ -108,15 +147,15 @@ describe 'Smalruby.Character', ->
108
147
 
109
148
  it '任意のオブジェクトとの結びつきを解除してusingプロパティをfalseにできること', ->
110
149
  self.unlink(o) for o in linkedObjects
111
- expect(self.get('using')).to.not.be.ok
150
+ expect(self.get('using')).to.not.be.ok()
112
151
 
113
152
  it 'すべてのオブジェクトとの結びつきを解除するまではusingプロパティがtrueのままであること', ->
114
153
  self.unlink(linkedObjects[0])
115
- expect(self.get('using')).to.be.ok
154
+ expect(self.get('using')).to.be.ok()
116
155
  self.unlink(linkedObjects[1])
117
- expect(self.get('using')).to.be.ok
156
+ expect(self.get('using')).to.be.ok()
118
157
  self.unlink(linkedObjects[2])
119
- expect(self.get('using')).to.not.be.ok
158
+ expect(self.get('using')).to.not.be.ok()
120
159
 
121
160
  it '解除済みのオブジェクトを指定しても例外が発生しないこと', ->
122
161
  self.unlink(linkedObjects[0])
@@ -49,6 +49,15 @@ step 'テキストエディタのプログラムは以下であること:' do |p
49
49
  JS
50
50
  end
51
51
 
52
+ step 'テキストエディタのプログラムは以下を含むこと:' do |program|
53
+ expect(page.evaluate_script(<<-JS)).to include(program)
54
+ ace.edit('#{NAME_INFO[text_editor][:id]}')
55
+ .getSession()
56
+ .getDocument()
57
+ .getValue()
58
+ JS
59
+ end
60
+
52
61
  step 'テキストエディタのプログラムは :program であること' do |program|
53
62
  expect(page.evaluate_script(<<-JS)).to eq(program)
54
63
  ace.edit('#{NAME_INFO[text_editor][:id]}')
@@ -13,11 +13,25 @@ step '次のブロックを配置する:' do |haml|
13
13
  JS
14
14
  end
15
15
 
16
+ step '次のブロック(:comment)を配置する:' do |_, haml|
17
+ haml = %(%xml{:xmlns => "http://www.w3.org/1999/xhtml"}\n) +
18
+ haml.lines.map { |s| " #{s}" }.join
19
+ engine = Haml::Engine.new(haml)
20
+ xml = engine.render
21
+ page.execute_script(<<-JS)
22
+ do {
23
+ var dom = Blockly.Xml.textToDom('#{escape_javascript(xml)}');
24
+ Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, dom);
25
+ } while (false);
26
+ JS
27
+ end
28
+
16
29
  step 'すべてのブロックをクリアする' do
17
30
  page.execute_script('Blockly.mainWorkspace.clear()')
18
31
  end
19
32
 
20
33
  step 'ブロックからソースコードを生成する' do
34
+ step '"ブロックタブ" にタブを切り替える'
21
35
  step '"Rubyタブ" にタブを切り替える'
22
36
  end
23
37
 
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Doc Stringsに含まれるシナリオアウトラインのプレースホルダを置き換える
3
+ # ためのモンキーパッチ。turnip-1.1.0で動作確認済み。
4
+ # rubocop:disable all
5
+ class Turnip::Builder
6
+ class ScenarioOutline
7
+ def to_scenarios(examples)
8
+ rows = examples.rows.map(&:cells)
9
+ headers = rows.shift
10
+ rows.map do |row|
11
+ Scenario.new(@raw).tap do |scenario|
12
+ scenario.steps = steps.map do |step|
13
+ new_description = substitute(step.description, headers, row)
14
+ new_extra_args = step.extra_args.map do |ea|
15
+ if ea.instance_of?(Turnip::Table)
16
+ Turnip::Table.new(ea.map {|t_row| t_row.map {|t_col| substitute(t_col, headers, row) } })
17
+ else
18
+ substitute_only_matched(ea, headers, row)
19
+ end
20
+ end
21
+ Step.new(new_description, new_extra_args, step.line)
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def substitute_only_matched(text, headers, row)
30
+ text.gsub(/<([^<>]*)>/) { |s|
31
+ (res = Hash[headers.zip(row)][$1]) ? res : s
32
+ }
33
+ end
34
+ end
35
+ end