mirror of
https://github.com/google/blockly.git
synced 2026-01-06 08:30:13 +01:00
feat!: delete angle, colour, and multiline input fields and blocks (#7932)
* chore: delete mocha tests for angle field * feat! : delete angle field * chore(tests): delete colour tests from generator tests and golden files * chore: delete colour blocks and associated generators * chore: remove colour blocks from playgrounds * chore: delete mocha tests for colour fields * chore: fix incorrect comment * chore: delete colour field from core * chore: delete multiline input tests from generators tests and golden files * chore: delete multiline text block and associated generators * chore: remove multiline text block from playgrounds * chore: delete mocha tests for multiline input field * chore: delete multiline input field from core
This commit is contained in:
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
// Former goog.module ID: Blockly.libraryBlocks
|
// Former goog.module ID: Blockly.libraryBlocks
|
||||||
|
|
||||||
import * as colour from './colour.js';
|
|
||||||
import * as lists from './lists.js';
|
import * as lists from './lists.js';
|
||||||
import * as logic from './logic.js';
|
import * as logic from './logic.js';
|
||||||
import * as loops from './loops.js';
|
import * as loops from './loops.js';
|
||||||
@@ -18,7 +17,6 @@ import * as variablesDynamic from './variables_dynamic.js';
|
|||||||
import type {BlockDefinition} from '../core/blocks.js';
|
import type {BlockDefinition} from '../core/blocks.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
colour,
|
|
||||||
lists,
|
lists,
|
||||||
logic,
|
logic,
|
||||||
loops,
|
loops,
|
||||||
@@ -35,7 +33,6 @@ export {
|
|||||||
*/
|
*/
|
||||||
export const blocks: {[key: string]: BlockDefinition} = Object.assign(
|
export const blocks: {[key: string]: BlockDefinition} = Object.assign(
|
||||||
{},
|
{},
|
||||||
colour.blocks,
|
|
||||||
lists.blocks,
|
lists.blocks,
|
||||||
logic.blocks,
|
logic.blocks,
|
||||||
loops.blocks,
|
loops.blocks,
|
||||||
|
|||||||
112
blocks/colour.ts
112
blocks/colour.ts
@@ -1,112 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2012 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Former goog.module ID: Blockly.libraryBlocks.colour
|
|
||||||
|
|
||||||
import {
|
|
||||||
createBlockDefinitionsFromJsonArray,
|
|
||||||
defineBlocks,
|
|
||||||
} from '../core/common.js';
|
|
||||||
import '../core/field_colour.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A dictionary of the block definitions provided by this module.
|
|
||||||
*/
|
|
||||||
export const blocks = createBlockDefinitionsFromJsonArray([
|
|
||||||
// Block for colour picker.
|
|
||||||
{
|
|
||||||
'type': 'colour_picker',
|
|
||||||
'message0': '%1',
|
|
||||||
'args0': [
|
|
||||||
{
|
|
||||||
'type': 'field_colour',
|
|
||||||
'name': 'COLOUR',
|
|
||||||
'colour': '#ff0000',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'output': 'Colour',
|
|
||||||
'helpUrl': '%{BKY_COLOUR_PICKER_HELPURL}',
|
|
||||||
'style': 'colour_blocks',
|
|
||||||
'tooltip': '%{BKY_COLOUR_PICKER_TOOLTIP}',
|
|
||||||
'extensions': ['parent_tooltip_when_inline'],
|
|
||||||
},
|
|
||||||
|
|
||||||
// Block for random colour.
|
|
||||||
{
|
|
||||||
'type': 'colour_random',
|
|
||||||
'message0': '%{BKY_COLOUR_RANDOM_TITLE}',
|
|
||||||
'output': 'Colour',
|
|
||||||
'helpUrl': '%{BKY_COLOUR_RANDOM_HELPURL}',
|
|
||||||
'style': 'colour_blocks',
|
|
||||||
'tooltip': '%{BKY_COLOUR_RANDOM_TOOLTIP}',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Block for composing a colour from RGB components.
|
|
||||||
{
|
|
||||||
'type': 'colour_rgb',
|
|
||||||
'message0':
|
|
||||||
'%{BKY_COLOUR_RGB_TITLE} %{BKY_COLOUR_RGB_RED} %1 %{BKY_COLOUR_RGB_GREEN} %2 %{BKY_COLOUR_RGB_BLUE} %3',
|
|
||||||
'args0': [
|
|
||||||
{
|
|
||||||
'type': 'input_value',
|
|
||||||
'name': 'RED',
|
|
||||||
'check': 'Number',
|
|
||||||
'align': 'RIGHT',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'type': 'input_value',
|
|
||||||
'name': 'GREEN',
|
|
||||||
'check': 'Number',
|
|
||||||
'align': 'RIGHT',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'type': 'input_value',
|
|
||||||
'name': 'BLUE',
|
|
||||||
'check': 'Number',
|
|
||||||
'align': 'RIGHT',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'output': 'Colour',
|
|
||||||
'helpUrl': '%{BKY_COLOUR_RGB_HELPURL}',
|
|
||||||
'style': 'colour_blocks',
|
|
||||||
'tooltip': '%{BKY_COLOUR_RGB_TOOLTIP}',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Block for blending two colours together.
|
|
||||||
{
|
|
||||||
'type': 'colour_blend',
|
|
||||||
'message0':
|
|
||||||
'%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} ' +
|
|
||||||
'%1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3',
|
|
||||||
'args0': [
|
|
||||||
{
|
|
||||||
'type': 'input_value',
|
|
||||||
'name': 'COLOUR1',
|
|
||||||
'check': 'Colour',
|
|
||||||
'align': 'RIGHT',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'type': 'input_value',
|
|
||||||
'name': 'COLOUR2',
|
|
||||||
'check': 'Colour',
|
|
||||||
'align': 'RIGHT',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'type': 'input_value',
|
|
||||||
'name': 'RATIO',
|
|
||||||
'check': 'Number',
|
|
||||||
'align': 'RIGHT',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'output': 'Colour',
|
|
||||||
'helpUrl': '%{BKY_COLOUR_BLEND_HELPURL}',
|
|
||||||
'style': 'colour_blocks',
|
|
||||||
'tooltip': '%{BKY_COLOUR_BLEND_TOOLTIP}',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Register provided blocks.
|
|
||||||
defineBlocks(blocks);
|
|
||||||
@@ -23,7 +23,6 @@ import {
|
|||||||
createBlockDefinitionsFromJsonArray,
|
createBlockDefinitionsFromJsonArray,
|
||||||
defineBlocks,
|
defineBlocks,
|
||||||
} from '../core/common.js';
|
} from '../core/common.js';
|
||||||
import '../core/field_multilineinput.js';
|
|
||||||
import '../core/field_variable.js';
|
import '../core/field_variable.js';
|
||||||
import {ValueInput} from '../core/inputs/value_input.js';
|
import {ValueInput} from '../core/inputs/value_input.js';
|
||||||
|
|
||||||
@@ -48,38 +47,6 @@ export const blocks = createBlockDefinitionsFromJsonArray([
|
|||||||
'tooltip': '%{BKY_TEXT_TEXT_TOOLTIP}',
|
'tooltip': '%{BKY_TEXT_TEXT_TOOLTIP}',
|
||||||
'extensions': ['text_quotes', 'parent_tooltip_when_inline'],
|
'extensions': ['text_quotes', 'parent_tooltip_when_inline'],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
'type': 'text_multiline',
|
|
||||||
'message0': '%1 %2',
|
|
||||||
'args0': [
|
|
||||||
{
|
|
||||||
'type': 'field_image',
|
|
||||||
'src':
|
|
||||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAARCAYAAADpP' +
|
|
||||||
'U2iAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAdhgAAHYYBXaITgQAAABh0RVh0' +
|
|
||||||
'U29mdHdhcmUAcGFpbnQubmV0IDQuMS42/U4J6AAAAP1JREFUOE+Vks0KQUEYhjm' +
|
|
||||||
'RIja4ABtZ2dm5A3t3Ia6AUm7CylYuQRaUhZSlLZJiQbFAyRnPN33y01HOW08z88' +
|
|
||||||
'73zpwzM4F3GWOCruvGIE4/rLaV+Nq1hVGMBqzhqlxgCys4wJA65xnogMHsQ5luj' +
|
|
||||||
'nYHTejBBCK2mE4abjCgMGhNxHgDFWjDSG07kdfVa2pZMf4ZyMAdWmpZMfYOsLiD' +
|
|
||||||
'MYMjlMB+K613QISRhTnITnsYg5yUd0DETmEoMlkFOeIT/A58iyK5E18BuTBfgYX' +
|
|
||||||
'fwNJv4P9/oEBerLylOnRhygmGdPpTTBZAPkde61lbQe4moWUvYUZYLfUNftIY4z' +
|
|
||||||
'wA5X2Z9AYnQrEAAAAASUVORK5CYII=',
|
|
||||||
'width': 12,
|
|
||||||
'height': 17,
|
|
||||||
'alt': '\u00B6',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'type': 'field_multilinetext',
|
|
||||||
'name': 'TEXT',
|
|
||||||
'text': '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'output': 'String',
|
|
||||||
'style': 'text_blocks',
|
|
||||||
'helpUrl': '%{BKY_TEXT_TEXT_HELPURL}',
|
|
||||||
'tooltip': '%{BKY_TEXT_TEXT_TOOLTIP}',
|
|
||||||
'extensions': ['parent_tooltip_when_inline'],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
'type': 'text_join',
|
'type': 'text_join',
|
||||||
'message0': '',
|
'message0': '',
|
||||||
|
|||||||
@@ -50,24 +50,12 @@ import {
|
|||||||
FieldValidator,
|
FieldValidator,
|
||||||
UnattachedFieldError,
|
UnattachedFieldError,
|
||||||
} from './field.js';
|
} from './field.js';
|
||||||
import {
|
|
||||||
FieldAngle,
|
|
||||||
FieldAngleConfig,
|
|
||||||
FieldAngleFromJsonConfig,
|
|
||||||
FieldAngleValidator,
|
|
||||||
} from './field_angle.js';
|
|
||||||
import {
|
import {
|
||||||
FieldCheckbox,
|
FieldCheckbox,
|
||||||
FieldCheckboxConfig,
|
FieldCheckboxConfig,
|
||||||
FieldCheckboxFromJsonConfig,
|
FieldCheckboxFromJsonConfig,
|
||||||
FieldCheckboxValidator,
|
FieldCheckboxValidator,
|
||||||
} from './field_checkbox.js';
|
} from './field_checkbox.js';
|
||||||
import {
|
|
||||||
FieldColour,
|
|
||||||
FieldColourConfig,
|
|
||||||
FieldColourFromJsonConfig,
|
|
||||||
FieldColourValidator,
|
|
||||||
} from './field_colour.js';
|
|
||||||
import {
|
import {
|
||||||
FieldDropdown,
|
FieldDropdown,
|
||||||
FieldDropdownConfig,
|
FieldDropdownConfig,
|
||||||
@@ -88,12 +76,6 @@ import {
|
|||||||
FieldLabelFromJsonConfig,
|
FieldLabelFromJsonConfig,
|
||||||
} from './field_label.js';
|
} from './field_label.js';
|
||||||
import {FieldLabelSerializable} from './field_label_serializable.js';
|
import {FieldLabelSerializable} from './field_label_serializable.js';
|
||||||
import {
|
|
||||||
FieldMultilineInput,
|
|
||||||
FieldMultilineInputConfig,
|
|
||||||
FieldMultilineInputFromJsonConfig,
|
|
||||||
FieldMultilineInputValidator,
|
|
||||||
} from './field_multilineinput.js';
|
|
||||||
import {
|
import {
|
||||||
FieldNumber,
|
FieldNumber,
|
||||||
FieldNumberConfig,
|
FieldNumberConfig,
|
||||||
@@ -487,24 +469,12 @@ export {DeleteArea};
|
|||||||
export {DragTarget};
|
export {DragTarget};
|
||||||
export const DropDownDiv = dropDownDiv;
|
export const DropDownDiv = dropDownDiv;
|
||||||
export {Field, FieldConfig, FieldValidator, UnattachedFieldError};
|
export {Field, FieldConfig, FieldValidator, UnattachedFieldError};
|
||||||
export {
|
|
||||||
FieldAngle,
|
|
||||||
FieldAngleConfig,
|
|
||||||
FieldAngleFromJsonConfig,
|
|
||||||
FieldAngleValidator,
|
|
||||||
};
|
|
||||||
export {
|
export {
|
||||||
FieldCheckbox,
|
FieldCheckbox,
|
||||||
FieldCheckboxConfig,
|
FieldCheckboxConfig,
|
||||||
FieldCheckboxFromJsonConfig,
|
FieldCheckboxFromJsonConfig,
|
||||||
FieldCheckboxValidator,
|
FieldCheckboxValidator,
|
||||||
};
|
};
|
||||||
export {
|
|
||||||
FieldColour,
|
|
||||||
FieldColourConfig,
|
|
||||||
FieldColourFromJsonConfig,
|
|
||||||
FieldColourValidator,
|
|
||||||
};
|
|
||||||
export {
|
export {
|
||||||
FieldDropdown,
|
FieldDropdown,
|
||||||
FieldDropdownConfig,
|
FieldDropdownConfig,
|
||||||
@@ -517,12 +487,6 @@ export {
|
|||||||
export {FieldImage, FieldImageConfig, FieldImageFromJsonConfig};
|
export {FieldImage, FieldImageConfig, FieldImageFromJsonConfig};
|
||||||
export {FieldLabel, FieldLabelConfig, FieldLabelFromJsonConfig};
|
export {FieldLabel, FieldLabelConfig, FieldLabelFromJsonConfig};
|
||||||
export {FieldLabelSerializable};
|
export {FieldLabelSerializable};
|
||||||
export {
|
|
||||||
FieldMultilineInput,
|
|
||||||
FieldMultilineInputConfig,
|
|
||||||
FieldMultilineInputFromJsonConfig,
|
|
||||||
FieldMultilineInputValidator,
|
|
||||||
};
|
|
||||||
export {
|
export {
|
||||||
FieldNumber,
|
FieldNumber,
|
||||||
FieldNumberConfig,
|
FieldNumberConfig,
|
||||||
|
|||||||
@@ -1,612 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2013 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Angle input field.
|
|
||||||
*
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
// Former goog.module ID: Blockly.FieldAngle
|
|
||||||
|
|
||||||
import {BlockSvg} from './block_svg.js';
|
|
||||||
import * as browserEvents from './browser_events.js';
|
|
||||||
import * as Css from './css.js';
|
|
||||||
import * as dropDownDiv from './dropdowndiv.js';
|
|
||||||
import * as eventUtils from './events/utils.js';
|
|
||||||
import {Field, UnattachedFieldError} from './field.js';
|
|
||||||
import * as fieldRegistry from './field_registry.js';
|
|
||||||
import {
|
|
||||||
FieldInput,
|
|
||||||
FieldInputConfig,
|
|
||||||
FieldInputValidator,
|
|
||||||
} from './field_input.js';
|
|
||||||
import * as dom from './utils/dom.js';
|
|
||||||
import * as math from './utils/math.js';
|
|
||||||
import {Svg} from './utils/svg.js';
|
|
||||||
import * as userAgent from './utils/useragent.js';
|
|
||||||
import * as WidgetDiv from './widgetdiv.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for an editable angle field.
|
|
||||||
*/
|
|
||||||
export class FieldAngle extends FieldInput<number> {
|
|
||||||
/** Half the width of protractor image. */
|
|
||||||
static readonly HALF = 100 / 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Radius of protractor circle. Slightly smaller than protractor size since
|
|
||||||
* otherwise SVG crops off half the border at the edges.
|
|
||||||
*/
|
|
||||||
static readonly RADIUS: number = FieldAngle.HALF - 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default property describing which direction makes an angle field's value
|
|
||||||
* increase. Angle increases clockwise (true) or counterclockwise (false).
|
|
||||||
*/
|
|
||||||
static readonly CLOCKWISE = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default offset of 0 degrees (and all angles). Always offsets in the
|
|
||||||
* counterclockwise direction, regardless of the field's clockwise property.
|
|
||||||
* Usually either 0 (0 = right) or 90 (0 = up).
|
|
||||||
*/
|
|
||||||
static readonly OFFSET = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default maximum angle to allow before wrapping.
|
|
||||||
* Usually either 360 (for 0 to 359.9) or 180 (for -179.9 to 180).
|
|
||||||
*/
|
|
||||||
static readonly WRAP = 360;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default amount to round angles to when using a mouse or keyboard nav
|
|
||||||
* input. Must be a positive integer to support keyboard navigation.
|
|
||||||
*/
|
|
||||||
static readonly ROUND = 15;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the angle should increase as the angle picker is moved clockwise
|
|
||||||
* (true) or counterclockwise (false).
|
|
||||||
*/
|
|
||||||
private clockwise = FieldAngle.CLOCKWISE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The offset of zero degrees (and all other angles).
|
|
||||||
*/
|
|
||||||
private offset = FieldAngle.OFFSET;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum angle to allow before wrapping.
|
|
||||||
*/
|
|
||||||
private wrap = FieldAngle.WRAP;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The amount to round angles to when using a mouse or keyboard nav input.
|
|
||||||
*/
|
|
||||||
private round = FieldAngle.ROUND;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array holding info needed to unbind events.
|
|
||||||
* Used for disposing.
|
|
||||||
* Ex: [[node, name, func], [node, name, func]].
|
|
||||||
*/
|
|
||||||
private boundEvents: browserEvents.Data[] = [];
|
|
||||||
|
|
||||||
/** Dynamic red line pointing at the value's angle. */
|
|
||||||
private line: SVGLineElement | null = null;
|
|
||||||
|
|
||||||
/** Dynamic pink area extending from 0 to the value's angle. */
|
|
||||||
private gauge: SVGPathElement | null = null;
|
|
||||||
|
|
||||||
/** The degree symbol for this field. */
|
|
||||||
protected symbol_: SVGTSpanElement | null = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param value The initial value of the field. Should cast to a number.
|
|
||||||
* Defaults to 0. Also accepts Field.SKIP_SETUP if you wish to skip setup
|
|
||||||
* (only used by subclasses that want to handle configuration and setting
|
|
||||||
* the field value after their own constructors have run).
|
|
||||||
* @param validator A function that is called to validate changes to the
|
|
||||||
* field's value. Takes in a number & returns a validated number, or null
|
|
||||||
* to abort the change.
|
|
||||||
* @param config A map of options used to configure the field.
|
|
||||||
* See the [field creation documentation]{@link
|
|
||||||
* https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/angle#creation}
|
|
||||||
* for a list of properties this parameter supports.
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
value?: string | number | typeof Field.SKIP_SETUP,
|
|
||||||
validator?: FieldAngleValidator,
|
|
||||||
config?: FieldAngleConfig,
|
|
||||||
) {
|
|
||||||
super(Field.SKIP_SETUP);
|
|
||||||
|
|
||||||
if (value === Field.SKIP_SETUP) return;
|
|
||||||
if (config) {
|
|
||||||
this.configure_(config);
|
|
||||||
}
|
|
||||||
this.setValue(value);
|
|
||||||
if (validator) {
|
|
||||||
this.setValidator(validator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure the field based on the given map of options.
|
|
||||||
*
|
|
||||||
* @param config A map of options to configure the field based on.
|
|
||||||
*/
|
|
||||||
protected override configure_(config: FieldAngleConfig) {
|
|
||||||
super.configure_(config);
|
|
||||||
|
|
||||||
switch (config.mode) {
|
|
||||||
case Mode.COMPASS:
|
|
||||||
this.clockwise = true;
|
|
||||||
this.offset = 90;
|
|
||||||
break;
|
|
||||||
case Mode.PROTRACTOR:
|
|
||||||
// This is the default mode, so we could do nothing. But just to
|
|
||||||
// future-proof, we'll set it anyway.
|
|
||||||
this.clockwise = false;
|
|
||||||
this.offset = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow individual settings to override the mode setting.
|
|
||||||
if (config.clockwise) this.clockwise = config.clockwise;
|
|
||||||
if (config.offset) this.offset = config.offset;
|
|
||||||
if (config.wrap) this.wrap = config.wrap;
|
|
||||||
if (config.round) this.round = config.round;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the block UI for this field.
|
|
||||||
*/
|
|
||||||
override initView() {
|
|
||||||
super.initView();
|
|
||||||
// Add the degree symbol to the left of the number,
|
|
||||||
// even in RTL (issue #2380).
|
|
||||||
this.symbol_ = dom.createSvgElement(Svg.TSPAN, {});
|
|
||||||
this.symbol_.appendChild(document.createTextNode('°'));
|
|
||||||
this.getTextElement().appendChild(this.symbol_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Updates the angle when the field rerenders. */
|
|
||||||
protected override render_() {
|
|
||||||
super.render_();
|
|
||||||
this.updateGraph();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and show the angle field's editor.
|
|
||||||
*
|
|
||||||
* @param e Optional mouse event that triggered the field to open,
|
|
||||||
* or undefined if triggered programmatically.
|
|
||||||
*/
|
|
||||||
protected override showEditor_(e?: Event) {
|
|
||||||
// Mobile browsers have issues with in-line textareas (focus & keyboards).
|
|
||||||
const noFocus = userAgent.MOBILE || userAgent.ANDROID || userAgent.IPAD;
|
|
||||||
super.showEditor_(e, noFocus);
|
|
||||||
|
|
||||||
const editor = this.dropdownCreate();
|
|
||||||
dropDownDiv.getContentDiv().appendChild(editor);
|
|
||||||
|
|
||||||
if (this.sourceBlock_ instanceof BlockSvg) {
|
|
||||||
dropDownDiv.setColour(
|
|
||||||
this.sourceBlock_.style.colourPrimary,
|
|
||||||
this.sourceBlock_.style.colourTertiary,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
dropDownDiv.showPositionedByField(this, this.dropdownDispose.bind(this));
|
|
||||||
|
|
||||||
this.updateGraph();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the angle dropdown editor.
|
|
||||||
*
|
|
||||||
* @returns The newly created slider.
|
|
||||||
*/
|
|
||||||
private dropdownCreate(): SVGSVGElement {
|
|
||||||
const svg = dom.createSvgElement(Svg.SVG, {
|
|
||||||
'xmlns': dom.SVG_NS,
|
|
||||||
'xmlns:html': dom.HTML_NS,
|
|
||||||
'xmlns:xlink': dom.XLINK_NS,
|
|
||||||
'version': '1.1',
|
|
||||||
'height': FieldAngle.HALF * 2 + 'px',
|
|
||||||
'width': FieldAngle.HALF * 2 + 'px',
|
|
||||||
});
|
|
||||||
svg.style.touchAction = 'none';
|
|
||||||
const circle = dom.createSvgElement(
|
|
||||||
Svg.CIRCLE,
|
|
||||||
{
|
|
||||||
'cx': FieldAngle.HALF,
|
|
||||||
'cy': FieldAngle.HALF,
|
|
||||||
'r': FieldAngle.RADIUS,
|
|
||||||
'class': 'blocklyAngleCircle',
|
|
||||||
},
|
|
||||||
svg,
|
|
||||||
);
|
|
||||||
this.gauge = dom.createSvgElement(
|
|
||||||
Svg.PATH,
|
|
||||||
{'class': 'blocklyAngleGauge'},
|
|
||||||
svg,
|
|
||||||
);
|
|
||||||
this.line = dom.createSvgElement(
|
|
||||||
Svg.LINE,
|
|
||||||
{
|
|
||||||
'x1': FieldAngle.HALF,
|
|
||||||
'y1': FieldAngle.HALF,
|
|
||||||
'class': 'blocklyAngleLine',
|
|
||||||
},
|
|
||||||
svg,
|
|
||||||
);
|
|
||||||
// Draw markers around the edge.
|
|
||||||
for (let angle = 0; angle < 360; angle += 15) {
|
|
||||||
dom.createSvgElement(
|
|
||||||
Svg.LINE,
|
|
||||||
{
|
|
||||||
'x1': FieldAngle.HALF + FieldAngle.RADIUS,
|
|
||||||
'y1': FieldAngle.HALF,
|
|
||||||
'x2':
|
|
||||||
FieldAngle.HALF + FieldAngle.RADIUS - (angle % 45 === 0 ? 10 : 5),
|
|
||||||
'y2': FieldAngle.HALF,
|
|
||||||
'class': 'blocklyAngleMarks',
|
|
||||||
'transform':
|
|
||||||
'rotate(' +
|
|
||||||
angle +
|
|
||||||
',' +
|
|
||||||
FieldAngle.HALF +
|
|
||||||
',' +
|
|
||||||
FieldAngle.HALF +
|
|
||||||
')',
|
|
||||||
},
|
|
||||||
svg,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The angle picker is different from other fields in that it updates on
|
|
||||||
// mousemove even if it's not in the middle of a drag. In future we may
|
|
||||||
// change this behaviour.
|
|
||||||
this.boundEvents.push(
|
|
||||||
browserEvents.conditionalBind(svg, 'click', this, this.hide),
|
|
||||||
);
|
|
||||||
// On touch devices, the picker's value is only updated with a drag. Add
|
|
||||||
// a click handler on the drag surface to update the value if the surface
|
|
||||||
// is clicked.
|
|
||||||
this.boundEvents.push(
|
|
||||||
browserEvents.conditionalBind(
|
|
||||||
circle,
|
|
||||||
'pointerdown',
|
|
||||||
this,
|
|
||||||
this.onMouseMove_,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
this.boundEvents.push(
|
|
||||||
browserEvents.conditionalBind(
|
|
||||||
circle,
|
|
||||||
'pointermove',
|
|
||||||
this,
|
|
||||||
this.onMouseMove_,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return svg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Disposes of events and DOM-references belonging to the angle editor. */
|
|
||||||
private dropdownDispose() {
|
|
||||||
for (const event of this.boundEvents) {
|
|
||||||
browserEvents.unbind(event);
|
|
||||||
}
|
|
||||||
this.boundEvents.length = 0;
|
|
||||||
this.gauge = null;
|
|
||||||
this.line = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Hide the editor. */
|
|
||||||
private hide() {
|
|
||||||
dropDownDiv.hideIfOwner(this);
|
|
||||||
WidgetDiv.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the angle to match the mouse's position.
|
|
||||||
*
|
|
||||||
* @param e Mouse move event.
|
|
||||||
*/
|
|
||||||
protected onMouseMove_(e: PointerEvent) {
|
|
||||||
// Calculate angle.
|
|
||||||
const bBox = this.gauge!.ownerSVGElement!.getBoundingClientRect();
|
|
||||||
const dx = e.clientX - bBox.left - FieldAngle.HALF;
|
|
||||||
const dy = e.clientY - bBox.top - FieldAngle.HALF;
|
|
||||||
let angle = Math.atan(-dy / dx);
|
|
||||||
if (isNaN(angle)) {
|
|
||||||
// This shouldn't happen, but let's not let this error propagate further.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
angle = math.toDegrees(angle);
|
|
||||||
// 0: East, 90: North, 180: West, 270: South.
|
|
||||||
if (dx < 0) {
|
|
||||||
angle += 180;
|
|
||||||
} else if (dy > 0) {
|
|
||||||
angle += 360;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do offsetting.
|
|
||||||
if (this.clockwise) {
|
|
||||||
angle = this.offset + 360 - angle;
|
|
||||||
} else {
|
|
||||||
angle = 360 - (this.offset - angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.displayMouseOrKeyboardValue(angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles and displays values that are input via mouse or arrow key input.
|
|
||||||
* These values need to be rounded and wrapped before being displayed so
|
|
||||||
* that the text input's value is appropriate.
|
|
||||||
*
|
|
||||||
* @param angle New angle.
|
|
||||||
*/
|
|
||||||
private displayMouseOrKeyboardValue(angle: number) {
|
|
||||||
if (this.round) {
|
|
||||||
angle = Math.round(angle / this.round) * this.round;
|
|
||||||
}
|
|
||||||
angle = this.wrapValue(angle);
|
|
||||||
if (angle !== this.value_) {
|
|
||||||
// Intermediate value changes from user input are not confirmed until the
|
|
||||||
// user closes the editor, and may be numerous. Inhibit reporting these as
|
|
||||||
// normal block change events, and instead report them as special
|
|
||||||
// intermediate changes that do not get recorded in undo history.
|
|
||||||
const oldValue = this.value_;
|
|
||||||
this.setEditorValue_(angle, false);
|
|
||||||
if (
|
|
||||||
this.sourceBlock_ &&
|
|
||||||
eventUtils.isEnabled() &&
|
|
||||||
this.value_ !== oldValue
|
|
||||||
) {
|
|
||||||
eventUtils.fire(
|
|
||||||
new (eventUtils.get(eventUtils.BLOCK_FIELD_INTERMEDIATE_CHANGE))(
|
|
||||||
this.sourceBlock_,
|
|
||||||
this.name || null,
|
|
||||||
oldValue,
|
|
||||||
this.value_,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Redraw the graph with the current angle. */
|
|
||||||
private updateGraph() {
|
|
||||||
if (!this.gauge || !this.line) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Always display the input (i.e. getText) even if it is invalid.
|
|
||||||
let angleDegrees = Number(this.getText()) + this.offset;
|
|
||||||
angleDegrees %= 360;
|
|
||||||
let angleRadians = math.toRadians(angleDegrees);
|
|
||||||
const path = ['M ', FieldAngle.HALF, ',', FieldAngle.HALF];
|
|
||||||
let x2 = FieldAngle.HALF;
|
|
||||||
let y2 = FieldAngle.HALF;
|
|
||||||
if (!isNaN(angleRadians)) {
|
|
||||||
const clockwiseFlag = Number(this.clockwise);
|
|
||||||
const angle1 = math.toRadians(this.offset);
|
|
||||||
const x1 = Math.cos(angle1) * FieldAngle.RADIUS;
|
|
||||||
const y1 = Math.sin(angle1) * -FieldAngle.RADIUS;
|
|
||||||
if (clockwiseFlag) {
|
|
||||||
angleRadians = 2 * angle1 - angleRadians;
|
|
||||||
}
|
|
||||||
x2 += Math.cos(angleRadians) * FieldAngle.RADIUS;
|
|
||||||
y2 -= Math.sin(angleRadians) * FieldAngle.RADIUS;
|
|
||||||
// Don't ask how the flag calculations work. They just do.
|
|
||||||
let largeFlag = Math.abs(
|
|
||||||
Math.floor((angleRadians - angle1) / Math.PI) % 2,
|
|
||||||
);
|
|
||||||
if (clockwiseFlag) {
|
|
||||||
largeFlag = 1 - largeFlag;
|
|
||||||
}
|
|
||||||
path.push(
|
|
||||||
' l ',
|
|
||||||
x1,
|
|
||||||
',',
|
|
||||||
y1,
|
|
||||||
' A ',
|
|
||||||
FieldAngle.RADIUS,
|
|
||||||
',',
|
|
||||||
FieldAngle.RADIUS,
|
|
||||||
' 0 ',
|
|
||||||
largeFlag,
|
|
||||||
' ',
|
|
||||||
clockwiseFlag,
|
|
||||||
' ',
|
|
||||||
x2,
|
|
||||||
',',
|
|
||||||
y2,
|
|
||||||
' z',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this.gauge.setAttribute('d', path.join(''));
|
|
||||||
this.line.setAttribute('x2', `${x2}`);
|
|
||||||
this.line.setAttribute('y2', `${y2}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle key down to the editor.
|
|
||||||
*
|
|
||||||
* @param e Keyboard event.
|
|
||||||
*/
|
|
||||||
protected override onHtmlInputKeyDown_(e: KeyboardEvent) {
|
|
||||||
super.onHtmlInputKeyDown_(e);
|
|
||||||
const block = this.getSourceBlock();
|
|
||||||
if (!block) {
|
|
||||||
throw new UnattachedFieldError();
|
|
||||||
}
|
|
||||||
|
|
||||||
let multiplier = 0;
|
|
||||||
switch (e.key) {
|
|
||||||
case 'ArrowLeft':
|
|
||||||
// decrement (increment in RTL)
|
|
||||||
multiplier = block.RTL ? 1 : -1;
|
|
||||||
break;
|
|
||||||
case 'ArrowRight':
|
|
||||||
// increment (decrement in RTL)
|
|
||||||
multiplier = block.RTL ? -1 : 1;
|
|
||||||
break;
|
|
||||||
case 'ArrowDown':
|
|
||||||
// decrement
|
|
||||||
multiplier = -1;
|
|
||||||
break;
|
|
||||||
case 'ArrowUp':
|
|
||||||
// increment
|
|
||||||
multiplier = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (multiplier) {
|
|
||||||
const value = this.getValue() as number;
|
|
||||||
this.displayMouseOrKeyboardValue(value + multiplier * this.round);
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensure that the input value is a valid angle.
|
|
||||||
*
|
|
||||||
* @param newValue The input value.
|
|
||||||
* @returns A valid angle, or null if invalid.
|
|
||||||
*/
|
|
||||||
protected override doClassValidation_(newValue?: any): number | null {
|
|
||||||
const value = Number(newValue);
|
|
||||||
if (isNaN(value) || !isFinite(value)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this.wrapValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wraps the value so that it is in the range (-360 + wrap, wrap).
|
|
||||||
*
|
|
||||||
* @param value The value to wrap.
|
|
||||||
* @returns The wrapped value.
|
|
||||||
*/
|
|
||||||
private wrapValue(value: number): number {
|
|
||||||
value %= 360;
|
|
||||||
if (value < 0) {
|
|
||||||
value += 360;
|
|
||||||
}
|
|
||||||
if (value > this.wrap) {
|
|
||||||
value -= 360;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a FieldAngle from a JSON arg object.
|
|
||||||
*
|
|
||||||
* @param options A JSON object with options (angle).
|
|
||||||
* @returns The new field instance.
|
|
||||||
* @nocollapse
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static fromJson(options: FieldAngleFromJsonConfig): FieldAngle {
|
|
||||||
// `this` might be a subclass of FieldAngle if that class doesn't override
|
|
||||||
// the static fromJson method.
|
|
||||||
return new this(options.angle, undefined, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldRegistry.register('field_angle', FieldAngle);
|
|
||||||
|
|
||||||
FieldAngle.prototype.DEFAULT_VALUE = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CSS for angle field.
|
|
||||||
*/
|
|
||||||
Css.register(`
|
|
||||||
.blocklyAngleCircle {
|
|
||||||
stroke: #444;
|
|
||||||
stroke-width: 1;
|
|
||||||
fill: #ddd;
|
|
||||||
fill-opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklyAngleMarks {
|
|
||||||
stroke: #444;
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklyAngleGauge {
|
|
||||||
fill: #f88;
|
|
||||||
fill-opacity: 0.8;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklyAngleLine {
|
|
||||||
stroke: #f00;
|
|
||||||
stroke-width: 2;
|
|
||||||
stroke-linecap: round;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The two main modes of the angle field.
|
|
||||||
* Compass specifies:
|
|
||||||
* - clockwise: true
|
|
||||||
* - offset: 90
|
|
||||||
* - wrap: 0
|
|
||||||
* - round: 15
|
|
||||||
*
|
|
||||||
* Protractor specifies:
|
|
||||||
* - clockwise: false
|
|
||||||
* - offset: 0
|
|
||||||
* - wrap: 0
|
|
||||||
* - round: 15
|
|
||||||
*/
|
|
||||||
export enum Mode {
|
|
||||||
COMPASS = 'compass',
|
|
||||||
PROTRACTOR = 'protractor',
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extra configuration options for the angle field.
|
|
||||||
*/
|
|
||||||
export interface FieldAngleConfig extends FieldInputConfig {
|
|
||||||
mode?: Mode;
|
|
||||||
clockwise?: boolean;
|
|
||||||
offset?: number;
|
|
||||||
wrap?: number;
|
|
||||||
round?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fromJson configuration options for the angle field.
|
|
||||||
*/
|
|
||||||
export interface FieldAngleFromJsonConfig extends FieldAngleConfig {
|
|
||||||
angle?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function that is called to validate changes to the field's value before
|
|
||||||
* they are set.
|
|
||||||
*
|
|
||||||
* @see {@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/validators#return_values}
|
|
||||||
* @param newValue The value to be validated.
|
|
||||||
* @returns One of three instructions for setting the new value: `T`, `null`,
|
|
||||||
* or `undefined`.
|
|
||||||
*
|
|
||||||
* - `T` to set this function's returned value instead of `newValue`.
|
|
||||||
*
|
|
||||||
* - `null` to invoke `doValueInvalid_` and not set a value.
|
|
||||||
*
|
|
||||||
* - `undefined` to set `newValue` as is.
|
|
||||||
*/
|
|
||||||
export type FieldAngleValidator = FieldInputValidator<number>;
|
|
||||||
@@ -1,721 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2012 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Colour input field.
|
|
||||||
*
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
// Former goog.module ID: Blockly.FieldColour
|
|
||||||
|
|
||||||
// Unused import preserved for side-effects. Remove if unneeded.
|
|
||||||
import './events/events_block_change.js';
|
|
||||||
|
|
||||||
import {BlockSvg} from './block_svg.js';
|
|
||||||
import * as browserEvents from './browser_events.js';
|
|
||||||
import * as Css from './css.js';
|
|
||||||
import * as dom from './utils/dom.js';
|
|
||||||
import * as dropDownDiv from './dropdowndiv.js';
|
|
||||||
import {
|
|
||||||
Field,
|
|
||||||
FieldConfig,
|
|
||||||
FieldValidator,
|
|
||||||
UnattachedFieldError,
|
|
||||||
} from './field.js';
|
|
||||||
import * as fieldRegistry from './field_registry.js';
|
|
||||||
import * as aria from './utils/aria.js';
|
|
||||||
import * as colour from './utils/colour.js';
|
|
||||||
import * as idGenerator from './utils/idgenerator.js';
|
|
||||||
import {Size} from './utils/size.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for a colour input field.
|
|
||||||
*/
|
|
||||||
export class FieldColour extends Field<string> {
|
|
||||||
/**
|
|
||||||
* An array of colour strings for the palette.
|
|
||||||
* Copied from goog.ui.ColorPicker.SIMPLE_GRID_COLORS
|
|
||||||
* All colour pickers use this unless overridden with setColours.
|
|
||||||
*/
|
|
||||||
// prettier-ignore
|
|
||||||
static COLOURS: string[] = [
|
|
||||||
// grays
|
|
||||||
'#ffffff', '#cccccc', '#c0c0c0', '#999999',
|
|
||||||
'#666666', '#333333', '#000000', // reds
|
|
||||||
'#ffcccc', '#ff6666', '#ff0000', '#cc0000',
|
|
||||||
'#990000', '#660000', '#330000', // oranges
|
|
||||||
'#ffcc99', '#ff9966', '#ff9900', '#ff6600',
|
|
||||||
'#cc6600', '#993300', '#663300', // yellows
|
|
||||||
'#ffff99', '#ffff66', '#ffcc66', '#ffcc33',
|
|
||||||
'#cc9933', '#996633', '#663333', // olives
|
|
||||||
'#ffffcc', '#ffff33', '#ffff00', '#ffcc00',
|
|
||||||
'#999900', '#666600', '#333300', // greens
|
|
||||||
'#99ff99', '#66ff99', '#33ff33', '#33cc00',
|
|
||||||
'#009900', '#006600', '#003300', // turquoises
|
|
||||||
'#99ffff', '#33ffff', '#66cccc', '#00cccc',
|
|
||||||
'#339999', '#336666', '#003333', // blues
|
|
||||||
'#ccffff', '#66ffff', '#33ccff', '#3366ff',
|
|
||||||
'#3333ff', '#000099', '#000066', // purples
|
|
||||||
'#ccccff', '#9999ff', '#6666cc', '#6633ff',
|
|
||||||
'#6600cc', '#333399', '#330099', // violets
|
|
||||||
'#ffccff', '#ff99ff', '#cc66cc', '#cc33cc',
|
|
||||||
'#993399', '#663366', '#330033',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of tooltip strings for the palette. If not the same length as
|
|
||||||
* COLOURS, the colour's hex code will be used for any missing titles.
|
|
||||||
* All colour pickers use this unless overridden with setColours.
|
|
||||||
*/
|
|
||||||
static TITLES: string[] = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of columns in the palette.
|
|
||||||
* All colour pickers use this unless overridden with setColumns.
|
|
||||||
*/
|
|
||||||
static COLUMNS = 7;
|
|
||||||
|
|
||||||
/** The field's colour picker element. */
|
|
||||||
private picker: HTMLElement | null = null;
|
|
||||||
|
|
||||||
/** Index of the currently highlighted element. */
|
|
||||||
private highlightedIndex: number | null = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array holding info needed to unbind events.
|
|
||||||
* Used for disposing.
|
|
||||||
* Ex: [[node, name, func], [node, name, func]].
|
|
||||||
*/
|
|
||||||
private boundEvents: browserEvents.Data[] = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serializable fields are saved by the serializer, non-serializable fields
|
|
||||||
* are not. Editable fields should also be serializable.
|
|
||||||
*/
|
|
||||||
override SERIALIZABLE = true;
|
|
||||||
|
|
||||||
/** Mouse cursor style when over the hotspot that initiates the editor. */
|
|
||||||
override CURSOR = 'default';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to tell if the field needs to be rendered the next time the block is
|
|
||||||
* rendered. Colour fields are statically sized, and only need to be
|
|
||||||
* rendered at initialization.
|
|
||||||
*/
|
|
||||||
protected override isDirty_ = false;
|
|
||||||
|
|
||||||
/** Array of colours used by this field. If null, use the global list. */
|
|
||||||
private colours: string[] | null = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array of colour tooltips used by this field. If null, use the global
|
|
||||||
* list.
|
|
||||||
*/
|
|
||||||
private titles: string[] | null = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of colour columns used by this field. If 0, use the global
|
|
||||||
* setting. By default use the global constants for columns.
|
|
||||||
*/
|
|
||||||
private columns = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param value The initial value of the field. Should be in '#rrggbb'
|
|
||||||
* format. Defaults to the first value in the default colour array. Also
|
|
||||||
* accepts Field.SKIP_SETUP if you wish to skip setup (only used by
|
|
||||||
* subclasses that want to handle configuration and setting the field
|
|
||||||
* value after their own constructors have run).
|
|
||||||
* @param validator A function that is called to validate changes to the
|
|
||||||
* field's value. Takes in a colour string & returns a validated colour
|
|
||||||
* string ('#rrggbb' format), or null to abort the change.
|
|
||||||
* @param config A map of options used to configure the field.
|
|
||||||
* See the [field creation documentation]{@link
|
|
||||||
* https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/colour}
|
|
||||||
* for a list of properties this parameter supports.
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
value?: string | typeof Field.SKIP_SETUP,
|
|
||||||
validator?: FieldColourValidator,
|
|
||||||
config?: FieldColourConfig,
|
|
||||||
) {
|
|
||||||
super(Field.SKIP_SETUP);
|
|
||||||
|
|
||||||
if (value === Field.SKIP_SETUP) return;
|
|
||||||
if (config) {
|
|
||||||
this.configure_(config);
|
|
||||||
}
|
|
||||||
this.setValue(value);
|
|
||||||
if (validator) {
|
|
||||||
this.setValidator(validator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure the field based on the given map of options.
|
|
||||||
*
|
|
||||||
* @param config A map of options to configure the field based on.
|
|
||||||
*/
|
|
||||||
protected override configure_(config: FieldColourConfig) {
|
|
||||||
super.configure_(config);
|
|
||||||
if (config.colourOptions) this.colours = config.colourOptions;
|
|
||||||
if (config.colourTitles) this.titles = config.colourTitles;
|
|
||||||
if (config.columns) this.columns = config.columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the block UI for this colour field.
|
|
||||||
*/
|
|
||||||
override initView() {
|
|
||||||
this.size_ = new Size(
|
|
||||||
this.getConstants()!.FIELD_COLOUR_DEFAULT_WIDTH,
|
|
||||||
this.getConstants()!.FIELD_COLOUR_DEFAULT_HEIGHT,
|
|
||||||
);
|
|
||||||
this.createBorderRect_();
|
|
||||||
this.getBorderRect().style['fillOpacity'] = '1';
|
|
||||||
this.getBorderRect().setAttribute('stroke', '#fff');
|
|
||||||
if (this.isFullBlockField()) {
|
|
||||||
this.clickTarget_ = (this.sourceBlock_ as BlockSvg).getSvgRoot();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override isFullBlockField(): boolean {
|
|
||||||
const block = this.getSourceBlock();
|
|
||||||
if (!block) throw new UnattachedFieldError();
|
|
||||||
|
|
||||||
const constants = this.getConstants();
|
|
||||||
return block.isSimpleReporter() && !!constants?.FIELD_COLOUR_FULL_BLOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates text field to match the colour/style of the block.
|
|
||||||
*/
|
|
||||||
override applyColour() {
|
|
||||||
const block = this.getSourceBlock() as BlockSvg | null;
|
|
||||||
if (!block) throw new UnattachedFieldError();
|
|
||||||
|
|
||||||
if (!this.fieldGroup_) return;
|
|
||||||
|
|
||||||
const borderRect = this.borderRect_;
|
|
||||||
if (!borderRect) {
|
|
||||||
throw new Error('The border rect has not been initialized');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.isFullBlockField()) {
|
|
||||||
borderRect.style.display = 'block';
|
|
||||||
borderRect.style.fill = this.getValue() as string;
|
|
||||||
} else {
|
|
||||||
borderRect.style.display = 'none';
|
|
||||||
// In general, do *not* let fields control the color of blocks. Having the
|
|
||||||
// field control the color is unexpected, and could have performance
|
|
||||||
// impacts.
|
|
||||||
block.pathObject.svgPath.setAttribute('fill', this.getValue() as string);
|
|
||||||
block.pathObject.svgPath.setAttribute('stroke', '#fff');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the height and width of the field.
|
|
||||||
*
|
|
||||||
* This should *in general* be the only place render_ gets called from.
|
|
||||||
*
|
|
||||||
* @returns Height and width.
|
|
||||||
*/
|
|
||||||
override getSize(): Size {
|
|
||||||
if (this.getConstants()?.FIELD_COLOUR_FULL_BLOCK) {
|
|
||||||
// In general, do *not* let fields control the color of blocks. Having the
|
|
||||||
// field control the color is unexpected, and could have performance
|
|
||||||
// impacts.
|
|
||||||
// Full block fields have more control of the block than they should
|
|
||||||
// (i.e. updating fill colour). Whenever we get the size, the field may
|
|
||||||
// no longer be a full-block field, so we need to rerender.
|
|
||||||
this.render_();
|
|
||||||
this.isDirty_ = false;
|
|
||||||
}
|
|
||||||
return super.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the colour of the block to reflect whether this is a full
|
|
||||||
* block field or not.
|
|
||||||
*/
|
|
||||||
protected override render_() {
|
|
||||||
super.render_();
|
|
||||||
|
|
||||||
const block = this.getSourceBlock() as BlockSvg | null;
|
|
||||||
if (!block) throw new UnattachedFieldError();
|
|
||||||
// Calling applyColour updates the UI (full-block vs non-full-block) for the
|
|
||||||
// colour field, and the colour of the field/block.
|
|
||||||
block.applyColour();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the size of the field based on whether it is a full block field
|
|
||||||
* or not.
|
|
||||||
*
|
|
||||||
* @param margin margin to use when positioning the field.
|
|
||||||
*/
|
|
||||||
protected updateSize_(margin?: number) {
|
|
||||||
const constants = this.getConstants();
|
|
||||||
let totalWidth;
|
|
||||||
let totalHeight;
|
|
||||||
if (this.isFullBlockField()) {
|
|
||||||
const xOffset = margin ?? 0;
|
|
||||||
totalWidth = xOffset * 2;
|
|
||||||
totalHeight = constants!.FIELD_TEXT_HEIGHT;
|
|
||||||
} else {
|
|
||||||
totalWidth = constants!.FIELD_COLOUR_DEFAULT_WIDTH;
|
|
||||||
totalHeight = constants!.FIELD_COLOUR_DEFAULT_HEIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.size_.height = totalHeight;
|
|
||||||
this.size_.width = totalWidth;
|
|
||||||
|
|
||||||
this.positionBorderRect_();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensure that the input value is a valid colour.
|
|
||||||
*
|
|
||||||
* @param newValue The input value.
|
|
||||||
* @returns A valid colour, or null if invalid.
|
|
||||||
*/
|
|
||||||
protected override doClassValidation_(newValue?: any): string | null {
|
|
||||||
if (typeof newValue !== 'string') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return colour.parse(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the text for this field. Used when the block is collapsed.
|
|
||||||
*
|
|
||||||
* @returns Text representing the value of this field.
|
|
||||||
*/
|
|
||||||
override getText(): string {
|
|
||||||
let colour = this.value_ as string;
|
|
||||||
// Try to use #rgb format if possible, rather than #rrggbb.
|
|
||||||
if (/^#(.)\1(.)\2(.)\3$/.test(colour)) {
|
|
||||||
colour = '#' + colour[1] + colour[3] + colour[5];
|
|
||||||
}
|
|
||||||
return colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a custom colour grid for this field.
|
|
||||||
*
|
|
||||||
* @param colours Array of colours for this block, or null to use default
|
|
||||||
* (FieldColour.COLOURS).
|
|
||||||
* @param titles Optional array of colour tooltips, or null to use default
|
|
||||||
* (FieldColour.TITLES).
|
|
||||||
* @returns Returns itself (for method chaining).
|
|
||||||
*/
|
|
||||||
setColours(colours: string[], titles?: string[]): FieldColour {
|
|
||||||
this.colours = colours;
|
|
||||||
if (titles) {
|
|
||||||
this.titles = titles;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a custom grid size for this field.
|
|
||||||
*
|
|
||||||
* @param columns Number of columns for this block, or 0 to use default
|
|
||||||
* (FieldColour.COLUMNS).
|
|
||||||
* @returns Returns itself (for method chaining).
|
|
||||||
*/
|
|
||||||
setColumns(columns: number): FieldColour {
|
|
||||||
this.columns = columns;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create and show the colour field's editor. */
|
|
||||||
protected override showEditor_() {
|
|
||||||
this.dropdownCreate();
|
|
||||||
dropDownDiv.getContentDiv().appendChild(this.picker!);
|
|
||||||
|
|
||||||
dropDownDiv.showPositionedByField(this, this.dropdownDispose.bind(this));
|
|
||||||
|
|
||||||
// Focus so we can start receiving keyboard events.
|
|
||||||
this.picker!.focus({preventScroll: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a click on a colour cell.
|
|
||||||
*
|
|
||||||
* @param e Mouse event.
|
|
||||||
*/
|
|
||||||
private onClick(e: PointerEvent) {
|
|
||||||
const cell = e.target as Element;
|
|
||||||
const colour = cell && cell.getAttribute('data-colour');
|
|
||||||
if (colour !== null) {
|
|
||||||
this.setValue(colour);
|
|
||||||
dropDownDiv.hideIfOwner(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a key down event. Navigate around the grid with the
|
|
||||||
* arrow keys. Enter selects the highlighted colour.
|
|
||||||
*
|
|
||||||
* @param e Keyboard event.
|
|
||||||
*/
|
|
||||||
private onKeyDown(e: KeyboardEvent) {
|
|
||||||
let handled = true;
|
|
||||||
let highlighted: HTMLElement | null;
|
|
||||||
switch (e.key) {
|
|
||||||
case 'ArrowUp':
|
|
||||||
this.moveHighlightBy(0, -1);
|
|
||||||
break;
|
|
||||||
case 'ArrowDown':
|
|
||||||
this.moveHighlightBy(0, 1);
|
|
||||||
break;
|
|
||||||
case 'ArrowLeft':
|
|
||||||
this.moveHighlightBy(-1, 0);
|
|
||||||
break;
|
|
||||||
case 'ArrowRight':
|
|
||||||
this.moveHighlightBy(1, 0);
|
|
||||||
break;
|
|
||||||
case 'Enter':
|
|
||||||
// Select the highlighted colour.
|
|
||||||
highlighted = this.getHighlighted();
|
|
||||||
if (highlighted) {
|
|
||||||
const colour = highlighted.getAttribute('data-colour');
|
|
||||||
if (colour !== null) {
|
|
||||||
this.setValue(colour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dropDownDiv.hideWithoutAnimation();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
handled = false;
|
|
||||||
}
|
|
||||||
if (handled) {
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move the currently highlighted position by dx and dy.
|
|
||||||
*
|
|
||||||
* @param dx Change of x.
|
|
||||||
* @param dy Change of y.
|
|
||||||
*/
|
|
||||||
private moveHighlightBy(dx: number, dy: number) {
|
|
||||||
if (!this.highlightedIndex) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const colours = this.colours || FieldColour.COLOURS;
|
|
||||||
const columns = this.columns || FieldColour.COLUMNS;
|
|
||||||
|
|
||||||
// Get the current x and y coordinates.
|
|
||||||
let x = this.highlightedIndex % columns;
|
|
||||||
let y = Math.floor(this.highlightedIndex / columns);
|
|
||||||
|
|
||||||
// Add the offset.
|
|
||||||
x += dx;
|
|
||||||
y += dy;
|
|
||||||
|
|
||||||
if (dx < 0) {
|
|
||||||
// Move left one grid cell, even in RTL.
|
|
||||||
// Loop back to the end of the previous row if we have room.
|
|
||||||
if (x < 0 && y > 0) {
|
|
||||||
x = columns - 1;
|
|
||||||
y--;
|
|
||||||
} else if (x < 0) {
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
} else if (dx > 0) {
|
|
||||||
// Move right one grid cell, even in RTL.
|
|
||||||
// Loop to the start of the next row, if there's room.
|
|
||||||
if (x > columns - 1 && y < Math.floor(colours.length / columns) - 1) {
|
|
||||||
x = 0;
|
|
||||||
y++;
|
|
||||||
} else if (x > columns - 1) {
|
|
||||||
x--;
|
|
||||||
}
|
|
||||||
} else if (dy < 0) {
|
|
||||||
// Move up one grid cell, stop at the top.
|
|
||||||
if (y < 0) {
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
} else if (dy > 0) {
|
|
||||||
// Move down one grid cell, stop at the bottom.
|
|
||||||
if (y > Math.floor(colours.length / columns) - 1) {
|
|
||||||
y = Math.floor(colours.length / columns) - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the highlight to the new coordinates.
|
|
||||||
const cell = this.picker!.childNodes[y].childNodes[x] as Element;
|
|
||||||
const index = y * columns + x;
|
|
||||||
this.setHighlightedCell(cell, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a mouse move event. Highlight the hovered colour.
|
|
||||||
*
|
|
||||||
* @param e Mouse event.
|
|
||||||
*/
|
|
||||||
private onMouseMove(e: PointerEvent) {
|
|
||||||
const cell = e.target as Element;
|
|
||||||
const index = cell && Number(cell.getAttribute('data-index'));
|
|
||||||
if (index !== null && index !== this.highlightedIndex) {
|
|
||||||
this.setHighlightedCell(cell, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle a mouse enter event. Focus the picker. */
|
|
||||||
private onMouseEnter() {
|
|
||||||
this.picker?.focus({preventScroll: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a mouse leave event. Blur the picker and unhighlight
|
|
||||||
* the currently highlighted colour.
|
|
||||||
*/
|
|
||||||
private onMouseLeave() {
|
|
||||||
this.picker?.blur();
|
|
||||||
const highlighted = this.getHighlighted();
|
|
||||||
if (highlighted) {
|
|
||||||
dom.removeClass(highlighted, 'blocklyColourHighlighted');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the currently highlighted item (if any).
|
|
||||||
*
|
|
||||||
* @returns Highlighted item (null if none).
|
|
||||||
*/
|
|
||||||
private getHighlighted(): HTMLElement | null {
|
|
||||||
if (!this.highlightedIndex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const columns = this.columns || FieldColour.COLUMNS;
|
|
||||||
const x = this.highlightedIndex % columns;
|
|
||||||
const y = Math.floor(this.highlightedIndex / columns);
|
|
||||||
const row = this.picker!.childNodes[y];
|
|
||||||
if (!row) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return row.childNodes[x] as HTMLElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the currently highlighted cell.
|
|
||||||
*
|
|
||||||
* @param cell The new cell to highlight.
|
|
||||||
* @param index The index of the new cell.
|
|
||||||
*/
|
|
||||||
private setHighlightedCell(cell: Element, index: number) {
|
|
||||||
// Unhighlight the current item.
|
|
||||||
const highlighted = this.getHighlighted();
|
|
||||||
if (highlighted) {
|
|
||||||
dom.removeClass(highlighted, 'blocklyColourHighlighted');
|
|
||||||
}
|
|
||||||
// Highlight new item.
|
|
||||||
dom.addClass(cell, 'blocklyColourHighlighted');
|
|
||||||
// Set new highlighted index.
|
|
||||||
this.highlightedIndex = index;
|
|
||||||
|
|
||||||
// Update accessibility roles.
|
|
||||||
const cellId = cell.getAttribute('id');
|
|
||||||
if (cellId && this.picker) {
|
|
||||||
aria.setState(this.picker, aria.State.ACTIVEDESCENDANT, cellId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a colour picker dropdown editor. */
|
|
||||||
private dropdownCreate() {
|
|
||||||
const columns = this.columns || FieldColour.COLUMNS;
|
|
||||||
const colours = this.colours || FieldColour.COLOURS;
|
|
||||||
const titles = this.titles || FieldColour.TITLES;
|
|
||||||
const selectedColour = this.getValue();
|
|
||||||
// Create the palette.
|
|
||||||
const table = document.createElement('table');
|
|
||||||
table.className = 'blocklyColourTable';
|
|
||||||
table.tabIndex = 0;
|
|
||||||
table.dir = 'ltr';
|
|
||||||
aria.setRole(table, aria.Role.GRID);
|
|
||||||
aria.setState(table, aria.State.EXPANDED, true);
|
|
||||||
aria.setState(
|
|
||||||
table,
|
|
||||||
aria.State.ROWCOUNT,
|
|
||||||
Math.floor(colours.length / columns),
|
|
||||||
);
|
|
||||||
aria.setState(table, aria.State.COLCOUNT, columns);
|
|
||||||
let row: Element;
|
|
||||||
for (let i = 0; i < colours.length; i++) {
|
|
||||||
if (i % columns === 0) {
|
|
||||||
row = document.createElement('tr');
|
|
||||||
aria.setRole(row, aria.Role.ROW);
|
|
||||||
table.appendChild(row);
|
|
||||||
}
|
|
||||||
const cell = document.createElement('td');
|
|
||||||
row!.appendChild(cell);
|
|
||||||
// This becomes the value, if clicked.
|
|
||||||
cell.setAttribute('data-colour', colours[i]);
|
|
||||||
cell.title = titles[i] || colours[i];
|
|
||||||
cell.id = idGenerator.getNextUniqueId();
|
|
||||||
cell.setAttribute('data-index', `${i}`);
|
|
||||||
aria.setRole(cell, aria.Role.GRIDCELL);
|
|
||||||
aria.setState(cell, aria.State.LABEL, colours[i]);
|
|
||||||
aria.setState(cell, aria.State.SELECTED, colours[i] === selectedColour);
|
|
||||||
cell.style.backgroundColor = colours[i];
|
|
||||||
if (colours[i] === selectedColour) {
|
|
||||||
cell.className = 'blocklyColourSelected';
|
|
||||||
this.highlightedIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure event handler on the table to listen for any event in a cell.
|
|
||||||
this.boundEvents.push(
|
|
||||||
browserEvents.conditionalBind(
|
|
||||||
table,
|
|
||||||
'pointerdown',
|
|
||||||
this,
|
|
||||||
this.onClick,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
this.boundEvents.push(
|
|
||||||
browserEvents.conditionalBind(
|
|
||||||
table,
|
|
||||||
'pointermove',
|
|
||||||
this,
|
|
||||||
this.onMouseMove,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
this.boundEvents.push(
|
|
||||||
browserEvents.conditionalBind(
|
|
||||||
table,
|
|
||||||
'pointerenter',
|
|
||||||
this,
|
|
||||||
this.onMouseEnter,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
this.boundEvents.push(
|
|
||||||
browserEvents.conditionalBind(
|
|
||||||
table,
|
|
||||||
'pointerleave',
|
|
||||||
this,
|
|
||||||
this.onMouseLeave,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
this.boundEvents.push(
|
|
||||||
browserEvents.conditionalBind(
|
|
||||||
table,
|
|
||||||
'keydown',
|
|
||||||
this,
|
|
||||||
this.onKeyDown,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
this.picker = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Disposes of events and DOM-references belonging to the colour editor. */
|
|
||||||
private dropdownDispose() {
|
|
||||||
for (const event of this.boundEvents) {
|
|
||||||
browserEvents.unbind(event);
|
|
||||||
}
|
|
||||||
this.boundEvents.length = 0;
|
|
||||||
this.picker = null;
|
|
||||||
this.highlightedIndex = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a FieldColour from a JSON arg object.
|
|
||||||
*
|
|
||||||
* @param options A JSON object with options (colour).
|
|
||||||
* @returns The new field instance.
|
|
||||||
* @nocollapse
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static fromJson(options: FieldColourFromJsonConfig): FieldColour {
|
|
||||||
// `this` might be a subclass of FieldColour if that class doesn't override
|
|
||||||
// the static fromJson method.
|
|
||||||
return new this(options.colour, undefined, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The default value for this field. */
|
|
||||||
FieldColour.prototype.DEFAULT_VALUE = FieldColour.COLOURS[0];
|
|
||||||
|
|
||||||
fieldRegistry.register('field_colour', FieldColour);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CSS for colour picker.
|
|
||||||
*/
|
|
||||||
Css.register(`
|
|
||||||
.blocklyColourTable {
|
|
||||||
border-collapse: collapse;
|
|
||||||
display: block;
|
|
||||||
outline: none;
|
|
||||||
padding: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklyColourTable>tr>td {
|
|
||||||
border: 0.5px solid #888;
|
|
||||||
box-sizing: border-box;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
height: 20px;
|
|
||||||
padding: 0;
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklyColourTable>tr>td.blocklyColourHighlighted {
|
|
||||||
border-color: #eee;
|
|
||||||
box-shadow: 2px 2px 7px 2px rgba(0, 0, 0, 0.3);
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklyColourSelected, .blocklyColourSelected:hover {
|
|
||||||
border-color: #eee !important;
|
|
||||||
outline: 1px solid #333;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config options for the colour field.
|
|
||||||
*/
|
|
||||||
export interface FieldColourConfig extends FieldConfig {
|
|
||||||
colourOptions?: string[];
|
|
||||||
colourTitles?: string[];
|
|
||||||
columns?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fromJson config options for the colour field.
|
|
||||||
*/
|
|
||||||
export interface FieldColourFromJsonConfig extends FieldColourConfig {
|
|
||||||
colour?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function that is called to validate changes to the field's value before
|
|
||||||
* they are set.
|
|
||||||
*
|
|
||||||
* @see {@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/validators#return_values}
|
|
||||||
* @param newValue The value to be validated.
|
|
||||||
* @returns One of three instructions for setting the new value: `T`, `null`,
|
|
||||||
* or `undefined`.
|
|
||||||
*
|
|
||||||
* - `T` to set this function's returned value instead of `newValue`.
|
|
||||||
*
|
|
||||||
* - `null` to invoke `doValueInvalid_` and not set a value.
|
|
||||||
*
|
|
||||||
* - `undefined` to set `newValue` as is.
|
|
||||||
*/
|
|
||||||
export type FieldColourValidator = FieldValidator<string>;
|
|
||||||
@@ -284,7 +284,7 @@ export interface FieldImageConfig extends FieldConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fromJson config options for the colour field.
|
* fromJson config options for the image field.
|
||||||
*/
|
*/
|
||||||
export interface FieldImageFromJsonConfig extends FieldImageConfig {
|
export interface FieldImageFromJsonConfig extends FieldImageConfig {
|
||||||
src?: string;
|
src?: string;
|
||||||
|
|||||||
@@ -1,526 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Text Area field.
|
|
||||||
*
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
// Former goog.module ID: Blockly.FieldMultilineInput
|
|
||||||
|
|
||||||
import * as Css from './css.js';
|
|
||||||
import {Field, UnattachedFieldError} from './field.js';
|
|
||||||
import * as fieldRegistry from './field_registry.js';
|
|
||||||
import {
|
|
||||||
FieldTextInput,
|
|
||||||
FieldTextInputConfig,
|
|
||||||
FieldTextInputValidator,
|
|
||||||
} from './field_textinput.js';
|
|
||||||
import * as aria from './utils/aria.js';
|
|
||||||
import * as dom from './utils/dom.js';
|
|
||||||
import * as parsing from './utils/parsing.js';
|
|
||||||
import {Svg} from './utils/svg.js';
|
|
||||||
import * as userAgent from './utils/useragent.js';
|
|
||||||
import * as WidgetDiv from './widgetdiv.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for an editable text area field.
|
|
||||||
*/
|
|
||||||
export class FieldMultilineInput extends FieldTextInput {
|
|
||||||
/**
|
|
||||||
* The SVG group element that will contain a text element for each text row
|
|
||||||
* when initialized.
|
|
||||||
*/
|
|
||||||
textGroup: SVGGElement | null = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines the maximum number of lines of field.
|
|
||||||
* If exceeded, scrolling functionality is enabled.
|
|
||||||
*/
|
|
||||||
protected maxLines_ = Infinity;
|
|
||||||
|
|
||||||
/** Whether Y overflow is currently occurring. */
|
|
||||||
protected isOverflowedY_ = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param value The initial content of the field. Should cast to a string.
|
|
||||||
* Defaults to an empty string if null or undefined. Also accepts
|
|
||||||
* Field.SKIP_SETUP if you wish to skip setup (only used by subclasses
|
|
||||||
* that want to handle configuration and setting the field value after
|
|
||||||
* their own constructors have run).
|
|
||||||
* @param validator An optional function that is called to validate any
|
|
||||||
* constraints on what the user entered. Takes the new text as an
|
|
||||||
* argument and returns either the accepted text, a replacement text, or
|
|
||||||
* null to abort the change.
|
|
||||||
* @param config A map of options used to configure the field.
|
|
||||||
* See the [field creation documentation]{@link
|
|
||||||
* https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/multiline-text-input#creation}
|
|
||||||
* for a list of properties this parameter supports.
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
value?: string | typeof Field.SKIP_SETUP,
|
|
||||||
validator?: FieldMultilineInputValidator,
|
|
||||||
config?: FieldMultilineInputConfig,
|
|
||||||
) {
|
|
||||||
super(Field.SKIP_SETUP);
|
|
||||||
|
|
||||||
if (value === Field.SKIP_SETUP) return;
|
|
||||||
if (config) {
|
|
||||||
this.configure_(config);
|
|
||||||
}
|
|
||||||
this.setValue(value);
|
|
||||||
if (validator) {
|
|
||||||
this.setValidator(validator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure the field based on the given map of options.
|
|
||||||
*
|
|
||||||
* @param config A map of options to configure the field based on.
|
|
||||||
*/
|
|
||||||
protected override configure_(config: FieldMultilineInputConfig) {
|
|
||||||
super.configure_(config);
|
|
||||||
if (config.maxLines) this.setMaxLines(config.maxLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serializes this field's value to XML. Should only be called by Blockly.Xml.
|
|
||||||
*
|
|
||||||
* @param fieldElement The element to populate with info about the field's
|
|
||||||
* state.
|
|
||||||
* @returns The element containing info about the field's state.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
override toXml(fieldElement: Element): Element {
|
|
||||||
// Replace '\n' characters with HTML-escaped equivalent '
'. This is
|
|
||||||
// needed so the plain-text representation of the XML produced by
|
|
||||||
// `Blockly.Xml.domToText` will appear on a single line (this is a
|
|
||||||
// limitation of the plain-text format).
|
|
||||||
fieldElement.textContent = (this.getValue() as string).replace(
|
|
||||||
/\n/g,
|
|
||||||
' ',
|
|
||||||
);
|
|
||||||
return fieldElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the field's value based on the given XML element. Should only be
|
|
||||||
* called by Blockly.Xml.
|
|
||||||
*
|
|
||||||
* @param fieldElement The element containing info about the field's state.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
override fromXml(fieldElement: Element) {
|
|
||||||
this.setValue(fieldElement.textContent!.replace(/ /g, '\n'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves this field's value.
|
|
||||||
* This function only exists for subclasses of FieldMultilineInput which
|
|
||||||
* predate the load/saveState API and only define to/fromXml.
|
|
||||||
*
|
|
||||||
* @returns The state of this field.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
override saveState(): AnyDuringMigration {
|
|
||||||
const legacyState = this.saveLegacyState(FieldMultilineInput);
|
|
||||||
if (legacyState !== null) {
|
|
||||||
return legacyState;
|
|
||||||
}
|
|
||||||
return this.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the field's value based on the given state.
|
|
||||||
* This function only exists for subclasses of FieldMultilineInput which
|
|
||||||
* predate the load/saveState API and only define to/fromXml.
|
|
||||||
*
|
|
||||||
* @param state The state of the variable to assign to this variable field.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
override loadState(state: AnyDuringMigration) {
|
|
||||||
if (this.loadLegacyState(Field, state)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setValue(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the block UI for this field.
|
|
||||||
*/
|
|
||||||
override initView() {
|
|
||||||
this.createBorderRect_();
|
|
||||||
this.textGroup = dom.createSvgElement(
|
|
||||||
Svg.G,
|
|
||||||
{
|
|
||||||
'class': 'blocklyEditableText',
|
|
||||||
},
|
|
||||||
this.fieldGroup_,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the text from this field as displayed on screen. May differ from
|
|
||||||
* getText due to ellipsis, and other formatting.
|
|
||||||
*
|
|
||||||
* @returns Currently displayed text.
|
|
||||||
*/
|
|
||||||
protected override getDisplayText_(): string {
|
|
||||||
const block = this.getSourceBlock();
|
|
||||||
if (!block) {
|
|
||||||
throw new UnattachedFieldError();
|
|
||||||
}
|
|
||||||
let textLines = this.getText();
|
|
||||||
if (!textLines) {
|
|
||||||
// Prevent the field from disappearing if empty.
|
|
||||||
return Field.NBSP;
|
|
||||||
}
|
|
||||||
const lines = textLines.split('\n');
|
|
||||||
textLines = '';
|
|
||||||
const displayLinesNumber = this.isOverflowedY_
|
|
||||||
? this.maxLines_
|
|
||||||
: lines.length;
|
|
||||||
for (let i = 0; i < displayLinesNumber; i++) {
|
|
||||||
let text = lines[i];
|
|
||||||
if (text.length > this.maxDisplayLength) {
|
|
||||||
// Truncate displayed string and add an ellipsis ('...').
|
|
||||||
text = text.substring(0, this.maxDisplayLength - 4) + '...';
|
|
||||||
} else if (this.isOverflowedY_ && i === displayLinesNumber - 1) {
|
|
||||||
text = text.substring(0, text.length - 3) + '...';
|
|
||||||
}
|
|
||||||
// Replace whitespace with non-breaking spaces so the text doesn't
|
|
||||||
// collapse.
|
|
||||||
text = text.replace(/\s/g, Field.NBSP);
|
|
||||||
|
|
||||||
textLines += text;
|
|
||||||
if (i !== displayLinesNumber - 1) {
|
|
||||||
textLines += '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (block.RTL) {
|
|
||||||
// The SVG is LTR, force value to be RTL.
|
|
||||||
textLines += '\u200F';
|
|
||||||
}
|
|
||||||
return textLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by setValue if the text input is valid. Updates the value of the
|
|
||||||
* field, and updates the text of the field if it is not currently being
|
|
||||||
* edited (i.e. handled by the htmlInput_). Is being redefined here to update
|
|
||||||
* overflow state of the field.
|
|
||||||
*
|
|
||||||
* @param newValue The value to be saved. The default validator guarantees
|
|
||||||
* that this is a string.
|
|
||||||
*/
|
|
||||||
protected override doValueUpdate_(newValue: string) {
|
|
||||||
super.doValueUpdate_(newValue);
|
|
||||||
if (this.value_ !== null) {
|
|
||||||
this.isOverflowedY_ = this.value_.split('\n').length > this.maxLines_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Updates the text of the textElement. */
|
|
||||||
protected override render_() {
|
|
||||||
const block = this.getSourceBlock();
|
|
||||||
if (!block) {
|
|
||||||
throw new UnattachedFieldError();
|
|
||||||
}
|
|
||||||
// Remove all text group children.
|
|
||||||
let currentChild;
|
|
||||||
const textGroup = this.textGroup;
|
|
||||||
while ((currentChild = textGroup!.firstChild)) {
|
|
||||||
textGroup!.removeChild(currentChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add in text elements into the group.
|
|
||||||
const lines = this.getDisplayText_().split('\n');
|
|
||||||
let y = 0;
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
|
||||||
const lineHeight =
|
|
||||||
this.getConstants()!.FIELD_TEXT_HEIGHT +
|
|
||||||
this.getConstants()!.FIELD_BORDER_RECT_Y_PADDING;
|
|
||||||
const span = dom.createSvgElement(
|
|
||||||
Svg.TEXT,
|
|
||||||
{
|
|
||||||
'class': 'blocklyText blocklyMultilineText',
|
|
||||||
'x': this.getConstants()!.FIELD_BORDER_RECT_X_PADDING,
|
|
||||||
'y': y + this.getConstants()!.FIELD_BORDER_RECT_Y_PADDING,
|
|
||||||
'dy': this.getConstants()!.FIELD_TEXT_BASELINE,
|
|
||||||
},
|
|
||||||
textGroup,
|
|
||||||
);
|
|
||||||
span.appendChild(document.createTextNode(lines[i]));
|
|
||||||
y += lineHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isBeingEdited_) {
|
|
||||||
const htmlInput = this.htmlInput_ as HTMLElement;
|
|
||||||
if (this.isOverflowedY_) {
|
|
||||||
dom.addClass(htmlInput, 'blocklyHtmlTextAreaInputOverflowedY');
|
|
||||||
} else {
|
|
||||||
dom.removeClass(htmlInput, 'blocklyHtmlTextAreaInputOverflowedY');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateSize_();
|
|
||||||
|
|
||||||
if (this.isBeingEdited_) {
|
|
||||||
if (block.RTL) {
|
|
||||||
// in RTL, we need to let the browser reflow before resizing
|
|
||||||
// in order to get the correct bounding box of the borderRect
|
|
||||||
// avoiding issue #2777.
|
|
||||||
setTimeout(this.resizeEditor_.bind(this), 0);
|
|
||||||
} else {
|
|
||||||
this.resizeEditor_();
|
|
||||||
}
|
|
||||||
const htmlInput = this.htmlInput_ as HTMLElement;
|
|
||||||
if (!this.isTextValid_) {
|
|
||||||
dom.addClass(htmlInput, 'blocklyInvalidInput');
|
|
||||||
aria.setState(htmlInput, aria.State.INVALID, true);
|
|
||||||
} else {
|
|
||||||
dom.removeClass(htmlInput, 'blocklyInvalidInput');
|
|
||||||
aria.setState(htmlInput, aria.State.INVALID, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Updates the size of the field based on the text. */
|
|
||||||
protected override updateSize_() {
|
|
||||||
const nodes = (this.textGroup as SVGElement).childNodes;
|
|
||||||
const fontSize = this.getConstants()!.FIELD_TEXT_FONTSIZE;
|
|
||||||
const fontWeight = this.getConstants()!.FIELD_TEXT_FONTWEIGHT;
|
|
||||||
const fontFamily = this.getConstants()!.FIELD_TEXT_FONTFAMILY;
|
|
||||||
let totalWidth = 0;
|
|
||||||
let totalHeight = 0;
|
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
|
||||||
const tspan = nodes[i] as SVGTextElement;
|
|
||||||
const textWidth = dom.getFastTextWidth(
|
|
||||||
tspan,
|
|
||||||
fontSize,
|
|
||||||
fontWeight,
|
|
||||||
fontFamily,
|
|
||||||
);
|
|
||||||
if (textWidth > totalWidth) {
|
|
||||||
totalWidth = textWidth;
|
|
||||||
}
|
|
||||||
totalHeight +=
|
|
||||||
this.getConstants()!.FIELD_TEXT_HEIGHT +
|
|
||||||
(i > 0 ? this.getConstants()!.FIELD_BORDER_RECT_Y_PADDING : 0);
|
|
||||||
}
|
|
||||||
if (this.isBeingEdited_) {
|
|
||||||
// The default width is based on the longest line in the display text,
|
|
||||||
// but when it's being edited, width should be calculated based on the
|
|
||||||
// absolute longest line, even if it would be truncated after editing.
|
|
||||||
// Otherwise we would get wrong editor width when there are more
|
|
||||||
// lines than this.maxLines_.
|
|
||||||
const actualEditorLines = String(this.value_).split('\n');
|
|
||||||
const dummyTextElement = dom.createSvgElement(Svg.TEXT, {
|
|
||||||
'class': 'blocklyText blocklyMultilineText',
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let i = 0; i < actualEditorLines.length; i++) {
|
|
||||||
if (actualEditorLines[i].length > this.maxDisplayLength) {
|
|
||||||
actualEditorLines[i] = actualEditorLines[i].substring(
|
|
||||||
0,
|
|
||||||
this.maxDisplayLength,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
dummyTextElement.textContent = actualEditorLines[i];
|
|
||||||
const lineWidth = dom.getFastTextWidth(
|
|
||||||
dummyTextElement,
|
|
||||||
fontSize,
|
|
||||||
fontWeight,
|
|
||||||
fontFamily,
|
|
||||||
);
|
|
||||||
if (lineWidth > totalWidth) {
|
|
||||||
totalWidth = lineWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrollbarWidth =
|
|
||||||
this.htmlInput_!.offsetWidth - this.htmlInput_!.clientWidth;
|
|
||||||
totalWidth += scrollbarWidth;
|
|
||||||
}
|
|
||||||
if (this.borderRect_) {
|
|
||||||
totalHeight += this.getConstants()!.FIELD_BORDER_RECT_Y_PADDING * 2;
|
|
||||||
totalWidth += this.getConstants()!.FIELD_BORDER_RECT_X_PADDING * 2;
|
|
||||||
this.borderRect_.setAttribute('width', `${totalWidth}`);
|
|
||||||
this.borderRect_.setAttribute('height', `${totalHeight}`);
|
|
||||||
}
|
|
||||||
this.size_.width = totalWidth;
|
|
||||||
this.size_.height = totalHeight;
|
|
||||||
|
|
||||||
this.positionBorderRect_();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the inline free-text editor on top of the text.
|
|
||||||
* Overrides the default behaviour to force rerender in order to
|
|
||||||
* correct block size, based on editor text.
|
|
||||||
*
|
|
||||||
* @param e Optional mouse event that triggered the field to open, or
|
|
||||||
* undefined if triggered programmatically.
|
|
||||||
* @param quietInput True if editor should be created without focus.
|
|
||||||
* Defaults to false.
|
|
||||||
*/
|
|
||||||
override showEditor_(e?: Event, quietInput?: boolean) {
|
|
||||||
super.showEditor_(e, quietInput);
|
|
||||||
this.forceRerender();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the text input editor widget.
|
|
||||||
*
|
|
||||||
* @returns The newly created text input editor.
|
|
||||||
*/
|
|
||||||
protected override widgetCreate_(): HTMLTextAreaElement {
|
|
||||||
const div = WidgetDiv.getDiv();
|
|
||||||
const scale = this.workspace_!.getScale();
|
|
||||||
|
|
||||||
const htmlInput = document.createElement('textarea');
|
|
||||||
htmlInput.className = 'blocklyHtmlInput blocklyHtmlTextAreaInput';
|
|
||||||
htmlInput.setAttribute('spellcheck', String(this.spellcheck_));
|
|
||||||
const fontSize = this.getConstants()!.FIELD_TEXT_FONTSIZE * scale + 'pt';
|
|
||||||
div!.style.fontSize = fontSize;
|
|
||||||
htmlInput.style.fontSize = fontSize;
|
|
||||||
const borderRadius = FieldTextInput.BORDERRADIUS * scale + 'px';
|
|
||||||
htmlInput.style.borderRadius = borderRadius;
|
|
||||||
const paddingX = this.getConstants()!.FIELD_BORDER_RECT_X_PADDING * scale;
|
|
||||||
const paddingY =
|
|
||||||
(this.getConstants()!.FIELD_BORDER_RECT_Y_PADDING * scale) / 2;
|
|
||||||
htmlInput.style.padding =
|
|
||||||
paddingY + 'px ' + paddingX + 'px ' + paddingY + 'px ' + paddingX + 'px';
|
|
||||||
const lineHeight =
|
|
||||||
this.getConstants()!.FIELD_TEXT_HEIGHT +
|
|
||||||
this.getConstants()!.FIELD_BORDER_RECT_Y_PADDING;
|
|
||||||
htmlInput.style.lineHeight = lineHeight * scale + 'px';
|
|
||||||
|
|
||||||
div!.appendChild(htmlInput);
|
|
||||||
|
|
||||||
htmlInput.value = htmlInput.defaultValue = this.getEditorText_(this.value_);
|
|
||||||
htmlInput.setAttribute('data-untyped-default-value', String(this.value_));
|
|
||||||
htmlInput.setAttribute('data-old-value', '');
|
|
||||||
if (userAgent.GECKO) {
|
|
||||||
// In FF, ensure the browser reflows before resizing to avoid issue #2777.
|
|
||||||
setTimeout(this.resizeEditor_.bind(this), 0);
|
|
||||||
} else {
|
|
||||||
this.resizeEditor_();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.bindInputEvents_(htmlInput);
|
|
||||||
|
|
||||||
return htmlInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the maxLines config for this field.
|
|
||||||
*
|
|
||||||
* @param maxLines Defines the maximum number of lines allowed, before
|
|
||||||
* scrolling functionality is enabled.
|
|
||||||
*/
|
|
||||||
setMaxLines(maxLines: number) {
|
|
||||||
if (
|
|
||||||
typeof maxLines === 'number' &&
|
|
||||||
maxLines > 0 &&
|
|
||||||
maxLines !== this.maxLines_
|
|
||||||
) {
|
|
||||||
this.maxLines_ = maxLines;
|
|
||||||
this.forceRerender();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the maxLines config of this field.
|
|
||||||
*
|
|
||||||
* @returns The maxLines config value.
|
|
||||||
*/
|
|
||||||
getMaxLines(): number {
|
|
||||||
return this.maxLines_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle key down to the editor. Override the text input definition of this
|
|
||||||
* so as to not close the editor when enter is typed in.
|
|
||||||
*
|
|
||||||
* @param e Keyboard event.
|
|
||||||
*/
|
|
||||||
protected override onHtmlInputKeyDown_(e: KeyboardEvent) {
|
|
||||||
if (e.key !== 'Enter') {
|
|
||||||
super.onHtmlInputKeyDown_(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a FieldMultilineInput from a JSON arg object,
|
|
||||||
* dereferencing any string table references.
|
|
||||||
*
|
|
||||||
* @param options A JSON object with options (text, and spellcheck).
|
|
||||||
* @returns The new field instance.
|
|
||||||
* @nocollapse
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static override fromJson(
|
|
||||||
options: FieldMultilineInputFromJsonConfig,
|
|
||||||
): FieldMultilineInput {
|
|
||||||
const text = parsing.replaceMessageReferences(options.text);
|
|
||||||
// `this` might be a subclass of FieldMultilineInput if that class doesn't
|
|
||||||
// override the static fromJson method.
|
|
||||||
return new this(text, undefined, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldRegistry.register('field_multilinetext', FieldMultilineInput);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CSS for multiline field.
|
|
||||||
*/
|
|
||||||
Css.register(`
|
|
||||||
.blocklyHtmlTextAreaInput {
|
|
||||||
font-family: monospace;
|
|
||||||
resize: none;
|
|
||||||
overflow: hidden;
|
|
||||||
height: 100%;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklyHtmlTextAreaInputOverflowedY {
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config options for the multiline input field.
|
|
||||||
*/
|
|
||||||
export interface FieldMultilineInputConfig extends FieldTextInputConfig {
|
|
||||||
maxLines?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fromJson config options for the multiline input field.
|
|
||||||
*/
|
|
||||||
export interface FieldMultilineInputFromJsonConfig
|
|
||||||
extends FieldMultilineInputConfig {
|
|
||||||
text?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function that is called to validate changes to the field's value before
|
|
||||||
* they are set.
|
|
||||||
*
|
|
||||||
* @see {@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/validators#return_values}
|
|
||||||
* @param newValue The value to be validated.
|
|
||||||
* @returns One of three instructions for setting the new value: `T`, `null`,
|
|
||||||
* or `undefined`.
|
|
||||||
*
|
|
||||||
* - `T` to set this function's returned value instead of `newValue`.
|
|
||||||
*
|
|
||||||
* - `null` to invoke `doValueInvalid_` and not set a value.
|
|
||||||
*
|
|
||||||
* - `undefined` to set `newValue` as is.
|
|
||||||
*/
|
|
||||||
export type FieldMultilineInputValidator = FieldTextInputValidator;
|
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
// Former goog.module ID: Blockly.Dart.all
|
// Former goog.module ID: Blockly.Dart.all
|
||||||
|
|
||||||
import {DartGenerator} from './dart/dart_generator.js';
|
import {DartGenerator} from './dart/dart_generator.js';
|
||||||
import * as colour from './dart/colour.js';
|
|
||||||
import * as lists from './dart/lists.js';
|
import * as lists from './dart/lists.js';
|
||||||
import * as logic from './dart/logic.js';
|
import * as logic from './dart/logic.js';
|
||||||
import * as loops from './dart/loops.js';
|
import * as loops from './dart/loops.js';
|
||||||
@@ -37,7 +36,6 @@ dartGenerator.addReservedWords('Html,Math');
|
|||||||
|
|
||||||
// Install per-block-type generator functions:
|
// Install per-block-type generator functions:
|
||||||
const generators: typeof dartGenerator.forBlock = {
|
const generators: typeof dartGenerator.forBlock = {
|
||||||
...colour,
|
|
||||||
...lists,
|
...lists,
|
||||||
...logic,
|
...logic,
|
||||||
...loops,
|
...loops,
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2014 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file Generating Dart for colour blocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Former goog.module ID: Blockly.Dart.colour
|
|
||||||
|
|
||||||
import type {Block} from '../../core/block.js';
|
|
||||||
import type {DartGenerator} from './dart_generator.js';
|
|
||||||
import {Order} from './dart_generator.js';
|
|
||||||
|
|
||||||
// RESERVED WORDS: 'Math'
|
|
||||||
|
|
||||||
export function colour_picker(
|
|
||||||
block: Block,
|
|
||||||
generator: DartGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Colour picker.
|
|
||||||
const code = generator.quote_(block.getFieldValue('COLOUR'));
|
|
||||||
return [code, Order.ATOMIC];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_random(
|
|
||||||
block: Block,
|
|
||||||
generator: DartGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Generate a random colour.
|
|
||||||
// TODO(#7600): find better approach than casting to any to override
|
|
||||||
// CodeGenerator declaring .definitions protected.
|
|
||||||
(generator as AnyDuringMigration).definitions_['import_dart_math'] =
|
|
||||||
"import 'dart:math' as Math;";
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_random',
|
|
||||||
`
|
|
||||||
String ${generator.FUNCTION_NAME_PLACEHOLDER_}() {
|
|
||||||
String hex = '0123456789abcdef';
|
|
||||||
var rnd = new Math.Random();
|
|
||||||
return '#\${hex[rnd.nextInt(16)]}\${hex[rnd.nextInt(16)]}'
|
|
||||||
'\${hex[rnd.nextInt(16)]}\${hex[rnd.nextInt(16)]}'
|
|
||||||
'\${hex[rnd.nextInt(16)]}\${hex[rnd.nextInt(16)]}';
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '()';
|
|
||||||
return [code, Order.UNARY_POSTFIX];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_rgb(
|
|
||||||
block: Block,
|
|
||||||
generator: DartGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Compose a colour from RGB components expressed as percentages.
|
|
||||||
const red = generator.valueToCode(block, 'RED', Order.NONE) || 0;
|
|
||||||
const green = generator.valueToCode(block, 'GREEN', Order.NONE) || 0;
|
|
||||||
const blue = generator.valueToCode(block, 'BLUE', Order.NONE) || 0;
|
|
||||||
|
|
||||||
// TODO(#7600): find better approach than casting to any to override
|
|
||||||
// CodeGenerator declaring .definitions protected.
|
|
||||||
(generator as AnyDuringMigration).definitions_['import_dart_math'] =
|
|
||||||
"import 'dart:math' as Math;";
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_rgb',
|
|
||||||
`
|
|
||||||
String ${generator.FUNCTION_NAME_PLACEHOLDER_}(num r, num g, num b) {
|
|
||||||
num rn = (Math.max(Math.min(r, 100), 0) * 2.55).round();
|
|
||||||
String rs = rn.toInt().toRadixString(16);
|
|
||||||
rs = '0$rs';
|
|
||||||
rs = rs.substring(rs.length - 2);
|
|
||||||
num gn = (Math.max(Math.min(g, 100), 0) * 2.55).round();
|
|
||||||
String gs = gn.toInt().toRadixString(16);
|
|
||||||
gs = '0$gs';
|
|
||||||
gs = gs.substring(gs.length - 2);
|
|
||||||
num bn = (Math.max(Math.min(b, 100), 0) * 2.55).round();
|
|
||||||
String bs = bn.toInt().toRadixString(16);
|
|
||||||
bs = '0$bs';
|
|
||||||
bs = bs.substring(bs.length - 2);
|
|
||||||
return '#$rs$gs$bs';
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
|
|
||||||
return [code, Order.UNARY_POSTFIX];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_blend(
|
|
||||||
block: Block,
|
|
||||||
generator: DartGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Blend two colours together.
|
|
||||||
const c1 = generator.valueToCode(block, 'COLOUR1', Order.NONE) || "'#000000'";
|
|
||||||
const c2 = generator.valueToCode(block, 'COLOUR2', Order.NONE) || "'#000000'";
|
|
||||||
const ratio = generator.valueToCode(block, 'RATIO', Order.NONE) || 0.5;
|
|
||||||
|
|
||||||
// TODO(#7600): find better approach than casting to any to override
|
|
||||||
// CodeGenerator declaring .definitions protected.
|
|
||||||
(generator as AnyDuringMigration).definitions_['import_dart_math'] =
|
|
||||||
"import 'dart:math' as Math;";
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_blend',
|
|
||||||
`
|
|
||||||
String ${generator.FUNCTION_NAME_PLACEHOLDER_}(String c1, String c2, num ratio) {
|
|
||||||
ratio = Math.max(Math.min(ratio, 1), 0);
|
|
||||||
int r1 = int.parse('0x\${c1.substring(1, 3)}');
|
|
||||||
int g1 = int.parse('0x\${c1.substring(3, 5)}');
|
|
||||||
int b1 = int.parse('0x\${c1.substring(5, 7)}');
|
|
||||||
int r2 = int.parse('0x\${c2.substring(1, 3)}');
|
|
||||||
int g2 = int.parse('0x\${c2.substring(3, 5)}');
|
|
||||||
int b2 = int.parse('0x\${c2.substring(5, 7)}');
|
|
||||||
num rn = (r1 * (1 - ratio) + r2 * ratio).round();
|
|
||||||
String rs = rn.toInt().toRadixString(16);
|
|
||||||
num gn = (g1 * (1 - ratio) + g2 * ratio).round();
|
|
||||||
String gs = gn.toInt().toRadixString(16);
|
|
||||||
num bn = (b1 * (1 - ratio) + b2 * ratio).round();
|
|
||||||
String bs = bn.toInt().toRadixString(16);
|
|
||||||
rs = '0$rs';
|
|
||||||
rs = rs.substring(rs.length - 2);
|
|
||||||
gs = '0$gs';
|
|
||||||
gs = gs.substring(gs.length - 2);
|
|
||||||
bs = '0$bs';
|
|
||||||
bs = bs.substring(bs.length - 2);
|
|
||||||
return '#$rs$gs$bs';
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
|
|
||||||
return [code, Order.UNARY_POSTFIX];
|
|
||||||
}
|
|
||||||
@@ -23,16 +23,6 @@ export function text(block: Block, generator: DartGenerator): [string, Order] {
|
|||||||
return [code, Order.ATOMIC];
|
return [code, Order.ATOMIC];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function text_multiline(
|
|
||||||
block: Block,
|
|
||||||
generator: DartGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Text value.
|
|
||||||
const code = generator.multiline_quote_(block.getFieldValue('TEXT'));
|
|
||||||
const order = code.indexOf('+') !== -1 ? Order.ADDITIVE : Order.ATOMIC;
|
|
||||||
return [code, order];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function text_join(
|
export function text_join(
|
||||||
block: Block,
|
block: Block,
|
||||||
generator: DartGenerator,
|
generator: DartGenerator,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
// Former goog.module ID: Blockly.JavaScript.all
|
// Former goog.module ID: Blockly.JavaScript.all
|
||||||
|
|
||||||
import {JavascriptGenerator} from './javascript/javascript_generator.js';
|
import {JavascriptGenerator} from './javascript/javascript_generator.js';
|
||||||
import * as colour from './javascript/colour.js';
|
|
||||||
import * as lists from './javascript/lists.js';
|
import * as lists from './javascript/lists.js';
|
||||||
import * as logic from './javascript/logic.js';
|
import * as logic from './javascript/logic.js';
|
||||||
import * as loops from './javascript/loops.js';
|
import * as loops from './javascript/loops.js';
|
||||||
@@ -33,7 +32,6 @@ export const javascriptGenerator = new JavascriptGenerator();
|
|||||||
|
|
||||||
// Install per-block-type generator functions:
|
// Install per-block-type generator functions:
|
||||||
const generators: typeof javascriptGenerator.forBlock = {
|
const generators: typeof javascriptGenerator.forBlock = {
|
||||||
...colour,
|
|
||||||
...lists,
|
...lists,
|
||||||
...logic,
|
...logic,
|
||||||
...loops,
|
...loops,
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2012 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file Generating JavaScript for colour blocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Former goog.module ID: Blockly.JavaScript.colour
|
|
||||||
|
|
||||||
import type {Block} from '../../core/block.js';
|
|
||||||
import type {JavascriptGenerator} from './javascript_generator.js';
|
|
||||||
import {Order} from './javascript_generator.js';
|
|
||||||
|
|
||||||
export function colour_picker(
|
|
||||||
block: Block,
|
|
||||||
generator: JavascriptGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Colour picker.
|
|
||||||
const code = generator.quote_(block.getFieldValue('COLOUR'));
|
|
||||||
return [code, Order.ATOMIC];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_random(
|
|
||||||
block: Block,
|
|
||||||
generator: JavascriptGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Generate a random colour.
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colourRandom',
|
|
||||||
`
|
|
||||||
function ${generator.FUNCTION_NAME_PLACEHOLDER_}() {
|
|
||||||
var num = Math.floor(Math.random() * Math.pow(2, 24));
|
|
||||||
return '#' + ('00000' + num.toString(16)).substr(-6);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '()';
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_rgb(
|
|
||||||
block: Block,
|
|
||||||
generator: JavascriptGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Compose a colour from RGB components expressed as percentages.
|
|
||||||
const red = generator.valueToCode(block, 'RED', Order.NONE) || 0;
|
|
||||||
const green = generator.valueToCode(block, 'GREEN', Order.NONE) || 0;
|
|
||||||
const blue = generator.valueToCode(block, 'BLUE', Order.NONE) || 0;
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colourRgb',
|
|
||||||
`
|
|
||||||
function ${generator.FUNCTION_NAME_PLACEHOLDER_}(r, g, b) {
|
|
||||||
r = Math.max(Math.min(Number(r), 100), 0) * 2.55;
|
|
||||||
g = Math.max(Math.min(Number(g), 100), 0) * 2.55;
|
|
||||||
b = Math.max(Math.min(Number(b), 100), 0) * 2.55;
|
|
||||||
r = ('0' + (Math.round(r) || 0).toString(16)).slice(-2);
|
|
||||||
g = ('0' + (Math.round(g) || 0).toString(16)).slice(-2);
|
|
||||||
b = ('0' + (Math.round(b) || 0).toString(16)).slice(-2);
|
|
||||||
return '#' + r + g + b;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_blend(
|
|
||||||
block: Block,
|
|
||||||
generator: JavascriptGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Blend two colours together.
|
|
||||||
const c1 = generator.valueToCode(block, 'COLOUR1', Order.NONE) || "'#000000'";
|
|
||||||
const c2 = generator.valueToCode(block, 'COLOUR2', Order.NONE) || "'#000000'";
|
|
||||||
const ratio = generator.valueToCode(block, 'RATIO', Order.NONE) || 0.5;
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colourBlend',
|
|
||||||
`
|
|
||||||
function ${generator.FUNCTION_NAME_PLACEHOLDER_}(c1, c2, ratio) {
|
|
||||||
ratio = Math.max(Math.min(Number(ratio), 1), 0);
|
|
||||||
var r1 = parseInt(c1.substring(1, 3), 16);
|
|
||||||
var g1 = parseInt(c1.substring(3, 5), 16);
|
|
||||||
var b1 = parseInt(c1.substring(5, 7), 16);
|
|
||||||
var r2 = parseInt(c2.substring(1, 3), 16);
|
|
||||||
var g2 = parseInt(c2.substring(3, 5), 16);
|
|
||||||
var b2 = parseInt(c2.substring(5, 7), 16);
|
|
||||||
var r = Math.round(r1 * (1 - ratio) + r2 * ratio);
|
|
||||||
var g = Math.round(g1 * (1 - ratio) + g2 * ratio);
|
|
||||||
var b = Math.round(b1 * (1 - ratio) + b2 * ratio);
|
|
||||||
r = ('0' + (r || 0).toString(16)).slice(-2);
|
|
||||||
g = ('0' + (g || 0).toString(16)).slice(-2);
|
|
||||||
b = ('0' + (b || 0).toString(16)).slice(-2);
|
|
||||||
return '#' + r + g + b;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
@@ -66,16 +66,6 @@ export function text(
|
|||||||
return [code, Order.ATOMIC];
|
return [code, Order.ATOMIC];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function text_multiline(
|
|
||||||
block: Block,
|
|
||||||
generator: JavascriptGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Text value.
|
|
||||||
const code = generator.multiline_quote_(block.getFieldValue('TEXT'));
|
|
||||||
const order = code.indexOf('+') !== -1 ? Order.ADDITION : Order.ATOMIC;
|
|
||||||
return [code, order];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function text_join(
|
export function text_join(
|
||||||
block: Block,
|
block: Block,
|
||||||
generator: JavascriptGenerator,
|
generator: JavascriptGenerator,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
// Former goog.module ID: Blockly.Lua.all
|
// Former goog.module ID: Blockly.Lua.all
|
||||||
|
|
||||||
import {LuaGenerator} from './lua/lua_generator.js';
|
import {LuaGenerator} from './lua/lua_generator.js';
|
||||||
import * as colour from './lua/colour.js';
|
|
||||||
import * as lists from './lua/lists.js';
|
import * as lists from './lua/lists.js';
|
||||||
import * as logic from './lua/logic.js';
|
import * as logic from './lua/logic.js';
|
||||||
import * as loops from './lua/loops.js';
|
import * as loops from './lua/loops.js';
|
||||||
@@ -31,7 +30,6 @@ export const luaGenerator = new LuaGenerator();
|
|||||||
|
|
||||||
// Install per-block-type generator functions:
|
// Install per-block-type generator functions:
|
||||||
const generators: typeof luaGenerator.forBlock = {
|
const generators: typeof luaGenerator.forBlock = {
|
||||||
...colour,
|
|
||||||
...lists,
|
...lists,
|
||||||
...logic,
|
...logic,
|
||||||
...loops,
|
...loops,
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2016 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file Generating Lua for colour blocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Former goog.module ID: Blockly.Lua.colour
|
|
||||||
|
|
||||||
import type {Block} from '../../core/block.js';
|
|
||||||
import type {LuaGenerator} from './lua_generator.js';
|
|
||||||
import {Order} from './lua_generator.js';
|
|
||||||
|
|
||||||
export function colour_picker(
|
|
||||||
block: Block,
|
|
||||||
generator: LuaGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Colour picker.
|
|
||||||
const code = generator.quote_(block.getFieldValue('COLOUR'));
|
|
||||||
return [code, Order.ATOMIC];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_random(
|
|
||||||
block: Block,
|
|
||||||
generator: LuaGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Generate a random colour.
|
|
||||||
const code = 'string.format("#%06x", math.random(0, 2^24 - 1))';
|
|
||||||
return [code, Order.HIGH];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_rgb(
|
|
||||||
block: Block,
|
|
||||||
generator: LuaGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Compose a colour from RGB components expressed as percentages.
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_rgb',
|
|
||||||
`
|
|
||||||
function ${generator.FUNCTION_NAME_PLACEHOLDER_}(r, g, b)
|
|
||||||
r = math.floor(math.min(100, math.max(0, r)) * 2.55 + .5)
|
|
||||||
g = math.floor(math.min(100, math.max(0, g)) * 2.55 + .5)
|
|
||||||
b = math.floor(math.min(100, math.max(0, b)) * 2.55 + .5)
|
|
||||||
return string.format("#%02x%02x%02x", r, g, b)
|
|
||||||
end
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const r = generator.valueToCode(block, 'RED', Order.NONE) || 0;
|
|
||||||
const g = generator.valueToCode(block, 'GREEN', Order.NONE) || 0;
|
|
||||||
const b = generator.valueToCode(block, 'BLUE', Order.NONE) || 0;
|
|
||||||
const code = functionName + '(' + r + ', ' + g + ', ' + b + ')';
|
|
||||||
return [code, Order.HIGH];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_blend(
|
|
||||||
block: Block,
|
|
||||||
generator: LuaGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Blend two colours together.
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_blend',
|
|
||||||
`
|
|
||||||
function ${generator.FUNCTION_NAME_PLACEHOLDER_}(colour1, colour2, ratio)
|
|
||||||
local r1 = tonumber(string.sub(colour1, 2, 3), 16)
|
|
||||||
local r2 = tonumber(string.sub(colour2, 2, 3), 16)
|
|
||||||
local g1 = tonumber(string.sub(colour1, 4, 5), 16)
|
|
||||||
local g2 = tonumber(string.sub(colour2, 4, 5), 16)
|
|
||||||
local b1 = tonumber(string.sub(colour1, 6, 7), 16)
|
|
||||||
local b2 = tonumber(string.sub(colour2, 6, 7), 16)
|
|
||||||
local ratio = math.min(1, math.max(0, ratio))
|
|
||||||
local r = math.floor(r1 * (1 - ratio) + r2 * ratio + .5)
|
|
||||||
local g = math.floor(g1 * (1 - ratio) + g2 * ratio + .5)
|
|
||||||
local b = math.floor(b1 * (1 - ratio) + b2 * ratio + .5)
|
|
||||||
return string.format("#%02x%02x%02x", r, g, b)
|
|
||||||
end
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const colour1 =
|
|
||||||
generator.valueToCode(block, 'COLOUR1', Order.NONE) || "'#000000'";
|
|
||||||
const colour2 =
|
|
||||||
generator.valueToCode(block, 'COLOUR2', Order.NONE) || "'#000000'";
|
|
||||||
const ratio = generator.valueToCode(block, 'RATIO', Order.NONE) || 0;
|
|
||||||
const code =
|
|
||||||
functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')';
|
|
||||||
return [code, Order.HIGH];
|
|
||||||
}
|
|
||||||
@@ -21,16 +21,6 @@ export function text(block: Block, generator: LuaGenerator): [string, Order] {
|
|||||||
return [code, Order.ATOMIC];
|
return [code, Order.ATOMIC];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function text_multiline(
|
|
||||||
block: Block,
|
|
||||||
generator: LuaGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Text value.
|
|
||||||
const code = generator.multiline_quote_(block.getFieldValue('TEXT'));
|
|
||||||
const order = code.indexOf('..') !== -1 ? Order.CONCATENATION : Order.ATOMIC;
|
|
||||||
return [code, order];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function text_join(
|
export function text_join(
|
||||||
block: Block,
|
block: Block,
|
||||||
generator: LuaGenerator,
|
generator: LuaGenerator,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
// Former goog.module ID: Blockly.PHP.all
|
// Former goog.module ID: Blockly.PHP.all
|
||||||
|
|
||||||
import {PhpGenerator} from './php/php_generator.js';
|
import {PhpGenerator} from './php/php_generator.js';
|
||||||
import * as colour from './php/colour.js';
|
|
||||||
import * as lists from './php/lists.js';
|
import * as lists from './php/lists.js';
|
||||||
import * as logic from './php/logic.js';
|
import * as logic from './php/logic.js';
|
||||||
import * as loops from './php/loops.js';
|
import * as loops from './php/loops.js';
|
||||||
@@ -33,7 +32,6 @@ export const phpGenerator = new PhpGenerator();
|
|||||||
|
|
||||||
// Install per-block-type generator functions:
|
// Install per-block-type generator functions:
|
||||||
const generators: typeof phpGenerator.forBlock = {
|
const generators: typeof phpGenerator.forBlock = {
|
||||||
...colour,
|
|
||||||
...lists,
|
...lists,
|
||||||
...logic,
|
...logic,
|
||||||
...loops,
|
...loops,
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2015 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file Generating PHP for colour blocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Former goog.module ID: Blockly.PHP.colour
|
|
||||||
|
|
||||||
import type {Block} from '../../core/block.js';
|
|
||||||
import {Order} from './php_generator.js';
|
|
||||||
import type {PhpGenerator} from './php_generator.js';
|
|
||||||
|
|
||||||
export function colour_picker(
|
|
||||||
block: Block,
|
|
||||||
generator: PhpGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Colour picker.
|
|
||||||
const code = generator.quote_(block.getFieldValue('COLOUR'));
|
|
||||||
return [code, Order.ATOMIC];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_random(
|
|
||||||
block: Block,
|
|
||||||
generator: PhpGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Generate a random colour.
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_random',
|
|
||||||
`
|
|
||||||
function ${generator.FUNCTION_NAME_PLACEHOLDER_}() {
|
|
||||||
return '#' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '()';
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_rgb(
|
|
||||||
block: Block,
|
|
||||||
generator: PhpGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Compose a colour from RGB components expressed as percentages.
|
|
||||||
const red = generator.valueToCode(block, 'RED', Order.NONE) || 0;
|
|
||||||
const green = generator.valueToCode(block, 'GREEN', Order.NONE) || 0;
|
|
||||||
const blue = generator.valueToCode(block, 'BLUE', Order.NONE) || 0;
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_rgb',
|
|
||||||
`
|
|
||||||
function ${generator.FUNCTION_NAME_PLACEHOLDER_}($r, $g, $b) {
|
|
||||||
$r = round(max(min($r, 100), 0) * 2.55);
|
|
||||||
$g = round(max(min($g, 100), 0) * 2.55);
|
|
||||||
$b = round(max(min($b, 100), 0) * 2.55);
|
|
||||||
$hex = '#';
|
|
||||||
$hex .= str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
|
|
||||||
$hex .= str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
|
|
||||||
$hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
|
|
||||||
return $hex;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_blend(
|
|
||||||
block: Block,
|
|
||||||
generator: PhpGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Blend two colours together.
|
|
||||||
const c1 = generator.valueToCode(block, 'COLOUR1', Order.NONE) || "'#000000'";
|
|
||||||
const c2 = generator.valueToCode(block, 'COLOUR2', Order.NONE) || "'#000000'";
|
|
||||||
const ratio = generator.valueToCode(block, 'RATIO', Order.NONE) || 0.5;
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_blend',
|
|
||||||
`
|
|
||||||
function ${generator.FUNCTION_NAME_PLACEHOLDER_}($c1, $c2, $ratio) {
|
|
||||||
$ratio = max(min($ratio, 1), 0);
|
|
||||||
$r1 = hexdec(substr($c1, 1, 2));
|
|
||||||
$g1 = hexdec(substr($c1, 3, 2));
|
|
||||||
$b1 = hexdec(substr($c1, 5, 2));
|
|
||||||
$r2 = hexdec(substr($c2, 1, 2));
|
|
||||||
$g2 = hexdec(substr($c2, 3, 2));
|
|
||||||
$b2 = hexdec(substr($c2, 5, 2));
|
|
||||||
$r = round($r1 * (1 - $ratio) + $r2 * $ratio);
|
|
||||||
$g = round($g1 * (1 - $ratio) + $g2 * $ratio);
|
|
||||||
$b = round($b1 * (1 - $ratio) + $b2 * $ratio);
|
|
||||||
$hex = '#';
|
|
||||||
$hex .= str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
|
|
||||||
$hex .= str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
|
|
||||||
$hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
|
|
||||||
return $hex;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
@@ -21,16 +21,6 @@ export function text(block: Block, generator: PhpGenerator): [string, Order] {
|
|||||||
return [code, Order.ATOMIC];
|
return [code, Order.ATOMIC];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function text_multiline(
|
|
||||||
block: Block,
|
|
||||||
generator: PhpGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Text value.
|
|
||||||
const code = generator.multiline_quote_(block.getFieldValue('TEXT'));
|
|
||||||
const order = code.indexOf('.') !== -1 ? Order.STRING_CONCAT : Order.ATOMIC;
|
|
||||||
return [code, order];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function text_join(
|
export function text_join(
|
||||||
block: Block,
|
block: Block,
|
||||||
generator: PhpGenerator,
|
generator: PhpGenerator,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
// Former goog.module ID: Blockly.Python.all
|
// Former goog.module ID: Blockly.Python.all
|
||||||
|
|
||||||
import {PythonGenerator} from './python/python_generator.js';
|
import {PythonGenerator} from './python/python_generator.js';
|
||||||
import * as colour from './python/colour.js';
|
|
||||||
import * as lists from './python/lists.js';
|
import * as lists from './python/lists.js';
|
||||||
import * as logic from './python/logic.js';
|
import * as logic from './python/logic.js';
|
||||||
import * as loops from './python/loops.js';
|
import * as loops from './python/loops.js';
|
||||||
@@ -38,7 +37,6 @@ pythonGenerator.addReservedWords('math,random,Number');
|
|||||||
// Install per-block-type generator functions:
|
// Install per-block-type generator functions:
|
||||||
// Install per-block-type generator functions:
|
// Install per-block-type generator functions:
|
||||||
const generators: typeof pythonGenerator.forBlock = {
|
const generators: typeof pythonGenerator.forBlock = {
|
||||||
...colour,
|
|
||||||
...lists,
|
...lists,
|
||||||
...logic,
|
...logic,
|
||||||
...loops,
|
...loops,
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2012 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file Generating Python for colour blocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Former goog.module ID: Blockly.Python.colour
|
|
||||||
|
|
||||||
import type {Block} from '../../core/block.js';
|
|
||||||
import type {PythonGenerator} from './python_generator.js';
|
|
||||||
import {Order} from './python_generator.js';
|
|
||||||
|
|
||||||
export function colour_picker(
|
|
||||||
block: Block,
|
|
||||||
generator: PythonGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Colour picker.
|
|
||||||
const code = generator.quote_(block.getFieldValue('COLOUR'));
|
|
||||||
return [code, Order.ATOMIC];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_random(
|
|
||||||
block: Block,
|
|
||||||
generator: PythonGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Generate a random colour.
|
|
||||||
// TODO(#7600): find better approach than casting to any to override
|
|
||||||
// CodeGenerator declaring .definitions protected.
|
|
||||||
(generator as AnyDuringMigration).definitions_['import_random'] =
|
|
||||||
'import random';
|
|
||||||
const code = "'#%06x' % random.randint(0, 2**24 - 1)";
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_rgb(
|
|
||||||
block: Block,
|
|
||||||
generator: PythonGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Compose a colour from RGB components expressed as percentages.
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_rgb',
|
|
||||||
`
|
|
||||||
def ${generator.FUNCTION_NAME_PLACEHOLDER_}(r, g, b):
|
|
||||||
r = round(min(100, max(0, r)) * 2.55)
|
|
||||||
g = round(min(100, max(0, g)) * 2.55)
|
|
||||||
b = round(min(100, max(0, b)) * 2.55)
|
|
||||||
return '#%02x%02x%02x' % (r, g, b)
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const r = generator.valueToCode(block, 'RED', Order.NONE) || 0;
|
|
||||||
const g = generator.valueToCode(block, 'GREEN', Order.NONE) || 0;
|
|
||||||
const b = generator.valueToCode(block, 'BLUE', Order.NONE) || 0;
|
|
||||||
const code = functionName + '(' + r + ', ' + g + ', ' + b + ')';
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colour_blend(
|
|
||||||
block: Block,
|
|
||||||
generator: PythonGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Blend two colours together.
|
|
||||||
const functionName = generator.provideFunction_(
|
|
||||||
'colour_blend',
|
|
||||||
`
|
|
||||||
def ${generator.FUNCTION_NAME_PLACEHOLDER_}(colour1, colour2, ratio):
|
|
||||||
r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)
|
|
||||||
g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)
|
|
||||||
b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)
|
|
||||||
ratio = min(1, max(0, ratio))
|
|
||||||
r = round(r1 * (1 - ratio) + r2 * ratio)
|
|
||||||
g = round(g1 * (1 - ratio) + g2 * ratio)
|
|
||||||
b = round(b1 * (1 - ratio) + b2 * ratio)
|
|
||||||
return '#%02x%02x%02x' % (r, g, b)
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
const colour1 =
|
|
||||||
generator.valueToCode(block, 'COLOUR1', Order.NONE) || "'#000000'";
|
|
||||||
const colour2 =
|
|
||||||
generator.valueToCode(block, 'COLOUR2', Order.NONE) || "'#000000'";
|
|
||||||
const ratio = generator.valueToCode(block, 'RATIO', Order.NONE) || 0;
|
|
||||||
const code =
|
|
||||||
functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')';
|
|
||||||
return [code, Order.FUNCTION_CALL];
|
|
||||||
}
|
|
||||||
@@ -26,16 +26,6 @@ export function text(
|
|||||||
return [code, Order.ATOMIC];
|
return [code, Order.ATOMIC];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function text_multiline(
|
|
||||||
block: Block,
|
|
||||||
generator: PythonGenerator,
|
|
||||||
): [string, Order] {
|
|
||||||
// Text value.
|
|
||||||
const code = generator.multiline_quote_(block.getFieldValue('TEXT'));
|
|
||||||
const order = code.indexOf('+') !== -1 ? Order.ADDITIVE : Order.ATOMIC;
|
|
||||||
return [code, order];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regular expression to detect a single-quoted string literal.
|
* Regular expression to detect a single-quoted string literal.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,318 +0,0 @@
|
|||||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
|
||||||
<block type="procedures_defnoreturn" x="260" y="14">
|
|
||||||
<field name="NAME">test colour picker</field>
|
|
||||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
|
||||||
<statement name="STACK">
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">static colour</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="colour_picker">
|
|
||||||
<field name="COLOUR">#ff6600</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">#ff6600</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</statement>
|
|
||||||
</block>
|
|
||||||
<block type="procedures_defnoreturn" x="630" y="13">
|
|
||||||
<field name="NAME">test rgb</field>
|
|
||||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
|
||||||
<statement name="STACK">
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">from rgb</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="colour_rgb" inline="false">
|
|
||||||
<value name="RED">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">100</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="GREEN">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">40</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="BLUE">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">0</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">#ff6600</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</statement>
|
|
||||||
</block>
|
|
||||||
<block type="unittest_main" x="-5" y="49">
|
|
||||||
<field name="SUITE_NAME">Colour</field>
|
|
||||||
<statement name="DO">
|
|
||||||
<block type="procedures_callnoreturn">
|
|
||||||
<mutation name="test colour picker"></mutation>
|
|
||||||
<next>
|
|
||||||
<block type="procedures_callnoreturn">
|
|
||||||
<mutation name="test blend"></mutation>
|
|
||||||
<next>
|
|
||||||
<block type="procedures_callnoreturn">
|
|
||||||
<mutation name="test rgb"></mutation>
|
|
||||||
<next>
|
|
||||||
<block type="procedures_callnoreturn">
|
|
||||||
<mutation name="test colour random"></mutation>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</statement>
|
|
||||||
</block>
|
|
||||||
<block type="procedures_defnoreturn" x="-7" y="223">
|
|
||||||
<field name="NAME">test colour random</field>
|
|
||||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
|
||||||
<statement name="STACK">
|
|
||||||
<block type="controls_repeat_ext" inline="true">
|
|
||||||
<value name="TIMES">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">100</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<statement name="DO">
|
|
||||||
<block type="variables_set" inline="false">
|
|
||||||
<field name="VAR">item</field>
|
|
||||||
<value name="VALUE">
|
|
||||||
<block type="colour_random"></block>
|
|
||||||
</value>
|
|
||||||
<next>
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text_join">
|
|
||||||
<mutation items="2"></mutation>
|
|
||||||
<value name="ADD0">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">length of random colour string: </field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ADD1">
|
|
||||||
<block type="variables_get">
|
|
||||||
<field name="VAR">item</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="text_length" inline="false">
|
|
||||||
<value name="VALUE">
|
|
||||||
<block type="variables_get">
|
|
||||||
<field name="VAR">item</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">7</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<next>
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text_join">
|
|
||||||
<mutation items="2"></mutation>
|
|
||||||
<value name="ADD0">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">format of random colour string: </field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ADD1">
|
|
||||||
<block type="variables_get">
|
|
||||||
<field name="VAR">item</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="text_charAt">
|
|
||||||
<mutation at="false"></mutation>
|
|
||||||
<field name="WHERE">FIRST</field>
|
|
||||||
<value name="VALUE">
|
|
||||||
<block type="variables_get">
|
|
||||||
<field name="VAR">item</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">#</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<next>
|
|
||||||
<block type="controls_for">
|
|
||||||
<field name="VAR">i</field>
|
|
||||||
<value name="FROM">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">1</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="TO">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">6</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<statement name="DO">
|
|
||||||
<block type="unittest_assertvalue" inline="false">
|
|
||||||
<field name="EXPECTED">TRUE</field>
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text_join">
|
|
||||||
<mutation items="4"></mutation>
|
|
||||||
<value name="ADD0">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">contents of random colour string: </field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ADD1">
|
|
||||||
<block type="variables_get">
|
|
||||||
<field name="VAR">item</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ADD2">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT"> at index: </field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ADD3">
|
|
||||||
<block type="unittest_adjustindex">
|
|
||||||
<value name="INDEX">
|
|
||||||
<block type="variables_get">
|
|
||||||
<field name="VAR">i</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="logic_compare">
|
|
||||||
<field name="OP">NEQ</field>
|
|
||||||
<value name="A">
|
|
||||||
<block type="unittest_adjustindex">
|
|
||||||
<value name="INDEX">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">-1</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="B">
|
|
||||||
<block type="text_indexOf" inline="false">
|
|
||||||
<field name="END">FIRST</field>
|
|
||||||
<value name="VALUE">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">abcdefABDEF0123456789</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="FIND">
|
|
||||||
<block type="text_charAt">
|
|
||||||
<mutation at="true"></mutation>
|
|
||||||
<field name="WHERE">FROM_START</field>
|
|
||||||
<value name="VALUE">
|
|
||||||
<block type="variables_get">
|
|
||||||
<field name="VAR">item</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="AT">
|
|
||||||
<block type="unittest_adjustindex">
|
|
||||||
<value name="INDEX">
|
|
||||||
<block type="variables_get">
|
|
||||||
<field name="VAR">i</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</statement>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</statement>
|
|
||||||
</block>
|
|
||||||
</statement>
|
|
||||||
</block>
|
|
||||||
<block type="procedures_defnoreturn" x="638" y="213">
|
|
||||||
<field name="NAME">test blend</field>
|
|
||||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
|
||||||
<statement name="STACK">
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">blend</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="colour_blend" inline="false">
|
|
||||||
<value name="COLOUR1">
|
|
||||||
<block type="colour_picker">
|
|
||||||
<field name="COLOUR">#ff0000</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="COLOUR2">
|
|
||||||
<block type="colour_rgb" inline="false">
|
|
||||||
<value name="RED">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">100</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="GREEN">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">40</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="BLUE">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">0</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="RATIO">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">0.4</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">#ff2900</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</statement>
|
|
||||||
</block>
|
|
||||||
</xml>
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'dart:math' as Math;
|
import 'dart:math' as Math;
|
||||||
|
|
||||||
var unittestResults, test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy;
|
var unittestResults, test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy;
|
||||||
|
|
||||||
String unittest_report() {
|
String unittest_report() {
|
||||||
// Create test report.
|
// Create test report.
|
||||||
@@ -941,20 +941,6 @@ void test_replace() {
|
|||||||
unittest_assertequals(''.replaceAll('a', 'chicken'), '', 'empty source');
|
unittest_assertequals(''.replaceAll('a', 'chicken'), '', 'empty source');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests the "multiline" block.
|
|
||||||
void test_multiline() {
|
|
||||||
unittest_assertequals('', '', 'no text');
|
|
||||||
unittest_assertequals('Google', 'Google', 'simple');
|
|
||||||
unittest_assertequals('paragraph' + '\n' +
|
|
||||||
'with newlines' + '\n' +
|
|
||||||
'yup', 'paragraph' + '\n' +
|
|
||||||
'with newlines' + '\n' +
|
|
||||||
'yup', 'no compile error with newlines');
|
|
||||||
unittest_assertequals(text_count('bark bark' + '\n' +
|
|
||||||
'bark bark bark' + '\n' +
|
|
||||||
'bark bark bark bark', 'bark'), 9, 'count with newlines');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks that the number of calls is one in order
|
/// Checks that the number of calls is one in order
|
||||||
/// to confirm that a function was only called once.
|
/// to confirm that a function was only called once.
|
||||||
void check_number_of_calls2(test_name) {
|
void check_number_of_calls2(test_name) {
|
||||||
@@ -1426,80 +1412,6 @@ void test_lists_reverse() {
|
|||||||
unittest_assertequals(new List.from(list.reversed), [], 'empty list');
|
unittest_assertequals(new List.from(list.reversed), [], 'empty list');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describe this function...
|
|
||||||
void test_colour_picker() {
|
|
||||||
unittest_assertequals('#ff6600', '#ff6600', 'static colour');
|
|
||||||
}
|
|
||||||
|
|
||||||
String colour_rgb(num r, num g, num b) {
|
|
||||||
num rn = (Math.max(Math.min(r, 100), 0) * 2.55).round();
|
|
||||||
String rs = rn.toInt().toRadixString(16);
|
|
||||||
rs = '0$rs';
|
|
||||||
rs = rs.substring(rs.length - 2);
|
|
||||||
num gn = (Math.max(Math.min(g, 100), 0) * 2.55).round();
|
|
||||||
String gs = gn.toInt().toRadixString(16);
|
|
||||||
gs = '0$gs';
|
|
||||||
gs = gs.substring(gs.length - 2);
|
|
||||||
num bn = (Math.max(Math.min(b, 100), 0) * 2.55).round();
|
|
||||||
String bs = bn.toInt().toRadixString(16);
|
|
||||||
bs = '0$bs';
|
|
||||||
bs = bs.substring(bs.length - 2);
|
|
||||||
return '#$rs$gs$bs';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Describe this function...
|
|
||||||
void test_rgb() {
|
|
||||||
unittest_assertequals(colour_rgb(100, 40, 0), '#ff6600', 'from rgb');
|
|
||||||
}
|
|
||||||
|
|
||||||
String colour_random() {
|
|
||||||
String hex = '0123456789abcdef';
|
|
||||||
var rnd = new Math.Random();
|
|
||||||
return '#${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}'
|
|
||||||
'${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}'
|
|
||||||
'${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Describe this function...
|
|
||||||
void test_colour_random() {
|
|
||||||
for (int count4 = 0; count4 < 100; count4++) {
|
|
||||||
item = colour_random();
|
|
||||||
unittest_assertequals(item.length, 7, ['length of random colour string: ',item].join());
|
|
||||||
unittest_assertequals(item[0], '#', ['format of random colour string: ',item].join());
|
|
||||||
for (i = 1; i <= 6; i++) {
|
|
||||||
unittest_assertequals(0 != 'abcdefABDEF0123456789'.indexOf(item[((i + 1) - 1)]) + 1, true, ['contents of random colour string: ',item,' at index: ',i + 1].join());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String colour_blend(String c1, String c2, num ratio) {
|
|
||||||
ratio = Math.max(Math.min(ratio, 1), 0);
|
|
||||||
int r1 = int.parse('0x${c1.substring(1, 3)}');
|
|
||||||
int g1 = int.parse('0x${c1.substring(3, 5)}');
|
|
||||||
int b1 = int.parse('0x${c1.substring(5, 7)}');
|
|
||||||
int r2 = int.parse('0x${c2.substring(1, 3)}');
|
|
||||||
int g2 = int.parse('0x${c2.substring(3, 5)}');
|
|
||||||
int b2 = int.parse('0x${c2.substring(5, 7)}');
|
|
||||||
num rn = (r1 * (1 - ratio) + r2 * ratio).round();
|
|
||||||
String rs = rn.toInt().toRadixString(16);
|
|
||||||
num gn = (g1 * (1 - ratio) + g2 * ratio).round();
|
|
||||||
String gs = gn.toInt().toRadixString(16);
|
|
||||||
num bn = (b1 * (1 - ratio) + b2 * ratio).round();
|
|
||||||
String bs = bn.toInt().toRadixString(16);
|
|
||||||
rs = '0$rs';
|
|
||||||
rs = rs.substring(rs.length - 2);
|
|
||||||
gs = '0$gs';
|
|
||||||
gs = gs.substring(gs.length - 2);
|
|
||||||
bs = '0$bs';
|
|
||||||
bs = bs.substring(bs.length - 2);
|
|
||||||
return '#$rs$gs$bs';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Describe this function...
|
|
||||||
void test_blend() {
|
|
||||||
unittest_assertequals(colour_blend('#ff0000', colour_rgb(100, 40, 0), 0.4), '#ff2900', 'blend');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Describe this function...
|
/// Describe this function...
|
||||||
void test_procedure() {
|
void test_procedure() {
|
||||||
procedure_1(8, 2);
|
procedure_1(8, 2);
|
||||||
@@ -1642,7 +1554,6 @@ main() {
|
|||||||
test_count_text();
|
test_count_text();
|
||||||
test_text_reverse();
|
test_text_reverse();
|
||||||
test_replace();
|
test_replace();
|
||||||
test_multiline();
|
|
||||||
print(unittest_report());
|
print(unittest_report());
|
||||||
unittestResults = null;
|
unittestResults = null;
|
||||||
|
|
||||||
@@ -1671,15 +1582,6 @@ main() {
|
|||||||
print(unittest_report());
|
print(unittest_report());
|
||||||
unittestResults = null;
|
unittestResults = null;
|
||||||
|
|
||||||
unittestResults = [];
|
|
||||||
print('\n====================\n\nRunning suite: Colour');
|
|
||||||
test_colour_picker();
|
|
||||||
test_blend();
|
|
||||||
test_rgb();
|
|
||||||
test_colour_random();
|
|
||||||
print(unittest_report());
|
|
||||||
unittestResults = null;
|
|
||||||
|
|
||||||
unittestResults = [];
|
unittestResults = [];
|
||||||
print('\n====================\n\nRunning suite: Variables');
|
print('\n====================\n\nRunning suite: Variables');
|
||||||
item = 123;
|
item = 123;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var unittestResults, test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy;
|
var unittestResults, test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy;
|
||||||
|
|
||||||
function unittest_report() {
|
function unittest_report() {
|
||||||
// Create test report.
|
// Create test report.
|
||||||
@@ -920,20 +920,6 @@ function test_replace() {
|
|||||||
assertEquals(textReplace('', 'a', 'chicken'), '', 'empty source');
|
assertEquals(textReplace('', 'a', 'chicken'), '', 'empty source');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "multiline" block.
|
|
||||||
function test_multiline() {
|
|
||||||
assertEquals('', '', 'no text');
|
|
||||||
assertEquals('Google', 'Google', 'simple');
|
|
||||||
assertEquals('paragraph' + '\n' +
|
|
||||||
'with newlines' + '\n' +
|
|
||||||
'yup', 'paragraph' + '\n' +
|
|
||||||
'with newlines' + '\n' +
|
|
||||||
'yup', 'no compile error with newlines');
|
|
||||||
assertEquals(textCount('bark bark' + '\n' +
|
|
||||||
'bark bark bark' + '\n' +
|
|
||||||
'bark bark bark bark', 'bark'), 9, 'count with newlines');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks that the number of calls is one in order
|
// Checks that the number of calls is one in order
|
||||||
// to confirm that a function was only called once.
|
// to confirm that a function was only called once.
|
||||||
function check_number_of_calls2(test_name) {
|
function check_number_of_calls2(test_name) {
|
||||||
@@ -1376,65 +1362,6 @@ function test_lists_reverse() {
|
|||||||
assertEquals(list.slice().reverse(), [], 'empty list');
|
assertEquals(list.slice().reverse(), [], 'empty list');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe this function...
|
|
||||||
function test_colour_picker() {
|
|
||||||
assertEquals('#ff6600', '#ff6600', 'static colour');
|
|
||||||
}
|
|
||||||
|
|
||||||
function colourRgb(r, g, b) {
|
|
||||||
r = Math.max(Math.min(Number(r), 100), 0) * 2.55;
|
|
||||||
g = Math.max(Math.min(Number(g), 100), 0) * 2.55;
|
|
||||||
b = Math.max(Math.min(Number(b), 100), 0) * 2.55;
|
|
||||||
r = ('0' + (Math.round(r) || 0).toString(16)).slice(-2);
|
|
||||||
g = ('0' + (Math.round(g) || 0).toString(16)).slice(-2);
|
|
||||||
b = ('0' + (Math.round(b) || 0).toString(16)).slice(-2);
|
|
||||||
return '#' + r + g + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe this function...
|
|
||||||
function test_rgb() {
|
|
||||||
assertEquals(colourRgb(100, 40, 0), '#ff6600', 'from rgb');
|
|
||||||
}
|
|
||||||
|
|
||||||
function colourRandom() {
|
|
||||||
var num = Math.floor(Math.random() * Math.pow(2, 24));
|
|
||||||
return '#' + ('00000' + num.toString(16)).substr(-6);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe this function...
|
|
||||||
function test_colour_random() {
|
|
||||||
for (var count4 = 0; count4 < 100; count4++) {
|
|
||||||
item = colourRandom();
|
|
||||||
assertEquals(item.length, 7, 'length of random colour string: ' + String(item));
|
|
||||||
assertEquals(item.charAt(0), '#', 'format of random colour string: ' + String(item));
|
|
||||||
for (i = 1; i <= 6; i++) {
|
|
||||||
assertEquals(0 != 'abcdefABDEF0123456789'.indexOf(item.charAt(((i + 1) - 1))) + 1, true, ['contents of random colour string: ',item,' at index: ',i + 1].join(''));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function colourBlend(c1, c2, ratio) {
|
|
||||||
ratio = Math.max(Math.min(Number(ratio), 1), 0);
|
|
||||||
var r1 = parseInt(c1.substring(1, 3), 16);
|
|
||||||
var g1 = parseInt(c1.substring(3, 5), 16);
|
|
||||||
var b1 = parseInt(c1.substring(5, 7), 16);
|
|
||||||
var r2 = parseInt(c2.substring(1, 3), 16);
|
|
||||||
var g2 = parseInt(c2.substring(3, 5), 16);
|
|
||||||
var b2 = parseInt(c2.substring(5, 7), 16);
|
|
||||||
var r = Math.round(r1 * (1 - ratio) + r2 * ratio);
|
|
||||||
var g = Math.round(g1 * (1 - ratio) + g2 * ratio);
|
|
||||||
var b = Math.round(b1 * (1 - ratio) + b2 * ratio);
|
|
||||||
r = ('0' + (r || 0).toString(16)).slice(-2);
|
|
||||||
g = ('0' + (g || 0).toString(16)).slice(-2);
|
|
||||||
b = ('0' + (b || 0).toString(16)).slice(-2);
|
|
||||||
return '#' + r + g + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe this function...
|
|
||||||
function test_blend() {
|
|
||||||
assertEquals(colourBlend('#ff0000', colourRgb(100, 40, 0), 0.4), '#ff2900', 'blend');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_procedure() {
|
function test_procedure() {
|
||||||
procedure_1(8, 2);
|
procedure_1(8, 2);
|
||||||
@@ -1576,7 +1503,6 @@ test_trim();
|
|||||||
test_count_text();
|
test_count_text();
|
||||||
test_text_reverse();
|
test_text_reverse();
|
||||||
test_replace();
|
test_replace();
|
||||||
test_multiline();
|
|
||||||
console.log(unittest_report());
|
console.log(unittest_report());
|
||||||
unittestResults = null;
|
unittestResults = null;
|
||||||
|
|
||||||
@@ -1605,15 +1531,6 @@ test_lists_reverse();
|
|||||||
console.log(unittest_report());
|
console.log(unittest_report());
|
||||||
unittestResults = null;
|
unittestResults = null;
|
||||||
|
|
||||||
unittestResults = [];
|
|
||||||
console.log('\n====================\n\nRunning suite: Colour')
|
|
||||||
test_colour_picker();
|
|
||||||
test_blend();
|
|
||||||
test_rgb();
|
|
||||||
test_colour_random();
|
|
||||||
console.log(unittest_report());
|
|
||||||
unittestResults = null;
|
|
||||||
|
|
||||||
unittestResults = [];
|
unittestResults = [];
|
||||||
console.log('\n====================\n\nRunning suite: Variables')
|
console.log('\n====================\n\nRunning suite: Variables')
|
||||||
item = 123;
|
item = 123;
|
||||||
|
|||||||
@@ -1015,21 +1015,6 @@ function test_replace()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Tests the "multiline" block.
|
|
||||||
function test_multiline()
|
|
||||||
assertEquals('', '', 'no text')
|
|
||||||
assertEquals('Google', 'Google', 'simple')
|
|
||||||
assertEquals('paragraph' .. '\n' ..
|
|
||||||
'with newlines' .. '\n' ..
|
|
||||||
'yup', 'paragraph' .. '\n' ..
|
|
||||||
'with newlines' .. '\n' ..
|
|
||||||
'yup', 'no compile error with newlines')
|
|
||||||
assertEquals(text_count('bark bark' .. '\n' ..
|
|
||||||
'bark bark bark' .. '\n' ..
|
|
||||||
'bark bark bark bark', 'bark'), 9, 'count with newlines')
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Checks that the number of calls is one in order
|
-- Checks that the number of calls is one in order
|
||||||
-- to confirm that a function was only called once.
|
-- to confirm that a function was only called once.
|
||||||
function check_number_of_calls2(test_name)
|
function check_number_of_calls2(test_name)
|
||||||
@@ -1645,58 +1630,6 @@ function test_lists_reverse()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Describe this function...
|
|
||||||
function test_colour_picker()
|
|
||||||
assertEquals('#ff6600', '#ff6600', 'static colour')
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function colour_rgb(r, g, b)
|
|
||||||
r = math.floor(math.min(100, math.max(0, r)) * 2.55 + .5)
|
|
||||||
g = math.floor(math.min(100, math.max(0, g)) * 2.55 + .5)
|
|
||||||
b = math.floor(math.min(100, math.max(0, b)) * 2.55 + .5)
|
|
||||||
return string.format("#%02x%02x%02x", r, g, b)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Describe this function...
|
|
||||||
function test_rgb()
|
|
||||||
assertEquals(colour_rgb(100, 40, 0), '#ff6600', 'from rgb')
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Describe this function...
|
|
||||||
function test_colour_random()
|
|
||||||
for count4 = 1, 100 do
|
|
||||||
item = string.format("#%06x", math.random(0, 2^24 - 1))
|
|
||||||
assertEquals(#item, 7, 'length of random colour string: ' .. item)
|
|
||||||
assertEquals(string.sub(item, 1, 1), '#', 'format of random colour string: ' .. item)
|
|
||||||
for i = 1, 6, 1 do
|
|
||||||
assertEquals(0 ~= firstIndexOf('abcdefABDEF0123456789', text_char_at(item, i + 1)), true, table.concat({'contents of random colour string: ', item, ' at index: ', i + 1}))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function colour_blend(colour1, colour2, ratio)
|
|
||||||
local r1 = tonumber(string.sub(colour1, 2, 3), 16)
|
|
||||||
local r2 = tonumber(string.sub(colour2, 2, 3), 16)
|
|
||||||
local g1 = tonumber(string.sub(colour1, 4, 5), 16)
|
|
||||||
local g2 = tonumber(string.sub(colour2, 4, 5), 16)
|
|
||||||
local b1 = tonumber(string.sub(colour1, 6, 7), 16)
|
|
||||||
local b2 = tonumber(string.sub(colour2, 6, 7), 16)
|
|
||||||
local ratio = math.min(1, math.max(0, ratio))
|
|
||||||
local r = math.floor(r1 * (1 - ratio) + r2 * ratio + .5)
|
|
||||||
local g = math.floor(g1 * (1 - ratio) + g2 * ratio + .5)
|
|
||||||
local b = math.floor(b1 * (1 - ratio) + b2 * ratio + .5)
|
|
||||||
return string.format("#%02x%02x%02x", r, g, b)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Describe this function...
|
|
||||||
function test_blend()
|
|
||||||
assertEquals(colour_blend('#ff0000', colour_rgb(100, 40, 0), 0.4), '#ff2900', 'blend')
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Describe this function...
|
-- Describe this function...
|
||||||
function test_procedure()
|
function test_procedure()
|
||||||
procedure_1(8, 2)
|
procedure_1(8, 2)
|
||||||
@@ -1846,7 +1779,6 @@ test_trim()
|
|||||||
test_count_text()
|
test_count_text()
|
||||||
test_text_reverse()
|
test_text_reverse()
|
||||||
test_replace()
|
test_replace()
|
||||||
test_multiline()
|
|
||||||
print(unittest_report())
|
print(unittest_report())
|
||||||
unittestResults = nil
|
unittestResults = nil
|
||||||
|
|
||||||
@@ -1875,15 +1807,6 @@ test_lists_reverse()
|
|||||||
print(unittest_report())
|
print(unittest_report())
|
||||||
unittestResults = nil
|
unittestResults = nil
|
||||||
|
|
||||||
unittestResults = {}
|
|
||||||
print('\n====================\n\nRunning suite: Colour')
|
|
||||||
test_colour_picker()
|
|
||||||
test_blend()
|
|
||||||
test_rgb()
|
|
||||||
test_colour_random()
|
|
||||||
print(unittest_report())
|
|
||||||
unittestResults = nil
|
|
||||||
|
|
||||||
unittestResults = {}
|
unittestResults = {}
|
||||||
print('\n====================\n\nRunning suite: Variables')
|
print('\n====================\n\nRunning suite: Variables')
|
||||||
item = 123
|
item = 123
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ function unittest_fail($message) {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_if() {
|
function test_if() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
if (false) {
|
if (false) {
|
||||||
unittest_fail('if false');
|
unittest_fail('if false');
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ function test_if() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_ifelse() {
|
function test_ifelse() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$ok = false;
|
$ok = false;
|
||||||
if (true) {
|
if (true) {
|
||||||
$ok = true;
|
$ok = true;
|
||||||
@@ -110,7 +110,7 @@ function test_ifelse() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_equalities() {
|
function test_equalities() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(2 == 2, true, 'Equal yes');
|
assertEquals(2 == 2, true, 'Equal yes');
|
||||||
assertEquals(3 == 4, false, 'Equal no');
|
assertEquals(3 == 4, false, 'Equal no');
|
||||||
assertEquals(5 != 6, true, 'Not equal yes');
|
assertEquals(5 != 6, true, 'Not equal yes');
|
||||||
@@ -127,7 +127,7 @@ function test_equalities() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_and() {
|
function test_and() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(true && true, true, 'And true/true');
|
assertEquals(true && true, true, 'And true/true');
|
||||||
assertEquals(false && true, false, 'And false/true');
|
assertEquals(false && true, false, 'And false/true');
|
||||||
assertEquals(true && false, false, 'And true/false');
|
assertEquals(true && false, false, 'And true/false');
|
||||||
@@ -136,7 +136,7 @@ function test_and() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_or() {
|
function test_or() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(true || true, true, 'Or true/true');
|
assertEquals(true || true, true, 'Or true/true');
|
||||||
assertEquals(false || true, true, 'Or false/true');
|
assertEquals(false || true, true, 'Or false/true');
|
||||||
assertEquals(true || false, true, 'Or true/false');
|
assertEquals(true || false, true, 'Or true/false');
|
||||||
@@ -145,14 +145,14 @@ function test_or() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_ternary() {
|
function test_ternary() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(true ? 42 : 99, 42, 'if true');
|
assertEquals(true ? 42 : 99, 42, 'if true');
|
||||||
assertEquals(false ? 42 : 99, 99, 'if true');
|
assertEquals(false ? 42 : 99, 99, 'if true');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_foreach() {
|
function test_foreach() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$log = '';
|
$log = '';
|
||||||
foreach (array('a', 'b', 'c') as $x) {
|
foreach (array('a', 'b', 'c') as $x) {
|
||||||
$log .= $x;
|
$log .= $x;
|
||||||
@@ -162,7 +162,7 @@ function test_foreach() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_repeat() {
|
function test_repeat() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$count = 0;
|
$count = 0;
|
||||||
for ($count2 = 0; $count2 < 10; $count2++) {
|
for ($count2 = 0; $count2 < 10; $count2++) {
|
||||||
$count += 1;
|
$count += 1;
|
||||||
@@ -172,7 +172,7 @@ function test_repeat() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_while() {
|
function test_while() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
while (false) {
|
while (false) {
|
||||||
unittest_fail('while 0');
|
unittest_fail('while 0');
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ function test_while() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_repeat_ext() {
|
function test_repeat_ext() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$count = 0;
|
$count = 0;
|
||||||
for ($count3 = 0; $count3 < 10; $count3++) {
|
for ($count3 = 0; $count3 < 10; $count3++) {
|
||||||
$count += 1;
|
$count += 1;
|
||||||
@@ -203,7 +203,7 @@ function test_repeat_ext() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_count_by() {
|
function test_count_by() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$log = '';
|
$log = '';
|
||||||
for ($x = 1; $x <= 8; $x += 2) {
|
for ($x = 1; $x <= 8; $x += 2) {
|
||||||
$log .= $x;
|
$log .= $x;
|
||||||
@@ -256,7 +256,7 @@ function test_count_by() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_count_loops() {
|
function test_count_loops() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$log = '';
|
$log = '';
|
||||||
for ($x = 1; $x <= 8; $x++) {
|
for ($x = 1; $x <= 8; $x++) {
|
||||||
$log .= $x;
|
$log .= $x;
|
||||||
@@ -293,7 +293,7 @@ function test_count_loops() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_continue() {
|
function test_continue() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$log = '';
|
$log = '';
|
||||||
$count = 0;
|
$count = 0;
|
||||||
while ($count != 8) {
|
while ($count != 8) {
|
||||||
@@ -334,7 +334,7 @@ function test_continue() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_break() {
|
function test_break() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$count = 1;
|
$count = 1;
|
||||||
while ($count != 10) {
|
while ($count != 10) {
|
||||||
if ($count == 5) {
|
if ($count == 5) {
|
||||||
@@ -371,7 +371,7 @@ function test_break() {
|
|||||||
|
|
||||||
// Tests the "single" block.
|
// Tests the "single" block.
|
||||||
function test_single() {
|
function test_single() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(sqrt(25), 5, 'sqrt');
|
assertEquals(sqrt(25), 5, 'sqrt');
|
||||||
assertEquals(abs(-25), 25, 'abs');
|
assertEquals(abs(-25), 25, 'abs');
|
||||||
assertEquals(-(-25), 25, 'negate');
|
assertEquals(-(-25), 25, 'negate');
|
||||||
@@ -384,7 +384,7 @@ function test_single() {
|
|||||||
// Tests the "arithmetic" block for all operations and checks
|
// Tests the "arithmetic" block for all operations and checks
|
||||||
// parenthesis are properly generated for different orders.
|
// parenthesis are properly generated for different orders.
|
||||||
function test_arithmetic() {
|
function test_arithmetic() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(1 + 2, 3, 'add');
|
assertEquals(1 + 2, 3, 'add');
|
||||||
assertEquals(1 - 2, -1, 'subtract');
|
assertEquals(1 - 2, -1, 'subtract');
|
||||||
assertEquals(1 - (0 + 2), -1, 'subtract order with add');
|
assertEquals(1 - (0 + 2), -1, 'subtract order with add');
|
||||||
@@ -399,7 +399,7 @@ function test_arithmetic() {
|
|||||||
|
|
||||||
// Tests the "trig" block.
|
// Tests the "trig" block.
|
||||||
function test_trig() {
|
function test_trig() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(sin(90 / 180 * pi()), 1, 'sin');
|
assertEquals(sin(90 / 180 * pi()), 1, 'sin');
|
||||||
assertEquals(cos(180 / 180 * pi()), -1, 'cos');
|
assertEquals(cos(180 / 180 * pi()), -1, 'cos');
|
||||||
assertEquals(tan(0 / 180 * pi()), 0, 'tan');
|
assertEquals(tan(0 / 180 * pi()), 0, 'tan');
|
||||||
@@ -410,7 +410,7 @@ function test_trig() {
|
|||||||
|
|
||||||
// Tests the "constant" blocks.
|
// Tests the "constant" blocks.
|
||||||
function test_constant() {
|
function test_constant() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(floor(M_PI * 1000), 3141, 'const pi');
|
assertEquals(floor(M_PI * 1000), 3141, 'const pi');
|
||||||
assertEquals(floor(M_E * 1000), 2718, 'const e');
|
assertEquals(floor(M_E * 1000), 2718, 'const e');
|
||||||
assertEquals(floor(((1 + sqrt(5)) / 2) * 1000), 1618, 'const golden');
|
assertEquals(floor(((1 + sqrt(5)) / 2) * 1000), 1618, 'const golden');
|
||||||
@@ -440,7 +440,7 @@ function math_isPrime($n) {
|
|||||||
|
|
||||||
// Tests the "number property" blocks.
|
// Tests the "number property" blocks.
|
||||||
function test_number_properties() {
|
function test_number_properties() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(42 % 2 == 0, true, 'even');
|
assertEquals(42 % 2 == 0, true, 'even');
|
||||||
assertEquals(42.1 % 2 == 1, false, 'odd');
|
assertEquals(42.1 % 2 == 1, false, 'odd');
|
||||||
assertEquals(math_isPrime(5), true, 'prime 5');
|
assertEquals(math_isPrime(5), true, 'prime 5');
|
||||||
@@ -458,7 +458,7 @@ function test_number_properties() {
|
|||||||
|
|
||||||
// Tests the "round" block.
|
// Tests the "round" block.
|
||||||
function test_round() {
|
function test_round() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(round(42.42), 42, 'round');
|
assertEquals(round(42.42), 42, 'round');
|
||||||
assertEquals(ceil(-42.42), -42, 'round up');
|
assertEquals(ceil(-42.42), -42, 'round up');
|
||||||
assertEquals(floor(42.42), 42, 'round down');
|
assertEquals(floor(42.42), 42, 'round down');
|
||||||
@@ -466,7 +466,7 @@ function test_round() {
|
|||||||
|
|
||||||
// Tests the "change" block.
|
// Tests the "change" block.
|
||||||
function test_change() {
|
function test_change() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$varToChange = 100;
|
$varToChange = 100;
|
||||||
$varToChange += 42;
|
$varToChange += 42;
|
||||||
assertEquals($varToChange, 142, 'change');
|
assertEquals($varToChange, 142, 'change');
|
||||||
@@ -512,7 +512,7 @@ function indexOf($haystack, $needle) {
|
|||||||
|
|
||||||
// Tests the "list operation" blocks.
|
// Tests the "list operation" blocks.
|
||||||
function test_operations_on_list() {
|
function test_operations_on_list() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(array_sum((array(3, 4, 5))), 12, 'sum');
|
assertEquals(array_sum((array(3, 4, 5))), 12, 'sum');
|
||||||
assertEquals(min((array(3, 4, 5))), 3, 'min');
|
assertEquals(min((array(3, 4, 5))), 3, 'min');
|
||||||
assertEquals(max((array(3, 4, 5))), 5, 'max');
|
assertEquals(max((array(3, 4, 5))), 5, 'max');
|
||||||
@@ -526,13 +526,13 @@ function test_operations_on_list() {
|
|||||||
|
|
||||||
// Tests the "mod" block.
|
// Tests the "mod" block.
|
||||||
function test_mod() {
|
function test_mod() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(42 % 5, 2, 'mod');
|
assertEquals(42 % 5, 2, 'mod');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "constrain" block.
|
// Tests the "constrain" block.
|
||||||
function test_constraint() {
|
function test_constraint() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(min(max(100, 0), 42), 42, 'constraint');
|
assertEquals(min(max(100, 0), 42), 42, 'constraint');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,7 +545,7 @@ function math_random_int($a, $b) {
|
|||||||
|
|
||||||
// Tests the "random integer" block.
|
// Tests the "random integer" block.
|
||||||
function test_random_integer() {
|
function test_random_integer() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$rand = math_random_int(5, 10);
|
$rand = math_random_int(5, 10);
|
||||||
assertEquals($rand >= 5 && $rand <= 10, true, 'randRange');
|
assertEquals($rand >= 5 && $rand <= 10, true, 'randRange');
|
||||||
assertEquals(is_int($rand), true, 'randInteger');
|
assertEquals(is_int($rand), true, 'randInteger');
|
||||||
@@ -553,14 +553,14 @@ function test_random_integer() {
|
|||||||
|
|
||||||
// Tests the "random fraction" block.
|
// Tests the "random fraction" block.
|
||||||
function test_random_fraction() {
|
function test_random_fraction() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$rand = (float)rand()/(float)getrandmax();
|
$rand = (float)rand()/(float)getrandmax();
|
||||||
assertEquals($rand >= 0 && $rand <= 1, true, 'randFloat');
|
assertEquals($rand >= 0 && $rand <= 1, true, 'randFloat');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_atan2() {
|
function test_atan2() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(atan2(5, -5) / pi() * 180, 135, 'atan2');
|
assertEquals(atan2(5, -5) / pi() * 180, 135, 'atan2');
|
||||||
assertEquals(atan2(-12, 0) / pi() * 180, -90, 'atan2');
|
assertEquals(atan2(-12, 0) / pi() * 180, -90, 'atan2');
|
||||||
}
|
}
|
||||||
@@ -568,14 +568,14 @@ function test_atan2() {
|
|||||||
// Checks that the number of calls is one in order
|
// Checks that the number of calls is one in order
|
||||||
// to confirm that a function was only called once.
|
// to confirm that a function was only called once.
|
||||||
function check_number_of_calls($test_name) {
|
function check_number_of_calls($test_name) {
|
||||||
global $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$test_name .= 'number of calls';
|
$test_name .= 'number of calls';
|
||||||
assertEquals($number_of_calls, 1, $test_name);
|
assertEquals($number_of_calls, 1, $test_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "create text with" block with varying number of inputs.
|
// Tests the "create text with" block with varying number of inputs.
|
||||||
function test_create_text() {
|
function test_create_text() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals('', '', 'no text');
|
assertEquals('', '', 'no text');
|
||||||
assertEquals('Hello', 'Hello', 'create single');
|
assertEquals('Hello', 'Hello', 'create single');
|
||||||
assertEquals(-1, '-1', 'create single number');
|
assertEquals(-1, '-1', 'create single number');
|
||||||
@@ -587,13 +587,13 @@ function test_create_text() {
|
|||||||
|
|
||||||
// Creates an empty string for use with the empty test.
|
// Creates an empty string for use with the empty test.
|
||||||
function get_empty() {
|
function get_empty() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "is empty" block".
|
// Tests the "is empty" block".
|
||||||
function test_empty_text() {
|
function test_empty_text() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(empty('Google'), false, 'not empty');
|
assertEquals(empty('Google'), false, 'not empty');
|
||||||
assertEquals(empty(''), true, 'empty');
|
assertEquals(empty(''), true, 'empty');
|
||||||
assertEquals(empty(get_empty()), true, 'empty complex');
|
assertEquals(empty(get_empty()), true, 'empty complex');
|
||||||
@@ -609,7 +609,7 @@ function length($value) {
|
|||||||
|
|
||||||
// Tests the "length" block.
|
// Tests the "length" block.
|
||||||
function test_text_length() {
|
function test_text_length() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(length(''), 0, 'zero length');
|
assertEquals(length(''), 0, 'zero length');
|
||||||
assertEquals(length('Google'), 6, 'non-zero length');
|
assertEquals(length('Google'), 6, 'non-zero length');
|
||||||
assertEquals(length(true ? 'car' : null), 3, 'length order');
|
assertEquals(length(true ? 'car' : null), 3, 'length order');
|
||||||
@@ -617,7 +617,7 @@ function test_text_length() {
|
|||||||
|
|
||||||
// Tests the "append text" block with different types of parameters.
|
// Tests the "append text" block with different types of parameters.
|
||||||
function test_append() {
|
function test_append() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$item = 'Miserable';
|
$item = 'Miserable';
|
||||||
$item .= 'Failure';
|
$item .= 'Failure';
|
||||||
assertEquals($item, 'MiserableFailure', 'append text');
|
assertEquals($item, 'MiserableFailure', 'append text');
|
||||||
@@ -641,7 +641,7 @@ function text_lastIndexOf($text, $search) {
|
|||||||
|
|
||||||
// Tests the "find" block with a variable.
|
// Tests the "find" block with a variable.
|
||||||
function test_find_text_simple() {
|
function test_find_text_simple() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$text = 'Banana';
|
$text = 'Banana';
|
||||||
assertEquals(text_indexOf($text, 'an'), 2, 'find first simple');
|
assertEquals(text_indexOf($text, 'an'), 2, 'find first simple');
|
||||||
assertEquals(text_lastIndexOf($text, 'an'), 4, 'find last simple');
|
assertEquals(text_lastIndexOf($text, 'an'), 4, 'find last simple');
|
||||||
@@ -650,14 +650,14 @@ function test_find_text_simple() {
|
|||||||
|
|
||||||
// Creates a string for use with the find test.
|
// Creates a string for use with the find test.
|
||||||
function get_fruit() {
|
function get_fruit() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls += 1;
|
$number_of_calls += 1;
|
||||||
return 'Banana';
|
return 'Banana';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "find" block with a function call.
|
// Tests the "find" block with a function call.
|
||||||
function test_find_text_complex() {
|
function test_find_text_complex() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls = 0;
|
$number_of_calls = 0;
|
||||||
assertEquals(text_indexOf(get_fruit(), 'an'), 2, 'find first complex');
|
assertEquals(text_indexOf(get_fruit(), 'an'), 2, 'find first complex');
|
||||||
check_number_of_calls('find first complex');
|
check_number_of_calls('find first complex');
|
||||||
@@ -684,7 +684,7 @@ function text_random_letter($text) {
|
|||||||
|
|
||||||
// Tests the "get letter" block with a variable.
|
// Tests the "get letter" block with a variable.
|
||||||
function test_get_text_simple() {
|
function test_get_text_simple() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$text = 'Blockly';
|
$text = 'Blockly';
|
||||||
assertEquals(substr($text, 0, 1), 'B', 'get first simple');
|
assertEquals(substr($text, 0, 1), 'B', 'get first simple');
|
||||||
assertEquals(substr($text, -1), 'y', 'get last simple');
|
assertEquals(substr($text, -1), 'y', 'get last simple');
|
||||||
@@ -698,14 +698,14 @@ function test_get_text_simple() {
|
|||||||
|
|
||||||
// Creates a string for use with the get test.
|
// Creates a string for use with the get test.
|
||||||
function get_Blockly() {
|
function get_Blockly() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls += 1;
|
$number_of_calls += 1;
|
||||||
return 'Blockly';
|
return 'Blockly';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "get letter" block with a function call.
|
// Tests the "get letter" block with a function call.
|
||||||
function test_get_text_complex() {
|
function test_get_text_complex() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$text = 'Blockly';
|
$text = 'Blockly';
|
||||||
$number_of_calls = 0;
|
$number_of_calls = 0;
|
||||||
assertEquals(substr(get_Blockly(), 0, 1), 'B', 'get first complex');
|
assertEquals(substr(get_Blockly(), 0, 1), 'B', 'get first complex');
|
||||||
@@ -742,7 +742,7 @@ function test_get_text_complex() {
|
|||||||
|
|
||||||
// Creates a string for use with the substring test.
|
// Creates a string for use with the substring test.
|
||||||
function get_numbers() {
|
function get_numbers() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls += 1;
|
$number_of_calls += 1;
|
||||||
return '123456789';
|
return '123456789';
|
||||||
}
|
}
|
||||||
@@ -770,7 +770,7 @@ function text_get_substring($text, $where1, $at1, $where2, $at2) {
|
|||||||
|
|
||||||
// Tests the "get substring" block with a variable.
|
// Tests the "get substring" block with a variable.
|
||||||
function test_substring_simple() {
|
function test_substring_simple() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$text = '123456789';
|
$text = '123456789';
|
||||||
assertEquals(text_get_substring($text, 'FROM_START', 1, 'FROM_START', 2), '23', 'substring # simple');
|
assertEquals(text_get_substring($text, 'FROM_START', 1, 'FROM_START', 2), '23', 'substring # simple');
|
||||||
assertEquals(text_get_substring($text, 'FROM_START', ((true ? 2 : null) - 1), 'FROM_START', ((true ? 3 : null) - 1)), '23', 'substring # simple order');
|
assertEquals(text_get_substring($text, 'FROM_START', ((true ? 2 : null) - 1), 'FROM_START', ((true ? 3 : null) - 1)), '23', 'substring # simple order');
|
||||||
@@ -792,7 +792,7 @@ function test_substring_simple() {
|
|||||||
|
|
||||||
// Tests the "get substring" block with a function call.
|
// Tests the "get substring" block with a function call.
|
||||||
function test_substring_complex() {
|
function test_substring_complex() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls = 0;
|
$number_of_calls = 0;
|
||||||
assertEquals(text_get_substring(get_numbers(), 'FROM_START', 1, 'FROM_START', 2), '23', 'substring # complex');
|
assertEquals(text_get_substring(get_numbers(), 'FROM_START', 1, 'FROM_START', 2), '23', 'substring # complex');
|
||||||
check_number_of_calls('substring # complex');
|
check_number_of_calls('substring # complex');
|
||||||
@@ -841,7 +841,7 @@ function test_substring_complex() {
|
|||||||
|
|
||||||
// Tests the "change casing" block.
|
// Tests the "change casing" block.
|
||||||
function test_case() {
|
function test_case() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$text = 'Hello World';
|
$text = 'Hello World';
|
||||||
assertEquals(strtoupper($text), 'HELLO WORLD', 'uppercase');
|
assertEquals(strtoupper($text), 'HELLO WORLD', 'uppercase');
|
||||||
assertEquals(strtoupper(true ? $text : null), 'HELLO WORLD', 'uppercase order');
|
assertEquals(strtoupper(true ? $text : null), 'HELLO WORLD', 'uppercase order');
|
||||||
@@ -855,7 +855,7 @@ function test_case() {
|
|||||||
|
|
||||||
// Tests the "trim" block.
|
// Tests the "trim" block.
|
||||||
function test_trim() {
|
function test_trim() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$text = ' abc def ';
|
$text = ' abc def ';
|
||||||
assertEquals(trim($text), 'abc def', 'trim both');
|
assertEquals(trim($text), 'abc def', 'trim both');
|
||||||
assertEquals(trim(true ? $text : null), 'abc def', 'trim both order');
|
assertEquals(trim(true ? $text : null), 'abc def', 'trim both order');
|
||||||
@@ -867,7 +867,7 @@ function test_trim() {
|
|||||||
|
|
||||||
// Tests the "trim" block.
|
// Tests the "trim" block.
|
||||||
function test_count_text() {
|
function test_count_text() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$text = 'woolloomooloo';
|
$text = 'woolloomooloo';
|
||||||
assertEquals(strlen('o') === 0 ? strlen($text) + 1 : substr_count($text, 'o'), 8, 'len 1');
|
assertEquals(strlen('o') === 0 ? strlen($text) + 1 : substr_count($text, 'o'), 8, 'len 1');
|
||||||
assertEquals(strlen('oo') === 0 ? strlen($text) + 1 : substr_count($text, 'oo'), 4, 'len 2');
|
assertEquals(strlen('oo') === 0 ? strlen($text) + 1 : substr_count($text, 'oo'), 4, 'len 2');
|
||||||
@@ -880,7 +880,7 @@ function test_count_text() {
|
|||||||
|
|
||||||
// Tests the "trim" block.
|
// Tests the "trim" block.
|
||||||
function test_text_reverse() {
|
function test_text_reverse() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(strrev(''), '', 'empty string');
|
assertEquals(strrev(''), '', 'empty string');
|
||||||
assertEquals(strrev('a'), 'a', 'len 1');
|
assertEquals(strrev('a'), 'a', 'len 1');
|
||||||
assertEquals(strrev('ab'), 'ba', 'len 2');
|
assertEquals(strrev('ab'), 'ba', 'len 2');
|
||||||
@@ -889,7 +889,7 @@ function test_text_reverse() {
|
|||||||
|
|
||||||
// Tests the "trim" block.
|
// Tests the "trim" block.
|
||||||
function test_replace() {
|
function test_replace() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(str_replace('oo', '123', 'woolloomooloo'), 'w123ll123m123l123', 'replace all instances 1');
|
assertEquals(str_replace('oo', '123', 'woolloomooloo'), 'w123ll123m123l123', 'replace all instances 1');
|
||||||
assertEquals(str_replace('.oo', 'X', 'woolloomooloo'), 'woolloomooloo', 'literal string replacement');
|
assertEquals(str_replace('.oo', 'X', 'woolloomooloo'), 'woolloomooloo', 'literal string replacement');
|
||||||
assertEquals(str_replace('abc', 'X', 'woolloomooloo'), 'woolloomooloo', 'not found');
|
assertEquals(str_replace('abc', 'X', 'woolloomooloo'), 'woolloomooloo', 'not found');
|
||||||
@@ -899,27 +899,10 @@ function test_replace() {
|
|||||||
assertEquals(str_replace('a', 'chicken', ''), '', 'empty source');
|
assertEquals(str_replace('a', 'chicken', ''), '', 'empty source');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "multiline" block.
|
|
||||||
function test_multiline() {
|
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
|
||||||
assertEquals('', '', 'no text');
|
|
||||||
assertEquals('Google', 'Google', 'simple');
|
|
||||||
assertEquals('paragraph' . "\n" .
|
|
||||||
'with newlines' . "\n" .
|
|
||||||
'yup', 'paragraph' . "\n" .
|
|
||||||
'with newlines' . "\n" .
|
|
||||||
'yup', 'no compile error with newlines');
|
|
||||||
assertEquals(strlen('bark') === 0 ? strlen('bark bark' . "\n" .
|
|
||||||
'bark bark bark' . "\n" .
|
|
||||||
'bark bark bark bark') + 1 : substr_count('bark bark' . "\n" .
|
|
||||||
'bark bark bark' . "\n" .
|
|
||||||
'bark bark bark bark', 'bark'), 9, 'count with newlines');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks that the number of calls is one in order
|
// Checks that the number of calls is one in order
|
||||||
// to confirm that a function was only called once.
|
// to confirm that a function was only called once.
|
||||||
function check_number_of_calls2($test_name) {
|
function check_number_of_calls2($test_name) {
|
||||||
global $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$test_name .= 'number of calls';
|
$test_name .= 'number of calls';
|
||||||
assertEquals($number_of_calls, 1, $test_name);
|
assertEquals($number_of_calls, 1, $test_name);
|
||||||
}
|
}
|
||||||
@@ -934,7 +917,7 @@ function lists_repeat($value, $count) {
|
|||||||
|
|
||||||
// Tests the "create list with" and "create empty list" blocks.
|
// Tests the "create list with" and "create empty list" blocks.
|
||||||
function test_create_lists() {
|
function test_create_lists() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(array(), array(), 'create empty');
|
assertEquals(array(), array(), 'create empty');
|
||||||
assertEquals(array(true, 'love'), array(true, 'love'), 'create items');
|
assertEquals(array(true, 'love'), array(true, 'love'), 'create items');
|
||||||
assertEquals(lists_repeat('Eject', 3), array('Eject', 'Eject', 'Eject'), 'create repeated');
|
assertEquals(lists_repeat('Eject', 3), array('Eject', 'Eject', 'Eject'), 'create repeated');
|
||||||
@@ -943,13 +926,13 @@ function test_create_lists() {
|
|||||||
|
|
||||||
// Creates an empty list for use with the empty test.
|
// Creates an empty list for use with the empty test.
|
||||||
function get_empty_list() {
|
function get_empty_list() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "is empty" block.
|
// Tests the "is empty" block.
|
||||||
function test_lists_empty() {
|
function test_lists_empty() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(empty((array(0))), false, 'not empty');
|
assertEquals(empty((array(0))), false, 'not empty');
|
||||||
assertEquals(empty((array())), true, 'empty');
|
assertEquals(empty((array())), true, 'empty');
|
||||||
assertEquals(empty((get_empty_list())), true, 'empty complex');
|
assertEquals(empty((get_empty_list())), true, 'empty complex');
|
||||||
@@ -958,7 +941,7 @@ function test_lists_empty() {
|
|||||||
|
|
||||||
// Tests the "length" block.
|
// Tests the "length" block.
|
||||||
function test_lists_length() {
|
function test_lists_length() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(length(array()), 0, 'zero length');
|
assertEquals(length(array()), 0, 'zero length');
|
||||||
assertEquals(length(array('cat')), 1, 'one length');
|
assertEquals(length(array('cat')), 1, 'one length');
|
||||||
assertEquals(length(array('cat', true, array())), 3, 'three length');
|
assertEquals(length(array('cat', true, array())), 3, 'three length');
|
||||||
@@ -975,7 +958,7 @@ function lastIndexOf($haystack, $needle) {
|
|||||||
|
|
||||||
// Tests the "find" block with a variable.
|
// Tests the "find" block with a variable.
|
||||||
function test_find_lists_simple() {
|
function test_find_lists_simple() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Alice', 'Eve', 'Bob', 'Eve');
|
$list2 = array('Alice', 'Eve', 'Bob', 'Eve');
|
||||||
assertEquals(indexOf($list2, 'Eve'), 2, 'find first simple');
|
assertEquals(indexOf($list2, 'Eve'), 2, 'find first simple');
|
||||||
assertEquals(lastIndexOf($list2, 'Eve'), 4, 'find last simple');
|
assertEquals(lastIndexOf($list2, 'Eve'), 4, 'find last simple');
|
||||||
@@ -984,14 +967,14 @@ function test_find_lists_simple() {
|
|||||||
|
|
||||||
// Creates a list for use with the find test.
|
// Creates a list for use with the find test.
|
||||||
function get_names() {
|
function get_names() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls += 1;
|
$number_of_calls += 1;
|
||||||
return array('Alice', 'Eve', 'Bob', 'Eve');
|
return array('Alice', 'Eve', 'Bob', 'Eve');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "find" block with a function call.
|
// Tests the "find" block with a function call.
|
||||||
function test_find_lists_complex() {
|
function test_find_lists_complex() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls = 0;
|
$number_of_calls = 0;
|
||||||
assertEquals(indexOf(get_names(), 'Eve'), 2, 'find first complex');
|
assertEquals(indexOf(get_names(), 'Eve'), 2, 'find first complex');
|
||||||
check_number_of_calls('find first complex');
|
check_number_of_calls('find first complex');
|
||||||
@@ -1018,7 +1001,7 @@ function lists_get_random_item($list) {
|
|||||||
|
|
||||||
// Tests the "get" block with a variable.
|
// Tests the "get" block with a variable.
|
||||||
function test_get_lists_simple() {
|
function test_get_lists_simple() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Kirk', 'Spock', 'McCoy');
|
$list2 = array('Kirk', 'Spock', 'McCoy');
|
||||||
assertEquals($list2[0], 'Kirk', 'get first simple');
|
assertEquals($list2[0], 'Kirk', 'get first simple');
|
||||||
assertEquals(end($list2), 'McCoy', 'get last simple');
|
assertEquals(end($list2), 'McCoy', 'get last simple');
|
||||||
@@ -1032,7 +1015,7 @@ function test_get_lists_simple() {
|
|||||||
|
|
||||||
// Tests the "get" block with create list call.
|
// Tests the "get" block with create list call.
|
||||||
function test_get_lists_create_list() {
|
function test_get_lists_create_list() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(array('Kirk', 'Spock', 'McCoy')[0], 'Kirk', 'get first create list');
|
assertEquals(array('Kirk', 'Spock', 'McCoy')[0], 'Kirk', 'get first create list');
|
||||||
assertEquals(end(array('Kirk', 'Spock', 'McCoy')), 'McCoy', 'get last simple');
|
assertEquals(end(array('Kirk', 'Spock', 'McCoy')), 'McCoy', 'get last simple');
|
||||||
assertEquals(indexOf(array('Kirk', 'Spock', 'McCoy'), lists_get_random_item(array('Kirk', 'Spock', 'McCoy'))) > 0, true, 'get random simple');
|
assertEquals(indexOf(array('Kirk', 'Spock', 'McCoy'), lists_get_random_item(array('Kirk', 'Spock', 'McCoy'))) > 0, true, 'get random simple');
|
||||||
@@ -1045,14 +1028,14 @@ function test_get_lists_create_list() {
|
|||||||
|
|
||||||
// Creates a list for use with the get test.
|
// Creates a list for use with the get test.
|
||||||
function get_star_wars() {
|
function get_star_wars() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls += 1;
|
$number_of_calls += 1;
|
||||||
return array('Kirk', 'Spock', 'McCoy');
|
return array('Kirk', 'Spock', 'McCoy');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the "get" block with a function call.
|
// Tests the "get" block with a function call.
|
||||||
function test_get_lists_complex() {
|
function test_get_lists_complex() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Kirk', 'Spock', 'McCoy');
|
$list2 = array('Kirk', 'Spock', 'McCoy');
|
||||||
$number_of_calls = 0;
|
$number_of_calls = 0;
|
||||||
assertEquals(get_star_wars()[0], 'Kirk', 'get first complex');
|
assertEquals(get_star_wars()[0], 'Kirk', 'get first complex');
|
||||||
@@ -1095,7 +1078,7 @@ function lists_get_remove_random_item(&$list) {
|
|||||||
|
|
||||||
// Tests the "get and remove" block.
|
// Tests the "get and remove" block.
|
||||||
function test_getRemove() {
|
function test_getRemove() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Kirk', 'Spock', 'McCoy');
|
$list2 = array('Kirk', 'Spock', 'McCoy');
|
||||||
assertEquals(array_shift($list2), 'Kirk', 'getremove first');
|
assertEquals(array_shift($list2), 'Kirk', 'getremove first');
|
||||||
assertEquals($list2, array('Spock', 'McCoy'), 'getremove first list');
|
assertEquals($list2, array('Spock', 'McCoy'), 'getremove first list');
|
||||||
@@ -1135,7 +1118,7 @@ function lists_remove_random_item(&$list) {
|
|||||||
|
|
||||||
// Tests the "remove" block.
|
// Tests the "remove" block.
|
||||||
function test_remove() {
|
function test_remove() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Kirk', 'Spock', 'McCoy');
|
$list2 = array('Kirk', 'Spock', 'McCoy');
|
||||||
array_shift($list2);
|
array_shift($list2);
|
||||||
assertEquals($list2, array('Spock', 'McCoy'), 'remove first list');
|
assertEquals($list2, array('Spock', 'McCoy'), 'remove first list');
|
||||||
@@ -1180,7 +1163,7 @@ function lists_set_from_end(&$list, $at, $value) {
|
|||||||
|
|
||||||
// Tests the "set" block.
|
// Tests the "set" block.
|
||||||
function test_set() {
|
function test_set() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Picard', 'Riker', 'Crusher');
|
$list2 = array('Picard', 'Riker', 'Crusher');
|
||||||
$list2[0] = 'Jean-Luc';
|
$list2[0] = 'Jean-Luc';
|
||||||
assertEquals($list2, array('Jean-Luc', 'Riker', 'Crusher'), 'set first list');
|
assertEquals($list2, array('Jean-Luc', 'Riker', 'Crusher'), 'set first list');
|
||||||
@@ -1224,7 +1207,7 @@ function lists_insert_from_end(&$list, $at, $value) {
|
|||||||
|
|
||||||
// Tests the "insert" block.
|
// Tests the "insert" block.
|
||||||
function test_insert() {
|
function test_insert() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Picard', 'Riker', 'Crusher');
|
$list2 = array('Picard', 'Riker', 'Crusher');
|
||||||
array_unshift($list2, 'Data');
|
array_unshift($list2, 'Data');
|
||||||
assertEquals($list2, array('Data', 'Picard', 'Riker', 'Crusher'), 'insert first list');
|
assertEquals($list2, array('Data', 'Picard', 'Riker', 'Crusher'), 'insert first list');
|
||||||
@@ -1264,7 +1247,7 @@ function test_insert() {
|
|||||||
|
|
||||||
// Tests the "get sub-list" block with a variable.
|
// Tests the "get sub-list" block with a variable.
|
||||||
function test_sublist_simple() {
|
function test_sublist_simple() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour');
|
$list2 = array('Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour');
|
||||||
assertEquals(array_slice($list2, 1, 2 - 1 + 1), array('Challenger', 'Discovery'), 'sublist # simple');
|
assertEquals(array_slice($list2, 1, 2 - 1 + 1), array('Challenger', 'Discovery'), 'sublist # simple');
|
||||||
assertEquals(array_slice($list2, ((true ? 2 : null) - 1), ((true ? 3 : null) - 1) - ((true ? 2 : null) - 1) + 1), array('Challenger', 'Discovery'), 'sublist # simple order');
|
assertEquals(array_slice($list2, ((true ? 2 : null) - 1), ((true ? 3 : null) - 1) - ((true ? 2 : null) - 1) + 1), array('Challenger', 'Discovery'), 'sublist # simple order');
|
||||||
@@ -1290,7 +1273,7 @@ function test_sublist_simple() {
|
|||||||
|
|
||||||
// Creates a list for use with the sublist test.
|
// Creates a list for use with the sublist test.
|
||||||
function get_space_shuttles() {
|
function get_space_shuttles() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls += 1;
|
$number_of_calls += 1;
|
||||||
return array('Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour');
|
return array('Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour');
|
||||||
}
|
}
|
||||||
@@ -1318,7 +1301,7 @@ function lists_get_sublist($list, $where1, $at1, $where2, $at2) {
|
|||||||
|
|
||||||
// Tests the "get sub-list" block with a function call.
|
// Tests the "get sub-list" block with a function call.
|
||||||
function test_sublist_complex() {
|
function test_sublist_complex() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$number_of_calls = 0;
|
$number_of_calls = 0;
|
||||||
assertEquals(array_slice(get_space_shuttles(), 1, 2 - 1 + 1), array('Challenger', 'Discovery'), 'sublist # start complex');
|
assertEquals(array_slice(get_space_shuttles(), 1, 2 - 1 + 1), array('Challenger', 'Discovery'), 'sublist # start complex');
|
||||||
check_number_of_calls('sublist # start complex');
|
check_number_of_calls('sublist # start complex');
|
||||||
@@ -1367,7 +1350,7 @@ function test_sublist_complex() {
|
|||||||
|
|
||||||
// Tests the "join" block.
|
// Tests the "join" block.
|
||||||
function test_join() {
|
function test_join() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Vulcan', 'Klingon', 'Borg');
|
$list2 = array('Vulcan', 'Klingon', 'Borg');
|
||||||
assertEquals(implode(',', $list2), 'Vulcan,Klingon,Borg', 'join');
|
assertEquals(implode(',', $list2), 'Vulcan,Klingon,Borg', 'join');
|
||||||
assertEquals(implode(',', true ? $list2 : null), 'Vulcan,Klingon,Borg', 'join order');
|
assertEquals(implode(',', true ? $list2 : null), 'Vulcan,Klingon,Borg', 'join order');
|
||||||
@@ -1375,7 +1358,7 @@ function test_join() {
|
|||||||
|
|
||||||
// Tests the "split" block.
|
// Tests the "split" block.
|
||||||
function test_split() {
|
function test_split() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$text = 'Vulcan,Klingon,Borg';
|
$text = 'Vulcan,Klingon,Borg';
|
||||||
assertEquals(explode(',', $text), array('Vulcan', 'Klingon', 'Borg'), 'split');
|
assertEquals(explode(',', $text), array('Vulcan', 'Klingon', 'Borg'), 'split');
|
||||||
assertEquals(explode(',', true ? $text : null), array('Vulcan', 'Klingon', 'Borg'), 'split order');
|
assertEquals(explode(',', true ? $text : null), array('Vulcan', 'Klingon', 'Borg'), 'split order');
|
||||||
@@ -1398,7 +1381,7 @@ function lists_sort($list, $type, $direction) {
|
|||||||
|
|
||||||
// Tests the "alphabetic sort" block.
|
// Tests the "alphabetic sort" block.
|
||||||
function test_sort_alphabetic() {
|
function test_sort_alphabetic() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Vulcan', 'klingon', 'Borg');
|
$list2 = array('Vulcan', 'klingon', 'Borg');
|
||||||
assertEquals(lists_sort($list2, "TEXT", 1), array('Borg', 'Vulcan', 'klingon'), 'sort alphabetic ascending');
|
assertEquals(lists_sort($list2, "TEXT", 1), array('Borg', 'Vulcan', 'klingon'), 'sort alphabetic ascending');
|
||||||
assertEquals(lists_sort(true ? $list2 : null, "TEXT", 1), array('Borg', 'Vulcan', 'klingon'), 'sort alphabetic ascending order');
|
assertEquals(lists_sort(true ? $list2 : null, "TEXT", 1), array('Borg', 'Vulcan', 'klingon'), 'sort alphabetic ascending order');
|
||||||
@@ -1406,7 +1389,7 @@ function test_sort_alphabetic() {
|
|||||||
|
|
||||||
// Tests the "alphabetic sort ignore case" block.
|
// Tests the "alphabetic sort ignore case" block.
|
||||||
function test_sort_ignoreCase() {
|
function test_sort_ignoreCase() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array('Vulcan', 'klingon', 'Borg');
|
$list2 = array('Vulcan', 'klingon', 'Borg');
|
||||||
assertEquals(lists_sort($list2, "IGNORE_CASE", 1), array('Borg', 'klingon', 'Vulcan'), 'sort ignore case ascending');
|
assertEquals(lists_sort($list2, "IGNORE_CASE", 1), array('Borg', 'klingon', 'Vulcan'), 'sort ignore case ascending');
|
||||||
assertEquals(lists_sort(true ? $list2 : null, "IGNORE_CASE", 1), array('Borg', 'klingon', 'Vulcan'), 'sort ignore case ascending order');
|
assertEquals(lists_sort(true ? $list2 : null, "IGNORE_CASE", 1), array('Borg', 'klingon', 'Vulcan'), 'sort ignore case ascending order');
|
||||||
@@ -1414,7 +1397,7 @@ function test_sort_ignoreCase() {
|
|||||||
|
|
||||||
// Tests the "numeric sort" block.
|
// Tests the "numeric sort" block.
|
||||||
function test_sort_numeric() {
|
function test_sort_numeric() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array(8, 18, -1);
|
$list2 = array(8, 18, -1);
|
||||||
assertEquals(lists_sort($list2, "NUMERIC", -1), array(18, 8, -1), 'sort numeric descending');
|
assertEquals(lists_sort($list2, "NUMERIC", -1), array(18, 8, -1), 'sort numeric descending');
|
||||||
assertEquals(lists_sort(true ? $list2 : null, "NUMERIC", -1), array(18, 8, -1), 'sort numeric descending order');
|
assertEquals(lists_sort(true ? $list2 : null, "NUMERIC", -1), array(18, 8, -1), 'sort numeric descending order');
|
||||||
@@ -1422,7 +1405,7 @@ function test_sort_numeric() {
|
|||||||
|
|
||||||
// Tests the "list reverse" block.
|
// Tests the "list reverse" block.
|
||||||
function test_lists_reverse() {
|
function test_lists_reverse() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$list2 = array(8, 18, -1, 64);
|
$list2 = array(8, 18, -1, 64);
|
||||||
assertEquals(array_reverse($list2), array(64, -1, 18, 8), 'reverse a copy');
|
assertEquals(array_reverse($list2), array(64, -1, 18, 8), 'reverse a copy');
|
||||||
assertEquals($list2, array(8, 18, -1, 64), 'reverse a copy original');
|
assertEquals($list2, array(8, 18, -1, 64), 'reverse a copy original');
|
||||||
@@ -1430,73 +1413,9 @@ function test_lists_reverse() {
|
|||||||
assertEquals(array_reverse($list2), array(), 'empty list');
|
assertEquals(array_reverse($list2), array(), 'empty list');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe this function...
|
|
||||||
function test_colour_picker() {
|
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
|
||||||
assertEquals('#ff6600', '#ff6600', 'static colour');
|
|
||||||
}
|
|
||||||
|
|
||||||
function colour_rgb($r, $g, $b) {
|
|
||||||
$r = round(max(min($r, 100), 0) * 2.55);
|
|
||||||
$g = round(max(min($g, 100), 0) * 2.55);
|
|
||||||
$b = round(max(min($b, 100), 0) * 2.55);
|
|
||||||
$hex = '#';
|
|
||||||
$hex .= str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
|
|
||||||
$hex .= str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
|
|
||||||
$hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
|
|
||||||
return $hex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe this function...
|
|
||||||
function test_rgb() {
|
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
|
||||||
assertEquals(colour_rgb(100, 40, 0), '#ff6600', 'from rgb');
|
|
||||||
}
|
|
||||||
|
|
||||||
function colour_random() {
|
|
||||||
return '#' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe this function...
|
|
||||||
function test_colour_random() {
|
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
|
||||||
for ($count4 = 0; $count4 < 100; $count4++) {
|
|
||||||
$item = colour_random();
|
|
||||||
assertEquals(length($item), 7, 'length of random colour string: ' . $item);
|
|
||||||
assertEquals(substr($item, 0, 1), '#', 'format of random colour string: ' . $item);
|
|
||||||
for ($i = 1; $i <= 6; $i++) {
|
|
||||||
assertEquals(0 != text_indexOf('abcdefABDEF0123456789', substr($item, (($i + 1) - 1), 1)), true, implode('', array('contents of random colour string: ',$item,' at index: ',$i + 1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function colour_blend($c1, $c2, $ratio) {
|
|
||||||
$ratio = max(min($ratio, 1), 0);
|
|
||||||
$r1 = hexdec(substr($c1, 1, 2));
|
|
||||||
$g1 = hexdec(substr($c1, 3, 2));
|
|
||||||
$b1 = hexdec(substr($c1, 5, 2));
|
|
||||||
$r2 = hexdec(substr($c2, 1, 2));
|
|
||||||
$g2 = hexdec(substr($c2, 3, 2));
|
|
||||||
$b2 = hexdec(substr($c2, 5, 2));
|
|
||||||
$r = round($r1 * (1 - $ratio) + $r2 * $ratio);
|
|
||||||
$g = round($g1 * (1 - $ratio) + $g2 * $ratio);
|
|
||||||
$b = round($b1 * (1 - $ratio) + $b2 * $ratio);
|
|
||||||
$hex = '#';
|
|
||||||
$hex .= str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
|
|
||||||
$hex .= str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
|
|
||||||
$hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
|
|
||||||
return $hex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe this function...
|
|
||||||
function test_blend() {
|
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
|
||||||
assertEquals(colour_blend('#ff0000', colour_rgb(100, 40, 0), 0.4), '#ff2900', 'blend');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_procedure() {
|
function test_procedure() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
procedure_1(8, 2);
|
procedure_1(8, 2);
|
||||||
assertEquals($proc_z, 4, 'procedure with global');
|
assertEquals($proc_z, 4, 'procedure with global');
|
||||||
$proc_w = false;
|
$proc_w = false;
|
||||||
@@ -1509,13 +1428,13 @@ function test_procedure() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function procedure_1($proc_x, $proc_y) {
|
function procedure_1($proc_x, $proc_y) {
|
||||||
global $test_name, $naked, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$proc_z = $proc_x / $proc_y;
|
$proc_z = $proc_x / $proc_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function procedure_2($proc_x) {
|
function procedure_2($proc_x) {
|
||||||
global $test_name, $naked, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
if ($proc_x) {
|
if ($proc_x) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1524,7 +1443,7 @@ function procedure_2($proc_x) {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function test_function() {
|
function test_function() {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
assertEquals(function_1(2, 3), -1, 'function with arguments');
|
assertEquals(function_1(2, 3), -1, 'function with arguments');
|
||||||
assertEquals($func_z, 'side effect', 'function with side effect');
|
assertEquals($func_z, 'side effect', 'function with side effect');
|
||||||
$func_a = 'unchanged';
|
$func_a = 'unchanged';
|
||||||
@@ -1537,21 +1456,21 @@ function test_function() {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function function_1($func_x, $func_y) {
|
function function_1($func_x, $func_y) {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_a, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$func_z = 'side effect';
|
$func_z = 'side effect';
|
||||||
return $func_x - $func_y;
|
return $func_x - $func_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function function_2($func_a) {
|
function function_2($func_a) {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
$func_a += 1;
|
$func_a += 1;
|
||||||
return $func_a . $func_c;
|
return $func_a . $func_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function function_3($func_a) {
|
function function_3($func_a) {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $n, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
if ($func_a) {
|
if ($func_a) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1560,7 +1479,7 @@ function function_3($func_a) {
|
|||||||
|
|
||||||
// Describe this function...
|
// Describe this function...
|
||||||
function recurse($n) {
|
function recurse($n) {
|
||||||
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $i, $loglist, $changing_list, $list_copy, $unittestResults;
|
global $test_name, $naked, $proc_x, $proc_y, $func_x, $func_y, $func_a, $ok, $log, $count, $varToChange, $rand, $item, $text, $number_of_calls, $list2, $proc_z, $func_z, $x, $proc_w, $func_c, $if2, $loglist, $changing_list, $list_copy, $unittestResults;
|
||||||
if ($n > 0) {
|
if ($n > 0) {
|
||||||
$text = implode('', array(recurse($n - 1),$n,recurse($n - 1)));
|
$text = implode('', array(recurse($n - 1),$n,recurse($n - 1)));
|
||||||
} else {
|
} else {
|
||||||
@@ -1643,7 +1562,6 @@ test_trim();
|
|||||||
test_count_text();
|
test_count_text();
|
||||||
test_text_reverse();
|
test_text_reverse();
|
||||||
test_replace();
|
test_replace();
|
||||||
test_multiline();
|
|
||||||
print(unittest_report());
|
print(unittest_report());
|
||||||
$unittestResults = null;
|
$unittestResults = null;
|
||||||
|
|
||||||
@@ -1672,15 +1590,6 @@ test_lists_reverse();
|
|||||||
print(unittest_report());
|
print(unittest_report());
|
||||||
$unittestResults = null;
|
$unittestResults = null;
|
||||||
|
|
||||||
$unittestResults = array();
|
|
||||||
print("\n====================\n\nRunning suite: Colour\n");
|
|
||||||
test_colour_picker();
|
|
||||||
test_blend();
|
|
||||||
test_rgb();
|
|
||||||
test_colour_random();
|
|
||||||
print(unittest_report());
|
|
||||||
$unittestResults = null;
|
|
||||||
|
|
||||||
$unittestResults = array();
|
$unittestResults = array();
|
||||||
print("\n====================\n\nRunning suite: Variables\n");
|
print("\n====================\n\nRunning suite: Variables\n");
|
||||||
$item = 123;
|
$item = 123;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ x = None
|
|||||||
proc_w = None
|
proc_w = None
|
||||||
func_c = None
|
func_c = None
|
||||||
if2 = None
|
if2 = None
|
||||||
i = None
|
|
||||||
loglist = None
|
loglist = None
|
||||||
changing_list = None
|
changing_list = None
|
||||||
list_copy = None
|
list_copy = None
|
||||||
@@ -73,7 +72,7 @@ def fail(message):
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_if():
|
def test_if():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
if False:
|
if False:
|
||||||
fail('if false')
|
fail('if false')
|
||||||
ok = False
|
ok = False
|
||||||
@@ -105,7 +104,7 @@ def test_if():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_ifelse():
|
def test_ifelse():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
ok = False
|
ok = False
|
||||||
if True:
|
if True:
|
||||||
ok = True
|
ok = True
|
||||||
@@ -121,7 +120,7 @@ def test_ifelse():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_equalities():
|
def test_equalities():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(2 == 2, True, 'Equal yes')
|
assertEquals(2 == 2, True, 'Equal yes')
|
||||||
assertEquals(3 == 4, False, 'Equal no')
|
assertEquals(3 == 4, False, 'Equal no')
|
||||||
assertEquals(5 != 6, True, 'Not equal yes')
|
assertEquals(5 != 6, True, 'Not equal yes')
|
||||||
@@ -137,7 +136,7 @@ def test_equalities():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_and():
|
def test_and():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(True and True, True, 'And true/true')
|
assertEquals(True and True, True, 'And true/true')
|
||||||
assertEquals(False and True, False, 'And false/true')
|
assertEquals(False and True, False, 'And false/true')
|
||||||
assertEquals(True and False, False, 'And true/false')
|
assertEquals(True and False, False, 'And true/false')
|
||||||
@@ -145,7 +144,7 @@ def test_and():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_or():
|
def test_or():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(True or True, True, 'Or true/true')
|
assertEquals(True or True, True, 'Or true/true')
|
||||||
assertEquals(False or True, True, 'Or false/true')
|
assertEquals(False or True, True, 'Or false/true')
|
||||||
assertEquals(True or False, True, 'Or true/false')
|
assertEquals(True or False, True, 'Or true/false')
|
||||||
@@ -153,13 +152,13 @@ def test_or():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_ternary():
|
def test_ternary():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(42 if True else 99, 42, 'if true')
|
assertEquals(42 if True else 99, 42, 'if true')
|
||||||
assertEquals(42 if False else 99, 99, 'if true')
|
assertEquals(42 if False else 99, 99, 'if true')
|
||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_foreach():
|
def test_foreach():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
log = ''
|
log = ''
|
||||||
for x in ['a', 'b', 'c']:
|
for x in ['a', 'b', 'c']:
|
||||||
log = str(log) + str(x)
|
log = str(log) + str(x)
|
||||||
@@ -167,7 +166,7 @@ def test_foreach():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_repeat():
|
def test_repeat():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
count = 0
|
count = 0
|
||||||
for count2 in range(10):
|
for count2 in range(10):
|
||||||
count = (count if isinstance(count, Number) else 0) + 1
|
count = (count if isinstance(count, Number) else 0) + 1
|
||||||
@@ -175,7 +174,7 @@ def test_repeat():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_while():
|
def test_while():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
while False:
|
while False:
|
||||||
fail('while 0')
|
fail('while 0')
|
||||||
while not True:
|
while not True:
|
||||||
@@ -191,7 +190,7 @@ def test_while():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_repeat_ext():
|
def test_repeat_ext():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
count = 0
|
count = 0
|
||||||
for count3 in range(10):
|
for count3 in range(10):
|
||||||
count = (count if isinstance(count, Number) else 0) + 1
|
count = (count if isinstance(count, Number) else 0) + 1
|
||||||
@@ -209,7 +208,7 @@ def downRange(start, stop, step):
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_count_by():
|
def test_count_by():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
log = ''
|
log = ''
|
||||||
for x in range(1, 9, 2):
|
for x in range(1, 9, 2):
|
||||||
log = str(log) + str(x)
|
log = str(log) + str(x)
|
||||||
@@ -245,7 +244,7 @@ def test_count_by():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_count_loops():
|
def test_count_loops():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
log = ''
|
log = ''
|
||||||
for x in range(1, 9):
|
for x in range(1, 9):
|
||||||
log = str(log) + str(x)
|
log = str(log) + str(x)
|
||||||
@@ -269,7 +268,7 @@ def test_count_loops():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_continue():
|
def test_continue():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
log = ''
|
log = ''
|
||||||
count = 0
|
count = 0
|
||||||
while count != 8:
|
while count != 8:
|
||||||
@@ -301,7 +300,7 @@ def test_continue():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_break():
|
def test_break():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
count = 1
|
count = 1
|
||||||
while count != 10:
|
while count != 10:
|
||||||
if count == 5:
|
if count == 5:
|
||||||
@@ -329,7 +328,7 @@ def test_break():
|
|||||||
|
|
||||||
# Tests the "single" block.
|
# Tests the "single" block.
|
||||||
def test_single():
|
def test_single():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(math.sqrt(25), 5, 'sqrt')
|
assertEquals(math.sqrt(25), 5, 'sqrt')
|
||||||
assertEquals(math.fabs(-25), 25, 'abs')
|
assertEquals(math.fabs(-25), 25, 'abs')
|
||||||
assertEquals(-(-25), 25, 'negate')
|
assertEquals(-(-25), 25, 'negate')
|
||||||
@@ -341,7 +340,7 @@ def test_single():
|
|||||||
# Tests the "arithmetic" block for all operations and checks
|
# Tests the "arithmetic" block for all operations and checks
|
||||||
# parenthesis are properly generated for different orders.
|
# parenthesis are properly generated for different orders.
|
||||||
def test_arithmetic():
|
def test_arithmetic():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(1 + 2, 3, 'add')
|
assertEquals(1 + 2, 3, 'add')
|
||||||
assertEquals(1 - 2, -1, 'subtract')
|
assertEquals(1 - 2, -1, 'subtract')
|
||||||
assertEquals(1 - (0 + 2), -1, 'subtract order with add')
|
assertEquals(1 - (0 + 2), -1, 'subtract order with add')
|
||||||
@@ -355,7 +354,7 @@ def test_arithmetic():
|
|||||||
|
|
||||||
# Tests the "trig" block.
|
# Tests the "trig" block.
|
||||||
def test_trig():
|
def test_trig():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(math.sin(90 / 180.0 * math.pi), 1, 'sin')
|
assertEquals(math.sin(90 / 180.0 * math.pi), 1, 'sin')
|
||||||
assertEquals(math.cos(180 / 180.0 * math.pi), -1, 'cos')
|
assertEquals(math.cos(180 / 180.0 * math.pi), -1, 'cos')
|
||||||
assertEquals(math.tan(0 / 180.0 * math.pi), 0, 'tan')
|
assertEquals(math.tan(0 / 180.0 * math.pi), 0, 'tan')
|
||||||
@@ -365,7 +364,7 @@ def test_trig():
|
|||||||
|
|
||||||
# Tests the "constant" blocks.
|
# Tests the "constant" blocks.
|
||||||
def test_constant():
|
def test_constant():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(math.floor(math.pi * 1000), 3141, 'const pi')
|
assertEquals(math.floor(math.pi * 1000), 3141, 'const pi')
|
||||||
assertEquals(math.floor(math.e * 1000), 2718, 'const e')
|
assertEquals(math.floor(math.e * 1000), 2718, 'const e')
|
||||||
assertEquals(math.floor(((1 + math.sqrt(5)) / 2) * 1000), 1618, 'const golden')
|
assertEquals(math.floor(((1 + math.sqrt(5)) / 2) * 1000), 1618, 'const golden')
|
||||||
@@ -394,7 +393,7 @@ def math_isPrime(n):
|
|||||||
|
|
||||||
# Tests the "number property" blocks.
|
# Tests the "number property" blocks.
|
||||||
def test_number_properties():
|
def test_number_properties():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(42 % 2 == 0, True, 'even')
|
assertEquals(42 % 2 == 0, True, 'even')
|
||||||
assertEquals(42.1 % 2 == 1, False, 'odd')
|
assertEquals(42.1 % 2 == 1, False, 'odd')
|
||||||
assertEquals(math_isPrime(5), True, 'prime 5')
|
assertEquals(math_isPrime(5), True, 'prime 5')
|
||||||
@@ -411,14 +410,14 @@ def test_number_properties():
|
|||||||
|
|
||||||
# Tests the "round" block.
|
# Tests the "round" block.
|
||||||
def test_round():
|
def test_round():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(round(42.42), 42, 'round')
|
assertEquals(round(42.42), 42, 'round')
|
||||||
assertEquals(math.ceil(-42.42), -42, 'round up')
|
assertEquals(math.ceil(-42.42), -42, 'round up')
|
||||||
assertEquals(math.floor(42.42), 42, 'round down')
|
assertEquals(math.floor(42.42), 42, 'round down')
|
||||||
|
|
||||||
# Tests the "change" block.
|
# Tests the "change" block.
|
||||||
def test_change():
|
def test_change():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
varToChange = 100
|
varToChange = 100
|
||||||
varToChange = (varToChange if isinstance(varToChange, Number) else 0) + 42
|
varToChange = (varToChange if isinstance(varToChange, Number) else 0) + 42
|
||||||
assertEquals(varToChange, 142, 'change')
|
assertEquals(varToChange, 142, 'change')
|
||||||
@@ -470,7 +469,7 @@ def first_index(my_list, elem):
|
|||||||
|
|
||||||
# Tests the "list operation" blocks.
|
# Tests the "list operation" blocks.
|
||||||
def test_operations_on_list():
|
def test_operations_on_list():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(sum([3, 4, 5]), 12, 'sum')
|
assertEquals(sum([3, 4, 5]), 12, 'sum')
|
||||||
assertEquals(min([3, 4, 5]), 3, 'min')
|
assertEquals(min([3, 4, 5]), 3, 'min')
|
||||||
assertEquals(max([3, 4, 5]), 5, 'max')
|
assertEquals(max([3, 4, 5]), 5, 'max')
|
||||||
@@ -483,43 +482,43 @@ def test_operations_on_list():
|
|||||||
|
|
||||||
# Tests the "mod" block.
|
# Tests the "mod" block.
|
||||||
def test_mod():
|
def test_mod():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(42 % 5, 2, 'mod')
|
assertEquals(42 % 5, 2, 'mod')
|
||||||
|
|
||||||
# Tests the "constrain" block.
|
# Tests the "constrain" block.
|
||||||
def test_constraint():
|
def test_constraint():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(min(max(100, 0), 42), 42, 'constraint')
|
assertEquals(min(max(100, 0), 42), 42, 'constraint')
|
||||||
|
|
||||||
# Tests the "random integer" block.
|
# Tests the "random integer" block.
|
||||||
def test_random_integer():
|
def test_random_integer():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
rand = random.randint(5, 10)
|
rand = random.randint(5, 10)
|
||||||
assertEquals(rand >= 5 and rand <= 10, True, 'randRange')
|
assertEquals(rand >= 5 and rand <= 10, True, 'randRange')
|
||||||
assertEquals(rand % 1 == 0, True, 'randInteger')
|
assertEquals(rand % 1 == 0, True, 'randInteger')
|
||||||
|
|
||||||
# Tests the "random fraction" block.
|
# Tests the "random fraction" block.
|
||||||
def test_random_fraction():
|
def test_random_fraction():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
rand = random.random()
|
rand = random.random()
|
||||||
assertEquals(rand >= 0 and rand <= 1, True, 'randFloat')
|
assertEquals(rand >= 0 and rand <= 1, True, 'randFloat')
|
||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_atan2():
|
def test_atan2():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(math.atan2(5, -5) / math.pi * 180, 135, 'atan2')
|
assertEquals(math.atan2(5, -5) / math.pi * 180, 135, 'atan2')
|
||||||
assertEquals(math.atan2(-12, 0) / math.pi * 180, -90, 'atan2')
|
assertEquals(math.atan2(-12, 0) / math.pi * 180, -90, 'atan2')
|
||||||
|
|
||||||
# Checks that the number of calls is one in order
|
# Checks that the number of calls is one in order
|
||||||
# to confirm that a function was only called once.
|
# to confirm that a function was only called once.
|
||||||
def check_number_of_calls(test_name):
|
def check_number_of_calls(test_name):
|
||||||
global naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
test_name = str(test_name) + 'number of calls'
|
test_name = str(test_name) + 'number of calls'
|
||||||
assertEquals(number_of_calls, 1, test_name)
|
assertEquals(number_of_calls, 1, test_name)
|
||||||
|
|
||||||
# Tests the "create text with" block with varying number of inputs.
|
# Tests the "create text with" block with varying number of inputs.
|
||||||
def test_create_text():
|
def test_create_text():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals('', '', 'no text')
|
assertEquals('', '', 'no text')
|
||||||
assertEquals('Hello', 'Hello', 'create single')
|
assertEquals('Hello', 'Hello', 'create single')
|
||||||
assertEquals(str(-1), '-1', 'create single number')
|
assertEquals(str(-1), '-1', 'create single number')
|
||||||
@@ -530,12 +529,12 @@ def test_create_text():
|
|||||||
|
|
||||||
# Creates an empty string for use with the empty test.
|
# Creates an empty string for use with the empty test.
|
||||||
def get_empty():
|
def get_empty():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
# Tests the "is empty" block".
|
# Tests the "is empty" block".
|
||||||
def test_empty_text():
|
def test_empty_text():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(not len('Google'), False, 'not empty')
|
assertEquals(not len('Google'), False, 'not empty')
|
||||||
assertEquals(not len(''), True, 'empty')
|
assertEquals(not len(''), True, 'empty')
|
||||||
assertEquals(not len(get_empty()), True, 'empty complex')
|
assertEquals(not len(get_empty()), True, 'empty complex')
|
||||||
@@ -543,14 +542,14 @@ def test_empty_text():
|
|||||||
|
|
||||||
# Tests the "length" block.
|
# Tests the "length" block.
|
||||||
def test_text_length():
|
def test_text_length():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(len(''), 0, 'zero length')
|
assertEquals(len(''), 0, 'zero length')
|
||||||
assertEquals(len('Google'), 6, 'non-zero length')
|
assertEquals(len('Google'), 6, 'non-zero length')
|
||||||
assertEquals(len('car' if True else None), 3, 'length order')
|
assertEquals(len('car' if True else None), 3, 'length order')
|
||||||
|
|
||||||
# Tests the "append text" block with different types of parameters.
|
# Tests the "append text" block with different types of parameters.
|
||||||
def test_append():
|
def test_append():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
item = 'Miserable'
|
item = 'Miserable'
|
||||||
item = str(item) + 'Failure'
|
item = str(item) + 'Failure'
|
||||||
assertEquals(item, 'MiserableFailure', 'append text')
|
assertEquals(item, 'MiserableFailure', 'append text')
|
||||||
@@ -563,7 +562,7 @@ def test_append():
|
|||||||
|
|
||||||
# Tests the "find" block with a variable.
|
# Tests the "find" block with a variable.
|
||||||
def test_find_text_simple():
|
def test_find_text_simple():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
text = 'Banana'
|
text = 'Banana'
|
||||||
assertEquals(text.find('an') + 1, 2, 'find first simple')
|
assertEquals(text.find('an') + 1, 2, 'find first simple')
|
||||||
assertEquals(text.rfind('an') + 1, 4, 'find last simple')
|
assertEquals(text.rfind('an') + 1, 4, 'find last simple')
|
||||||
@@ -571,13 +570,13 @@ def test_find_text_simple():
|
|||||||
|
|
||||||
# Creates a string for use with the find test.
|
# Creates a string for use with the find test.
|
||||||
def get_fruit():
|
def get_fruit():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
||||||
return 'Banana'
|
return 'Banana'
|
||||||
|
|
||||||
# Tests the "find" block with a function call.
|
# Tests the "find" block with a function call.
|
||||||
def test_find_text_complex():
|
def test_find_text_complex():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = 0
|
number_of_calls = 0
|
||||||
assertEquals(get_fruit().find('an') + 1, 2, 'find first complex')
|
assertEquals(get_fruit().find('an') + 1, 2, 'find first complex')
|
||||||
check_number_of_calls('find first complex')
|
check_number_of_calls('find first complex')
|
||||||
@@ -603,7 +602,7 @@ def text_random_letter(text):
|
|||||||
|
|
||||||
# Tests the "get letter" block with a variable.
|
# Tests the "get letter" block with a variable.
|
||||||
def test_get_text_simple():
|
def test_get_text_simple():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
text = 'Blockly'
|
text = 'Blockly'
|
||||||
assertEquals(text[0], 'B', 'get first simple')
|
assertEquals(text[0], 'B', 'get first simple')
|
||||||
assertEquals(text[-1], 'y', 'get last simple')
|
assertEquals(text[-1], 'y', 'get last simple')
|
||||||
@@ -616,13 +615,13 @@ def test_get_text_simple():
|
|||||||
|
|
||||||
# Creates a string for use with the get test.
|
# Creates a string for use with the get test.
|
||||||
def get_Blockly():
|
def get_Blockly():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
||||||
return 'Blockly'
|
return 'Blockly'
|
||||||
|
|
||||||
# Tests the "get letter" block with a function call.
|
# Tests the "get letter" block with a function call.
|
||||||
def test_get_text_complex():
|
def test_get_text_complex():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
text = 'Blockly'
|
text = 'Blockly'
|
||||||
number_of_calls = 0
|
number_of_calls = 0
|
||||||
assertEquals(get_Blockly()[0], 'B', 'get first complex')
|
assertEquals(get_Blockly()[0], 'B', 'get first complex')
|
||||||
@@ -658,13 +657,13 @@ def test_get_text_complex():
|
|||||||
|
|
||||||
# Creates a string for use with the substring test.
|
# Creates a string for use with the substring test.
|
||||||
def get_numbers():
|
def get_numbers():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
||||||
return '123456789'
|
return '123456789'
|
||||||
|
|
||||||
# Tests the "get substring" block with a variable.
|
# Tests the "get substring" block with a variable.
|
||||||
def test_substring_simple():
|
def test_substring_simple():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
text = '123456789'
|
text = '123456789'
|
||||||
assertEquals(text[1 : 3], '23', 'substring # simple')
|
assertEquals(text[1 : 3], '23', 'substring # simple')
|
||||||
assertEquals(text[int((2 if True else None) - 1) : int(3 if True else None)], '23', 'substring # simple order')
|
assertEquals(text[int((2 if True else None) - 1) : int(3 if True else None)], '23', 'substring # simple order')
|
||||||
@@ -685,7 +684,7 @@ def test_substring_simple():
|
|||||||
|
|
||||||
# Tests the "get substring" block with a function call.
|
# Tests the "get substring" block with a function call.
|
||||||
def test_substring_complex():
|
def test_substring_complex():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = 0
|
number_of_calls = 0
|
||||||
assertEquals(get_numbers()[1 : 3], '23', 'substring # complex')
|
assertEquals(get_numbers()[1 : 3], '23', 'substring # complex')
|
||||||
check_number_of_calls('substring # complex')
|
check_number_of_calls('substring # complex')
|
||||||
@@ -733,7 +732,7 @@ def test_substring_complex():
|
|||||||
|
|
||||||
# Tests the "change casing" block.
|
# Tests the "change casing" block.
|
||||||
def test_case():
|
def test_case():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
text = 'Hello World'
|
text = 'Hello World'
|
||||||
assertEquals(text.upper(), 'HELLO WORLD', 'uppercase')
|
assertEquals(text.upper(), 'HELLO WORLD', 'uppercase')
|
||||||
assertEquals((text if True else None).upper(), 'HELLO WORLD', 'uppercase order')
|
assertEquals((text if True else None).upper(), 'HELLO WORLD', 'uppercase order')
|
||||||
@@ -746,7 +745,7 @@ def test_case():
|
|||||||
|
|
||||||
# Tests the "trim" block.
|
# Tests the "trim" block.
|
||||||
def test_trim():
|
def test_trim():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
text = ' abc def '
|
text = ' abc def '
|
||||||
assertEquals(text.strip(), 'abc def', 'trim both')
|
assertEquals(text.strip(), 'abc def', 'trim both')
|
||||||
assertEquals((text if True else None).strip(), 'abc def', 'trim both order')
|
assertEquals((text if True else None).strip(), 'abc def', 'trim both order')
|
||||||
@@ -757,7 +756,7 @@ def test_trim():
|
|||||||
|
|
||||||
# Tests the "trim" block.
|
# Tests the "trim" block.
|
||||||
def test_count_text():
|
def test_count_text():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
text = 'woolloomooloo'
|
text = 'woolloomooloo'
|
||||||
assertEquals(text.count('o'), 8, 'len 1')
|
assertEquals(text.count('o'), 8, 'len 1')
|
||||||
assertEquals(text.count('oo'), 4, 'len 2')
|
assertEquals(text.count('oo'), 4, 'len 2')
|
||||||
@@ -769,7 +768,7 @@ def test_count_text():
|
|||||||
|
|
||||||
# Tests the "trim" block.
|
# Tests the "trim" block.
|
||||||
def test_text_reverse():
|
def test_text_reverse():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(''[::-1], '', 'empty string')
|
assertEquals(''[::-1], '', 'empty string')
|
||||||
assertEquals('a'[::-1], 'a', 'len 1')
|
assertEquals('a'[::-1], 'a', 'len 1')
|
||||||
assertEquals('ab'[::-1], 'ba', 'len 2')
|
assertEquals('ab'[::-1], 'ba', 'len 2')
|
||||||
@@ -777,7 +776,7 @@ def test_text_reverse():
|
|||||||
|
|
||||||
# Tests the "trim" block.
|
# Tests the "trim" block.
|
||||||
def test_replace():
|
def test_replace():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals('woolloomooloo'.replace('oo', '123'), 'w123ll123m123l123', 'replace all instances 1')
|
assertEquals('woolloomooloo'.replace('oo', '123'), 'w123ll123m123l123', 'replace all instances 1')
|
||||||
assertEquals('woolloomooloo'.replace('.oo', 'X'), 'woolloomooloo', 'literal string replacement')
|
assertEquals('woolloomooloo'.replace('.oo', 'X'), 'woolloomooloo', 'literal string replacement')
|
||||||
assertEquals('woolloomooloo'.replace('abc', 'X'), 'woolloomooloo', 'not found')
|
assertEquals('woolloomooloo'.replace('abc', 'X'), 'woolloomooloo', 'not found')
|
||||||
@@ -786,30 +785,16 @@ def test_replace():
|
|||||||
assertEquals('aaaaa'.replace('a', ''), '', 'empty replacement 3')
|
assertEquals('aaaaa'.replace('a', ''), '', 'empty replacement 3')
|
||||||
assertEquals(''.replace('a', 'chicken'), '', 'empty source')
|
assertEquals(''.replace('a', 'chicken'), '', 'empty source')
|
||||||
|
|
||||||
# Tests the "multiline" block.
|
|
||||||
def test_multiline():
|
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
|
||||||
assertEquals('', '', 'no text')
|
|
||||||
assertEquals('Google', 'Google', 'simple')
|
|
||||||
assertEquals('paragraph' + '\n' +
|
|
||||||
'with newlines' + '\n' +
|
|
||||||
'yup', 'paragraph' + '\n' +
|
|
||||||
'with newlines' + '\n' +
|
|
||||||
'yup', 'no compile error with newlines')
|
|
||||||
assertEquals(('bark bark' + '\n' +
|
|
||||||
'bark bark bark' + '\n' +
|
|
||||||
'bark bark bark bark').count('bark'), 9, 'count with newlines')
|
|
||||||
|
|
||||||
# Checks that the number of calls is one in order
|
# Checks that the number of calls is one in order
|
||||||
# to confirm that a function was only called once.
|
# to confirm that a function was only called once.
|
||||||
def check_number_of_calls2(test_name):
|
def check_number_of_calls2(test_name):
|
||||||
global naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
test_name = str(test_name) + 'number of calls'
|
test_name = str(test_name) + 'number of calls'
|
||||||
assertEquals(number_of_calls, 1, test_name)
|
assertEquals(number_of_calls, 1, test_name)
|
||||||
|
|
||||||
# Tests the "create list with" and "create empty list" blocks.
|
# Tests the "create list with" and "create empty list" blocks.
|
||||||
def test_create_lists():
|
def test_create_lists():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals([], [], 'create empty')
|
assertEquals([], [], 'create empty')
|
||||||
assertEquals([True, 'love'], [True, 'love'], 'create items')
|
assertEquals([True, 'love'], [True, 'love'], 'create items')
|
||||||
assertEquals(['Eject'] * 3, ['Eject', 'Eject', 'Eject'], 'create repeated')
|
assertEquals(['Eject'] * 3, ['Eject', 'Eject', 'Eject'], 'create repeated')
|
||||||
@@ -817,12 +802,12 @@ def test_create_lists():
|
|||||||
|
|
||||||
# Creates an empty list for use with the empty test.
|
# Creates an empty list for use with the empty test.
|
||||||
def get_empty_list():
|
def get_empty_list():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Tests the "is empty" block.
|
# Tests the "is empty" block.
|
||||||
def test_lists_empty():
|
def test_lists_empty():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(not len([0]), False, 'not empty')
|
assertEquals(not len([0]), False, 'not empty')
|
||||||
assertEquals(not len([]), True, 'empty')
|
assertEquals(not len([]), True, 'empty')
|
||||||
assertEquals(not len(get_empty_list()), True, 'empty complex')
|
assertEquals(not len(get_empty_list()), True, 'empty complex')
|
||||||
@@ -830,7 +815,7 @@ def test_lists_empty():
|
|||||||
|
|
||||||
# Tests the "length" block.
|
# Tests the "length" block.
|
||||||
def test_lists_length():
|
def test_lists_length():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(len([]), 0, 'zero length')
|
assertEquals(len([]), 0, 'zero length')
|
||||||
assertEquals(len(['cat']), 1, 'one length')
|
assertEquals(len(['cat']), 1, 'one length')
|
||||||
assertEquals(len(['cat', True, []]), 3, 'three length')
|
assertEquals(len(['cat', True, []]), 3, 'three length')
|
||||||
@@ -843,7 +828,7 @@ def last_index(my_list, elem):
|
|||||||
|
|
||||||
# Tests the "find" block with a variable.
|
# Tests the "find" block with a variable.
|
||||||
def test_find_lists_simple():
|
def test_find_lists_simple():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Alice', 'Eve', 'Bob', 'Eve']
|
list2 = ['Alice', 'Eve', 'Bob', 'Eve']
|
||||||
assertEquals(first_index(list2, 'Eve'), 2, 'find first simple')
|
assertEquals(first_index(list2, 'Eve'), 2, 'find first simple')
|
||||||
assertEquals(last_index(list2, 'Eve'), 4, 'find last simple')
|
assertEquals(last_index(list2, 'Eve'), 4, 'find last simple')
|
||||||
@@ -851,13 +836,13 @@ def test_find_lists_simple():
|
|||||||
|
|
||||||
# Creates a list for use with the find test.
|
# Creates a list for use with the find test.
|
||||||
def get_names():
|
def get_names():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
||||||
return ['Alice', 'Eve', 'Bob', 'Eve']
|
return ['Alice', 'Eve', 'Bob', 'Eve']
|
||||||
|
|
||||||
# Tests the "find" block with a function call.
|
# Tests the "find" block with a function call.
|
||||||
def test_find_lists_complex():
|
def test_find_lists_complex():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = 0
|
number_of_calls = 0
|
||||||
assertEquals(first_index(get_names(), 'Eve'), 2, 'find first complex')
|
assertEquals(first_index(get_names(), 'Eve'), 2, 'find first complex')
|
||||||
check_number_of_calls('find first complex')
|
check_number_of_calls('find first complex')
|
||||||
@@ -879,7 +864,7 @@ def test_find_lists_complex():
|
|||||||
|
|
||||||
# Tests the "get" block with a variable.
|
# Tests the "get" block with a variable.
|
||||||
def test_get_lists_simple():
|
def test_get_lists_simple():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Kirk', 'Spock', 'McCoy']
|
list2 = ['Kirk', 'Spock', 'McCoy']
|
||||||
assertEquals(list2[0], 'Kirk', 'get first simple')
|
assertEquals(list2[0], 'Kirk', 'get first simple')
|
||||||
assertEquals(list2[-1], 'McCoy', 'get last simple')
|
assertEquals(list2[-1], 'McCoy', 'get last simple')
|
||||||
@@ -892,7 +877,7 @@ def test_get_lists_simple():
|
|||||||
|
|
||||||
# Tests the "get" block with create list call.
|
# Tests the "get" block with create list call.
|
||||||
def test_get_lists_create_list():
|
def test_get_lists_create_list():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(['Kirk', 'Spock', 'McCoy'][0], 'Kirk', 'get first create list')
|
assertEquals(['Kirk', 'Spock', 'McCoy'][0], 'Kirk', 'get first create list')
|
||||||
assertEquals(['Kirk', 'Spock', 'McCoy'][-1], 'McCoy', 'get last simple')
|
assertEquals(['Kirk', 'Spock', 'McCoy'][-1], 'McCoy', 'get last simple')
|
||||||
assertEquals(first_index(['Kirk', 'Spock', 'McCoy'], random.choice(['Kirk', 'Spock', 'McCoy'])) > 0, True, 'get random simple')
|
assertEquals(first_index(['Kirk', 'Spock', 'McCoy'], random.choice(['Kirk', 'Spock', 'McCoy'])) > 0, True, 'get random simple')
|
||||||
@@ -904,13 +889,13 @@ def test_get_lists_create_list():
|
|||||||
|
|
||||||
# Creates a list for use with the get test.
|
# Creates a list for use with the get test.
|
||||||
def get_star_wars():
|
def get_star_wars():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
||||||
return ['Kirk', 'Spock', 'McCoy']
|
return ['Kirk', 'Spock', 'McCoy']
|
||||||
|
|
||||||
# Tests the "get" block with a function call.
|
# Tests the "get" block with a function call.
|
||||||
def test_get_lists_complex():
|
def test_get_lists_complex():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Kirk', 'Spock', 'McCoy']
|
list2 = ['Kirk', 'Spock', 'McCoy']
|
||||||
number_of_calls = 0
|
number_of_calls = 0
|
||||||
assertEquals(get_star_wars()[0], 'Kirk', 'get first complex')
|
assertEquals(get_star_wars()[0], 'Kirk', 'get first complex')
|
||||||
@@ -950,7 +935,7 @@ def lists_remove_random_item(myList):
|
|||||||
|
|
||||||
# Tests the "get and remove" block.
|
# Tests the "get and remove" block.
|
||||||
def test_getRemove():
|
def test_getRemove():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Kirk', 'Spock', 'McCoy']
|
list2 = ['Kirk', 'Spock', 'McCoy']
|
||||||
assertEquals(list2.pop(0), 'Kirk', 'getremove first')
|
assertEquals(list2.pop(0), 'Kirk', 'getremove first')
|
||||||
assertEquals(list2, ['Spock', 'McCoy'], 'getremove first list')
|
assertEquals(list2, ['Spock', 'McCoy'], 'getremove first list')
|
||||||
@@ -985,7 +970,7 @@ def test_getRemove():
|
|||||||
|
|
||||||
# Tests the "remove" block.
|
# Tests the "remove" block.
|
||||||
def test_remove():
|
def test_remove():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Kirk', 'Spock', 'McCoy']
|
list2 = ['Kirk', 'Spock', 'McCoy']
|
||||||
list2.pop(0)
|
list2.pop(0)
|
||||||
assertEquals(list2, ['Spock', 'McCoy'], 'remove first list')
|
assertEquals(list2, ['Spock', 'McCoy'], 'remove first list')
|
||||||
@@ -1021,7 +1006,7 @@ def test_remove():
|
|||||||
|
|
||||||
# Tests the "set" block.
|
# Tests the "set" block.
|
||||||
def test_set():
|
def test_set():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Picard', 'Riker', 'Crusher']
|
list2 = ['Picard', 'Riker', 'Crusher']
|
||||||
list2[0] = 'Jean-Luc'
|
list2[0] = 'Jean-Luc'
|
||||||
assertEquals(list2, ['Jean-Luc', 'Riker', 'Crusher'], 'set first list')
|
assertEquals(list2, ['Jean-Luc', 'Riker', 'Crusher'], 'set first list')
|
||||||
@@ -1060,7 +1045,7 @@ def test_set():
|
|||||||
|
|
||||||
# Tests the "insert" block.
|
# Tests the "insert" block.
|
||||||
def test_insert():
|
def test_insert():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Picard', 'Riker', 'Crusher']
|
list2 = ['Picard', 'Riker', 'Crusher']
|
||||||
list2.insert(0, 'Data')
|
list2.insert(0, 'Data')
|
||||||
assertEquals(list2, ['Data', 'Picard', 'Riker', 'Crusher'], 'insert first list')
|
assertEquals(list2, ['Data', 'Picard', 'Riker', 'Crusher'], 'insert first list')
|
||||||
@@ -1099,7 +1084,7 @@ def test_insert():
|
|||||||
|
|
||||||
# Tests the "get sub-list" block with a variable.
|
# Tests the "get sub-list" block with a variable.
|
||||||
def test_sublist_simple():
|
def test_sublist_simple():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']
|
list2 = ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']
|
||||||
assertEquals(list2[1 : 3], ['Challenger', 'Discovery'], 'sublist # simple')
|
assertEquals(list2[1 : 3], ['Challenger', 'Discovery'], 'sublist # simple')
|
||||||
assertEquals(list2[int((2 if True else None) - 1) : int(3 if True else None)], ['Challenger', 'Discovery'], 'sublist # simple order')
|
assertEquals(list2[int((2 if True else None) - 1) : int(3 if True else None)], ['Challenger', 'Discovery'], 'sublist # simple order')
|
||||||
@@ -1124,13 +1109,13 @@ def test_sublist_simple():
|
|||||||
|
|
||||||
# Creates a list for use with the sublist test.
|
# Creates a list for use with the sublist test.
|
||||||
def get_space_shuttles():
|
def get_space_shuttles():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1
|
||||||
return ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']
|
return ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']
|
||||||
|
|
||||||
# Tests the "get sub-list" block with a function call.
|
# Tests the "get sub-list" block with a function call.
|
||||||
def test_sublist_complex():
|
def test_sublist_complex():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
number_of_calls = 0
|
number_of_calls = 0
|
||||||
assertEquals(get_space_shuttles()[1 : 3], ['Challenger', 'Discovery'], 'sublist # start complex')
|
assertEquals(get_space_shuttles()[1 : 3], ['Challenger', 'Discovery'], 'sublist # start complex')
|
||||||
check_number_of_calls('sublist # start complex')
|
check_number_of_calls('sublist # start complex')
|
||||||
@@ -1178,14 +1163,14 @@ def test_sublist_complex():
|
|||||||
|
|
||||||
# Tests the "join" block.
|
# Tests the "join" block.
|
||||||
def test_join():
|
def test_join():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Vulcan', 'Klingon', 'Borg']
|
list2 = ['Vulcan', 'Klingon', 'Borg']
|
||||||
assertEquals(','.join(list2), 'Vulcan,Klingon,Borg', 'join')
|
assertEquals(','.join(list2), 'Vulcan,Klingon,Borg', 'join')
|
||||||
assertEquals(','.join(list2 if True else None), 'Vulcan,Klingon,Borg', 'join order')
|
assertEquals(','.join(list2 if True else None), 'Vulcan,Klingon,Borg', 'join order')
|
||||||
|
|
||||||
# Tests the "split" block.
|
# Tests the "split" block.
|
||||||
def test_split():
|
def test_split():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
text = 'Vulcan,Klingon,Borg'
|
text = 'Vulcan,Klingon,Borg'
|
||||||
assertEquals(text.split(','), ['Vulcan', 'Klingon', 'Borg'], 'split')
|
assertEquals(text.split(','), ['Vulcan', 'Klingon', 'Borg'], 'split')
|
||||||
assertEquals((text if True else None).split(','), ['Vulcan', 'Klingon', 'Borg'], 'split order')
|
assertEquals((text if True else None).split(','), ['Vulcan', 'Klingon', 'Borg'], 'split order')
|
||||||
@@ -1207,78 +1192,37 @@ def lists_sort(my_list, type, reverse):
|
|||||||
|
|
||||||
# Tests the "alphabetic sort" block.
|
# Tests the "alphabetic sort" block.
|
||||||
def test_sort_alphabetic():
|
def test_sort_alphabetic():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Vulcan', 'klingon', 'Borg']
|
list2 = ['Vulcan', 'klingon', 'Borg']
|
||||||
assertEquals(lists_sort(list2, "TEXT", False), ['Borg', 'Vulcan', 'klingon'], 'sort alphabetic ascending')
|
assertEquals(lists_sort(list2, "TEXT", False), ['Borg', 'Vulcan', 'klingon'], 'sort alphabetic ascending')
|
||||||
assertEquals(lists_sort(list2 if True else None, "TEXT", False), ['Borg', 'Vulcan', 'klingon'], 'sort alphabetic ascending order')
|
assertEquals(lists_sort(list2 if True else None, "TEXT", False), ['Borg', 'Vulcan', 'klingon'], 'sort alphabetic ascending order')
|
||||||
|
|
||||||
# Tests the "alphabetic sort ignore case" block.
|
# Tests the "alphabetic sort ignore case" block.
|
||||||
def test_sort_ignoreCase():
|
def test_sort_ignoreCase():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = ['Vulcan', 'klingon', 'Borg']
|
list2 = ['Vulcan', 'klingon', 'Borg']
|
||||||
assertEquals(lists_sort(list2, "IGNORE_CASE", False), ['Borg', 'klingon', 'Vulcan'], 'sort ignore case ascending')
|
assertEquals(lists_sort(list2, "IGNORE_CASE", False), ['Borg', 'klingon', 'Vulcan'], 'sort ignore case ascending')
|
||||||
assertEquals(lists_sort(list2 if True else None, "IGNORE_CASE", False), ['Borg', 'klingon', 'Vulcan'], 'sort ignore case ascending order')
|
assertEquals(lists_sort(list2 if True else None, "IGNORE_CASE", False), ['Borg', 'klingon', 'Vulcan'], 'sort ignore case ascending order')
|
||||||
|
|
||||||
# Tests the "numeric sort" block.
|
# Tests the "numeric sort" block.
|
||||||
def test_sort_numeric():
|
def test_sort_numeric():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = [8, 18, -1]
|
list2 = [8, 18, -1]
|
||||||
assertEquals(lists_sort(list2, "NUMERIC", True), [18, 8, -1], 'sort numeric descending')
|
assertEquals(lists_sort(list2, "NUMERIC", True), [18, 8, -1], 'sort numeric descending')
|
||||||
assertEquals(lists_sort(list2 if True else None, "NUMERIC", True), [18, 8, -1], 'sort numeric descending order')
|
assertEquals(lists_sort(list2 if True else None, "NUMERIC", True), [18, 8, -1], 'sort numeric descending order')
|
||||||
|
|
||||||
# Tests the "list reverse" block.
|
# Tests the "list reverse" block.
|
||||||
def test_lists_reverse():
|
def test_lists_reverse():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
list2 = [8, 18, -1, 64]
|
list2 = [8, 18, -1, 64]
|
||||||
assertEquals(list(reversed(list2)), [64, -1, 18, 8], 'reverse a copy')
|
assertEquals(list(reversed(list2)), [64, -1, 18, 8], 'reverse a copy')
|
||||||
assertEquals(list2, [8, 18, -1, 64], 'reverse a copy original')
|
assertEquals(list2, [8, 18, -1, 64], 'reverse a copy original')
|
||||||
list2 = []
|
list2 = []
|
||||||
assertEquals(list(reversed(list2)), [], 'empty list')
|
assertEquals(list(reversed(list2)), [], 'empty list')
|
||||||
|
|
||||||
# Describe this function...
|
|
||||||
def test_colour_picker():
|
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
|
||||||
assertEquals('#ff6600', '#ff6600', 'static colour')
|
|
||||||
|
|
||||||
def colour_rgb(r, g, b):
|
|
||||||
r = round(min(100, max(0, r)) * 2.55)
|
|
||||||
g = round(min(100, max(0, g)) * 2.55)
|
|
||||||
b = round(min(100, max(0, b)) * 2.55)
|
|
||||||
return '#%02x%02x%02x' % (r, g, b)
|
|
||||||
|
|
||||||
# Describe this function...
|
|
||||||
def test_rgb():
|
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
|
||||||
assertEquals(colour_rgb(100, 40, 0), '#ff6600', 'from rgb')
|
|
||||||
|
|
||||||
# Describe this function...
|
|
||||||
def test_colour_random():
|
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
|
||||||
for count4 in range(100):
|
|
||||||
item = '#%06x' % random.randint(0, 2**24 - 1)
|
|
||||||
assertEquals(len(item), 7, 'length of random colour string: ' + str(item))
|
|
||||||
assertEquals(item[0], '#', 'format of random colour string: ' + str(item))
|
|
||||||
for i in range(1, 7):
|
|
||||||
assertEquals(0 != 'abcdefABDEF0123456789'.find(item[int((i + 1) - 1)]) + 1, True, ''.join([str(x4) for x4 in ['contents of random colour string: ', item, ' at index: ', i + 1]]))
|
|
||||||
|
|
||||||
def colour_blend(colour1, colour2, ratio):
|
|
||||||
r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)
|
|
||||||
g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)
|
|
||||||
b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)
|
|
||||||
ratio = min(1, max(0, ratio))
|
|
||||||
r = round(r1 * (1 - ratio) + r2 * ratio)
|
|
||||||
g = round(g1 * (1 - ratio) + g2 * ratio)
|
|
||||||
b = round(b1 * (1 - ratio) + b2 * ratio)
|
|
||||||
return '#%02x%02x%02x' % (r, g, b)
|
|
||||||
|
|
||||||
# Describe this function...
|
|
||||||
def test_blend():
|
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
|
||||||
assertEquals(colour_blend('#ff0000', colour_rgb(100, 40, 0), 0.4), '#ff2900', 'blend')
|
|
||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_procedure():
|
def test_procedure():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
procedure_1(8, 2)
|
procedure_1(8, 2)
|
||||||
assertEquals(proc_z, 4, 'procedure with global')
|
assertEquals(proc_z, 4, 'procedure with global')
|
||||||
proc_w = False
|
proc_w = False
|
||||||
@@ -1290,19 +1234,19 @@ def test_procedure():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def procedure_1(proc_x, proc_y):
|
def procedure_1(proc_x, proc_y):
|
||||||
global test_name, naked, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
proc_z = proc_x / proc_y
|
proc_z = proc_x / proc_y
|
||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def procedure_2(proc_x):
|
def procedure_2(proc_x):
|
||||||
global test_name, naked, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
if proc_x:
|
if proc_x:
|
||||||
return
|
return
|
||||||
proc_w = True
|
proc_w = True
|
||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def test_function():
|
def test_function():
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
assertEquals(function_1(2, 3), -1, 'function with arguments')
|
assertEquals(function_1(2, 3), -1, 'function with arguments')
|
||||||
assertEquals(func_z, 'side effect', 'function with side effect')
|
assertEquals(func_z, 'side effect', 'function with side effect')
|
||||||
func_a = 'unchanged'
|
func_a = 'unchanged'
|
||||||
@@ -1314,28 +1258,28 @@ def test_function():
|
|||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def function_1(func_x, func_y):
|
def function_1(func_x, func_y):
|
||||||
global test_name, naked, proc_x, proc_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_a, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
func_z = 'side effect'
|
func_z = 'side effect'
|
||||||
return func_x - func_y
|
return func_x - func_y
|
||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def function_2(func_a):
|
def function_2(func_a):
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
func_a = (func_a if isinstance(func_a, Number) else 0) + 1
|
func_a = (func_a if isinstance(func_a, Number) else 0) + 1
|
||||||
return str(func_a) + str(func_c)
|
return str(func_a) + str(func_c)
|
||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def function_3(func_a):
|
def function_3(func_a):
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, n, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
if func_a:
|
if func_a:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Describe this function...
|
# Describe this function...
|
||||||
def recurse(n):
|
def recurse(n):
|
||||||
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, i, loglist, changing_list, list_copy, unittestResults
|
global test_name, naked, proc_x, proc_y, func_x, func_y, func_a, ok, log, count, varToChange, rand, item, text, number_of_calls, list2, proc_z, func_z, x, proc_w, func_c, if2, loglist, changing_list, list_copy, unittestResults
|
||||||
if n > 0:
|
if n > 0:
|
||||||
text = ''.join([str(x5) for x5 in [recurse(n - 1), n, recurse(n - 1)]])
|
text = ''.join([str(x4) for x4 in [recurse(n - 1), n, recurse(n - 1)]])
|
||||||
else:
|
else:
|
||||||
text = '-'
|
text = '-'
|
||||||
return text
|
return text
|
||||||
@@ -1414,7 +1358,6 @@ test_trim()
|
|||||||
test_count_text()
|
test_count_text()
|
||||||
test_text_reverse()
|
test_text_reverse()
|
||||||
test_replace()
|
test_replace()
|
||||||
test_multiline()
|
|
||||||
print(unittest_report())
|
print(unittest_report())
|
||||||
unittestResults = None
|
unittestResults = None
|
||||||
|
|
||||||
@@ -1443,15 +1386,6 @@ test_lists_reverse()
|
|||||||
print(unittest_report())
|
print(unittest_report())
|
||||||
unittestResults = None
|
unittestResults = None
|
||||||
|
|
||||||
unittestResults = []
|
|
||||||
print('\n====================\n\nRunning suite: Colour')
|
|
||||||
test_colour_picker()
|
|
||||||
test_blend()
|
|
||||||
test_rgb()
|
|
||||||
test_colour_random()
|
|
||||||
print(unittest_report())
|
|
||||||
unittestResults = None
|
|
||||||
|
|
||||||
unittestResults = []
|
unittestResults = []
|
||||||
print('\n====================\n\nRunning suite: Variables')
|
print('\n====================\n\nRunning suite: Variables')
|
||||||
item = 123
|
item = 123
|
||||||
|
|||||||
@@ -321,7 +321,6 @@ h1 {
|
|||||||
<block type="text_count"></block>
|
<block type="text_count"></block>
|
||||||
<block type="text_replace"></block>
|
<block type="text_replace"></block>
|
||||||
<block type="text_reverse"></block>
|
<block type="text_reverse"></block>
|
||||||
<block type="text_multiline"></block>
|
|
||||||
</category>
|
</category>
|
||||||
<category name="Lists" colour="260">
|
<category name="Lists" colour="260">
|
||||||
<block type="lists_create_empty"></block>
|
<block type="lists_create_empty"></block>
|
||||||
@@ -337,12 +336,6 @@ h1 {
|
|||||||
<block type="lists_split"></block>
|
<block type="lists_split"></block>
|
||||||
<block type="lists_reverse"></block>
|
<block type="lists_reverse"></block>
|
||||||
</category>
|
</category>
|
||||||
<category name="Colour" colour="20">
|
|
||||||
<block type="colour_picker"></block>
|
|
||||||
<block type="colour_random"></block>
|
|
||||||
<block type="colour_rgb"></block>
|
|
||||||
<block type="colour_blend"></block>
|
|
||||||
</category>
|
|
||||||
<sep></sep>
|
<sep></sep>
|
||||||
<category name="Variables" colour="330" custom="VARIABLE"></category>
|
<category name="Variables" colour="330" custom="VARIABLE"></category>
|
||||||
<category name="Functions" colour="290" custom="PROCEDURE"></category>
|
<category name="Functions" colour="290" custom="PROCEDURE"></category>
|
||||||
@@ -364,7 +357,6 @@ h1 {
|
|||||||
<input type="checkbox" class="suite_checkbox" value="math.xml">Math</input><br/>
|
<input type="checkbox" class="suite_checkbox" value="math.xml">Math</input><br/>
|
||||||
<input type="checkbox" class="suite_checkbox" value="text.xml">Text</input><br/>
|
<input type="checkbox" class="suite_checkbox" value="text.xml">Text</input><br/>
|
||||||
<input type="checkbox" class="suite_checkbox" value="lists.xml">Lists</input><br/>
|
<input type="checkbox" class="suite_checkbox" value="lists.xml">Lists</input><br/>
|
||||||
<input type="checkbox" class="suite_checkbox" value="colour.xml">Colour</input><br/>
|
|
||||||
<input type="checkbox" class="suite_checkbox" value="variables.xml">Variables</input><br/>
|
<input type="checkbox" class="suite_checkbox" value="variables.xml">Variables</input><br/>
|
||||||
<input type="checkbox" class="suite_checkbox" value="functions.xml">Functions</input><br/>
|
<input type="checkbox" class="suite_checkbox" value="functions.xml">Functions</input><br/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -46,11 +46,6 @@
|
|||||||
<next>
|
<next>
|
||||||
<block type="procedures_callnoreturn">
|
<block type="procedures_callnoreturn">
|
||||||
<mutation name="test replace"></mutation>
|
<mutation name="test replace"></mutation>
|
||||||
<next>
|
|
||||||
<block type="procedures_callnoreturn">
|
|
||||||
<mutation name="test multiline"></mutation>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
</block>
|
||||||
</next>
|
</next>
|
||||||
</block>
|
</block>
|
||||||
@@ -4653,93 +4648,4 @@
|
|||||||
</block>
|
</block>
|
||||||
</statement>
|
</statement>
|
||||||
</block>
|
</block>
|
||||||
<block type="procedures_defnoreturn" x="13" y="14063">
|
|
||||||
<field name="NAME">test multiline</field>
|
|
||||||
<comment pinned="false" h="80" w="160">Tests the "multiline" block.</comment>
|
|
||||||
<statement name="STACK">
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">no text</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="text_multiline">
|
|
||||||
<field name="TEXT"></field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT"></field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<next>
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">simple</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="text_multiline">
|
|
||||||
<field name="TEXT">Google</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">Google</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<next>
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">no compile error with newlines</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="text_multiline">
|
|
||||||
<field name="TEXT">paragraph with newlines yup</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="text_multiline">
|
|
||||||
<field name="TEXT">paragraph with newlines yup</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<next>
|
|
||||||
<block type="unittest_assertequals" inline="false">
|
|
||||||
<value name="MESSAGE">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">count with newlines</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="ACTUAL">
|
|
||||||
<block type="text_count">
|
|
||||||
<value name="SUB">
|
|
||||||
<block type="text">
|
|
||||||
<field name="TEXT">bark</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="TEXT">
|
|
||||||
<block type="text_multiline">
|
|
||||||
<field name="TEXT">bark bark bark bark bark bark bark bark bark</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
<value name="EXPECTED">
|
|
||||||
<block type="math_number">
|
|
||||||
<field name="NUM">9</field>
|
|
||||||
</block>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</next>
|
|
||||||
</block>
|
|
||||||
</statement>
|
|
||||||
</block>
|
|
||||||
</xml>
|
</xml>
|
||||||
@@ -1,389 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as Blockly from '../../build/src/core/blockly.js';
|
|
||||||
import {
|
|
||||||
assertFieldValue,
|
|
||||||
runConstructorSuiteTests,
|
|
||||||
runFromJsonSuiteTests,
|
|
||||||
runSetValueTests,
|
|
||||||
} from './test_helpers/fields.js';
|
|
||||||
import {
|
|
||||||
createTestBlock,
|
|
||||||
defineRowBlock,
|
|
||||||
} from './test_helpers/block_definitions.js';
|
|
||||||
import {
|
|
||||||
sharedTestSetup,
|
|
||||||
sharedTestTeardown,
|
|
||||||
workspaceTeardown,
|
|
||||||
} from './test_helpers/setup_teardown.js';
|
|
||||||
|
|
||||||
suite('Angle Fields', function () {
|
|
||||||
setup(function () {
|
|
||||||
sharedTestSetup.call(this);
|
|
||||||
});
|
|
||||||
teardown(function () {
|
|
||||||
sharedTestTeardown.call(this);
|
|
||||||
});
|
|
||||||
/**
|
|
||||||
* Configuration for field tests with invalid values.
|
|
||||||
* @type {!Array<!FieldCreationTestCase>}
|
|
||||||
*/
|
|
||||||
const invalidValueTestCases = [
|
|
||||||
{title: 'Undefined', value: undefined},
|
|
||||||
{title: 'Null', value: null},
|
|
||||||
{title: 'NaN', value: NaN},
|
|
||||||
{title: 'Non-Parsable String', value: 'bad'},
|
|
||||||
{title: 'Infinity', value: Infinity, expectedValue: Infinity},
|
|
||||||
{title: 'Negative Infinity', value: -Infinity, expectedValue: -Infinity},
|
|
||||||
{title: 'Infinity String', value: 'Infinity', expectedValue: Infinity},
|
|
||||||
{
|
|
||||||
title: 'Negative Infinity String',
|
|
||||||
value: '-Infinity',
|
|
||||||
expectedValue: -Infinity,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* Configuration for field tests with valid values.
|
|
||||||
* @type {!Array<!FieldCreationTestCase>}
|
|
||||||
*/
|
|
||||||
|
|
||||||
const validValueTestCases = [
|
|
||||||
{title: 'Integer', value: 1, expectedValue: 1},
|
|
||||||
{title: 'Float', value: 1.5, expectedValue: 1.5},
|
|
||||||
{title: 'Integer String', value: '1', expectedValue: 1},
|
|
||||||
{title: 'Float String', value: '1.5', expectedValue: 1.5},
|
|
||||||
{title: '> 360°', value: 362, expectedValue: 2},
|
|
||||||
];
|
|
||||||
const addArgsAndJson = function (testCase) {
|
|
||||||
testCase.args = [testCase.value];
|
|
||||||
testCase.json = {'angle': testCase.value};
|
|
||||||
};
|
|
||||||
invalidValueTestCases.forEach(addArgsAndJson);
|
|
||||||
validValueTestCases.forEach(addArgsAndJson);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The expected default value for the field being tested.
|
|
||||||
* @type {*}
|
|
||||||
*/
|
|
||||||
const defaultFieldValue = 0;
|
|
||||||
/**
|
|
||||||
* Asserts that the field property values are set to default.
|
|
||||||
* @param {FieldTemplate} field The field to check.
|
|
||||||
*/
|
|
||||||
const assertFieldDefault = function (field) {
|
|
||||||
assertFieldValue(field, defaultFieldValue);
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Asserts that the field properties are correct based on the test case.
|
|
||||||
* @param {!Blockly.FieldAngle} field The field to check.
|
|
||||||
* @param {!FieldValueTestCase} testCase The test case.
|
|
||||||
*/
|
|
||||||
const validTestCaseAssertField = function (field, testCase) {
|
|
||||||
assertFieldValue(field, testCase.expectedValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
runConstructorSuiteTests(
|
|
||||||
Blockly.FieldAngle,
|
|
||||||
validValueTestCases,
|
|
||||||
invalidValueTestCases,
|
|
||||||
validTestCaseAssertField,
|
|
||||||
assertFieldDefault,
|
|
||||||
);
|
|
||||||
|
|
||||||
runFromJsonSuiteTests(
|
|
||||||
Blockly.FieldAngle,
|
|
||||||
validValueTestCases,
|
|
||||||
invalidValueTestCases,
|
|
||||||
validTestCaseAssertField,
|
|
||||||
assertFieldDefault,
|
|
||||||
);
|
|
||||||
|
|
||||||
suite('setValue', function () {
|
|
||||||
suite('Empty -> New Value', function () {
|
|
||||||
setup(function () {
|
|
||||||
this.field = new Blockly.FieldAngle();
|
|
||||||
});
|
|
||||||
runSetValueTests(
|
|
||||||
validValueTestCases,
|
|
||||||
invalidValueTestCases,
|
|
||||||
defaultFieldValue,
|
|
||||||
);
|
|
||||||
test('With source block', function () {
|
|
||||||
this.field.setSourceBlock(createTestBlock());
|
|
||||||
this.field.setValue(2.5);
|
|
||||||
assertFieldValue(this.field, 2.5);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Value -> New Value', function () {
|
|
||||||
const initialValue = 1;
|
|
||||||
setup(function () {
|
|
||||||
this.field = new Blockly.FieldAngle(initialValue);
|
|
||||||
});
|
|
||||||
runSetValueTests(
|
|
||||||
validValueTestCases,
|
|
||||||
invalidValueTestCases,
|
|
||||||
initialValue,
|
|
||||||
);
|
|
||||||
test('With source block', function () {
|
|
||||||
this.field.setSourceBlock(createTestBlock());
|
|
||||||
this.field.setValue(2.5);
|
|
||||||
assertFieldValue(this.field, 2.5);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Validators', function () {
|
|
||||||
setup(function () {
|
|
||||||
this.field = new Blockly.FieldAngle(1);
|
|
||||||
this.field.htmlInput_ = document.createElement('input');
|
|
||||||
this.field.htmlInput_.setAttribute('data-old-value', '1');
|
|
||||||
this.field.htmlInput_.setAttribute('data-untyped-default-value', '1');
|
|
||||||
this.stub = sinon.stub(this.field, 'resizeEditor_');
|
|
||||||
});
|
|
||||||
teardown(function () {
|
|
||||||
sinon.restore();
|
|
||||||
});
|
|
||||||
const testSuites = [
|
|
||||||
{
|
|
||||||
title: 'Null Validator',
|
|
||||||
validator: function () {
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
value: 2,
|
|
||||||
expectedValue: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Force Mult of 30 Validator',
|
|
||||||
validator: function (newValue) {
|
|
||||||
return Math.round(newValue / 30) * 30;
|
|
||||||
},
|
|
||||||
value: 25,
|
|
||||||
expectedValue: 30,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Returns Undefined Validator',
|
|
||||||
validator: function () {},
|
|
||||||
value: 2,
|
|
||||||
expectedValue: 2,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
testSuites.forEach(function (suiteInfo) {
|
|
||||||
suite(suiteInfo.title, function () {
|
|
||||||
setup(function () {
|
|
||||||
this.field.setValidator(suiteInfo.validator);
|
|
||||||
});
|
|
||||||
test('When Editing', function () {
|
|
||||||
this.field.isBeingEdited_ = true;
|
|
||||||
this.field.htmlInput_.value = String(suiteInfo.value);
|
|
||||||
this.field.onHtmlInputChange_(null);
|
|
||||||
assertFieldValue(
|
|
||||||
this.field,
|
|
||||||
suiteInfo.expectedValue,
|
|
||||||
String(suiteInfo.value),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
test('When Not Editing', function () {
|
|
||||||
this.field.setValue(suiteInfo.value);
|
|
||||||
assertFieldValue(this.field, +suiteInfo.expectedValue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Customizations', function () {
|
|
||||||
suite('Clockwise', function () {
|
|
||||||
test('JS Configuration', function () {
|
|
||||||
const field = new Blockly.FieldAngle(0, null, {
|
|
||||||
clockwise: true,
|
|
||||||
});
|
|
||||||
chai.assert.isTrue(field.clockwise);
|
|
||||||
});
|
|
||||||
test('JSON Definition', function () {
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
clockwise: true,
|
|
||||||
});
|
|
||||||
chai.assert.isTrue(field.clockwise);
|
|
||||||
});
|
|
||||||
test('Constant', function () {
|
|
||||||
// Note: Generally constants should be set at compile time, not
|
|
||||||
// runtime (since they are constants) but for testing purposes we
|
|
||||||
// can do this.
|
|
||||||
Blockly.FieldAngle.CLOCKWISE = true;
|
|
||||||
const field = new Blockly.FieldAngle();
|
|
||||||
chai.assert.isTrue(field.clockwise);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Offset', function () {
|
|
||||||
test('JS Configuration', function () {
|
|
||||||
const field = new Blockly.FieldAngle(0, null, {
|
|
||||||
offset: 90,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.offset, 90);
|
|
||||||
});
|
|
||||||
test('JSON Definition', function () {
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
offset: 90,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.offset, 90);
|
|
||||||
});
|
|
||||||
test('Constant', function () {
|
|
||||||
// Note: Generally constants should be set at compile time, not
|
|
||||||
// runtime (since they are constants) but for testing purposes we
|
|
||||||
// can do this.
|
|
||||||
Blockly.FieldAngle.OFFSET = 90;
|
|
||||||
const field = new Blockly.FieldAngle();
|
|
||||||
chai.assert.equal(field.offset, 90);
|
|
||||||
});
|
|
||||||
test('Null', function () {
|
|
||||||
// Note: Generally constants should be set at compile time, not
|
|
||||||
// runtime (since they are constants) but for testing purposes we
|
|
||||||
// can do this.
|
|
||||||
Blockly.FieldAngle.OFFSET = 90;
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
offset: null,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.offset, 90);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Wrap', function () {
|
|
||||||
test('JS Configuration', function () {
|
|
||||||
const field = new Blockly.FieldAngle(0, null, {
|
|
||||||
wrap: 180,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.wrap, 180);
|
|
||||||
});
|
|
||||||
test('JSON Definition', function () {
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
wrap: 180,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.wrap, 180);
|
|
||||||
});
|
|
||||||
test('Constant', function () {
|
|
||||||
// Note: Generally constants should be set at compile time, not
|
|
||||||
// runtime (since they are constants) but for testing purposes we
|
|
||||||
// can do this.
|
|
||||||
Blockly.FieldAngle.WRAP = 180;
|
|
||||||
const field = new Blockly.FieldAngle();
|
|
||||||
chai.assert.equal(field.wrap, 180);
|
|
||||||
});
|
|
||||||
test('Null', function () {
|
|
||||||
// Note: Generally constants should be set at compile time, not
|
|
||||||
// runtime (since they are constants) but for testing purposes we
|
|
||||||
// can do this.
|
|
||||||
Blockly.FieldAngle.WRAP = 180;
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
wrap: null,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.wrap, 180);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Round', function () {
|
|
||||||
test('JS Configuration', function () {
|
|
||||||
const field = new Blockly.FieldAngle(0, null, {
|
|
||||||
round: 30,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.round, 30);
|
|
||||||
});
|
|
||||||
test('JSON Definition', function () {
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
round: 30,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.round, 30);
|
|
||||||
});
|
|
||||||
test('Constant', function () {
|
|
||||||
// Note: Generally constants should be set at compile time, not
|
|
||||||
// runtime (since they are constants) but for testing purposes we
|
|
||||||
// can do this.
|
|
||||||
Blockly.FieldAngle.ROUND = 30;
|
|
||||||
const field = new Blockly.FieldAngle();
|
|
||||||
chai.assert.equal(field.round, 30);
|
|
||||||
});
|
|
||||||
test('Null', function () {
|
|
||||||
// Note: Generally constants should be set at compile time, not
|
|
||||||
// runtime (since they are constants) but for testing purposes we
|
|
||||||
// can do this.
|
|
||||||
Blockly.FieldAngle.ROUND = 30;
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
round: null,
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.round, 30);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Mode', function () {
|
|
||||||
suite('Compass', function () {
|
|
||||||
test('JS Configuration', function () {
|
|
||||||
const field = new Blockly.FieldAngle(0, null, {
|
|
||||||
mode: 'compass',
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.offset, 90);
|
|
||||||
chai.assert.isTrue(field.clockwise);
|
|
||||||
});
|
|
||||||
test('JS Configuration', function () {
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
mode: 'compass',
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.offset, 90);
|
|
||||||
chai.assert.isTrue(field.clockwise);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Protractor', function () {
|
|
||||||
test('JS Configuration', function () {
|
|
||||||
const field = new Blockly.FieldAngle(0, null, {
|
|
||||||
mode: 'protractor',
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.offset, 0);
|
|
||||||
chai.assert.isFalse(field.clockwise);
|
|
||||||
});
|
|
||||||
test('JS Configuration', function () {
|
|
||||||
const field = Blockly.FieldAngle.fromJson({
|
|
||||||
value: 0,
|
|
||||||
mode: 'protractor',
|
|
||||||
});
|
|
||||||
chai.assert.equal(field.offset, 0);
|
|
||||||
chai.assert.isFalse(field.clockwise);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
suite('Serialization', function () {
|
|
||||||
setup(function () {
|
|
||||||
this.workspace = new Blockly.Workspace();
|
|
||||||
defineRowBlock();
|
|
||||||
|
|
||||||
this.assertValue = (value) => {
|
|
||||||
const block = this.workspace.newBlock('row_block');
|
|
||||||
const field = new Blockly.FieldAngle(value);
|
|
||||||
block.getInput('INPUT').appendField(field, 'ANGLE');
|
|
||||||
const jso = Blockly.serialization.blocks.save(block);
|
|
||||||
chai.assert.deepEqual(jso['fields'], {'ANGLE': value});
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
teardown(function () {
|
|
||||||
workspaceTeardown.call(this, this.workspace);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Simple', function () {
|
|
||||||
this.assertValue(90);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Max precision', function () {
|
|
||||||
this.assertValue(1.000000000000001);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Smallest number', function () {
|
|
||||||
this.assertValue(5e-324);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,284 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2020 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as Blockly from '../../build/src/core/blockly.js';
|
|
||||||
import {
|
|
||||||
assertFieldValue,
|
|
||||||
runConstructorSuiteTests,
|
|
||||||
runFromJsonSuiteTests,
|
|
||||||
runSetValueTests,
|
|
||||||
} from './test_helpers/fields.js';
|
|
||||||
import {
|
|
||||||
createTestBlock,
|
|
||||||
defineRowBlock,
|
|
||||||
} from './test_helpers/block_definitions.js';
|
|
||||||
import {
|
|
||||||
sharedTestSetup,
|
|
||||||
sharedTestTeardown,
|
|
||||||
workspaceTeardown,
|
|
||||||
} from './test_helpers/setup_teardown.js';
|
|
||||||
import {runCodeGenerationTestSuites} from './test_helpers/code_generation.js';
|
|
||||||
import {dartGenerator} from '../../build/src/generators/dart.js';
|
|
||||||
import {javascriptGenerator} from '../../build/src/generators/javascript.js';
|
|
||||||
import {luaGenerator} from '../../build/src/generators/lua.js';
|
|
||||||
import {phpGenerator} from '../../build/src/generators/php.js';
|
|
||||||
import {pythonGenerator} from '../../build/src/generators/python.js';
|
|
||||||
|
|
||||||
suite('Multiline Input Fields', function () {
|
|
||||||
setup(function () {
|
|
||||||
sharedTestSetup.call(this);
|
|
||||||
});
|
|
||||||
teardown(function () {
|
|
||||||
sharedTestTeardown.call(this);
|
|
||||||
});
|
|
||||||
/**
|
|
||||||
* Configuration for field tests with invalid values.
|
|
||||||
* @type {!Array<!FieldCreationTestCase>}
|
|
||||||
*/
|
|
||||||
const invalidValueTestCases = [
|
|
||||||
{title: 'Undefined', value: undefined},
|
|
||||||
{title: 'Null', value: null},
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* Configuration for field tests with valid values.
|
|
||||||
* @type {!Array<!FieldCreationTestCase>}
|
|
||||||
*/
|
|
||||||
const validValueTestCases = [
|
|
||||||
{title: 'Empty string', value: '', expectedValue: ''},
|
|
||||||
{title: 'String no newline', value: 'value', expectedValue: 'value'},
|
|
||||||
{
|
|
||||||
title: 'String with newline',
|
|
||||||
value: 'bark bark\n bark bark bark\n bark bar bark bark\n',
|
|
||||||
expectedValue: 'bark bark\n bark bark bark\n bark bar bark bark\n',
|
|
||||||
},
|
|
||||||
{title: 'Boolean true', value: true, expectedValue: 'true'},
|
|
||||||
{title: 'Boolean false', value: false, expectedValue: 'false'},
|
|
||||||
{title: 'Number (Truthy)', value: 1, expectedValue: '1'},
|
|
||||||
{title: 'Number (Falsy)', value: 0, expectedValue: '0'},
|
|
||||||
{title: 'NaN', value: NaN, expectedValue: 'NaN'},
|
|
||||||
];
|
|
||||||
const addArgsAndJson = function (testCase) {
|
|
||||||
testCase.args = [testCase.value];
|
|
||||||
testCase.json = {'text': testCase.value};
|
|
||||||
};
|
|
||||||
invalidValueTestCases.forEach(addArgsAndJson);
|
|
||||||
validValueTestCases.forEach(addArgsAndJson);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The expected default value for the field being tested.
|
|
||||||
* @type {*}
|
|
||||||
*/
|
|
||||||
const defaultFieldValue = '';
|
|
||||||
/**
|
|
||||||
* Asserts that the field property values are set to default.
|
|
||||||
* @param {!Blockly.FieldMultilineInput} field The field to check.
|
|
||||||
*/
|
|
||||||
const assertFieldDefault = function (field) {
|
|
||||||
assertFieldValue(field, defaultFieldValue);
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Asserts that the field properties are correct based on the test case.
|
|
||||||
* @param {!Blockly.FieldMultilineInput} field The field to check.
|
|
||||||
* @param {!FieldValueTestCase} testCase The test case.
|
|
||||||
*/
|
|
||||||
const validTestCaseAssertField = function (field, testCase) {
|
|
||||||
assertFieldValue(field, testCase.expectedValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
runConstructorSuiteTests(
|
|
||||||
Blockly.FieldMultilineInput,
|
|
||||||
validValueTestCases,
|
|
||||||
invalidValueTestCases,
|
|
||||||
validTestCaseAssertField,
|
|
||||||
assertFieldDefault,
|
|
||||||
);
|
|
||||||
|
|
||||||
runFromJsonSuiteTests(
|
|
||||||
Blockly.FieldMultilineInput,
|
|
||||||
validValueTestCases,
|
|
||||||
invalidValueTestCases,
|
|
||||||
validTestCaseAssertField,
|
|
||||||
assertFieldDefault,
|
|
||||||
);
|
|
||||||
|
|
||||||
suite('setValue', function () {
|
|
||||||
suite('Empty -> New Value', function () {
|
|
||||||
setup(function () {
|
|
||||||
this.field = new Blockly.FieldMultilineInput();
|
|
||||||
});
|
|
||||||
runSetValueTests(
|
|
||||||
validValueTestCases,
|
|
||||||
invalidValueTestCases,
|
|
||||||
defaultFieldValue,
|
|
||||||
);
|
|
||||||
test('With source block', function () {
|
|
||||||
this.field.setSourceBlock(createTestBlock());
|
|
||||||
this.field.setValue('value');
|
|
||||||
assertFieldValue(this.field, 'value');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
suite('Value -> New Value', function () {
|
|
||||||
const initialValue = 'oldValue';
|
|
||||||
setup(function () {
|
|
||||||
this.field = new Blockly.FieldMultilineInput(initialValue);
|
|
||||||
});
|
|
||||||
runSetValueTests(
|
|
||||||
validValueTestCases,
|
|
||||||
invalidValueTestCases,
|
|
||||||
initialValue,
|
|
||||||
);
|
|
||||||
test('With source block', function () {
|
|
||||||
this.field.setSourceBlock(createTestBlock());
|
|
||||||
this.field.setValue('value');
|
|
||||||
assertFieldValue(this.field, 'value');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
suite('blockToCode', function () {
|
|
||||||
setup(function () {
|
|
||||||
this.workspace = new Blockly.Workspace();
|
|
||||||
});
|
|
||||||
const createBlockFn = (value) => {
|
|
||||||
return (workspace) => {
|
|
||||||
const block = workspace.newBlock('text_multiline');
|
|
||||||
const textField = block.getField('TEXT');
|
|
||||||
textField.setValue(value);
|
|
||||||
return block;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test suites for code generation tests.s
|
|
||||||
* @type {Array<CodeGenerationTestSuite>}
|
|
||||||
*/
|
|
||||||
const testSuites = [
|
|
||||||
{
|
|
||||||
title: 'Dart',
|
|
||||||
generator: dartGenerator,
|
|
||||||
testCases: [
|
|
||||||
{
|
|
||||||
title: 'Empty string',
|
|
||||||
expectedCode: "''",
|
|
||||||
createBlock: createBlockFn(''),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'String with newline',
|
|
||||||
expectedCode:
|
|
||||||
"'bark bark' + '\\n' + \n' bark bark bark' + '\\n' + \n' bark bar bark bark' + '\\n' + \n''",
|
|
||||||
createBlock: createBlockFn(
|
|
||||||
'bark bark\n bark bark bark\n bark bar bark bark\n',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'JavaScript',
|
|
||||||
generator: javascriptGenerator,
|
|
||||||
testCases: [
|
|
||||||
{
|
|
||||||
title: 'Empty string',
|
|
||||||
expectedCode: "''",
|
|
||||||
createBlock: createBlockFn(''),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'String with newline',
|
|
||||||
expectedCode:
|
|
||||||
"'bark bark' + '\\n' +\n' bark bark bark' + '\\n' +\n' bark bar bark bark' + '\\n' +\n''",
|
|
||||||
createBlock: createBlockFn(
|
|
||||||
'bark bark\n bark bark bark\n bark bar bark bark\n',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Lua',
|
|
||||||
generator: luaGenerator,
|
|
||||||
testCases: [
|
|
||||||
{
|
|
||||||
title: 'Empty string',
|
|
||||||
expectedCode: "''",
|
|
||||||
createBlock: createBlockFn(''),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'String with newline',
|
|
||||||
expectedCode:
|
|
||||||
"'bark bark' .. '\\n' ..\n' bark bark bark' .. '\\n' ..\n' bark bar bark bark' .. '\\n' ..\n''",
|
|
||||||
createBlock: createBlockFn(
|
|
||||||
'bark bark\n bark bark bark\n bark bar bark bark\n',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'PHP',
|
|
||||||
generator: phpGenerator,
|
|
||||||
testCases: [
|
|
||||||
{
|
|
||||||
title: 'Empty string',
|
|
||||||
expectedCode: "''",
|
|
||||||
createBlock: createBlockFn(''),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'String with newline',
|
|
||||||
expectedCode:
|
|
||||||
"'bark bark' . \"\\n\" .\n' bark bark bark' . \"\\n\" .\n' bark bar bark bark' . \"\\n\" .\n''",
|
|
||||||
createBlock: createBlockFn(
|
|
||||||
'bark bark\n bark bark bark\n bark bar bark bark\n',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Python',
|
|
||||||
generator: pythonGenerator,
|
|
||||||
testCases: [
|
|
||||||
{
|
|
||||||
title: 'Empty string',
|
|
||||||
expectedCode: "''",
|
|
||||||
createBlock: createBlockFn(''),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'String with newline',
|
|
||||||
expectedCode:
|
|
||||||
"'bark bark' + '\\n' + \n' bark bark bark' + '\\n' + \n' bark bar bark bark' + '\\n' + \n''",
|
|
||||||
createBlock: createBlockFn(
|
|
||||||
'bark bark\n bark bark bark\n bark bar bark bark\n',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
runCodeGenerationTestSuites(testSuites);
|
|
||||||
});
|
|
||||||
|
|
||||||
suite('Serialization', function () {
|
|
||||||
setup(function () {
|
|
||||||
this.workspace = new Blockly.Workspace();
|
|
||||||
defineRowBlock();
|
|
||||||
|
|
||||||
this.assertValue = (value) => {
|
|
||||||
const block = this.workspace.newBlock('row_block');
|
|
||||||
const field = new Blockly.FieldMultilineInput(value);
|
|
||||||
block.getInput('INPUT').appendField(field, 'MULTILINE');
|
|
||||||
const jso = Blockly.serialization.blocks.save(block);
|
|
||||||
chai.assert.deepEqual(jso['fields'], {'MULTILINE': value});
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
teardown(function () {
|
|
||||||
workspaceTeardown.call(this, this.workspace);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Single line', function () {
|
|
||||||
this.assertValue('this is a single line');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Multiple lines', function () {
|
|
||||||
this.assertValue('this\nis\n multiple\n lines');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -76,14 +76,11 @@
|
|||||||
import './event_var_rename_test.js';
|
import './event_var_rename_test.js';
|
||||||
import './event_viewport_test.js';
|
import './event_viewport_test.js';
|
||||||
import './extensions_test.js';
|
import './extensions_test.js';
|
||||||
import './field_angle_test.js';
|
|
||||||
import './field_checkbox_test.js';
|
import './field_checkbox_test.js';
|
||||||
import './field_colour_test.js';
|
|
||||||
import './field_dropdown_test.js';
|
import './field_dropdown_test.js';
|
||||||
import './field_image_test.js';
|
import './field_image_test.js';
|
||||||
import './field_label_serializable_test.js';
|
import './field_label_serializable_test.js';
|
||||||
import './field_label_test.js';
|
import './field_label_test.js';
|
||||||
import './field_multilineinput_test.js';
|
|
||||||
import './field_number_test.js';
|
import './field_number_test.js';
|
||||||
import './field_registry_test.js';
|
import './field_registry_test.js';
|
||||||
import './field_test.js';
|
import './field_test.js';
|
||||||
|
|||||||
@@ -223,55 +223,6 @@ Serializer.Attributes.testSuites = [
|
|||||||
|
|
||||||
Serializer.Fields = new SerializerTestSuite('Fields');
|
Serializer.Fields = new SerializerTestSuite('Fields');
|
||||||
|
|
||||||
Serializer.Fields.Angle = new SerializerTestSuite('Angle');
|
|
||||||
Serializer.Fields.Angle.Simple = new SerializerTestCase(
|
|
||||||
'Simple',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_angle" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="FIELDNAME">90</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.Angle.Negative = new SerializerTestCase(
|
|
||||||
'Negative',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_angles_wrap" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="FIELDNAME">-90</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.Angle.Decimals = new SerializerTestCase(
|
|
||||||
'Decimals',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_angle" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="FIELDNAME">1.5</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.Angle.MaxPrecision = new SerializerTestCase(
|
|
||||||
'MaxPrecision',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_angle" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="FIELDNAME">1.000000000000001</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.Angle.SmallestNumber = new SerializerTestCase(
|
|
||||||
'SmallestNumber',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_angle" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="FIELDNAME">5e-324</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.Angle.testCases = [
|
|
||||||
Serializer.Fields.Angle.Simple,
|
|
||||||
Serializer.Fields.Angle.Negative,
|
|
||||||
Serializer.Fields.Angle.Decimals,
|
|
||||||
Serializer.Fields.Angle.MaxPrecision,
|
|
||||||
Serializer.Fields.Angle.SmallestNumber,
|
|
||||||
];
|
|
||||||
|
|
||||||
Serializer.Fields.Checkbox = new SerializerTestSuite('Checkbox');
|
Serializer.Fields.Checkbox = new SerializerTestSuite('Checkbox');
|
||||||
Serializer.Fields.Checkbox.True = new SerializerTestCase(
|
Serializer.Fields.Checkbox.True = new SerializerTestCase(
|
||||||
'True',
|
'True',
|
||||||
@@ -294,37 +245,6 @@ Serializer.Fields.Checkbox.testCases = [
|
|||||||
Serializer.Fields.Checkbox.False,
|
Serializer.Fields.Checkbox.False,
|
||||||
];
|
];
|
||||||
|
|
||||||
Serializer.Fields.Colour = new SerializerTestSuite('Colour');
|
|
||||||
Serializer.Fields.Colour.ThreeChar = new SerializerTestCase(
|
|
||||||
'ThreeChar',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_colour" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="COLOUR">#ffcc00</field>' + // Could use a 3 char code.
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.Colour.SixChar = new SerializerTestCase(
|
|
||||||
'SixChar',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_colour" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="COLOUR">#f1c101</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.Colour.Black = new SerializerTestCase(
|
|
||||||
'Black',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_colour" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="COLOUR">#000000</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.Colour.testCases = [
|
|
||||||
Serializer.Fields.Colour.ThreeChar,
|
|
||||||
Serializer.Fields.Colour.SixChar,
|
|
||||||
Serializer.Fields.Colour.Black,
|
|
||||||
];
|
|
||||||
|
|
||||||
Serializer.Fields.Dropdown = new SerializerTestSuite('Dropdown');
|
Serializer.Fields.Dropdown = new SerializerTestSuite('Dropdown');
|
||||||
Serializer.Fields.Dropdown.Default = new SerializerTestCase(
|
Serializer.Fields.Dropdown.Default = new SerializerTestCase(
|
||||||
'Default',
|
'Default',
|
||||||
@@ -462,141 +382,6 @@ Serializer.Fields.LabelSerializable.testCases = [
|
|||||||
// Serializer.Fields.LabelSerializable.ControlChars,
|
// Serializer.Fields.LabelSerializable.ControlChars,
|
||||||
];
|
];
|
||||||
|
|
||||||
Serializer.Fields.MultilineInput = new SerializerTestSuite('MultilineInput');
|
|
||||||
Serializer.Fields.MultilineInput.SingleLine = new SerializerTestCase(
|
|
||||||
'SingleLine',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">test</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.MultipleLines = new SerializerTestCase(
|
|
||||||
'MultipleLines',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">line1&#10;line2&#10;line3</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.Indentation = new SerializerTestCase(
|
|
||||||
'Indentation',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">line1&#10; line2&#10; line3</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
/* eslint-disable no-tabs */
|
|
||||||
Serializer.Fields.MultilineInput.Tabs = new SerializerTestCase(
|
|
||||||
'Tabs',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">' +
|
|
||||||
'line1&#10;&#x9line2&#10;&#x9line3' +
|
|
||||||
'</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
/* eslint-enable no-tabs */
|
|
||||||
Serializer.Fields.MultilineInput.Symbols = new SerializerTestCase(
|
|
||||||
'Symbols',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">~`!@#$%^*()_+-={[}]|\\:;,.?/</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.EscapedSymbols = new SerializerTestCase(
|
|
||||||
'EscapedSymbols',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">&<></field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.SingleQuotes = new SerializerTestCase(
|
|
||||||
'SingleQuotes',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">\'test\'</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.DoubleQuotes = new SerializerTestCase(
|
|
||||||
'DoubleQuotes',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">"test"</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.Numbers = new SerializerTestCase(
|
|
||||||
'Numbers',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">1234567890a123a123a</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.Emoji = new SerializerTestCase(
|
|
||||||
'Emoji',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">😀👋🏿👋🏾👋🏽👋🏼👋🏻😀❤❤❤</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.Russian = new SerializerTestCase(
|
|
||||||
'Russian',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">ты любопытный кот</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.Japanese = new SerializerTestCase(
|
|
||||||
'Japanese',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">あなたは好奇心旺盛な猫です</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.Zalgo = new SerializerTestCase(
|
|
||||||
'Zalgo',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">z̴̪͈̲̜͕̽̈̀͒͂̓̋̉̍a̸̧̧̜̻̘̤̫̱̲͎̞̻͆̋ļ̸̛̖̜̳͚̖͔̟̈́͂̉̀͑̑͑̎ǵ̸̫̳̽̐̃̑̚̕o̶͇̫͔̮̼̭͕̹̘̬͋̀͆̂̇̋͊̒̽</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.ControlChars = new SerializerTestCase(
|
|
||||||
'ControlChars',
|
|
||||||
'<xml xmlns="https://developers.google.com/blockly/xml">' +
|
|
||||||
'<block type="test_fields_multilinetext" id="id******************" x="42" y="42">' +
|
|
||||||
'<field name="CODE">&#a1;</field>' +
|
|
||||||
'</block>' +
|
|
||||||
'</xml>',
|
|
||||||
);
|
|
||||||
Serializer.Fields.MultilineInput.testCases = [
|
|
||||||
Serializer.Fields.MultilineInput.SingleLine,
|
|
||||||
Serializer.Fields.MultilineInput.MultipleLines,
|
|
||||||
Serializer.Fields.MultilineInput.Indentation,
|
|
||||||
Serializer.Fields.MultilineInput.Tabs,
|
|
||||||
Serializer.Fields.MultilineInput.Symbols,
|
|
||||||
Serializer.Fields.MultilineInput.EscapedSymbols,
|
|
||||||
Serializer.Fields.MultilineInput.SingleQuotes,
|
|
||||||
Serializer.Fields.MultilineInput.DoubleQuotes,
|
|
||||||
Serializer.Fields.MultilineInput.Numbers,
|
|
||||||
Serializer.Fields.MultilineInput.Emoji,
|
|
||||||
Serializer.Fields.MultilineInput.Russian,
|
|
||||||
Serializer.Fields.MultilineInput.Japanese,
|
|
||||||
Serializer.Fields.MultilineInput.Zalgo,
|
|
||||||
// TODO: Uncoment once #4945 is merged.
|
|
||||||
// Serializer.Fields.MultilineInput.ControlChars,
|
|
||||||
];
|
|
||||||
|
|
||||||
Serializer.Fields.Number = new SerializerTestSuite('Number');
|
Serializer.Fields.Number = new SerializerTestSuite('Number');
|
||||||
Serializer.Fields.Number.Simple = new SerializerTestCase(
|
Serializer.Fields.Number.Simple = new SerializerTestCase(
|
||||||
'Simple',
|
'Simple',
|
||||||
@@ -1070,12 +855,9 @@ Serializer.Fields.Variable.Id.testSuites = [
|
|||||||
Serializer.Fields.Variable.testSuites = [Serializer.Fields.Variable.Id];
|
Serializer.Fields.Variable.testSuites = [Serializer.Fields.Variable.Id];
|
||||||
|
|
||||||
Serializer.Fields.testSuites = [
|
Serializer.Fields.testSuites = [
|
||||||
Serializer.Fields.Angle,
|
|
||||||
Serializer.Fields.Checkbox,
|
Serializer.Fields.Checkbox,
|
||||||
Serializer.Fields.Colour,
|
|
||||||
Serializer.Fields.Dropdown,
|
Serializer.Fields.Dropdown,
|
||||||
Serializer.Fields.LabelSerializable,
|
Serializer.Fields.LabelSerializable,
|
||||||
Serializer.Fields.MultilineInput,
|
|
||||||
Serializer.Fields.Number,
|
Serializer.Fields.Number,
|
||||||
Serializer.Fields.TextInput,
|
Serializer.Fields.TextInput,
|
||||||
Serializer.Fields.Variable,
|
Serializer.Fields.Variable,
|
||||||
|
|||||||
@@ -127,27 +127,6 @@ suite('XML', function () {
|
|||||||
workspaceTeardown.call(this, this.workspace);
|
workspaceTeardown.call(this, this.workspace);
|
||||||
});
|
});
|
||||||
suite('Fields', function () {
|
suite('Fields', function () {
|
||||||
test('Angle', function () {
|
|
||||||
Blockly.defineBlocksWithJsonArray([
|
|
||||||
{
|
|
||||||
'type': 'field_angle_test_block',
|
|
||||||
'message0': '%1',
|
|
||||||
'args0': [
|
|
||||||
{
|
|
||||||
'type': 'field_angle',
|
|
||||||
'name': 'ANGLE',
|
|
||||||
'angle': 90,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
const block = new Blockly.Block(
|
|
||||||
this.workspace,
|
|
||||||
'field_angle_test_block',
|
|
||||||
);
|
|
||||||
const resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0];
|
|
||||||
assertNonVariableField(resultFieldDom, 'ANGLE', '90');
|
|
||||||
});
|
|
||||||
test('Checkbox', function () {
|
test('Checkbox', function () {
|
||||||
Blockly.defineBlocksWithJsonArray([
|
Blockly.defineBlocksWithJsonArray([
|
||||||
{
|
{
|
||||||
@@ -169,27 +148,6 @@ suite('XML', function () {
|
|||||||
const resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0];
|
const resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0];
|
||||||
assertNonVariableField(resultFieldDom, 'CHECKBOX', 'TRUE');
|
assertNonVariableField(resultFieldDom, 'CHECKBOX', 'TRUE');
|
||||||
});
|
});
|
||||||
test('Colour', function () {
|
|
||||||
Blockly.defineBlocksWithJsonArray([
|
|
||||||
{
|
|
||||||
'type': 'field_colour_test_block',
|
|
||||||
'message0': '%1',
|
|
||||||
'args0': [
|
|
||||||
{
|
|
||||||
'type': 'field_colour',
|
|
||||||
'name': 'COLOUR',
|
|
||||||
'colour': '#000099',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
const block = new Blockly.Block(
|
|
||||||
this.workspace,
|
|
||||||
'field_colour_test_block',
|
|
||||||
);
|
|
||||||
const resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0];
|
|
||||||
assertNonVariableField(resultFieldDom, 'COLOUR', '#000099');
|
|
||||||
});
|
|
||||||
test('Dropdown', function () {
|
test('Dropdown', function () {
|
||||||
Blockly.defineBlocksWithJsonArray([
|
Blockly.defineBlocksWithJsonArray([
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -342,7 +342,6 @@
|
|||||||
</category>
|
</category>
|
||||||
<category name="Text" categorystyle="text_category">
|
<category name="Text" categorystyle="text_category">
|
||||||
<block type="text"></block>
|
<block type="text"></block>
|
||||||
<block type="text_multiline"></block>
|
|
||||||
<block type="text_join"></block>
|
<block type="text_join"></block>
|
||||||
<block type="text_append">
|
<block type="text_append">
|
||||||
<value name="TEXT">
|
<value name="TEXT">
|
||||||
@@ -469,44 +468,6 @@
|
|||||||
</block>
|
</block>
|
||||||
<block type="lists_sort"></block>
|
<block type="lists_sort"></block>
|
||||||
</category>
|
</category>
|
||||||
<category name="Colour" categorystyle="colour_category">
|
|
||||||
<block type="colour_picker"></block>
|
|
||||||
<block type="colour_random"></block>
|
|
||||||
<block type="colour_rgb">
|
|
||||||
<value name="RED">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">100</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
<value name="GREEN">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">50</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
<value name="BLUE">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">0</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
<block type="colour_blend">
|
|
||||||
<value name="COLOUR1">
|
|
||||||
<shadow type="colour_picker">
|
|
||||||
<field name="COLOUR">#ff0000</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
<value name="COLOUR2">
|
|
||||||
<shadow type="colour_picker">
|
|
||||||
<field name="COLOUR">#3333ff</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
<value name="RATIO">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">0.5</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</category>
|
|
||||||
<sep></sep>
|
<sep></sep>
|
||||||
<category
|
<category
|
||||||
name="Variables"
|
name="Variables"
|
||||||
|
|||||||
@@ -765,7 +765,6 @@
|
|||||||
</category>
|
</category>
|
||||||
<category name="Text" categorystyle="text_category">
|
<category name="Text" categorystyle="text_category">
|
||||||
<block type="text"></block>
|
<block type="text"></block>
|
||||||
<block type="text_multiline"></block>
|
|
||||||
<block type="text_join"></block>
|
<block type="text_join"></block>
|
||||||
<block type="text_append">
|
<block type="text_append">
|
||||||
<value name="TEXT">
|
<value name="TEXT">
|
||||||
@@ -918,44 +917,6 @@
|
|||||||
<block type="lists_sort"></block>
|
<block type="lists_sort"></block>
|
||||||
<block type="lists_reverse"></block>
|
<block type="lists_reverse"></block>
|
||||||
</category>
|
</category>
|
||||||
<category name="Colour" categorystyle="colour_category">
|
|
||||||
<block type="colour_picker"></block>
|
|
||||||
<block type="colour_random"></block>
|
|
||||||
<block type="colour_rgb">
|
|
||||||
<value name="RED">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">100</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
<value name="GREEN">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">50</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
<value name="BLUE">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">0</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
<block type="colour_blend">
|
|
||||||
<value name="COLOUR1">
|
|
||||||
<shadow type="colour_picker">
|
|
||||||
<field name="COLOUR">#ff0000</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
<value name="COLOUR2">
|
|
||||||
<shadow type="colour_picker">
|
|
||||||
<field name="COLOUR">#3333ff</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
<value name="RATIO">
|
|
||||||
<shadow type="math_number">
|
|
||||||
<field name="NUM">0.5</field>
|
|
||||||
</shadow>
|
|
||||||
</value>
|
|
||||||
</block>
|
|
||||||
</category>
|
|
||||||
<sep></sep>
|
<sep></sep>
|
||||||
<category
|
<category
|
||||||
name="Variables"
|
name="Variables"
|
||||||
@@ -1116,7 +1077,6 @@
|
|||||||
</category>
|
</category>
|
||||||
<category name="Text" categorystyle="text_category">
|
<category name="Text" categorystyle="text_category">
|
||||||
<block type="text"></block>
|
<block type="text"></block>
|
||||||
<block type="text_multiline"></block>
|
|
||||||
<block type="text_join"></block>
|
<block type="text_join"></block>
|
||||||
<block type="text_append">
|
<block type="text_append">
|
||||||
<value name="TEXT">
|
<value name="TEXT">
|
||||||
|
|||||||
Reference in New Issue
Block a user