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:
Rachel Fenichel
2024-03-13 13:28:26 -07:00
committed by GitHub
parent a5126d1176
commit 67c3aae76c
38 changed files with 164 additions and 4629 deletions

View File

@@ -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,

View File

@@ -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);

View File

@@ -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': '',

View File

@@ -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,

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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;

View File

@@ -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 '&#10'. 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,
'&#10;',
);
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(/&#10;/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;

View File

@@ -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,

View File

@@ -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];
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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];
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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];
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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];
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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];
}

View File

@@ -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.
*/ */

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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&#10;with newlines&#10;yup</field>
</block>
</value>
<value name="EXPECTED">
<block type="text_multiline">
<field name="TEXT">paragraph&#10;with newlines&#10;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&#10;bark bark bark&#10;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>

View File

@@ -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);
});
});
});

View File

@@ -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');
});
});
});

View File

@@ -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';

View File

@@ -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&amp;#10;line2&amp;#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&amp;#10; line2&amp;#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&amp;#10;&amp;#x9line2&amp;#10;&amp;#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">&amp;&lt;&gt;</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">&#01;&#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,

View File

@@ -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([
{ {

View File

@@ -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"

View File

@@ -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">