release: Merge branch 'develop' into rc/v12.0.0

This commit is contained in:
Aaron Dodson
2025-01-10 10:53:09 -08:00
20 changed files with 474 additions and 342 deletions

View File

@@ -38,7 +38,7 @@ function start() {
* If some tests are failing, load test suites individually to continue
* debugging.
*/
function loadSelected() {
async function loadSelected() {
var output = document.getElementById('importExport');
output.style.background = 'gray';
@@ -53,9 +53,12 @@ function loadSelected() {
if (boxList[i].checked) {
var testUrl = boxList[i].value;
if (testUrl) {
var xmlText = fetchFile(testUrl);
var xmlText = await fetchFile(testUrl);
if (xmlText !== null) {
fromXml(testUrl, xmlText, /* opt_append */ true);
// Clean up the workspace to normalize the position of blocks and
// thus the order of functions in the generated code.
Blockly.getMainWorkspace().cleanUp();
}
}
}
@@ -67,23 +70,24 @@ function loadSelected() {
/**
* Ask the user for a file name, then load that file's contents.
*/
function loadOther() {
async function loadOther() {
var url = window.prompt('Enter URL of test file.');
if (!url) {
return;
}
var xmlText = fetchFile(url);
var xmlText = await fetchFile(url);
if (xmlText !== null) {
fromXml(url, xmlText);
}
}
function fetchFile(xmlUrl) {
async function fetchFile(xmlUrl) {
try {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('GET', xmlUrl, false);
xmlHttp.setRequestHeader('Content-Type', 'text/xml');
xmlHttp.send('');
const response = await fetch(xmlUrl);
if (!response.ok) {
throw new Error(`Got a 404 when loading ${xmlUrl}`);
}
return response.text();
} catch (e) {
// Attempt to diagnose the problem.
var msg = 'Error: Unable to load XML data.\n';
@@ -95,7 +99,6 @@ function fetchFile(xmlUrl) {
alert(msg + '\n' + e);
return null;
}
return xmlHttp.responseText;
}
/**
@@ -188,7 +191,7 @@ function toDart() {
function changeIndex() {
var oneBasedIndex = document.getElementById('indexing').checked;
demoWorkspace.options.oneBasedIndex = oneBasedIndex;
demoWorkspace.getToolbox().flyout_.workspace_.options.oneBasedIndex = oneBasedIndex;
demoWorkspace.getToolbox().getFlyout().getWorkspace().options.oneBasedIndex = oneBasedIndex;
}
</script>

View File

@@ -78,7 +78,7 @@ async function runGeneratorsInBrowser(outputDir) {
await browser.execute(function() {
checkAll();
loadSelected();
return loadSelected();
});
await runLangGeneratorInBrowser(browser, prefix + '.js',

View File

@@ -181,16 +181,58 @@ suite('Lists', function () {
* Test cases for serialization tests.
* @type {Array<SerializationTestCase>}
*/
const testCases = makeTestCasesForBlockNotNeedingExtraState_(
const testCases = [
{
'type': 'lists_split',
'id': '1',
'fields': {
'MODE': 'SPLIT',
title: 'JSON for splitting',
json: {
type: 'lists_split',
id: '1',
extraState: {mode: 'SPLIT'},
fields: {MODE: 'SPLIT'},
inputs: {
DELIM: {
shadow: {
type: 'text',
id: '2',
fields: {
TEXT: ',',
},
},
},
},
},
assertBlockStructure: (block) => {
assert.equal(block.type, 'lists_split');
assert.deepEqual(block.outputConnection.getCheck(), ['Array']);
assert.isTrue(block.getField('MODE').getValue() === 'SPLIT');
},
},
'<mutation mode="SPLIT"></mutation>',
);
{
title: 'JSON for joining',
json: {
type: 'lists_split',
id: '1',
extraState: {mode: 'JOIN'},
fields: {MODE: 'JOIN'},
inputs: {
DELIM: {
shadow: {
type: 'text',
id: '2',
fields: {
TEXT: ',',
},
},
},
},
},
assertBlockStructure: (block) => {
assert.equal(block.type, 'lists_split');
assert.deepEqual(block.outputConnection.getCheck(), ['String']);
assert.isTrue(block.getField('MODE').getValue() === 'JOIN');
},
},
];
runSerializationTestSuite(testCases);
});
});

View File

@@ -61,6 +61,30 @@ suite('Clipboard', function () {
);
});
test('copied from a mutator pastes them into the mutator', async function () {
const block = Blockly.serialization.blocks.append(
{
'type': 'controls_if',
'id': 'blockId',
'extraState': {
'elseIfCount': 1,
},
},
this.workspace,
);
const mutatorIcon = block.getIcon(Blockly.icons.IconType.MUTATOR);
await mutatorIcon.setBubbleVisible(true);
const mutatorWorkspace = mutatorIcon.getWorkspace();
const elseIf = mutatorWorkspace.getBlocksByType('controls_if_elseif')[0];
assert.notEqual(elseIf, undefined);
assert.lengthOf(mutatorWorkspace.getAllBlocks(), 2);
assert.lengthOf(this.workspace.getAllBlocks(), 1);
const data = elseIf.toCopyData();
Blockly.clipboard.paste(data, mutatorWorkspace);
assert.lengthOf(mutatorWorkspace.getAllBlocks(), 3);
assert.lengthOf(this.workspace.getAllBlocks(), 1);
});
suite('pasted blocks are placed in unambiguous locations', function () {
test('pasted blocks are bumped to not overlap', function () {
const block = Blockly.serialization.blocks.append(