Skip to content

Commit 001c8fe

Browse files
committed
event_whenkeypressed
1 parent 97a3aab commit 001c8fe

File tree

3 files changed

+161
-11
lines changed

3 files changed

+161
-11
lines changed

src/lib/ruby-to-blocks-converter/event.js

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,75 @@
11
/* global Opal */
22
import _ from 'lodash';
33

4+
const KeyOptions = [
5+
'space',
6+
'left arrow',
7+
'right arrow',
8+
'down arrow',
9+
'up arrow',
10+
'any',
11+
'a',
12+
'b',
13+
'c',
14+
'd',
15+
'e',
16+
'f',
17+
'g',
18+
'h',
19+
'i',
20+
'j',
21+
'k',
22+
'l',
23+
'm',
24+
'n',
25+
'o',
26+
'p',
27+
'q',
28+
'r',
29+
's',
30+
't',
31+
'u',
32+
'v',
33+
'w',
34+
'x',
35+
'y',
36+
'z',
37+
'0',
38+
'1',
39+
'2',
40+
'3',
41+
'4',
42+
'5',
43+
'6',
44+
'7',
45+
'8',
46+
'9'
47+
];
48+
449
/**
550
* Event converter
651
*/
752
const EventConverter = {
853
// eslint-disable-next-line no-unused-vars
954
onSend: function (receiver, name, args, rubyBlockArgs, rubyBlock) {
1055
let block;
11-
if (this._isSelf(receiver) || receiver === Opal.nil) {
12-
switch (name) {
13-
case 'when':
56+
if ((this._isSelf(receiver) || receiver === Opal.nil) &&
57+
name === 'when' &&
58+
args.length >= 1 && args[0].type === 'sym' &&
59+
rubyBlockArgs && rubyBlockArgs.length === 0 &&
60+
rubyBlock) {
61+
switch (args[0].value) {
62+
case 'flag_clicked':
1463
if (args.length === 1) {
15-
if (args[0].type === 'sym' && args[0].value === 'flag_clicked' &&
16-
rubyBlockArgs && rubyBlockArgs.length === 0) {
17-
block = this._createBlock('event_whenflagclicked', 'hat');
18-
if (this._isBlock(rubyBlock)) {
19-
rubyBlock.parent = block.id;
20-
block.next = rubyBlock.id;
21-
}
22-
}
64+
block = this._createBlock('event_whenflagclicked', 'hat');
65+
this._setParent(rubyBlock, block);
66+
}
67+
break;
68+
case 'key_pressed':
69+
if (args.length === 2 && this._isString(args[1]) && KeyOptions.indexOf(args[1].toString()) >= 0) {
70+
block = this._createBlock('event_whenkeypressed', 'hat');
71+
this._addField(block, 'KEY_OPTION', args[1]);
72+
this._setParent(rubyBlock, block);
2373
}
2474
break;
2575
}

src/lib/ruby-to-blocks-converter/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,13 @@ class RubyToBlocksConverter {
603603
return true;
604604
}
605605

606+
_setParent (block, parent) {
607+
if (this._isBlock(block)) {
608+
block.parent = parent.id;
609+
parent.next = block.id;
610+
}
611+
}
612+
606613
_matchRubyExpression (block, regexp) {
607614
if (!this._isBlock(block) || block.opcode !== 'ruby_expression') {
608615
return false;

test/unit/lib/ruby-to-blocks-converter/event.test.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,97 @@ describe('RubyToBlocksConverter/Event', () => {
8888
expect(res).toBeFalsy();
8989
});
9090
});
91+
92+
describe('event_whenkeypressed', () => {
93+
test('normal', () => {
94+
code = 'self.when(:key_pressed, "space") { bounce_if_on_edge }';
95+
expected = [
96+
{
97+
opcode: 'event_whenkeypressed',
98+
fields: [
99+
{
100+
name: 'KEY_OPTION',
101+
value: 'space'
102+
}
103+
],
104+
next: {
105+
opcode: 'motion_ifonedgebounce'
106+
}
107+
}
108+
];
109+
convertAndExpectToEqualBlocks(converter, target, code, expected);
110+
111+
code = 'self.when(:key_pressed, "space") { bounce_if_on_edge; move(10) }';
112+
expected = [
113+
{
114+
opcode: 'event_whenkeypressed',
115+
fields: [
116+
{
117+
name: 'KEY_OPTION',
118+
value: 'space'
119+
}
120+
],
121+
next: rubyToExpected(converter, target, 'bounce_if_on_edge; move(10)')[0]
122+
}
123+
];
124+
convertAndExpectToEqualBlocks(converter, target, code, expected);
125+
});
126+
127+
test('hat', () => {
128+
code = `
129+
bounce_if_on_edge
130+
self.when(:key_pressed, "space") do
131+
end
132+
bounce_if_on_edge
133+
`;
134+
expected = [
135+
rubyToExpected(converter, target, 'bounce_if_on_edge')[0],
136+
{
137+
opcode: 'event_whenkeypressed',
138+
fields: [
139+
{
140+
name: 'KEY_OPTION',
141+
value: 'space'
142+
}
143+
]
144+
},
145+
rubyToExpected(converter, target, 'bounce_if_on_edge')[0]
146+
];
147+
convertAndExpectToEqualBlocks(converter, target, code, expected);
148+
});
149+
150+
test('invalid', () => {
151+
[
152+
'self.when(:key_pressed)',
153+
'self.when("space")',
154+
'self.when(:key_pressed, "space", 1)',
155+
'self.when(:key_pressed, "invalid key")'
156+
].forEach(c => {
157+
convertAndExpectToEqualRubyStatement(converter, target, c, c);
158+
});
159+
160+
[
161+
'self.when(:key_pressed) { bounce_if_on_edge }',
162+
'self.when(:key_pressed, "space", 1) { bounce_if_on_edge }',
163+
'self.when(:key_pressed, "invalid key") { bounce_if_on_edge }'
164+
].forEach(c => {
165+
expect(converter.targetCodeToBlocks(target, c)).toBeTruthy();
166+
const blockId = Object.keys(converter.blocks).filter(id => converter.blocks[id].topLevel)[0];
167+
expect(converter.blocks[blockId].opcode).toEqual('ruby_statement_with_block');
168+
});
169+
});
170+
171+
test('error', () => {
172+
code = `
173+
forever do
174+
self.when(:key_pressed, "space") do
175+
end
176+
end
177+
`;
178+
const res = converter.targetCodeToBlocks(target, code);
179+
expect(converter.errors).toHaveLength(1);
180+
expect(converter.errors[0].row).toEqual(2);
181+
expect(res).toBeFalsy();
182+
});
183+
});
91184
});

0 commit comments

Comments
 (0)