smalruby-editor 0.1.6 → 0.1.7

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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/blocks/hardware.js.coffee.erb +40 -3
  3. data/app/assets/stylesheets/toolbox.css.scss.erb +1 -6
  4. data/app/controllers/source_codes_controller.rb +5 -1
  5. data/app/models/concerns/ruby_to_block.rb +17 -360
  6. data/app/models/concerns/ruby_to_block/block.rb +97 -0
  7. data/app/models/concerns/ruby_to_block/block/base.rb +251 -0
  8. data/app/models/concerns/ruby_to_block/block/character.rb +42 -0
  9. data/app/models/concerns/ruby_to_block/block/character_event.rb +27 -0
  10. data/app/models/concerns/ruby_to_block/block/character_method_call.rb +29 -0
  11. data/app/models/concerns/ruby_to_block/block/character_new.rb +7 -0
  12. data/app/models/concerns/ruby_to_block/block/character_operation.rb +80 -0
  13. data/app/models/concerns/ruby_to_block/block/control_if.rb +45 -0
  14. data/app/models/concerns/ruby_to_block/block/control_loop.rb +19 -0
  15. data/app/models/concerns/ruby_to_block/block/control_sleep.rb +18 -0
  16. data/app/models/concerns/ruby_to_block/block/do.rb +24 -0
  17. data/app/models/concerns/ruby_to_block/block/else.rb +12 -0
  18. data/app/models/concerns/ruby_to_block/block/end.rb +26 -0
  19. data/app/models/concerns/ruby_to_block/block/events_on_click.rb +14 -0
  20. data/app/models/concerns/ruby_to_block/block/events_on_key_push_or_down.rb +17 -0
  21. data/app/models/concerns/ruby_to_block/block/events_on_start.rb +14 -0
  22. data/app/models/concerns/ruby_to_block/block/hardware_init_hardware.rb +14 -0
  23. data/app/models/concerns/ruby_to_block/block/hardware_led_off.rb +16 -0
  24. data/app/models/concerns/ruby_to_block/block/hardware_led_on.rb +16 -0
  25. data/app/models/concerns/ruby_to_block/block/hardware_on_sensor_change.rb +17 -0
  26. data/app/models/concerns/ruby_to_block/block/hardware_rgb_led_off.rb +18 -0
  27. data/app/models/concerns/ruby_to_block/block/hardware_rgb_led_on.rb +23 -0
  28. data/app/models/concerns/ruby_to_block/block/hardware_sensor_value.rb +23 -0
  29. data/app/models/concerns/ruby_to_block/block/hardware_two_wheel_drive_car.rb +26 -0
  30. data/app/models/concerns/ruby_to_block/block/looks_hide.rb +8 -0
  31. data/app/models/concerns/ruby_to_block/block/looks_say.rb +20 -0
  32. data/app/models/concerns/ruby_to_block/block/looks_show.rb +8 -0
  33. data/app/models/concerns/ruby_to_block/block/looks_vanish.rb +8 -0
  34. data/app/models/concerns/ruby_to_block/block/math_number.rb +14 -0
  35. data/app/models/concerns/ruby_to_block/block/motion_change_x_by.rb +20 -0
  36. data/app/models/concerns/ruby_to_block/block/motion_change_y_by.rb +20 -0
  37. data/app/models/concerns/ruby_to_block/block/motion_move.rb +15 -0
  38. data/app/models/concerns/ruby_to_block/block/motion_point_towards_character.rb +24 -0
  39. data/app/models/concerns/ruby_to_block/block/motion_point_towards_mouse.rb +9 -0
  40. data/app/models/concerns/ruby_to_block/block/motion_reach_wall.rb +24 -0
  41. data/app/models/concerns/ruby_to_block/block/motion_rotate_left.rb +20 -0
  42. data/app/models/concerns/ruby_to_block/block/motion_rotate_right.rb +20 -0
  43. data/app/models/concerns/ruby_to_block/block/motion_self_angle.rb +23 -0
  44. data/app/models/concerns/ruby_to_block/block/motion_self_x.rb +23 -0
  45. data/app/models/concerns/ruby_to_block/block/motion_self_y.rb +23 -0
  46. data/app/models/concerns/ruby_to_block/block/motion_set_angle.rb +15 -0
  47. data/app/models/concerns/ruby_to_block/block/motion_set_x.rb +38 -0
  48. data/app/models/concerns/ruby_to_block/block/motion_set_y.rb +15 -0
  49. data/app/models/concerns/ruby_to_block/block/motion_turn.rb +8 -0
  50. data/app/models/concerns/ruby_to_block/block/motion_turn_if_reach_wall.rb +8 -0
  51. data/app/models/concerns/ruby_to_block/block/null.rb +17 -0
  52. data/app/models/concerns/ruby_to_block/block/operators_compare.rb +36 -0
  53. data/app/models/concerns/ruby_to_block/block/operators_false.rb +8 -0
  54. data/app/models/concerns/ruby_to_block/block/operators_true.rb +8 -0
  55. data/app/models/concerns/ruby_to_block/block/require_smalruby.rb +7 -0
  56. data/app/models/concerns/ruby_to_block/block/ruby_comment.rb +16 -0
  57. data/app/models/concerns/ruby_to_block/block/ruby_expression.rb +14 -0
  58. data/app/models/concerns/ruby_to_block/block/ruby_statement.rb +23 -0
  59. data/app/models/concerns/ruby_to_block/block/sensing_hit.rb +23 -0
  60. data/app/models/concerns/ruby_to_block/block/sound_play.rb +15 -0
  61. data/app/models/concerns/ruby_to_block/block/sound_preset_sounds.rb +31 -0
  62. data/app/models/concerns/ruby_to_block/block/text.rb +15 -0
  63. data/app/models/concerns/ruby_to_block/block/value.rb +12 -0
  64. data/app/models/concerns/ruby_to_block/context.rb +97 -0
  65. data/app/models/concerns/ruby_to_block/formatter.rb +26 -0
  66. data/app/models/source_code.rb +3 -1
  67. data/app/views/editor/_toolbox.html.haml +16 -0
  68. data/lib/smalruby_editor/version.rb +3 -3
  69. data/smalruby-editor.gemspec +1 -1
  70. data/spec/acceptance/block_mode/blocks/hardware/two_wheel_drive_car.feature +69 -0
  71. data/spec/acceptance/ruby_mode/translate.feature +1 -1
  72. data/spec/controllers/source_codes_controller_spec.rb +14 -11
  73. data/spec/models/concerns/ruby_to_block/block/character_method_call_spec.rb +175 -0
  74. data/spec/models/concerns/ruby_to_block/block/control_if_spec.rb +75 -0
  75. data/spec/models/concerns/ruby_to_block/block/control_loop_spec.rb +68 -0
  76. data/spec/models/concerns/ruby_to_block/block/events_on_start_spec.rb +120 -0
  77. data/spec/models/concerns/ruby_to_block/block/hardware_spec.rb +120 -0
  78. data/spec/models/concerns/ruby_to_block/block/looks_say_spec.rb +79 -0
  79. data/spec/models/concerns/ruby_to_block/block/looks_spec.rb +74 -0
  80. data/spec/models/concerns/ruby_to_block/block/motion_move_spec.rb +63 -0
  81. data/spec/models/concerns/ruby_to_block/block/motion_reach_wall_spec.rb +67 -0
  82. data/spec/models/concerns/ruby_to_block/block/motion_spec.rb +392 -0
  83. data/spec/models/concerns/ruby_to_block/block/motion_turn_spec.rb +54 -0
  84. data/spec/models/concerns/ruby_to_block/block/require_smalruby_spec.rb +39 -0
  85. data/spec/models/concerns/ruby_to_block/block/ruby_comment_spec.rb +55 -0
  86. data/spec/models/concerns/ruby_to_block/block/ruby_statement_spec.rb +113 -0
  87. data/spec/models/concerns/ruby_to_block/block/shared/block_examples.rb +44 -0
  88. data/spec/models/concerns/ruby_to_block/block/sound_spec.rb +46 -0
  89. data/spec/models/concerns/ruby_to_block/block_spec.rb +49 -0
  90. data/spec/models/concerns/ruby_to_block_spec.rb +421 -217
  91. data/spec/support/ruby_to_block.rb +10 -0
  92. metadata +108 -10
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require_relative 'shared/block_examples'
4
+
5
+ # rubocop:disable EmptyLines, LineLength
6
+
7
+ describe RubyToBlock::Block::MotionTurn, to_blocks: true do
8
+ _parts = <<-EOS
9
+ turn
10
+ EOS
11
+ describe compact_source_code(_parts), on_start_data: true do
12
+ __parts = _parts
13
+ let(:parts) { __parts }
14
+
15
+ it '結果が正しいこと' do
16
+ should eq_block_xml(<<-XML)
17
+ <block type="motion_turn" />
18
+ XML
19
+ end
20
+ end
21
+
22
+ _parts = <<-EOS
23
+ car1.turn
24
+ EOS
25
+ describe compact_source_code(_parts), character_new_data: true do
26
+ __parts = _parts
27
+ let(:parts) { __parts }
28
+
29
+ it '結果が正しいこと' do
30
+ should eq_block_xml(<<-XML)
31
+ <field name="NAME">car1</field>
32
+ <statement name="DO">
33
+ <block type="motion_turn" />
34
+ </statement>
35
+ XML
36
+ end
37
+ end
38
+
39
+ _parts = <<-EOS
40
+ turn
41
+ EOS
42
+ describe compact_source_code(_parts) do
43
+ __parts = _parts
44
+ let(:data) { __parts }
45
+
46
+ it '結果が正しいこと' do
47
+ should eq_block_xml(<<-XML)
48
+ <block type="ruby_statement">
49
+ <field name="STATEMENT">turn</field>
50
+ </block>
51
+ XML
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require_relative 'shared/block_examples'
4
+
5
+ # rubocop:disable EmptyLines, LineLength
6
+
7
+ describe RubyToBlock::Block::RequireSmalruby, to_blocks: true do
8
+ _data = 'require "smalruby"'
9
+ describe compact_source_code(_data) do
10
+ __data = _data
11
+ let(:data) { __data }
12
+
13
+ it { should eq('') }
14
+ end
15
+
16
+ _data = ' require "smalruby"'
17
+ describe compact_source_code(_data) do
18
+ __data = _data
19
+ let(:data) { __data }
20
+
21
+ it { should eq('') }
22
+ end
23
+
24
+ _data = 'require "smalruby" '
25
+ describe compact_source_code(_data) do
26
+ __data = _data
27
+ let(:data) { __data }
28
+
29
+ it { should eq('') }
30
+ end
31
+
32
+ _data = ' require "smalruby" '
33
+ describe compact_source_code(_data) do
34
+ __data = _data
35
+ let(:data) { __data }
36
+
37
+ it { should eq('') }
38
+ end
39
+ end
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require_relative 'shared/block_examples'
4
+
5
+ # rubocop:disable EmptyLines, LineLength
6
+
7
+ describe RubyToBlock::Block::RubyComment, to_blocks: true do
8
+ _data = <<-EOS
9
+ # 逃げる車
10
+ EOS
11
+ describe compact_source_code(_data) do
12
+ __data = _data
13
+ let(:data) { __data }
14
+
15
+ it '結果が正しいこと' do
16
+ should eq_block_xml(<<-XML)
17
+ <block type="ruby_comment">
18
+ <field name="COMMENT">逃げる車</field>
19
+ </block>
20
+ XML
21
+ end
22
+ end
23
+
24
+ _data = <<-EOS
25
+ # 逃げる車
26
+ EOS
27
+ describe compact_source_code(_data) do
28
+ __data = _data
29
+ let(:data) { __data }
30
+
31
+ it '結果が正しいこと' do
32
+ should eq_block_xml(<<-XML)
33
+ <block type="ruby_comment">
34
+ <field name="COMMENT"> 逃げる車</field>
35
+ </block>
36
+ XML
37
+ end
38
+ end
39
+
40
+ _data = <<-EOS
41
+ #逃げる車
42
+ EOS
43
+ describe compact_source_code(_data) do
44
+ __data = _data
45
+ let(:data) { __data }
46
+
47
+ it '結果が正しいこと' do
48
+ should eq_block_xml(<<-XML)
49
+ <block type="ruby_statement">
50
+ <field name="STATEMENT">#逃げる車</field>
51
+ </block>
52
+ XML
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,113 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require_relative 'shared/block_examples'
4
+
5
+ # rubocop:disable EmptyLines, LineLength
6
+
7
+ describe RubyToBlock::Block::RubyStatement, to_blocks: true do
8
+ parts = <<-EOS
9
+ s = :a
10
+ case s
11
+ when :a
12
+ puts "エー"
13
+ when :b
14
+ puts "ビー"
15
+ end
16
+ EOS
17
+ describe compact_source_code(parts), on_start_data: true do
18
+ _parts = parts
19
+ let(:parts) { _parts }
20
+
21
+ it '結果が正しいこと' do
22
+ should eq_block_xml(<<-XML)
23
+ <block type="ruby_statement">
24
+ <field name="STATEMENT">s = :a</field>
25
+ <next>
26
+ <block type="ruby_statement">
27
+ <field name="STATEMENT">case s</field>
28
+ <next>
29
+ <block type="ruby_statement">
30
+ <field name="STATEMENT">when :a</field>
31
+ <next>
32
+ <block type="ruby_statement">
33
+ <field name="STATEMENT"> puts &quot;エー&quot;</field>
34
+ <next>
35
+ <block type="ruby_statement">
36
+ <field name="STATEMENT">when :b</field>
37
+ <next>
38
+ <block type="ruby_statement">
39
+ <field name="STATEMENT"> puts &quot;ビー&quot;</field>
40
+ <next>
41
+ <block type="ruby_statement">
42
+ <field name="STATEMENT">end</field>
43
+ </block>
44
+ </next>
45
+ </block>
46
+ </next>
47
+ </block>
48
+ </next>
49
+ </block>
50
+ </next>
51
+ </block>
52
+ </next>
53
+ </block>
54
+ </next>
55
+ </block>
56
+ XML
57
+ end
58
+ end
59
+
60
+ parts = <<-EOS
61
+ require "smalruby"
62
+
63
+ s = :a
64
+ case s
65
+ when :a
66
+ puts "エー"
67
+ when :b
68
+ puts "ビー"
69
+ end
70
+ EOS
71
+ describe compact_source_code(parts) do
72
+ _parts = parts
73
+ let(:data) { _parts }
74
+
75
+ it '結果が正しいこと' do
76
+ should eq_block_xml(<<-XML)
77
+ <block type="ruby_statement">
78
+ <field name="STATEMENT">s = :a</field>
79
+ <next>
80
+ <block type="ruby_statement">
81
+ <field name="STATEMENT">case s</field>
82
+ <next>
83
+ <block type="ruby_statement">
84
+ <field name="STATEMENT">when :a</field>
85
+ <next>
86
+ <block type="ruby_statement">
87
+ <field name="STATEMENT"> puts &quot;エー&quot;</field>
88
+ <next>
89
+ <block type="ruby_statement">
90
+ <field name="STATEMENT">when :b</field>
91
+ <next>
92
+ <block type="ruby_statement">
93
+ <field name="STATEMENT"> puts &quot;ビー&quot;</field>
94
+ <next>
95
+ <block type="ruby_statement">
96
+ <field name="STATEMENT">end</field>
97
+ </block>
98
+ </next>
99
+ </block>
100
+ </next>
101
+ </block>
102
+ </next>
103
+ </block>
104
+ </next>
105
+ </block>
106
+ </next>
107
+ </block>
108
+ </next>
109
+ </block>
110
+ XML
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,44 @@
1
+ shared_context ':to_blocks', to_blocks: true do
2
+ let(:source_code) { SourceCode.new(data: data) }
3
+
4
+ subject { source_code.to_blocks }
5
+ end
6
+
7
+ shared_context ':character_new_data', character_new_data: true do
8
+ let(:data) {
9
+ <<-EOS.strip_heredoc
10
+ require "smalruby"
11
+
12
+ car1 = Character.new(costume: "car1.png", x: 0, y: 0, angle: 0)
13
+ #{parts}
14
+ EOS
15
+ }
16
+ end
17
+
18
+ shared_context ':on_start_data', on_start_data: true do
19
+ let(:data) {
20
+ <<-EOS.strip_heredoc
21
+ require "smalruby"
22
+
23
+ car1 = Character.new(costume: "car1.png", x: 0, y: 0, angle: 0)
24
+
25
+ car1.on(:start) do
26
+ #{parts.lines.join(' ')}
27
+ end
28
+ EOS
29
+ }
30
+ end
31
+
32
+ class EqBlockXml < RSpec::Matchers::BuiltIn::Eq
33
+ def matches?(actual)
34
+ indent = @expected.slice(/\A(\s*).*$/, 1).length
35
+ re = /\A {#{indent},}/
36
+ @actual = actual.lines.select { |l| re.match(l) }.join
37
+ @actual = actual if @actual.empty?
38
+ match(@expected, @actual)
39
+ end
40
+ end
41
+
42
+ def eq_block_xml(xml)
43
+ EqBlockXml.new(xml)
44
+ end
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require_relative 'shared/block_examples'
4
+
5
+ # rubocop:disable EmptyLines, LineLength
6
+
7
+ describe RubyToBlock::Block, '音ジャンル', to_blocks: true do
8
+ parts = <<-EOS
9
+ car1.on(:start) do
10
+ play(name: "piano_do.wav")
11
+ end
12
+ car1.play(name: "piano_do.wav")
13
+ EOS
14
+ describe compact_source_code(parts), character_new_data: true do
15
+ _parts = parts
16
+ let(:parts) { _parts }
17
+
18
+ it '結果が正しいこと' do
19
+ should eq_block_xml(<<-XML)
20
+ <field name="NAME">car1</field>
21
+ <statement name="DO">
22
+ <block type="events_on_start">
23
+ <statement name="DO">
24
+ <block type="sound_play" inline="true">
25
+ <value name="NAME">
26
+ <block type="sound_preset_sounds">
27
+ <field name="NAME">piano_do.wav</field>
28
+ </block>
29
+ </value>
30
+ </block>
31
+ </statement>
32
+ <next>
33
+ <block type="sound_play" inline="true">
34
+ <value name="NAME">
35
+ <block type="sound_preset_sounds">
36
+ <field name="NAME">piano_do.wav</field>
37
+ </block>
38
+ </value>
39
+ </block>
40
+ </next>
41
+ </block>
42
+ </statement>
43
+ XML
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,49 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ # rubocop:disable EmptyLines, LineLength
5
+
6
+ describe RubyToBlock::Block do
7
+ describe '.new' do
8
+ subject { described_class.new(type) }
9
+
10
+ context '引数がruby_statementの場合'do
11
+ let(:type) { 'ruby_statement' }
12
+
13
+ it { should be_instance_of(described_class::RubyStatement) }
14
+ end
15
+ end
16
+
17
+ describe '.statement_regexp' do
18
+ subject { described_class.statement_regexp }
19
+
20
+ it { should be_kind_of(Regexp) }
21
+ it {
22
+ expect(subject.to_s)
23
+ .to match(/#{Regexp.quote('|(?<ruby_statement>^.*$))')}$/)
24
+ }
25
+ its(:names) { should include('ruby_statement') }
26
+ end
27
+
28
+ describe '.value_regexp' do
29
+ subject { described_class.value_regexp }
30
+
31
+ it { should be_kind_of(Regexp) }
32
+ it {
33
+ expect(subject.to_s)
34
+ .to match(/#{Regexp.quote('|(?<ruby_expression>^.*$))')}$/)
35
+ }
36
+ its(:names) { should include('ruby_expression') }
37
+ end
38
+
39
+ describe '.regexp' do
40
+ subject { described_class.regexp(type) }
41
+
42
+ context '引数がruby_statementの場合'do
43
+ let(:type) { 'ruby_statement' }
44
+
45
+ it { should be_kind_of(Regexp) }
46
+ it { should eq(Regexp.new(described_class::RubyStatement.regexp)) }
47
+ end
48
+ end
49
+ end
@@ -1,268 +1,436 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require 'spec_helper'
3
-
4
- def compact_source_code(source_code)
5
- source_code.lines.map(&:strip).reject(&:empty?).join(';')[0...80]
6
- end
3
+ require_relative 'ruby_to_block/block/shared/block_examples'
7
4
 
8
5
  # rubocop:disable EmptyLines, LineLength
9
6
 
10
7
  describe RubyToBlock do
11
- describe '#to_blocks' do
12
- let(:source_code) { SourceCode.new(data: data) }
13
-
14
- subject { source_code.to_blocks }
15
-
16
- _data = <<-EOS.strip_heredoc
17
- require "smalruby"
18
- EOS
19
- describe compact_source_code(_data) do
20
- __data = _data
21
- let(:data) { __data }
22
-
23
- it { should eq('') }
24
- end
25
-
26
- _data = <<-EOS.strip_heredoc
8
+ describe '#to_blocks', to_blocks: true do
9
+ context '成功する場合' do
10
+ _data = <<-EOS
27
11
  require "smalruby"
28
12
 
29
13
  car1 = Character.new(costume: "car1.png", x: 0, y: 0, angle: 0)
30
14
 
31
15
  car1.on(:start) do
32
-
16
+ loop do
17
+ move(10)
18
+ turn_if_reach_wall
19
+ end
33
20
  end
34
- EOS
35
- describe compact_source_code(_data) do
36
- __data = _data
37
- let(:data) { __data }
21
+ EOS
22
+ describe compact_source_code(_data) do
23
+ __data = _data
24
+ let(:data) { __data }
38
25
 
39
- it '結果が正しいこと' do
40
- should eq(<<-XML.strip_heredoc)
41
- <xml xmlns="http://www.w3.org/1999/xhtml">
26
+ it '結果が正しいこと' do
27
+ should eq_block_xml(<<-XML)
42
28
  <character name="car1" x="0" y="0" angle="0" costumes="car1.png" />
43
29
  <block type="character_new">
44
30
  <field name="NAME">car1</field>
45
31
  <statement name="DO">
46
- <block type="events_on_start" />
32
+ <block type="events_on_start">
33
+ <statement name="DO">
34
+ <block type="control_loop">
35
+ <statement name="DO">
36
+ <block type="motion_move" inline="true">
37
+ <value name="STEP">
38
+ <block type="math_number">
39
+ <field name="NUM">10</field>
40
+ </block>
41
+ </value>
42
+ <next>
43
+ <block type="motion_turn_if_reach_wall" />
44
+ </next>
45
+ </block>
46
+ </statement>
47
+ </block>
48
+ </statement>
49
+ </block>
47
50
  </statement>
48
51
  </block>
49
- </xml>
50
- XML
52
+ XML
53
+ end
51
54
  end
52
- end
53
55
 
54
- _data = <<-EOS.strip_heredoc
56
+ _data = <<-EOS
55
57
  require "smalruby"
56
58
 
57
- car1 = Character.new(costume: "car1.png", x: 0, y: 0, angle: 0)
58
- cat1 = Character.new(costume: "cat1.png", x: 200, y: 150, angle: 90)
59
+ car1 = Character.new(costume: "car2.png", x: 0, y: 0, angle: 0)
60
+ # 逃げる車
59
61
 
60
62
  car1.on(:start) do
61
-
63
+ loop do
64
+ move(6)
65
+ if reach_wall?
66
+ turn
67
+ end
68
+ end
62
69
  end
63
70
 
64
- car1.on(:start) do
65
-
71
+ car1.on(:key_down, K_LEFT) do
72
+ rotate(-15)
66
73
  end
67
74
 
68
-
69
- cat1.on(:start) do
70
-
75
+ car1.on(:key_down, K_RIGHT) do
76
+ rotate(15)
71
77
  end
72
- EOS
73
- describe compact_source_code(_data) do
74
- __data = _data
75
- let(:data) { __data }
76
-
77
- it '結果が正しいこと' do
78
- should eq(<<-XML.strip_heredoc)
79
- <xml xmlns="http://www.w3.org/1999/xhtml">
80
- <character name="car1" x="0" y="0" angle="0" costumes="car1.png" />
81
- <character name="cat1" x="200" y="150" angle="90" costumes="cat1.png" />
82
- <block type="character_new">
83
- <field name="NAME">car1</field>
84
- <statement name="DO">
85
- <block type="events_on_start">
86
- <next>
87
- <block type="events_on_start" />
88
- </next>
78
+ EOS
79
+ describe compact_source_code(_data) do
80
+ __data = _data
81
+ let(:data) { __data }
82
+
83
+ it '結果が正しいこと' do
84
+ should eq_block_xml(<<-XML)
85
+ <character name="car1" x="0" y="0" angle="0" costumes="car2.png" />
86
+ <block type="ruby_comment">
87
+ <field name="COMMENT">逃げる車</field>
88
+ <next>
89
+ <block type="character_new">
90
+ <field name="NAME">car1</field>
91
+ <statement name="DO">
92
+ <block type="events_on_start">
93
+ <statement name="DO">
94
+ <block type="control_loop">
95
+ <statement name="DO">
96
+ <block type="motion_move" inline="true">
97
+ <value name="STEP">
98
+ <block type="math_number">
99
+ <field name="NUM">6</field>
100
+ </block>
101
+ </value>
102
+ <next>
103
+ <block type="control_if" inline="true">
104
+ <value name="COND">
105
+ <block type="motion_reach_wall" />
106
+ </value>
107
+ <statement name="THEN">
108
+ <block type="motion_turn" />
109
+ </statement>
110
+ </block>
111
+ </next>
112
+ </block>
113
+ </statement>
114
+ </block>
115
+ </statement>
116
+ <next>
117
+ <block type="events_on_key_push_or_down">
118
+ <field name="KEY">K_LEFT</field>
119
+ <field name="POD">down</field>
120
+ <statement name="DO">
121
+ <block type="motion_rotate_left" inline="true">
122
+ <value name="ANGLE">
123
+ <block type="math_number">
124
+ <field name="NUM">15</field>
125
+ </block>
126
+ </value>
127
+ </block>
128
+ </statement>
129
+ <next>
130
+ <block type="events_on_key_push_or_down">
131
+ <field name="KEY">K_RIGHT</field>
132
+ <field name="POD">down</field>
133
+ <statement name="DO">
134
+ <block type="motion_rotate_right" inline="true">
135
+ <value name="ANGLE">
136
+ <block type="math_number">
137
+ <field name="NUM">15</field>
138
+ </block>
139
+ </value>
140
+ </block>
141
+ </statement>
142
+ </block>
143
+ </next>
144
+ </block>
145
+ </next>
146
+ </block>
147
+ </statement>
89
148
  </block>
90
- </statement>
91
- </block>
92
- <block type="character_new">
93
- <field name="NAME">cat1</field>
94
- <statement name="DO">
95
- <block type="events_on_start" />
96
- </statement>
149
+ </next>
97
150
  </block>
98
- </xml>
99
- XML
151
+ XML
152
+ end
100
153
  end
101
- end
102
154
 
103
- _data = <<-EOS.strip_heredoc
155
+ _data = <<-EOS
104
156
  require "smalruby"
105
157
 
106
- car1 = Character.new(costume: "car1.png", x: 0, y: 0, angle: 0)
107
- cat1 = Character.new(costume: "cat1.png", x: 200, y: 150, angle: 90)
108
-
109
- car1.on(:start) do
110
-
111
- cat1.on(:start) do
112
-
158
+ car1 = Character.new(costume: "car2.png", x: 0, y: 0, angle: 0)
159
+ car2 = Character.new(costume: "car3.png", x: 0, y: 415, angle: 0)
160
+ # 追いかける車
161
+
162
+ car2.on(:start) do
163
+ loop do
164
+ point_towards(car1)
165
+ move(3)
166
+ if hit?(car1)
167
+ say(message: "追いつきました!")
168
+ else
169
+ say(message: "")
170
+ end
113
171
  end
114
172
  end
115
- EOS
116
- describe compact_source_code(_data) do
117
- __data = _data
118
- let(:data) { __data }
119
-
120
- it '結果が正しいこと' do
121
- should eq(<<-XML.strip_heredoc)
122
- <xml xmlns="http://www.w3.org/1999/xhtml">
123
- <character name="car1" x="0" y="0" angle="0" costumes="car1.png" />
124
- <character name="cat1" x="200" y="150" angle="90" costumes="cat1.png" />
125
- <block type="character_new">
126
- <field name="NAME">car1</field>
127
- <statement name="DO">
128
- <block type="events_on_start">
173
+ EOS
174
+ describe compact_source_code(_data) do
175
+ __data = _data
176
+ let(:data) { __data }
177
+
178
+ it '結果が正しいこと' do
179
+ should eq_block_xml(<<-XML)
180
+ <character name="car1" x="0" y="0" angle="0" costumes="car2.png" />
181
+ <character name="car2" x="0" y="415" angle="0" costumes="car3.png" />
182
+ <block type="ruby_comment">
183
+ <field name="COMMENT">追いかける車</field>
184
+ <next>
185
+ <block type="character_new">
186
+ <field name="NAME">car2</field>
129
187
  <statement name="DO">
130
- <block type="character_new">
131
- <field name="NAME">cat1</field>
188
+ <block type="events_on_start">
132
189
  <statement name="DO">
133
- <block type="events_on_start" />
190
+ <block type="control_loop">
191
+ <statement name="DO">
192
+ <block type="motion_point_towards_character">
193
+ <field name="CHAR">car1</field>
194
+ <next>
195
+ <block type="motion_move" inline="true">
196
+ <value name="STEP">
197
+ <block type="math_number">
198
+ <field name="NUM">3</field>
199
+ </block>
200
+ </value>
201
+ <next>
202
+ <block type="control_if_else" inline="true">
203
+ <value name="COND">
204
+ <block type="sensing_hit">
205
+ <field name="CHAR">car1</field>
206
+ </block>
207
+ </value>
208
+ <statement name="THEN">
209
+ <block type="looks_say" inline="true">
210
+ <value name="TEXT">
211
+ <block type="text">
212
+ <field name="TEXT">追いつきました!</field>
213
+ </block>
214
+ </value>
215
+ </block>
216
+ </statement>
217
+ <statement name="ELSE">
218
+ <block type="looks_say" inline="true">
219
+ <value name="TEXT">
220
+ <block type="text">
221
+ <field name="TEXT"></field>
222
+ </block>
223
+ </value>
224
+ </block>
225
+ </statement>
226
+ </block>
227
+ </next>
228
+ </block>
229
+ </next>
230
+ </block>
231
+ </statement>
232
+ </block>
134
233
  </statement>
135
234
  </block>
136
235
  </statement>
137
236
  </block>
138
- </statement>
237
+ </next>
139
238
  </block>
140
- </xml>
141
- XML
239
+ XML
240
+ end
142
241
  end
143
- end
144
242
 
145
- _data = <<-EOS.strip_heredoc
243
+ _data = <<-EOS
146
244
  require "smalruby"
147
245
 
148
- car1 = Character.new(costume: "car1.png", x: 0, y: 0, angle: 0)
246
+ car1 = Character.new(costume: "car2.png", x: 0, y: 0, angle: 0)
247
+ car2 = Character.new(costume: "car3.png", x: 0, y: 415, angle: 0)
248
+ # 逃げる車
149
249
 
150
250
  car1.on(:start) do
151
-
152
- on(:start) do
153
-
251
+ loop do
252
+ move(6)
253
+ if reach_wall?
254
+ turn
255
+ end
154
256
  end
155
257
  end
156
- EOS
157
- describe compact_source_code(_data) do
158
- __data = _data
159
- let(:data) { __data }
160
258
 
161
- it '結果が正しいこと' do
162
- should eq(<<-XML.strip_heredoc)
163
- <xml xmlns="http://www.w3.org/1999/xhtml">
164
- <character name="car1" x="0" y="0" angle="0" costumes="car1.png" />
165
- <block type="character_new">
166
- <field name="NAME">car1</field>
167
- <statement name="DO">
168
- <block type="events_on_start">
169
- <statement name="DO">
170
- <block type="events_on_start" />
171
- </statement>
172
- </block>
173
- </statement>
174
- </block>
175
- </xml>
176
- XML
177
- end
178
- end
179
-
180
- _data = <<-EOS.strip_heredoc
181
- require "smalruby"
259
+ car1.on(:key_down, K_LEFT) do
260
+ rotate(-15)
261
+ end
182
262
 
183
- car1 = Character.new(costume: "car1.png", x: 0, y: 0, angle: 0)
263
+ car1.on(:key_down, K_RIGHT) do
264
+ rotate(15)
265
+ end
184
266
 
185
- car1.on(:start) do
267
+ # 追いかける車
186
268
 
187
- s = 'a'
188
- if s == 'a'
189
- puts 'エー'
190
- elsif s == 'b'
191
- puts 'ビー'
192
- else
193
- puts 'その他'
269
+ car2.on(:start) do
270
+ loop do
271
+ point_towards(car1)
272
+ move(3)
273
+ if hit?(car1)
274
+ say(message: "追いつきました!")
275
+ else
276
+ say(message: "")
277
+ end
194
278
  end
195
279
  end
196
- EOS
197
- describe compact_source_code(_data) do
198
- __data = _data
199
- let(:data) { __data }
200
-
201
- it '結果が正しいこと' do
202
- should eq(<<-XML.strip_heredoc)
203
- <xml xmlns="http://www.w3.org/1999/xhtml">
204
- <character name="car1" x="0" y="0" angle="0" costumes="car1.png" />
205
- <block type="character_new">
206
- <field name="NAME">car1</field>
207
- <statement name="DO">
208
- <block type="events_on_start">
280
+ EOS
281
+ describe compact_source_code(_data) do
282
+ __data = _data
283
+ let(:data) { __data }
284
+
285
+ it '結果が正しいこと' do
286
+ should eq_block_xml(<<-XML)
287
+ <character name="car1" x="0" y="0" angle="0" costumes="car2.png" />
288
+ <character name="car2" x="0" y="415" angle="0" costumes="car3.png" />
289
+ <block type="ruby_comment">
290
+ <field name="COMMENT">逃げる車</field>
291
+ <next>
292
+ <block type="character_new">
293
+ <field name="NAME">car1</field>
209
294
  <statement name="DO">
210
- <block type="ruby_statement">
211
- <field name="STATEMENT">s = &apos;a&apos;</field>
295
+ <block type="events_on_start">
296
+ <statement name="DO">
297
+ <block type="control_loop">
298
+ <statement name="DO">
299
+ <block type="motion_move" inline="true">
300
+ <value name="STEP">
301
+ <block type="math_number">
302
+ <field name="NUM">6</field>
303
+ </block>
304
+ </value>
305
+ <next>
306
+ <block type="control_if" inline="true">
307
+ <value name="COND">
308
+ <block type="motion_reach_wall" />
309
+ </value>
310
+ <statement name="THEN">
311
+ <block type="motion_turn" />
312
+ </statement>
313
+ </block>
314
+ </next>
315
+ </block>
316
+ </statement>
317
+ </block>
318
+ </statement>
212
319
  <next>
213
- <block type="ruby_statement">
214
- <field name="STATEMENT">if s == &apos;a&apos;</field>
320
+ <block type="events_on_key_push_or_down">
321
+ <field name="KEY">K_LEFT</field>
322
+ <field name="POD">down</field>
323
+ <statement name="DO">
324
+ <block type="motion_rotate_left" inline="true">
325
+ <value name="ANGLE">
326
+ <block type="math_number">
327
+ <field name="NUM">15</field>
328
+ </block>
329
+ </value>
330
+ </block>
331
+ </statement>
215
332
  <next>
216
- <block type="ruby_statement">
217
- <field name="STATEMENT"> puts &apos;エー&apos;</field>
218
- <next>
219
- <block type="ruby_statement">
220
- <field name="STATEMENT">elsif s == &apos;b&apos;</field>
221
- <next>
222
- <block type="ruby_statement">
223
- <field name="STATEMENT"> puts &apos;ビー&apos;</field>
333
+ <block type="events_on_key_push_or_down">
334
+ <field name="KEY">K_RIGHT</field>
335
+ <field name="POD">down</field>
336
+ <statement name="DO">
337
+ <block type="motion_rotate_right" inline="true">
338
+ <value name="ANGLE">
339
+ <block type="math_number">
340
+ <field name="NUM">15</field>
341
+ </block>
342
+ </value>
343
+ </block>
344
+ </statement>
345
+ </block>
346
+ </next>
347
+ </block>
348
+ </next>
349
+ </block>
350
+ </statement>
351
+ <next>
352
+ <block type="ruby_comment">
353
+ <field name="COMMENT">追いかける車</field>
354
+ <next>
355
+ <block type="character_new">
356
+ <field name="NAME">car2</field>
357
+ <statement name="DO">
358
+ <block type="events_on_start">
359
+ <statement name="DO">
360
+ <block type="control_loop">
361
+ <statement name="DO">
362
+ <block type="motion_point_towards_character">
363
+ <field name="CHAR">car1</field>
224
364
  <next>
225
- <block type="ruby_statement">
226
- <field name="STATEMENT">else</field>
365
+ <block type="motion_move" inline="true">
366
+ <value name="STEP">
367
+ <block type="math_number">
368
+ <field name="NUM">3</field>
369
+ </block>
370
+ </value>
227
371
  <next>
228
- <block type="ruby_statement">
229
- <field name="STATEMENT"> puts &apos;その他&apos;</field>
230
- <next>
231
- <block type="ruby_statement">
232
- <field name="STATEMENT">end</field>
372
+ <block type="control_if_else" inline="true">
373
+ <value name="COND">
374
+ <block type="sensing_hit">
375
+ <field name="CHAR">car1</field>
233
376
  </block>
234
- </next>
377
+ </value>
378
+ <statement name="THEN">
379
+ <block type="looks_say" inline="true">
380
+ <value name="TEXT">
381
+ <block type="text">
382
+ <field name="TEXT">追いつきました!</field>
383
+ </block>
384
+ </value>
385
+ </block>
386
+ </statement>
387
+ <statement name="ELSE">
388
+ <block type="looks_say" inline="true">
389
+ <value name="TEXT">
390
+ <block type="text">
391
+ <field name="TEXT"></field>
392
+ </block>
393
+ </value>
394
+ </block>
395
+ </statement>
235
396
  </block>
236
397
  </next>
237
398
  </block>
238
399
  </next>
239
400
  </block>
240
- </next>
401
+ </statement>
241
402
  </block>
242
- </next>
403
+ </statement>
243
404
  </block>
244
- </next>
405
+ </statement>
245
406
  </block>
246
407
  </next>
247
408
  </block>
248
- </statement>
409
+ </next>
249
410
  </block>
250
- </statement>
411
+ </next>
251
412
  </block>
252
- </xml>
253
- XML
413
+ XML
414
+ end
254
415
  end
255
416
  end
256
417
 
257
- _data = <<-EOS.strip_heredoc
418
+ _data = <<-EOS
258
419
  require "smalruby"
259
420
 
260
- s = :a
261
- case s
262
- when :a
263
- puts "エー"
264
- when :b
265
- puts "ビー"
421
+ init_hardware
422
+ frog1 = Character.new(costume: "frog1.png", x: 261, y: 191, angle: 0)
423
+
424
+ frog1.on(:click) do
425
+ say(message: "ライトをぴかっとさせるでよ♪")
426
+ rgb_led_anode("D3").on(color: [51, 51, 255])
427
+ sleep(1)
428
+ rgb_led_anode("D3").on(color: [255, 255, 153])
429
+ sleep(1)
430
+ rgb_led_anode("D3").on(color: [255, 0, 0])
431
+ sleep(1)
432
+ rgb_led_anode("D3").off
433
+ say(message: "")
266
434
  end
267
435
  EOS
268
436
  describe compact_source_code(_data) do
@@ -270,28 +438,75 @@ end
270
438
  let(:data) { __data }
271
439
 
272
440
  it '結果が正しいこと' do
273
- should eq(<<-XML.strip_heredoc)
274
- <xml xmlns="http://www.w3.org/1999/xhtml">
275
- <block type="ruby_statement">
276
- <field name="STATEMENT">s = :a</field>
277
- <next>
278
- <block type="ruby_statement">
279
- <field name="STATEMENT">case s</field>
280
- <next>
281
- <block type="ruby_statement">
282
- <field name="STATEMENT">when :a</field>
441
+ should eq_block_xml(<<-XML)
442
+ <character name="frog1" x="261" y="191" angle="0" costumes="frog1.png" />
443
+ <block type="hardware_init_hardware" />
444
+ <block type="character_new">
445
+ <field name="NAME">frog1</field>
446
+ <statement name="DO">
447
+ <block type="events_on_click">
448
+ <statement name="DO">
449
+ <block type="looks_say" inline="true">
450
+ <value name="TEXT">
451
+ <block type="text">
452
+ <field name="TEXT">ライトをぴかっとさせるでよ♪</field>
453
+ </block>
454
+ </value>
283
455
  <next>
284
- <block type="ruby_statement">
285
- <field name="STATEMENT"> puts &quot;エー&quot;</field>
456
+ <block type="hardware_rgb_led_on">
457
+ <field name="AC">anode</field>
458
+ <field name="PIN">D3</field>
459
+ <field name="COLOUR">#3333ff</field>
286
460
  <next>
287
- <block type="ruby_statement">
288
- <field name="STATEMENT">when :b</field>
461
+ <block type="control_sleep" inline="true">
462
+ <value name="SEC">
463
+ <block type="math_number">
464
+ <field name="NUM">1</field>
465
+ </block>
466
+ </value>
289
467
  <next>
290
- <block type="ruby_statement">
291
- <field name="STATEMENT"> puts &quot;ビー&quot;</field>
468
+ <block type="hardware_rgb_led_on">
469
+ <field name="AC">anode</field>
470
+ <field name="PIN">D3</field>
471
+ <field name="COLOUR">#ffff99</field>
292
472
  <next>
293
- <block type="ruby_statement">
294
- <field name="STATEMENT">end</field>
473
+ <block type="control_sleep" inline="true">
474
+ <value name="SEC">
475
+ <block type="math_number">
476
+ <field name="NUM">1</field>
477
+ </block>
478
+ </value>
479
+ <next>
480
+ <block type="hardware_rgb_led_on">
481
+ <field name="AC">anode</field>
482
+ <field name="PIN">D3</field>
483
+ <field name="COLOUR">#ff0000</field>
484
+ <next>
485
+ <block type="control_sleep" inline="true">
486
+ <value name="SEC">
487
+ <block type="math_number">
488
+ <field name="NUM">1</field>
489
+ </block>
490
+ </value>
491
+ <next>
492
+ <block type="hardware_rgb_led_off">
493
+ <field name="AC">anode</field>
494
+ <field name="PIN">D3</field>
495
+ <next>
496
+ <block type="looks_say" inline="true">
497
+ <value name="TEXT">
498
+ <block type="text">
499
+ <field name="TEXT"></field>
500
+ </block>
501
+ </value>
502
+ </block>
503
+ </next>
504
+ </block>
505
+ </next>
506
+ </block>
507
+ </next>
508
+ </block>
509
+ </next>
295
510
  </block>
296
511
  </next>
297
512
  </block>
@@ -301,29 +516,18 @@ end
301
516
  </block>
302
517
  </next>
303
518
  </block>
304
- </next>
519
+ </statement>
305
520
  </block>
306
- </next>
521
+ </statement>
307
522
  </block>
308
- </xml>
309
523
  XML
310
524
  end
311
525
  end
312
526
 
313
- describe '動作確認用のモックアップ' do
314
- context '成功する場合' do
315
- let(:data) { SourceCode::SUCCESS_DATA_MOCK }
527
+ context '失敗する場合' do
528
+ let(:data) { '__FAIL__' }
316
529
 
317
- it 'XML形式のブロックを返すこと' do
318
- should eq(SourceCode::SUCCESS_XML_MOCK)
319
- end
320
- end
321
-
322
- context '失敗する場合' do
323
- let(:data) { '__FAIL__' }
324
-
325
- it { expect { subject }.to raise_error }
326
- end
530
+ it { expect { subject }.to raise_error }
327
531
  end
328
532
  end
329
533
  end