diff --git a/.travis.yml b/.travis.yml index de6192206..82b96f3d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,12 @@ matrix: apt: packages: - google-chrome-stable - - os: osx - node_js: stable - osx_image: xcode8.3 + # TODO (#2114): reenable osx build. + # - os: osx + # node_js: stable + # osx_image: xcode8.3 + # addons: + # firefox: latest before_script: # Symlink closure library used by test/jsunit diff --git a/tests/generators/golden/generated.dart b/tests/generators/golden/generated.dart new file mode 100644 index 000000000..6a1311cbd --- /dev/null +++ b/tests/generators/golden/generated.dart @@ -0,0 +1,1670 @@ +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; + +String unittest_report() { + // Create test report. + List report = []; + StringBuffer summary = new StringBuffer(); + int fails = 0; + for (int x = 0; x < unittestResults.length; x++) { + if (unittestResults[x][0]) { + summary.write("."); + } else { + summary.write("F"); + fails++; + report.add(""); + report.add("FAIL: ${unittestResults[x][2]}"); + report.add(unittestResults[x][1]); + } + } + report.insert(0, summary.toString()); + report.add(""); + report.add("Ran ${unittestResults.length} tests."); + report.add(""); + if (fails != 0) { + report.add("FAILED (failures=$fails)"); + } else { + report.add("OK"); + } + return report.join("\n"); +} + +void unittest_assertequals(dynamic actual, dynamic expected, String message) { + // Asserts that a value equals another value. + if (unittestResults == null) { + throw "Orphaned assert: ${message}"; + } + bool equals(a, b) { + if (a == b) { + return true; + } else if (a is List && b is List) { + if (a.length != b.length) { + return false; + } + for (num i = 0; i < a.length; i++) { + if (!equals(a[i], b[i])) { + return false; + } + } + return true; + } + return false; + } + if (equals(actual, expected)) { + unittestResults.add([true, "OK", message]); + } else { + unittestResults.add([false, "Expected: $expected\nActual: $actual", message]); + } +} + +void unittest_fail(String message) { + // Always assert an error. + if (unittestResults == null) { + throw "Orphaned assert fail: ${message}"; + } + unittestResults.add([false, "Fail.", message]); +} + +/// Describe this function... +void test_if() { + if (false) { + unittest_fail('if false'); + } + ok = false; + if (true) { + ok = true; + } + unittest_assertequals(ok, true, 'if true'); + ok = false; + if (false) { + unittest_fail('if/else false'); + } else { + ok = true; + } + unittest_assertequals(ok, true, 'if/else false'); + ok = false; + if (true) { + ok = true; + } else { + unittest_fail('if/else true'); + } + unittest_assertequals(ok, true, 'if/else true'); + ok = false; + if (false) { + unittest_fail('elseif 1'); + }else if (true) { + ok = true; + }else if (true) { + unittest_fail('elseif 2'); + } else { + unittest_fail('elseif 3'); + } + unittest_assertequals(ok, true, 'elseif 4'); +} + +/// Describe this function... +void test_ifelse() { + ok = false; + if (true) { + ok = true; + } else { + unittest_fail('ifelse true'); + } + unittest_assertequals(ok, true, 'ifelse true'); + ok = false; + if (false) { + unittest_fail('ifelse false'); + } else { + ok = true; + } + unittest_assertequals(ok, true, 'ifelse false'); +} + +/// Describe this function... +void test_equalities() { + unittest_assertequals(2 == 2, true, 'Equal yes'); + unittest_assertequals(3 == 4, false, 'Equal no'); + unittest_assertequals(5 != 6, true, 'Not equal yes'); + unittest_assertequals(3 == 4, false, 'Not equal no'); + unittest_assertequals(5 < 6, true, 'Smaller yes'); + unittest_assertequals(7 < 7, false, 'Smaller no'); + unittest_assertequals(9 > 8, true, 'Greater yes'); + unittest_assertequals(10 > 10, false, 'Greater no'); + unittest_assertequals(11 <= 11, true, 'Smaller-equal yes'); + unittest_assertequals(13 <= 12, false, 'Smaller-equal no'); + unittest_assertequals(14 >= 14, true, 'Greater-equal yes'); + unittest_assertequals(15 >= 16, false, 'Greater-equal no'); +} + +/// Describe this function... +void test_and() { + unittest_assertequals(true && true, true, 'And true/true'); + unittest_assertequals(false && true, false, 'And false/true'); + unittest_assertequals(true && false, false, 'And true/false'); + unittest_assertequals(false && false, false, 'And false/false'); +} + +/// Describe this function... +void test_or() { + unittest_assertequals(true || true, true, 'Or true/true'); + unittest_assertequals(false || true, true, 'Or false/true'); + unittest_assertequals(true || false, true, 'Or true/false'); + unittest_assertequals(false || false, false, 'Or false/false'); +} + +/// Describe this function... +void test_ternary() { + unittest_assertequals(true ? 42 : 99, 42, 'if true'); + unittest_assertequals(false ? 42 : 99, 99, 'if true'); +} + +/// Describe this function... +void test_foreach() { + log = ''; + for (var x in ['a', 'b', 'c']) { + log = [log, x].join(); + } + unittest_assertequals(log, 'abc', 'for loop'); +} + +/// Describe this function... +void test_repeat() { + count = 0; + for (int count2 = 0; count2 < 10; count2++) { + count = (count is num ? count : 0) + 1; + } + unittest_assertequals(count, 10, 'repeat 10'); +} + +/// Describe this function... +void test_while() { + while (false) { + unittest_fail('while 0'); + } + while (!true) { + unittest_fail('until 0'); + } + count = 1; + while (count != 10) { + count = (count is num ? count : 0) + 1; + } + unittest_assertequals(count, 10, 'while 10'); + count = 1; + while (!(count == 10)) { + count = (count is num ? count : 0) + 1; + } + unittest_assertequals(count, 10, 'until 10'); +} + +/// Describe this function... +void test_repeat_ext() { + count = 0; + for (int count3 = 0; count3 < 10; count3++) { + count = (count is num ? count : 0) + 1; + } + unittest_assertequals(count, 10, 'repeat 10'); +} + +/// Describe this function... +void test_count_by() { + log = ''; + for (x = 1; x <= 8; x += 2) { + log = [log, x].join(); + } + unittest_assertequals(log, '1357', 'count up ints'); + log = ''; + for (x = 8; x >= 1; x -= 2) { + log = [log, x].join(); + } + unittest_assertequals(log, '8642', 'count down ints'); + loglist = []; + for (x = 1; x <= 8; x += 1.5) { + loglist.add(x); + } + unittest_assertequals(loglist, [1, 2.5, 4, 5.5, 7], 'count with floats'); + loglist = []; + var x_start = 1 + 0; + var x_end = 8 + 0; + num x_inc = (1 - 2).abs(); + if (x_start > x_end) { + x_inc = -x_inc; + } + for (x = x_start; x_inc >= 0 ? x <= x_end : x >= x_end; x += x_inc) { + loglist.add(x); + } + unittest_assertequals(loglist, [1, 2, 3, 4, 5, 6, 7, 8], 'count up non-trivial ints'); + loglist = []; + var x_start2 = 8 + 0; + var x_end2 = 1 + 0; + num x_inc2 = 2; + if (x_start2 > x_end2) { + x_inc2 = -x_inc2; + } + for (x = x_start2; x_inc2 >= 0 ? x <= x_end2 : x >= x_end2; x += x_inc2) { + loglist.add(x); + } + unittest_assertequals(loglist, [8, 6, 4, 2], 'count down non-trivial ints'); + loglist = []; + var x_start3 = 5 + 0.5; + var x_end3 = 1 + 0; + num x_inc3 = (1 + 0).abs(); + if (x_start3 > x_end3) { + x_inc3 = -x_inc3; + } + for (x = x_start3; x_inc3 >= 0 ? x <= x_end3 : x >= x_end3; x += x_inc3) { + loglist.add(x); + } + unittest_assertequals(loglist, [5.5, 4.5, 3.5, 2.5, 1.5], 'count with floats'); +} + +/// Describe this function... +void test_count_loops() { + log = ''; + for (x = 1; x <= 8; x++) { + log = [log, x].join(); + } + unittest_assertequals(log, '12345678', 'count up'); + log = ''; + for (x = 8; x >= 1; x--) { + log = [log, x].join(); + } + unittest_assertequals(log, '87654321', 'count down'); + loglist = []; + var x_start4 = 1 + 0; + var x_end4 = 4 + 0; + num x_inc4 = 1; + if (x_start4 > x_end4) { + x_inc4 = -x_inc4; + } + for (x = x_start4; x_inc4 >= 0 ? x <= x_end4 : x >= x_end4; x += x_inc4) { + loglist.add(x); + } + unittest_assertequals(loglist, [1, 2, 3, 4], 'count up non-trivial'); + loglist = []; + var x_start5 = 3 + 1; + var x_end5 = 1 + 0; + num x_inc5 = 1; + if (x_start5 > x_end5) { + x_inc5 = -x_inc5; + } + for (x = x_start5; x_inc5 >= 0 ? x <= x_end5 : x >= x_end5; x += x_inc5) { + loglist.add(x); + } + unittest_assertequals(loglist, [4, 3, 2, 1], 'count down non-trivial'); +} + +/// Describe this function... +void test_continue() { + log = ''; + count = 0; + while (count != 8) { + count = (count is num ? count : 0) + 1; + if (count == 5) { + continue; + } + log = [log, count].join(); + } + unittest_assertequals(log, '1234678', 'while continue'); + log = ''; + count = 0; + while (!(count == 8)) { + count = (count is num ? count : 0) + 1; + if (count == 5) { + continue; + } + log = [log, count].join(); + } + unittest_assertequals(log, '1234678', 'until continue'); + log = ''; + for (x = 1; x <= 8; x++) { + if (x == 5) { + continue; + } + log = [log, x].join(); + } + unittest_assertequals(log, '1234678', 'count continue'); + log = ''; + for (var x in ['a', 'b', 'c', 'd']) { + if (x == 'c') { + continue; + } + log = [log, x].join(); + } + unittest_assertequals(log, 'abd', 'for continue'); +} + +/// Describe this function... +void test_break() { + count = 1; + while (count != 10) { + if (count == 5) { + break; + } + count = (count is num ? count : 0) + 1; + } + unittest_assertequals(count, 5, 'while break'); + count = 1; + while (!(count == 10)) { + if (count == 5) { + break; + } + count = (count is num ? count : 0) + 1; + } + unittest_assertequals(count, 5, 'until break'); + log = ''; + for (x = 1; x <= 8; x++) { + if (x == 5) { + break; + } + log = [log, x].join(); + } + unittest_assertequals(log, '1234', 'count break'); + log = ''; + for (var x in ['a', 'b', 'c', 'd']) { + if (x == 'c') { + break; + } + log = [log, x].join(); + } + unittest_assertequals(log, 'ab', 'for break'); +} + +/// Tests the "single" block. +void test_single() { + unittest_assertequals(Math.sqrt(25), 5, 'sqrt'); + unittest_assertequals((-25).abs(), 25, 'abs'); + unittest_assertequals(-(-25), 25, 'negate'); + unittest_assertequals(Math.log(1), 0, 'ln'); + unittest_assertequals(Math.log(100) / Math.log(10), 2, 'log10'); + unittest_assertequals(Math.exp(2), 7.38905609893065, 'exp'); + unittest_assertequals(Math.pow(10,2), 100, 'power10'); +} + +/// Tests the "arithmetic" block for all operations and checks +/// parenthesis are properly generated for different orders. +void test_arithmetic() { + unittest_assertequals(1 + 2, 3, 'add'); + unittest_assertequals(1 - 2, -1, 'subtract'); + unittest_assertequals(1 - (0 + 2), -1, 'subtract order with add'); + unittest_assertequals(1 - (0 - 2), 3, 'subtract order with subtract'); + unittest_assertequals(4 * 2.5, 10, 'multiply'); + unittest_assertequals(4 * (0 + 2.5), 10, 'multiply order'); + unittest_assertequals(8.2 / -5, -1.64, 'divide'); + unittest_assertequals(8.2 / (0 + -5), -1.64, 'divide order'); + unittest_assertequals(Math.pow(10, 4), 10000, 'power'); + unittest_assertequals(Math.pow(10, 0 + 4), 10000, 'power order'); +} + +/// Tests the "trig" block. +void test_trig() { + unittest_assertequals(Math.sin(90 / 180 * Math.pi), 1, 'sin'); + unittest_assertequals(Math.cos(180 / 180 * Math.pi), -1, 'cos'); + unittest_assertequals(Math.tan(0 / 180 * Math.pi), 0, 'tan'); + unittest_assertequals(Math.asin(-1) / Math.pi * 180, -90, 'asin'); + unittest_assertequals(Math.acos(1) / Math.pi * 180, 0, 'acos'); + unittest_assertequals(Math.atan(1) / Math.pi * 180, 45, 'atan'); +} + +/// Tests the "constant" blocks. +void test_constant() { + unittest_assertequals((Math.pi * 1000).floor(), 3141, 'const pi'); + unittest_assertequals((Math.e * 1000).floor(), 2718, 'const e'); + unittest_assertequals((((1 + Math.sqrt(5)) / 2) * 1000).floor(), 1618, 'const golden'); + unittest_assertequals((Math.sqrt2 * 1000).floor(), 1414, 'const sqrt 2'); + unittest_assertequals((Math.sqrt1_2 * 1000).floor(), 707, 'const sqrt 0.5'); + unittest_assertequals(9999 < double.infinity, true, 'const infinity'); +} + +bool math_isPrime(n) { + // https://en.wikipedia.org/wiki/Primality_test#Naive_methods + if (n == 2 || n == 3) { + return true; + } + // False if n is null, negative, is 1, or not whole. + // And false if n is divisible by 2 or 3. + if (n == null || n <= 1 || n % 1 != 0 || n % 2 == 0 || n % 3 == 0) { + return false; + } + // Check all the numbers of form 6k +/- 1, up to sqrt(n). + for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) { + if (n % (x - 1) == 0 || n % (x + 1) == 0) { + return false; + } + } + return true; +} + +/// Tests the "number property" blocks. +void test_number_properties() { + unittest_assertequals(42 % 2 == 0, true, 'even'); + unittest_assertequals(42.1 % 2 == 1, false, 'odd'); + unittest_assertequals(math_isPrime(5), true, 'prime 5'); + unittest_assertequals(math_isPrime(25), false, 'prime 25'); + unittest_assertequals(math_isPrime(-31.1), false, 'prime negative'); + unittest_assertequals(Math.pi % 1 == 0, false, 'whole'); + unittest_assertequals(double.infinity > 0, true, 'positive'); + unittest_assertequals(-42 < 0, true, 'negative'); + unittest_assertequals(42 % 2 == 0, true, 'divisible'); +} + +/// Tests the "round" block. +void test_round() { + unittest_assertequals(42.42.round(), 42, 'round'); + unittest_assertequals((-42.42).ceil(), -42, 'round up'); + unittest_assertequals(42.42.floor(), 42, 'round down'); +} + +/// Tests the "change" block. +void test_change() { + varToChange = 100; + varToChange = (varToChange is num ? varToChange : 0) + 42; + unittest_assertequals(varToChange, 142, 'change'); +} + +num math_sum(List myList) { + num sumVal = 0; + myList.forEach((num entry) {sumVal += entry;}); + return sumVal; +} + +num math_min(List myList) { + if (myList.isEmpty) return null; + num minVal = myList[0]; + myList.forEach((num entry) {minVal = Math.min(minVal, entry);}); + return minVal; +} + +num math_max(List myList) { + if (myList.isEmpty) return null; + num maxVal = myList[0]; + myList.forEach((num entry) {maxVal = Math.max(maxVal, entry);}); + return maxVal; +} + +num math_mean(List myList) { + // First filter list for numbers only. + List localList = new List.from(myList); + localList.removeWhere((a) => a is! num); + if (localList.isEmpty) return null; + num sumVal = 0; + localList.forEach((var entry) {sumVal += entry;}); + return sumVal / localList.length; +} + +num math_median(List myList) { + // First filter list for numbers only, then sort, then return middle value + // or the average of two middle values if list has an even number of elements. + List localList = new List.from(myList); + localList.removeWhere((a) => a is! num); + if (localList.isEmpty) return null; + localList.sort((a, b) => (a - b)); + int index = localList.length ~/ 2; + if (localList.length % 2 == 1) { + return localList[index]; + } else { + return (localList[index - 1] + localList[index]) / 2; + } +} + +List math_modes(List values) { + List modes = []; + List counts = []; + int maxCount = 0; + for (int i = 0; i < values.length; i++) { + var value = values[i]; + bool found = false; + int thisCount; + for (int j = 0; j < counts.length; j++) { + if (counts[j][0] == value) { + thisCount = ++counts[j][1]; + found = true; + break; + } + } + if (!found) { + counts.add([value, 1]); + thisCount = 1; + } + maxCount = Math.max(thisCount, maxCount); + } + for (int j = 0; j < counts.length; j++) { + if (counts[j][1] == maxCount) { + modes.add(counts[j][0]); + } + } + return modes; +} + +num math_standard_deviation(List myList) { + // First filter list for numbers only. + List numbers = new List.from(myList); + numbers.removeWhere((a) => a is! num); + if (numbers.isEmpty) return null; + num n = numbers.length; + num sum = 0; + numbers.forEach((x) => sum += x); + num mean = sum / n; + num sumSquare = 0; + numbers.forEach((x) => sumSquare += Math.pow(x - mean, 2)); + return Math.sqrt(sumSquare / n); +} + +dynamic math_random_item(List myList) { + int x = new Math.Random().nextInt(myList.length); + return myList[x]; +} + +/// Tests the "list operation" blocks. +void test_operations_on_list() { + unittest_assertequals(math_sum([3, 4, 5]), 12, 'sum'); + unittest_assertequals(math_min([3, 4, 5]), 3, 'min'); + unittest_assertequals(math_max([3, 4, 5]), 5, 'max'); + unittest_assertequals(math_mean([3, 4, 5]), 4, 'average'); + unittest_assertequals(math_median([3, 4, 5, 1]), 3.5, 'median'); + unittest_assertequals(math_modes([3, 4, 3]), [3], 'modes'); + unittest_assertequals(math_modes([3, 4, 3, 1, 4]), [3, 4], 'modes multiple'); + unittest_assertequals(math_standard_deviation([3, 3, 3]), 0, 'standard dev'); + unittest_assertequals([3, 4, 5].indexOf(math_random_item([3, 4, 5])) + 1 > 0, true, 'random'); +} + +/// Tests the "mod" block. +void test_mod() { + unittest_assertequals(42 % 5, 2, 'mod'); +} + +/// Tests the "constrain" block. +void test_constraint() { + unittest_assertequals(Math.min(Math.max(100, 0), 42), 42, 'constraint'); +} + +int math_random_int(num a, num b) { + if (a > b) { + // Swap a and b to ensure a is smaller. + num c = a; + a = b; + b = c; + } + return new Math.Random().nextInt(b - a + 1) + a; +} + +/// Tests the "random integer" block. +void test_random_integer() { + rand = math_random_int(5, 10); + unittest_assertequals(rand >= 5 && rand <= 10, true, 'randRange'); + unittest_assertequals(rand % 1 == 0, true, 'randInteger'); +} + +/// Tests the "random fraction" block. +void test_random_fraction() { + rand = new Math.Random().nextDouble(); + unittest_assertequals(rand >= 0 && rand <= 1, true, 'randFloat'); +} + +/// Describe this function... +void test_atan2() { + unittest_assertequals(Math.atan2(5, -5) / Math.pi * 180, 135, 'atan2'); + unittest_assertequals(Math.atan2(-12, 0) / Math.pi * 180, -90, 'atan2'); +} + +/// Checks that the number of calls is one in order +/// to confirm that a function was only called once. +void check_number_of_calls(test_name) { + test_name = [test_name, 'number of calls'].join(); + unittest_assertequals(number_of_calls, 1, test_name); +} + +/// Tests the "create text with" block with varying number of inputs. +void test_create_text() { + unittest_assertequals('', '', 'no text'); + unittest_assertequals('Hello'.toString(), 'Hello', 'create single'); + unittest_assertequals((-1).toString(), '-1', 'create single number'); + unittest_assertequals(['K',9].join(), 'K9', 'create double text'); + unittest_assertequals([4,2].join(), '42', 'create double text numbers'); + unittest_assertequals([1,2,3].join(), '123', 'create triple'); + unittest_assertequals([1,true ? 0 : null,'M'].join(), '10M', 'create order'); +} + +/// Creates an empty string for use with the empty test. +dynamic get_empty() { + return ''; +} + +/// Tests the "is empty" block". +void test_empty_text() { + unittest_assertequals('Google'.isEmpty, false, 'not empty'); + unittest_assertequals(''.isEmpty, true, 'empty'); + unittest_assertequals((get_empty()).isEmpty, true, 'empty complex'); + unittest_assertequals((true ? '' : null).isEmpty, true, 'empty order'); +} + +/// Tests the "length" block. +void test_text_length() { + unittest_assertequals(''.length, 0, 'zero length'); + unittest_assertequals('Google'.length, 6, 'non-zero length'); + unittest_assertequals((true ? 'car' : null).length, 3, 'length order'); +} + +/// Tests the "append text" block with different types of parameters. +void test_append() { + item = 'Miserable'; + item = [item, 'Failure'].join(); + unittest_assertequals(item, 'MiserableFailure', 'append text'); + item = 12; + item = [item, 34].join(); + unittest_assertequals(item, '1234', 'append number'); + item = 'Something '; + item = [item, true ? 'Positive' : null].join(); + unittest_assertequals(item, 'Something Positive', 'append order'); +} + +/// Tests the "find" block with a variable. +void test_find_text_simple() { + text = 'Banana'; + unittest_assertequals(text.indexOf('an') + 1, 2, 'find first simple'); + unittest_assertequals(text.lastIndexOf('an') + 1, 4, 'find last simple'); + unittest_assertequals(text.indexOf('Peel') + 1, 0, 'find none simple'); +} + +/// Creates a string for use with the find test. +dynamic get_fruit() { + number_of_calls = (number_of_calls is num ? number_of_calls : 0) + 1; + return 'Banana'; +} + +/// Tests the "find" block with a function call. +void test_find_text_complex() { + number_of_calls = 0; + unittest_assertequals((get_fruit()).indexOf('an') + 1, 2, 'find first complex'); + check_number_of_calls('find first complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_fruit() : null).indexOf('an') + 1, 2, 'find first order complex'); + check_number_of_calls('find first order complex'); + number_of_calls = 0; + unittest_assertequals((get_fruit()).lastIndexOf('an') + 1, 4, 'find last complex'); + check_number_of_calls('find last complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_fruit() : null).lastIndexOf('an') + 1, 4, 'find last order complex'); + check_number_of_calls('find last order complex'); + number_of_calls = 0; + unittest_assertequals((get_fruit()).indexOf('Peel') + 1, 0, 'find none complex'); + check_number_of_calls('find none complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_fruit() : null).indexOf('Peel') + 1, 0, 'find none order complex'); + check_number_of_calls('find none order complex'); +} + +String text_get_from_end(String text, num x) { + return text[text.length - x]; +} + +String text_random_letter(String text) { + int x = new Math.Random().nextInt(text.length); + return text[x]; +} + +/// Tests the "get letter" block with a variable. +void test_get_text_simple() { + text = 'Blockly'; + unittest_assertequals(text[0], 'B', 'get first simple'); + unittest_assertequals(text_get_from_end(text, 1), 'y', 'get last simple'); + unittest_assertequals(text.indexOf(text_random_letter(text)) + 1 > 0, true, 'get random simple'); + unittest_assertequals(text[2], 'o', 'get # simple'); + unittest_assertequals(text[((true ? 3 : null) - 1)], 'o', 'get # order simple'); + unittest_assertequals(text_get_from_end(text, 3), 'k', 'get #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(text_get_from_end(text, 0 + 3), 'k', 'get #-end order simple'); +} + +/// Creates a string for use with the get test. +dynamic get_Blockly() { + number_of_calls = (number_of_calls is num ? number_of_calls : 0) + 1; + return 'Blockly'; +} + +/// Tests the "get letter" block with a function call. +void test_get_text_complex() { + text = 'Blockly'; + number_of_calls = 0; + unittest_assertequals((get_Blockly())[0], 'B', 'get first complex'); + check_number_of_calls('get first complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_Blockly() : null)[0], 'B', 'get first order complex'); + check_number_of_calls('get first order complex'); + number_of_calls = 0; + unittest_assertequals(text_get_from_end((get_Blockly()), 1), 'y', 'get last complex'); + check_number_of_calls('get last complex'); + number_of_calls = 0; + unittest_assertequals(text_get_from_end((true ? get_Blockly() : null), 1), 'y', 'get last order complex'); + check_number_of_calls('get last order complex'); + number_of_calls = 0; + unittest_assertequals(text.indexOf(text_random_letter((get_Blockly()))) + 1 > 0, true, 'get random complex'); + check_number_of_calls('get random complex'); + number_of_calls = 0; + unittest_assertequals(text.indexOf(text_random_letter((true ? get_Blockly() : null))) + 1 > 0, true, 'get random order complex'); + check_number_of_calls('get random order complex'); + number_of_calls = 0; + unittest_assertequals((get_Blockly())[2], 'o', 'get # complex'); + check_number_of_calls('get # complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_Blockly() : null)[((true ? 3 : null) - 1)], 'o', 'get # order complex'); + check_number_of_calls('get # order complex'); + number_of_calls = 0; + unittest_assertequals(text_get_from_end((get_Blockly()), 3), 'k', 'get #-end complex'); + check_number_of_calls('get #-end complex'); + number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(text_get_from_end((true ? get_Blockly() : null), 0 + 3), 'k', 'get #-end order complex'); + check_number_of_calls('get #-end order complex'); +} + +/// Creates a string for use with the substring test. +dynamic get_numbers() { + number_of_calls = (number_of_calls is num ? number_of_calls : 0) + 1; + return '123456789'; +} + +/// Tests the "get substring" block with a variable. +void test_substring_simple() { + text = '123456789'; + unittest_assertequals(text.substring(1, 3), '23', 'substring # simple'); + unittest_assertequals(text.substring(((true ? 2 : null) - 1), true ? 3 : null), '23', 'substring # simple order'); + unittest_assertequals(text.substring(text.length - 3, text.length - 1), '78', 'substring #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(text.substring(text.length - (0 + 3), text.length - ((0 + 2) - 1)), '78', 'substring #-end simple order'); + unittest_assertequals(text, text, 'substring first-last simple'); + unittest_assertequals(text.substring(1, text.length - 1), '2345678', 'substring # #-end simple'); + unittest_assertequals(text.substring(text.length - 7, 4), '34', 'substring #-end # simple'); + unittest_assertequals(text.substring(0, 4), '1234', 'substring first # simple'); + unittest_assertequals(text.substring(0, text.length - 1), '12345678', 'substring first #-end simple'); + unittest_assertequals(text.substring(6), '789', 'substring # last simple'); + unittest_assertequals(text.substring(text.length - 3), '789', 'substring #-end last simple'); + unittest_assertequals(text.substring(0, text.length - 0), '123456789', 'substring all with # #-end simple'); + unittest_assertequals(text.substring(text.length - 9, 9), '123456789', 'substring all with #-end # simple'); + // Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + unittest_assertequals(text.substring(((0 + 1) - 1), text.length - ((0 + 1) - 1)), '123456789', 'substring all with # #-end math simple'); +} + +String text_get_substring(String text, String where1, num at1, String where2, num at2) { + int getAt(String where, num at) { + if (where == 'FROM_END') { + at = text.length - 1 - at; + } else if (where == 'FIRST') { + at = 0; + } else if (where == 'LAST') { + at = text.length - 1; + } else if (where != 'FROM_START') { + throw 'Unhandled option (text_getSubstring).'; + } + return at; + } + at1 = getAt(where1, at1); + at2 = getAt(where2, at2) + 1; + return text.substring(at1, at2); +} + +/// Tests the "get substring" block with a function call. +void test_substring_complex() { + number_of_calls = 0; + unittest_assertequals((get_numbers()).substring(1, 3), '23', 'substring # complex'); + check_number_of_calls('substring # complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_numbers() : null).substring(((true ? 2 : null) - 1), true ? 3 : null), '23', 'substring # complex order'); + check_number_of_calls('substring # complex order'); + number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(text_get_substring((get_numbers()), 'FROM_END', 2, 'FROM_END', 1), '78', 'substring #-end complex'); + check_number_of_calls('substring #-end complex'); + number_of_calls = 0; + unittest_assertequals(text_get_substring((true ? get_numbers() : null), 'FROM_END', ((0 + 3) - 1), 'FROM_END', ((0 + 2) - 1)), '78', 'substring #-end order order'); + check_number_of_calls('substring #-end order order'); + number_of_calls = 0; + unittest_assertequals((get_numbers()), text, 'substring first-last'); + check_number_of_calls('substring first-last'); + number_of_calls = 0; + unittest_assertequals(text_get_substring((get_numbers()), 'FROM_START', 1, 'FROM_END', 1), '2345678', 'substring # #-end complex'); + check_number_of_calls('substring # #-end complex'); + number_of_calls = 0; + unittest_assertequals(text_get_substring((get_numbers()), 'FROM_END', 6, 'FROM_START', 3), '34', 'substring #-end # complex'); + check_number_of_calls('substring #-end # complex'); + number_of_calls = 0; + unittest_assertequals((get_numbers()).substring(0, 4), '1234', 'substring first # complex'); + check_number_of_calls('substring first # complex'); + number_of_calls = 0; + unittest_assertequals(text_get_substring((get_numbers()), 'FIRST', 0, 'FROM_END', 1), '12345678', 'substring first #-end complex'); + check_number_of_calls('substring first #-end complex'); + number_of_calls = 0; + unittest_assertequals(text_get_substring((get_numbers()), 'FROM_START', 6, 'LAST', 0), '789', 'substring # last complex'); + check_number_of_calls('substring # last complex'); + number_of_calls = 0; + unittest_assertequals(text_get_substring((get_numbers()), 'FROM_END', 2, 'LAST', 0), '789', 'substring #-end last complex'); + check_number_of_calls('substring #-end last complex'); + number_of_calls = 0; + unittest_assertequals(text_get_substring((get_numbers()), 'FROM_START', 0, 'FROM_END', 0), '123456789', 'substring all with # #-end complex'); + check_number_of_calls('substring all with # #-end complex'); + number_of_calls = 0; + unittest_assertequals(text_get_substring((get_numbers()), 'FROM_END', 8, 'FROM_START', 8), '123456789', 'substring all with #-end # complex'); + check_number_of_calls('substring all with #-end # complex'); + number_of_calls = 0; + // Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + unittest_assertequals(text_get_substring((get_numbers()), 'FROM_START', ((0 + 1) - 1), 'FROM_END', ((0 + 1) - 1)), '123456789', 'substring all with # #-end math complex'); + check_number_of_calls('substring all with # #-end math complex'); +} + +String text_toTitleCase(String str) { + RegExp exp = new RegExp(r'\b'); + List list = str.split(exp); + final title = new StringBuffer(); + for (String part in list) { + if (part.length > 0) { + title.write(part[0].toUpperCase()); + if (part.length > 0) { + title.write(part.substring(1).toLowerCase()); + } + } + } + return title.toString(); +} + +/// Tests the "change casing" block. +void test_case() { + text = 'Hello World'; + unittest_assertequals(text.toUpperCase(), 'HELLO WORLD', 'uppercase'); + unittest_assertequals((true ? text : null).toUpperCase(), 'HELLO WORLD', 'uppercase order'); + text = 'Hello World'; + unittest_assertequals(text.toLowerCase(), 'hello world', 'lowercase'); + unittest_assertequals((true ? text : null).toLowerCase(), 'hello world', 'lowercase order'); + text = 'heLLo WorlD'; + unittest_assertequals(text_toTitleCase(text), 'Hello World', 'titlecase'); + unittest_assertequals(text_toTitleCase(true ? text : null), 'Hello World', 'titlecase order'); +} + +/// Tests the "trim" block. +void test_trim() { + text = ' abc def '; + unittest_assertequals(text.trim(), 'abc def', 'trim both'); + unittest_assertequals((true ? text : null).trim(), 'abc def', 'trim both order'); + unittest_assertequals(text.replaceFirst(new RegExp(r'^\s+'), ''), 'abc def ', 'trim left'); + unittest_assertequals((true ? text : null).replaceFirst(new RegExp(r'^\s+'), ''), 'abc def ', 'trim left order'); + unittest_assertequals(text.replaceFirst(new RegExp(r'\s+$'), ''), ' abc def', 'trim right'); + unittest_assertequals((true ? text : null).replaceFirst(new RegExp(r'\s+$'), ''), ' abc def', 'trim right order'); +} + +int text_count(String haystack, String needle) { + if (needle.length == 0) { + return haystack.length + 1; + } + int index = 0; + int count = 0; + while (index != -1) { + index = haystack.indexOf(needle, index); + if (index != -1) { + count++; + index += needle.length; + } + } + return count; +} + +/// Tests the "trim" block. +void test_count_text() { + text = 'woolloomooloo'; + unittest_assertequals(text_count(text, 'o'), 8, 'len 1'); + unittest_assertequals(text_count(text, 'oo'), 4, 'len 2'); + unittest_assertequals(text_count(text, 'loo'), 2, 'len 3'); + unittest_assertequals(text_count(text, 'wool'), 1, 'start'); + unittest_assertequals(text_count(text, 'chicken'), 0, 'missing'); + unittest_assertequals(text_count(text, ''), 14, 'empty needle'); + unittest_assertequals(text_count('', 'chicken'), 0, 'empty source'); +} + +/// Tests the "trim" block. +void test_text_reverse() { + unittest_assertequals(new String.fromCharCodes(''.runes.toList().reversed), '', 'empty string'); + unittest_assertequals(new String.fromCharCodes('a'.runes.toList().reversed), 'a', 'len 1'); + unittest_assertequals(new String.fromCharCodes('ab'.runes.toList().reversed), 'ba', 'len 2'); + unittest_assertequals(new String.fromCharCodes('woolloomooloo'.runes.toList().reversed), 'ooloomoolloow', 'longer'); +} + +/// Tests the "trim" block. +void test_replace() { + unittest_assertequals('woolloomooloo'.replaceAll('oo', '123'), 'w123ll123m123l123', 'replace all instances 1'); + unittest_assertequals('woolloomooloo'.replaceAll('.oo', 'X'), 'woolloomooloo', 'literal string replacement'); + unittest_assertequals('woolloomooloo'.replaceAll('abc', 'X'), 'woolloomooloo', 'not found'); + unittest_assertequals('woolloomooloo'.replaceAll('o', ''), 'wllml', 'empty replacement 1'); + unittest_assertequals('aaaaa'.replaceAll('aaaaa', ''), '', 'empty replacement 2'); + unittest_assertequals('aaaaa'.replaceAll('a', ''), '', 'empty replacement 3'); + unittest_assertequals(''.replaceAll('a', 'chicken'), '', 'empty source'); +} + +/// Checks that the number of calls is one in order +/// to confirm that a function was only called once. +void check_number_of_calls2(test_name) { + test_name = [test_name, 'number of calls'].join(); + unittest_assertequals(number_of_calls, 1, test_name); +} + +/// Tests the "create list with" and "create empty list" blocks. +void test_create_lists() { + unittest_assertequals([], [], 'create empty'); + unittest_assertequals([true, 'love'], [true, 'love'], 'create items'); + unittest_assertequals(new List.filled(3, 'Eject'), ['Eject', 'Eject', 'Eject'], 'create repeated'); + unittest_assertequals(new List.filled(0 + 3, 'Eject'), ['Eject', 'Eject', 'Eject'], 'create repeated order'); +} + +/// Creates an empty list for use with the empty test. +dynamic get_empty_list() { + return []; +} + +/// Tests the "is empty" block. +void test_lists_empty() { + unittest_assertequals([0].isEmpty, false, 'not empty'); + unittest_assertequals([].isEmpty, true, 'empty'); + unittest_assertequals((get_empty_list()).isEmpty, true, 'empty complex'); + unittest_assertequals((true ? [] : null).isEmpty, true, 'empty order'); +} + +/// Tests the "length" block. +void test_lists_length() { + unittest_assertequals([].length, 0, 'zero length'); + unittest_assertequals(['cat'].length, 1, 'one length'); + unittest_assertequals(['cat', true, []].length, 3, 'three length'); + unittest_assertequals((true ? ['cat', true] : null).length, 2, 'two length order'); +} + +/// Tests the "find" block with a variable. +void test_find_lists_simple() { + list = ['Alice', 'Eve', 'Bob', 'Eve']; + unittest_assertequals(list.indexOf('Eve') + 1, 2, 'find first simple'); + unittest_assertequals(list.lastIndexOf('Eve') + 1, 4, 'find last simple'); + unittest_assertequals(list.indexOf('Dave') + 1, 0, 'find none simple'); +} + +/// Creates a list for use with the find test. +dynamic get_names() { + number_of_calls = (number_of_calls is num ? number_of_calls : 0) + 1; + return ['Alice', 'Eve', 'Bob', 'Eve']; +} + +/// Tests the "find" block with a function call. +void test_find_lists_complex() { + number_of_calls = 0; + unittest_assertequals((get_names()).indexOf('Eve') + 1, 2, 'find first complex'); + check_number_of_calls('find first complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_names() : null).indexOf('Eve') + 1, 2, 'find first order complex'); + check_number_of_calls('find first order complex'); + number_of_calls = 0; + unittest_assertequals((get_names()).lastIndexOf('Eve') + 1, 4, 'find last complex'); + check_number_of_calls('find last complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_names() : null).lastIndexOf('Eve') + 1, 4, 'find last order complex'); + check_number_of_calls('find last order complex'); + number_of_calls = 0; + unittest_assertequals((get_names()).indexOf('Dave') + 1, 0, 'find none complex'); + check_number_of_calls('find none complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_names() : null).indexOf('Dave') + 1, 0, 'find none order complex'); + check_number_of_calls('find none order complex'); +} + +dynamic lists_get_random_item(List my_list) { + int x = new Math.Random().nextInt(my_list.length); + return my_list[x]; +} + +/// Tests the "get" block with a variable. +void test_get_lists_simple() { + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals(list.first, 'Kirk', 'get first simple'); + unittest_assertequals(list.last, 'McCoy', 'get last simple'); + unittest_assertequals(list.indexOf(lists_get_random_item(list)) + 1 > 0, true, 'get random simple'); + unittest_assertequals(list[1], 'Spock', 'get # simple'); + unittest_assertequals(list[((true ? 2 : null) - 1)], 'Spock', 'get # order simple'); + unittest_assertequals(list[list.length - 3], 'Kirk', 'get #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(list[list.length - (0 + 3)], 'Kirk', 'get #-end order simple'); +} + +/// Creates a list for use with the get test. +dynamic get_star_wars() { + number_of_calls = (number_of_calls is num ? number_of_calls : 0) + 1; + return ['Kirk', 'Spock', 'McCoy']; +} + +dynamic lists_get_from_end(List my_list, num x) { + x = my_list.length - x; + return my_list[x]; +} + +/// Tests the "get" block with a function call. +void test_get_lists_complex() { + list = ['Kirk', 'Spock', 'McCoy']; + number_of_calls = 0; + unittest_assertequals((get_star_wars()).first, 'Kirk', 'get first complex'); + check_number_of_calls('get first complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_star_wars() : null).first, 'Kirk', 'get first order complex'); + check_number_of_calls('get first order complex'); + number_of_calls = 0; + unittest_assertequals((get_star_wars()).last, 'McCoy', 'get last complex'); + check_number_of_calls('get last complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_star_wars() : null).last, 'McCoy', 'get last order complex'); + check_number_of_calls('get last order complex'); + number_of_calls = 0; + unittest_assertequals(list.indexOf(lists_get_random_item(get_star_wars())) + 1 > 0, true, 'get random complex'); + check_number_of_calls('get random complex'); + number_of_calls = 0; + unittest_assertequals(list.indexOf(lists_get_random_item(true ? get_star_wars() : null)) + 1 > 0, true, 'get random order complex'); + check_number_of_calls('get random order complex'); + number_of_calls = 0; + unittest_assertequals((get_star_wars())[1], 'Spock', 'get # complex'); + check_number_of_calls('get # complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_star_wars() : null)[((true ? 2 : null) - 1)], 'Spock', 'get # order complex'); + check_number_of_calls('get # order complex'); + number_of_calls = 0; + unittest_assertequals(lists_get_from_end(get_star_wars(), 3), 'Kirk', 'get #-end complex'); + check_number_of_calls('get #-end complex'); + number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(lists_get_from_end(true ? get_star_wars() : null, 0 + 3), 'Kirk', 'get #-end order complex'); + check_number_of_calls('get #-end order complex'); +} + +dynamic lists_remove_random_item(List my_list) { + int x = new Math.Random().nextInt(my_list.length); + return my_list.removeAt(x); +} + +dynamic lists_remove_from_end(List my_list, num x) { + x = my_list.length - x; + return my_list.removeAt(x); +} + +/// Tests the "get and remove" block. +void test_getRemove() { + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals(list.removeAt(0), 'Kirk', 'getremove first'); + unittest_assertequals(list, ['Spock', 'McCoy'], 'getremove first list'); + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals((true ? list : null).removeAt(0), 'Kirk', 'getremove first order'); + unittest_assertequals(list, ['Spock', 'McCoy'], 'getremove first order list'); + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals(list.removeLast(), 'McCoy', 'getremove last'); + unittest_assertequals(list, ['Kirk', 'Spock'], 'getremove last list'); + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals((true ? list : null).removeLast(), 'McCoy', 'getremove last order'); + unittest_assertequals(list, ['Kirk', 'Spock'], 'getremove last order list'); + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals(list.indexOf(lists_remove_random_item(list)) + 1 == 0, true, 'getremove random'); + unittest_assertequals(list.length, 2, 'getremove random list'); + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals(list.indexOf(lists_remove_random_item(true ? list : null)) + 1 == 0, true, 'getremove random order'); + unittest_assertequals(list.length, 2, 'getremove random order list'); + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals(list.removeAt(1), 'Spock', 'getremove #'); + unittest_assertequals(list, ['Kirk', 'McCoy'], 'getremove # list'); + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals((true ? list : null).removeAt(((true ? 2 : null) - 1)), 'Spock', 'getremove # order'); + unittest_assertequals(list, ['Kirk', 'McCoy'], 'getremove # order list'); + list = ['Kirk', 'Spock', 'McCoy']; + unittest_assertequals(list.removeAt(list.length - 3), 'Kirk', 'getremove #-end'); + unittest_assertequals(list, ['Spock', 'McCoy'], 'getremove #-end list'); + list = ['Kirk', 'Spock', 'McCoy']; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(lists_remove_from_end(true ? list : null, 0 + 3), 'Kirk', 'getremove #-end order'); + unittest_assertequals(list, ['Spock', 'McCoy'], 'getremove #-end order list'); +} + +/// Tests the "remove" block. +void test_remove() { + list = ['Kirk', 'Spock', 'McCoy']; + list.removeAt(0); + unittest_assertequals(list, ['Spock', 'McCoy'], 'remove first list'); + list = ['Kirk', 'Spock', 'McCoy']; + (true ? list : null).removeAt(0); + unittest_assertequals(list, ['Spock', 'McCoy'], 'remove first order list'); + list = ['Kirk', 'Spock', 'McCoy']; + list.removeLast(); + unittest_assertequals(list, ['Kirk', 'Spock'], 'remove last list'); + list = ['Kirk', 'Spock', 'McCoy']; + (true ? list : null).removeLast(); + unittest_assertequals(list, ['Kirk', 'Spock'], 'remove last order list'); + list = ['Kirk', 'Spock', 'McCoy']; + int tmp_x = new Math.Random().nextInt(list.length); + list.removeAt(tmp_x); + unittest_assertequals(list.length, 2, 'remove random list'); + list = ['Kirk', 'Spock', 'McCoy']; + List tmp_list = true ? list : null; + int tmp_x2 = new Math.Random().nextInt(tmp_list.length); + tmp_list.removeAt(tmp_x2); + unittest_assertequals(list.length, 2, 'remove random order list'); + list = ['Kirk', 'Spock', 'McCoy']; + list.removeAt(1); + unittest_assertequals(list, ['Kirk', 'McCoy'], 'remove # list'); + list = ['Kirk', 'Spock', 'McCoy']; + (true ? list : null).removeAt(((true ? 2 : null) - 1)); + unittest_assertequals(list, ['Kirk', 'McCoy'], 'remove # order list'); + list = ['Kirk', 'Spock', 'McCoy']; + list.removeAt(list.length - 3); + unittest_assertequals(list, ['Spock', 'McCoy'], 'remove #-end list'); + list = ['Kirk', 'Spock', 'McCoy']; + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + List tmp_list2 = true ? list : null; + tmp_list2.removeAt(tmp_list2.length - (0 + 3)); + unittest_assertequals(list, ['Spock', 'McCoy'], 'remove #-end order list'); +} + +/// Tests the "set" block. +void test_set() { + list = ['Picard', 'Riker', 'Crusher']; + list[0] = 'Jean-Luc'; + unittest_assertequals(list, ['Jean-Luc', 'Riker', 'Crusher'], 'set first list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null)[0] = 'Jean-Luc'; + unittest_assertequals(list, ['Jean-Luc', 'Riker', 'Crusher'], 'set first order list'); + list = ['Picard', 'Riker', 'Crusher']; + list[list.length - 1] = 'Beverly'; + unittest_assertequals(list, ['Picard', 'Riker', 'Beverly'], 'set last list'); + list = ['Picard', 'Riker', 'Crusher']; + List tmp_list3 = (true ? list : null); + tmp_list3[tmp_list3.length - 1] = 'Beverly'; + unittest_assertequals(list, ['Picard', 'Riker', 'Beverly'], 'set last order list'); + list = ['Picard', 'Riker', 'Crusher']; + int tmp_x3 = new Math.Random().nextInt(list.length); + list[tmp_x3] = 'Data'; + unittest_assertequals(list.length, 3, 'set random list'); + list = ['Picard', 'Riker', 'Crusher']; + List tmp_list4 = (true ? list : null); + int tmp_x4 = new Math.Random().nextInt(tmp_list4.length); + tmp_list4[tmp_x4] = 'Data'; + unittest_assertequals(list.length, 3, 'set random order list'); + list = ['Picard', 'Riker', 'Crusher']; + list[2] = 'Pulaski'; + unittest_assertequals(list, ['Picard', 'Riker', 'Pulaski'], 'set # list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null)[((true ? 3 : null) - 1)] = 'Pulaski'; + unittest_assertequals(list, ['Picard', 'Riker', 'Pulaski'], 'set # order list'); + list = ['Picard', 'Riker', 'Crusher']; + list[list.length - 1] = 'Pulaski'; + unittest_assertequals(list, ['Picard', 'Riker', 'Pulaski'], 'set #-end list'); + list = ['Picard', 'Riker', 'Crusher']; + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + List tmp_list5 = (true ? list : null); + tmp_list5[tmp_list5.length - (0 + 2)] = 'Pulaski'; + unittest_assertequals(list, ['Picard', 'Pulaski', 'Crusher'], 'set #-end order list'); +} + +/// Tests the "insert" block. +void test_insert() { + list = ['Picard', 'Riker', 'Crusher']; + list.insert(0, 'Data'); + unittest_assertequals(list, ['Data', 'Picard', 'Riker', 'Crusher'], 'insert first list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null).insert(0, 'Data'); + unittest_assertequals(list, ['Data', 'Picard', 'Riker', 'Crusher'], 'insert first order list'); + list = ['Picard', 'Riker', 'Crusher']; + list.add('Data'); + unittest_assertequals(list, ['Picard', 'Riker', 'Crusher', 'Data'], 'insert last list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null).add('Data'); + unittest_assertequals(list, ['Picard', 'Riker', 'Crusher', 'Data'], 'insert last order list'); + list = ['Picard', 'Riker', 'Crusher']; + int tmp_x5 = new Math.Random().nextInt(list.length); + list.insert(tmp_x5, 'Data'); + unittest_assertequals(list.length, 4, 'insert random list'); + list = ['Picard', 'Riker', 'Crusher']; + List tmp_list6 = (true ? list : null); + int tmp_x6 = new Math.Random().nextInt(tmp_list6.length); + tmp_list6.insert(tmp_x6, 'Data'); + unittest_assertequals(list.length, 4, 'insert random order list'); + list = ['Picard', 'Riker', 'Crusher']; + list.insert(2, 'Data'); + unittest_assertequals(list, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert # list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null).insert(((true ? 3 : null) - 1), 'Data'); + unittest_assertequals(list, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert # order list'); + list = ['Picard', 'Riker', 'Crusher']; + list.insert(list.length - 1, 'Data'); + unittest_assertequals(list, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert #-end list'); + list = ['Picard', 'Riker', 'Crusher']; + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + List tmp_list7 = (true ? list : null); + tmp_list7.insert(tmp_list7.length - (0 + 2), 'Data'); + unittest_assertequals(list, ['Picard', 'Data', 'Riker', 'Crusher'], 'insert #-end order list'); +} + +/// Tests the "get sub-list" block with a variable. +void test_sublist_simple() { + list = ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']; + unittest_assertequals(list.sublist(1, 3), ['Challenger', 'Discovery'], 'sublist # simple'); + unittest_assertequals(list.sublist(((true ? 2 : null) - 1), true ? 3 : null), ['Challenger', 'Discovery'], 'sublist # simple order'); + unittest_assertequals(list.sublist(list.length - 3, list.length - 1), ['Discovery', 'Atlantis'], 'sublist #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(list.sublist(list.length - (0 + 3), list.length - ((0 + 2) - 1)), ['Discovery', 'Atlantis'], 'sublist #-end simple order'); + unittest_assertequals(list.sublist(0), list, 'sublist first-last simple'); + changing_list = ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']; + list_copy = changing_list.sublist(0); + int tmp_x7 = new Math.Random().nextInt(changing_list.length); + changing_list.removeAt(tmp_x7); + unittest_assertequals(list_copy, list, 'sublist first-last simple copy check'); + unittest_assertequals(list.sublist(1, list.length - 1), ['Challenger', 'Discovery', 'Atlantis'], 'sublist # #-end simple'); + unittest_assertequals(list.sublist(list.length - 3, 4), ['Discovery', 'Atlantis'], 'sublist #-end # simple'); + unittest_assertequals(list.sublist(0, 4), ['Columbia', 'Challenger', 'Discovery', 'Atlantis'], 'sublist first # simple'); + unittest_assertequals(list.sublist(0, list.length - 3), ['Columbia', 'Challenger'], 'sublist first #-end simple'); + unittest_assertequals(list.sublist(3), ['Atlantis', 'Endeavour'], 'sublist # last simple'); + unittest_assertequals(list.sublist(list.length - 4), ['Challenger', 'Discovery', 'Atlantis', 'Endeavour'], 'sublist #-end last simple'); + unittest_assertequals(list.sublist(0, list.length - 0), list, 'sublist all with # #-end simple'); + unittest_assertequals(list.sublist(list.length - 5, 5), list, 'sublist all with #-end # simple'); + // Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + unittest_assertequals(list.sublist(((0 + 1) - 1), list.length - ((0 + 1) - 1)), list, 'sublist all with # #-end math simple'); +} + +/// Creates a list for use with the sublist test. +dynamic get_space_shuttles() { + number_of_calls = (number_of_calls is num ? number_of_calls : 0) + 1; + return ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']; +} + +List lists_get_sublist(List list, String where1, num at1, String where2, num at2) { + int getAt(String where, num at) { + if (where == 'FROM_END') { + at = list.length - 1 - at; + } else if (where == 'FIRST') { + at = 0; + } else if (where == 'LAST') { + at = list.length - 1; + } else if (where != 'FROM_START') { + throw 'Unhandled option (lists_getSublist).'; + } + return at; + } + at1 = getAt(where1, at1); + at2 = getAt(where2, at2) + 1; + return list.sublist(at1, at2); +} + +/// Tests the "get sub-list" block with a function call. +void test_sublist_complex() { + number_of_calls = 0; + unittest_assertequals((get_space_shuttles()).sublist(1, 3), ['Challenger', 'Discovery'], 'sublist # start complex'); + check_number_of_calls('sublist # start complex'); + number_of_calls = 0; + unittest_assertequals((true ? get_space_shuttles() : null).sublist(((true ? 2 : null) - 1), true ? 3 : null), ['Challenger', 'Discovery'], 'sublist # start order complex'); + check_number_of_calls('sublist # start order complex'); + number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FROM_END', 2, 'FROM_END', 1), ['Discovery', 'Atlantis'], 'sublist # end complex'); + unittest_assertequals(number_of_calls, 1, 'sublist # end complex number of calls'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((true ? get_space_shuttles() : null), 'FROM_END', ((0 + 3) - 1), 'FROM_END', ((0 + 2) - 1)), ['Discovery', 'Atlantis'], 'sublist # end order complex'); + check_number_of_calls('sublist # end order complex'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FIRST', 0, 'LAST', 0), list, 'sublist first-last complex'); + check_number_of_calls('sublist first-last complex'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FROM_START', 1, 'FROM_END', 1), ['Challenger', 'Discovery', 'Atlantis'], 'sublist # #-end complex'); + check_number_of_calls('sublist # #-end complex'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FROM_END', 2, 'FROM_START', 3), ['Discovery', 'Atlantis'], 'sublist #-end # complex'); + check_number_of_calls('sublist #-end # complex'); + number_of_calls = 0; + unittest_assertequals((get_space_shuttles()).sublist(0, 4), ['Columbia', 'Challenger', 'Discovery', 'Atlantis'], 'sublist first # complex'); + check_number_of_calls('sublist first # complex'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FIRST', 0, 'FROM_END', 3), ['Columbia', 'Challenger'], 'sublist first #-end complex'); + check_number_of_calls('sublist first #-end complex'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FROM_START', 3, 'LAST', 0), ['Atlantis', 'Endeavour'], 'sublist # last complex'); + check_number_of_calls('sublist # last complex'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FROM_END', 3, 'LAST', 0), ['Challenger', 'Discovery', 'Atlantis', 'Endeavour'], 'sublist #-end last simple'); + check_number_of_calls('sublist #-end last simple'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FROM_START', 0, 'FROM_END', 0), list, 'sublist all with # #-end complex'); + check_number_of_calls('sublist all with # #-end complex'); + number_of_calls = 0; + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FROM_END', 4, 'FROM_START', 4), list, 'sublist all with #-end # complex'); + check_number_of_calls('sublist all with #-end # complex'); + number_of_calls = 0; + // Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + unittest_assertequals(lists_get_sublist((get_space_shuttles()), 'FROM_START', ((0 + 1) - 1), 'FROM_END', ((0 + 1) - 1)), list, 'sublist all with # #-end math complex'); + check_number_of_calls('sublist all with # #-end math complex'); +} + +/// Tests the "join" block. +void test_join() { + list = ['Vulcan', 'Klingon', 'Borg']; + unittest_assertequals(list.join(','), 'Vulcan,Klingon,Borg', 'join'); + unittest_assertequals((true ? list : null).join(','), 'Vulcan,Klingon,Borg', 'join order'); +} + +/// Tests the "split" block. +void test_split() { + text = 'Vulcan,Klingon,Borg'; + unittest_assertequals(text.split(','), ['Vulcan', 'Klingon', 'Borg'], 'split'); + unittest_assertequals((true ? text : null).split(','), ['Vulcan', 'Klingon', 'Borg'], 'split order'); +} + +List lists_sort(List list, String type, int direction) { + var compareFuncs = { + "NUMERIC": (a, b) => (direction * a.compareTo(b)).toInt(), + "TEXT": (a, b) => direction * a.toString().compareTo(b.toString()), + "IGNORE_CASE": + (a, b) => direction * + a.toString().toLowerCase().compareTo(b.toString().toLowerCase()) + }; + list = new List.from(list); + var compare = compareFuncs[type]; + list.sort(compare); + return list; +} + +/// Tests the "alphabetic sort" block. +void test_sort_alphabetic() { + list = ['Vulcan', 'klingon', 'Borg']; + unittest_assertequals(lists_sort(list, "TEXT", 1), ['Borg', 'Vulcan', 'klingon'], 'sort alphabetic ascending'); + unittest_assertequals(lists_sort(true ? list : null, "TEXT", 1), ['Borg', 'Vulcan', 'klingon'], 'sort alphabetic ascending order'); +} + +/// Tests the "alphabetic sort ignore case" block. +void test_sort_ignoreCase() { + list = ['Vulcan', 'klingon', 'Borg']; + unittest_assertequals(lists_sort(list, "IGNORE_CASE", 1), ['Borg', 'klingon', 'Vulcan'], 'sort ignore case ascending'); + unittest_assertequals(lists_sort(true ? list : null, "IGNORE_CASE", 1), ['Borg', 'klingon', 'Vulcan'], 'sort ignore case ascending order'); +} + +/// Tests the "numeric sort" block. +void test_sort_numeric() { + list = [8, 18, -1]; + unittest_assertequals(lists_sort(list, "NUMERIC", -1), [18, 8, -1], 'sort numeric descending'); + unittest_assertequals(lists_sort(true ? list : null, "NUMERIC", -1), [18, 8, -1], 'sort numeric descending order'); +} + +/// Tests the "list reverse" block. +void test_lists_reverse() { + list = [8, 18, -1, 64]; + unittest_assertequals(new List.from(list.reversed), [64, -1, 18, 8], 'reverse a copy'); + unittest_assertequals(list, [8, 18, -1, 64], 'reverse a copy original'); + 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... +void test_procedure() { + procedure_1(8, 2); + unittest_assertequals(proc_z, 4, 'procedure with global'); + proc_w = false; + procedure_2(false); + unittest_assertequals(proc_w, true, 'procedure no return'); + proc_w = false; + procedure_2(true); + unittest_assertequals(proc_w, false, 'procedure return'); +} + +/// Describe this function... +void procedure_1(proc_x, proc_y) { + proc_z = proc_x / proc_y; +} + +/// Describe this function... +void procedure_2(proc_x) { + if (proc_x) { + return; + } + proc_w = true; +} + +/// Describe this function... +void test_function() { + unittest_assertequals(function_1(2, 3), -1, 'function with arguments'); + unittest_assertequals(func_z, 'side effect', 'function with side effect'); + func_a = 'unchanged'; + func_c = 'global'; + unittest_assertequals(function_2(2), '3global', 'function with global'); + unittest_assertequals(func_a, 'unchanged', 'function with scope'); + unittest_assertequals(function_3(true), true, 'function return'); + unittest_assertequals(function_3(false), false, 'function no return'); +} + +/// Describe this function... +dynamic function_1(func_x, func_y) { + func_z = 'side effect'; + return func_x - func_y; +} + +/// Describe this function... +dynamic function_2(func_a) { + func_a = (func_a is num ? func_a : 0) + 1; + return [func_a,func_c].join(); +} + +/// Describe this function... +dynamic function_3(func_a) { + if (func_a) { + return true; + } + return false; +} + +/// Describe this function... +dynamic recurse(n) { + if (n > 0) { + text = [recurse(n - 1),n,recurse(n - 1)].join(); + } else { + text = '-'; + } + return text; +} + + +main() { + unittestResults = []; + print('\n====================\n\nRunning suite: Logic'); + unittest_assertequals(true, true, 'True'); + unittest_assertequals(false, false, 'False'); + unittest_assertequals(!false, true, 'Not true'); + unittest_assertequals(!true, false, 'Not false'); + test_if(); + test_ifelse(); + test_equalities(); + test_and(); + test_or(); + test_ternary(); + print(unittest_report()); + unittestResults = null; + + unittestResults = []; + print('\n====================\n\nRunning suite: Loops 1'); + test_repeat(); + test_repeat_ext(); + test_while(); + test_foreach(); + print(unittest_report()); + unittestResults = null; + + unittestResults = []; + print('\n====================\n\nRunning suite: Loops 2'); + test_count_loops(); + test_count_by(); + print(unittest_report()); + unittestResults = null; + + unittestResults = []; + print('\n====================\n\nRunning suite: Loops 3'); + test_break(); + test_continue(); + print(unittest_report()); + unittestResults = null; + + unittestResults = []; + print('\n====================\n\nRunning suite: Math'); + test_arithmetic(); + test_single(); + test_trig(); + test_constant(); + test_change(); + test_number_properties(); + test_round(); + test_operations_on_list(); + test_constraint(); + test_mod(); + test_random_integer(); + test_random_fraction(); + test_atan2(); + print(unittest_report()); + unittestResults = null; + + unittestResults = []; + print('\n====================\n\nRunning suite: Text'); + test_text_length(); + test_empty_text(); + test_create_text(); + test_append(); + test_find_text_simple(); + test_find_text_complex(); + test_get_text_simple(); + test_get_text_complex(); + test_substring_simple(); + test_substring_complex(); + test_case(); + test_trim(); + test_count_text(); + test_text_reverse(); + test_replace(); + print(unittest_report()); + unittestResults = null; + + unittestResults = []; + print('\n====================\n\nRunning suite: Lists'); + test_create_lists(); + test_lists_empty(); + test_lists_length(); + test_find_lists_simple(); + test_find_lists_complex(); + test_get_lists_simple(); + test_get_lists_complex(); + test_getRemove(); + test_remove(); + test_set(); + test_insert(); + test_sublist_simple(); + test_sublist_complex(); + test_join(); + test_split(); + test_sort_alphabetic(); + test_sort_ignoreCase(); + test_sort_numeric(); + test_lists_reverse(); + print(unittest_report()); + 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 = []; + print('\n====================\n\nRunning suite: Variables'); + item = 123; + unittest_assertequals(item, 123, 'variable'); + if2 = 123; + unittest_assertequals(if2, 123, 'reserved variable'); + print(unittest_report()); + unittestResults = null; + + // Intentionally non-connected variable. + naked; + + unittestResults = []; + print('\n====================\n\nRunning suite: Functions'); + test_procedure(); + test_function(); + unittest_assertequals(recurse(3), '-1-2-1-3-1-2-1-', 'test recurse'); + print(unittest_report()); + unittestResults = null; +} \ No newline at end of file diff --git a/tests/generators/golden/generated.js b/tests/generators/golden/generated.js new file mode 100644 index 000000000..f59298f40 --- /dev/null +++ b/tests/generators/golden/generated.js @@ -0,0 +1,1769 @@ +'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; + +function unittest_report() { + // Create test report. + var report = []; + var summary = []; + var fails = 0; + for (var i = 0; i < unittestResults.length; i++) { + if (unittestResults[i][0]) { + summary.push("."); + } else { + summary.push("F"); + fails++; + report.push(""); + report.push("FAIL: " + unittestResults[i][2]); + report.push(unittestResults[i][1]); + } + } + report.unshift(summary.join("")); + report.push(""); + report.push("Number of tests run: " + unittestResults.length); + report.push(""); + if (fails) { + report.push("FAILED (failures=" + fails + ")"); + } else { + report.push("OK"); + } + return report.join("\n"); +} + +function assertEquals(actual, expected, message) { + // Asserts that a value equals another value. + if (!unittestResults) { + throw "Orphaned assert: " + message; + } + function equals(a, b) { + if (a === b) { + return true; + } else if ((typeof a == "number") && (typeof b == "number") && + (a.toPrecision(15) == b.toPrecision(15))) { + return true; + } else if (a instanceof Array && b instanceof Array) { + if (a.length != b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!equals(a[i], b[i])) { + return false; + } + } + return true; + } + return false; + } + if (equals(actual, expected)) { + unittestResults.push([true, "OK", message]); + } else { + unittestResults.push([false, "Expected: " + expected + "\nActual: " + actual, message]); + } +} + +function unittest_fail(message) { + // Always assert an error. + if (!unittestResults) { + throw "Orphaned assert fail: " + message; + } + unittestResults.push([false, "Fail.", message]); +} + +/** + * Describe this function... + */ +function test_if() { + if (false) { + unittest_fail('if false'); + } + ok = false; + if (true) { + ok = true; + } + assertEquals(ok, true, 'if true'); + ok = false; + if (false) { + unittest_fail('if/else false'); + } else { + ok = true; + } + assertEquals(ok, true, 'if/else false'); + ok = false; + if (true) { + ok = true; + } else { + unittest_fail('if/else true'); + } + assertEquals(ok, true, 'if/else true'); + ok = false; + if (false) { + unittest_fail('elseif 1'); + } else if (true) { + ok = true; + } else if (true) { + unittest_fail('elseif 2'); + } else { + unittest_fail('elseif 3'); + } + assertEquals(ok, true, 'elseif 4'); +} + +/** + * Describe this function... + */ +function test_ifelse() { + ok = false; + if (true) { + ok = true; + } else { + unittest_fail('ifelse true'); + } + assertEquals(ok, true, 'ifelse true'); + ok = false; + if (false) { + unittest_fail('ifelse false'); + } else { + ok = true; + } + assertEquals(ok, true, 'ifelse false'); +} + +/** + * Describe this function... + */ +function test_equalities() { + assertEquals(2 == 2, true, 'Equal yes'); + assertEquals(3 == 4, false, 'Equal no'); + assertEquals(5 != 6, true, 'Not equal yes'); + assertEquals(3 == 4, false, 'Not equal no'); + assertEquals(5 < 6, true, 'Smaller yes'); + assertEquals(7 < 7, false, 'Smaller no'); + assertEquals(9 > 8, true, 'Greater yes'); + assertEquals(10 > 10, false, 'Greater no'); + assertEquals(11 <= 11, true, 'Smaller-equal yes'); + assertEquals(13 <= 12, false, 'Smaller-equal no'); + assertEquals(14 >= 14, true, 'Greater-equal yes'); + assertEquals(15 >= 16, false, 'Greater-equal no'); +} + +/** + * Describe this function... + */ +function test_and() { + assertEquals(true && true, true, 'And true/true'); + assertEquals(false && true, false, 'And false/true'); + assertEquals(true && false, false, 'And true/false'); + assertEquals(false && false, false, 'And false/false'); +} + +/** + * Describe this function... + */ +function test_or() { + assertEquals(true || true, true, 'Or true/true'); + assertEquals(false || true, true, 'Or false/true'); + assertEquals(true || false, true, 'Or true/false'); + assertEquals(false || false, false, 'Or false/false'); +} + +/** + * Describe this function... + */ +function test_ternary() { + assertEquals(true ? 42 : 99, 42, 'if true'); + assertEquals(false ? 42 : 99, 99, 'if true'); +} + +/** + * Describe this function... + */ +function test_foreach() { + log = ''; + var x_list = ['a', 'b', 'c']; + for (var x_index in x_list) { + x = x_list[x_index]; + log += String(x); + } + assertEquals(log, 'abc', 'for loop'); +} + +/** + * Describe this function... + */ +function test_repeat() { + count = 0; + for (var count2 = 0; count2 < 10; count2++) { + count = (typeof count == 'number' ? count : 0) + 1; + } + assertEquals(count, 10, 'repeat 10'); +} + +/** + * Describe this function... + */ +function test_while() { + while (false) { + unittest_fail('while 0'); + } + while (!true) { + unittest_fail('until 0'); + } + count = 1; + while (count != 10) { + count = (typeof count == 'number' ? count : 0) + 1; + } + assertEquals(count, 10, 'while 10'); + count = 1; + while (!(count == 10)) { + count = (typeof count == 'number' ? count : 0) + 1; + } + assertEquals(count, 10, 'until 10'); +} + +/** + * Describe this function... + */ +function test_repeat_ext() { + count = 0; + for (var count3 = 0; count3 < 10; count3++) { + count = (typeof count == 'number' ? count : 0) + 1; + } + assertEquals(count, 10, 'repeat 10'); +} + +/** + * Describe this function... + */ +function test_count_by() { + log = ''; + for (x = 1; x <= 8; x += 2) { + log += String(x); + } + assertEquals(log, '1357', 'count up ints'); + log = ''; + for (x = 8; x >= 1; x -= 2) { + log += String(x); + } + assertEquals(log, '8642', 'count down ints'); + loglist = []; + for (x = 1; x <= 8; x += 1.5) { + loglist.push(x); + } + assertEquals(loglist, [1, 2.5, 4, 5.5, 7], 'count with floats'); + loglist = []; + var x_start = 1 + 0; + var x_end = 8 + 0; + var x_inc = Math.abs(1 - 2); + if (x_start > x_end) { + x_inc = -x_inc; + } + for (x = x_start; x_inc >= 0 ? x <= x_end : x >= x_end; x += x_inc) { + loglist.push(x); + } + assertEquals(loglist, [1, 2, 3, 4, 5, 6, 7, 8], 'count up non-trivial ints'); + loglist = []; + var x_start2 = 8 + 0; + var x_end2 = 1 + 0; + var x_inc2 = 2; + if (x_start2 > x_end2) { + x_inc2 = -x_inc2; + } + for (x = x_start2; x_inc2 >= 0 ? x <= x_end2 : x >= x_end2; x += x_inc2) { + loglist.push(x); + } + assertEquals(loglist, [8, 6, 4, 2], 'count down non-trivial ints'); + loglist = []; + var x_start3 = 5 + 0.5; + var x_end3 = 1 + 0; + var x_inc3 = Math.abs(1 + 0); + if (x_start3 > x_end3) { + x_inc3 = -x_inc3; + } + for (x = x_start3; x_inc3 >= 0 ? x <= x_end3 : x >= x_end3; x += x_inc3) { + loglist.push(x); + } + assertEquals(loglist, [5.5, 4.5, 3.5, 2.5, 1.5], 'count with floats'); +} + +/** + * Describe this function... + */ +function test_count_loops() { + log = ''; + for (x = 1; x <= 8; x++) { + log += String(x); + } + assertEquals(log, '12345678', 'count up'); + log = ''; + for (x = 8; x >= 1; x--) { + log += String(x); + } + assertEquals(log, '87654321', 'count down'); + loglist = []; + var x_start4 = 1 + 0; + var x_end4 = 4 + 0; + var x_inc4 = 1; + if (x_start4 > x_end4) { + x_inc4 = -x_inc4; + } + for (x = x_start4; x_inc4 >= 0 ? x <= x_end4 : x >= x_end4; x += x_inc4) { + loglist.push(x); + } + assertEquals(loglist, [1, 2, 3, 4], 'count up non-trivial'); + loglist = []; + var x_start5 = 3 + 1; + var x_end5 = 1 + 0; + var x_inc5 = 1; + if (x_start5 > x_end5) { + x_inc5 = -x_inc5; + } + for (x = x_start5; x_inc5 >= 0 ? x <= x_end5 : x >= x_end5; x += x_inc5) { + loglist.push(x); + } + assertEquals(loglist, [4, 3, 2, 1], 'count down non-trivial'); +} + +/** + * Describe this function... + */ +function test_continue() { + log = ''; + count = 0; + while (count != 8) { + count = (typeof count == 'number' ? count : 0) + 1; + if (count == 5) { + continue; + } + log += String(count); + } + assertEquals(log, '1234678', 'while continue'); + log = ''; + count = 0; + while (!(count == 8)) { + count = (typeof count == 'number' ? count : 0) + 1; + if (count == 5) { + continue; + } + log += String(count); + } + assertEquals(log, '1234678', 'until continue'); + log = ''; + for (x = 1; x <= 8; x++) { + if (x == 5) { + continue; + } + log += String(x); + } + assertEquals(log, '1234678', 'count continue'); + log = ''; + var x_list2 = ['a', 'b', 'c', 'd']; + for (var x_index2 in x_list2) { + x = x_list2[x_index2]; + if (x == 'c') { + continue; + } + log += String(x); + } + assertEquals(log, 'abd', 'for continue'); +} + +/** + * Describe this function... + */ +function test_break() { + count = 1; + while (count != 10) { + if (count == 5) { + break; + } + count = (typeof count == 'number' ? count : 0) + 1; + } + assertEquals(count, 5, 'while break'); + count = 1; + while (!(count == 10)) { + if (count == 5) { + break; + } + count = (typeof count == 'number' ? count : 0) + 1; + } + assertEquals(count, 5, 'until break'); + log = ''; + for (x = 1; x <= 8; x++) { + if (x == 5) { + break; + } + log += String(x); + } + assertEquals(log, '1234', 'count break'); + log = ''; + var x_list3 = ['a', 'b', 'c', 'd']; + for (var x_index3 in x_list3) { + x = x_list3[x_index3]; + if (x == 'c') { + break; + } + log += String(x); + } + assertEquals(log, 'ab', 'for break'); +} + +/** + * Tests the "single" block. + */ +function test_single() { + assertEquals(Math.sqrt(25), 5, 'sqrt'); + assertEquals(Math.abs(-25), 25, 'abs'); + assertEquals(-(-25), 25, 'negate'); + assertEquals(Math.log(1), 0, 'ln'); + assertEquals(Math.log(100) / Math.log(10), 2, 'log10'); + assertEquals(Math.exp(2), 7.38905609893065, 'exp'); + assertEquals(Math.pow(10,2), 100, 'power10'); +} + +/** + * Tests the "arithmetic" block for all operations and checks + * parenthesis are properly generated for different orders. + */ +function test_arithmetic() { + assertEquals(1 + 2, 3, 'add'); + assertEquals(1 - 2, -1, 'subtract'); + assertEquals(1 - (0 + 2), -1, 'subtract order with add'); + assertEquals(1 - (0 - 2), 3, 'subtract order with subtract'); + assertEquals(4 * 2.5, 10, 'multiply'); + assertEquals(4 * (0 + 2.5), 10, 'multiply order'); + assertEquals(8.2 / -5, -1.64, 'divide'); + assertEquals(8.2 / (0 + -5), -1.64, 'divide order'); + assertEquals(Math.pow(10, 4), 10000, 'power'); + assertEquals(Math.pow(10, 0 + 4), 10000, 'power order'); +} + +/** + * Tests the "trig" block. + */ +function test_trig() { + assertEquals(Math.sin(90 / 180 * Math.PI), 1, 'sin'); + assertEquals(Math.cos(180 / 180 * Math.PI), -1, 'cos'); + assertEquals(Math.tan(0 / 180 * Math.PI), 0, 'tan'); + assertEquals(Math.asin(-1) / Math.PI * 180, -90, 'asin'); + assertEquals(Math.acos(1) / Math.PI * 180, 0, 'acos'); + assertEquals(Math.atan(1) / Math.PI * 180, 45, 'atan'); +} + +/** + * Tests the "constant" blocks. + */ +function test_constant() { + assertEquals(Math.floor(Math.PI * 1000), 3141, 'const pi'); + assertEquals(Math.floor(Math.E * 1000), 2718, 'const e'); + assertEquals(Math.floor(((1 + Math.sqrt(5)) / 2) * 1000), 1618, 'const golden'); + assertEquals(Math.floor(Math.SQRT2 * 1000), 1414, 'const sqrt 2'); + assertEquals(Math.floor(Math.SQRT1_2 * 1000), 707, 'const sqrt 0.5'); + assertEquals(9999 < Infinity, true, 'const infinity'); +} + +function mathIsPrime(n) { + // https://en.wikipedia.org/wiki/Primality_test#Naive_methods + if (n == 2 || n == 3) { + return true; + } + // False if n is NaN, negative, is 1, or not whole. + // And false if n is divisible by 2 or 3. + if (isNaN(n) || n <= 1 || n % 1 != 0 || n % 2 == 0 || n % 3 == 0) { + return false; + } + // Check all the numbers of form 6k +/- 1, up to sqrt(n). + for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) { + if (n % (x - 1) == 0 || n % (x + 1) == 0) { + return false; + } + } + return true; +} + +/** + * Tests the "number property" blocks. + */ +function test_number_properties() { + assertEquals(42 % 2 == 0, true, 'even'); + assertEquals(42.1 % 2 == 1, false, 'odd'); + assertEquals(mathIsPrime(5), true, 'prime 5'); + assertEquals(mathIsPrime(25), false, 'prime 25'); + assertEquals(mathIsPrime(-31.1), false, 'prime negative'); + assertEquals(Math.PI % 1 == 0, false, 'whole'); + assertEquals(Infinity > 0, true, 'positive'); + assertEquals(-42 < 0, true, 'negative'); + assertEquals(42 % 2 == 0, true, 'divisible'); +} + +/** + * Tests the "round" block. + */ +function test_round() { + assertEquals(Math.round(42.42), 42, 'round'); + assertEquals(Math.ceil(-42.42), -42, 'round up'); + assertEquals(Math.floor(42.42), 42, 'round down'); +} + +/** + * Tests the "change" block. + */ +function test_change() { + varToChange = 100; + varToChange = (typeof varToChange == 'number' ? varToChange : 0) + 42; + assertEquals(varToChange, 142, 'change'); +} + +function mathMean(myList) { + return myList.reduce(function(x, y) {return x + y;}) / myList.length; +} + +function mathMedian(myList) { + var localList = myList.filter(function (x) {return typeof x == 'number';}); + if (!localList.length) return null; + localList.sort(function(a, b) {return b - a;}); + if (localList.length % 2 == 0) { + return (localList[localList.length / 2 - 1] + localList[localList.length / 2]) / 2; + } else { + return localList[(localList.length - 1) / 2]; + } +} + +function mathModes(values) { + var modes = []; + var counts = []; + var maxCount = 0; + for (var i = 0; i < values.length; i++) { + var value = values[i]; + var found = false; + var thisCount; + for (var j = 0; j < counts.length; j++) { + if (counts[j][0] === value) { + thisCount = ++counts[j][1]; + found = true; + break; + } + } + if (!found) { + counts.push([value, 1]); + thisCount = 1; + } + maxCount = Math.max(thisCount, maxCount); + } + for (var j = 0; j < counts.length; j++) { + if (counts[j][1] == maxCount) { + modes.push(counts[j][0]); + } + } + return modes; +} + +function mathStandardDeviation(numbers) { + var n = numbers.length; + if (!n) return null; + var mean = numbers.reduce(function(x, y) {return x + y;}) / n; + var variance = 0; + for (var j = 0; j < n; j++) { + variance += Math.pow(numbers[j] - mean, 2); + } + variance = variance / n; + return Math.sqrt(variance); +} + +function mathRandomList(list) { + var x = Math.floor(Math.random() * list.length); + return list[x]; +} + +/** + * Tests the "list operation" blocks. + */ +function test_operations_on_list() { + assertEquals([3, 4, 5].reduce(function(x, y) {return x + y;}), 12, 'sum'); + assertEquals(Math.min.apply(null, [3, 4, 5]), 3, 'min'); + assertEquals(Math.max.apply(null, [3, 4, 5]), 5, 'max'); + assertEquals(mathMean([3, 4, 5]), 4, 'average'); + assertEquals(mathMedian([3, 4, 5, 1]), 3.5, 'median'); + assertEquals(mathModes([3, 4, 3]), [3], 'modes'); + assertEquals(mathModes([3, 4, 3, 1, 4]), [3, 4], 'modes multiple'); + assertEquals(mathStandardDeviation([3, 3, 3]), 0, 'standard dev'); + assertEquals([3, 4, 5].indexOf(mathRandomList([3, 4, 5])) + 1 > 0, true, 'random'); +} + +/** + * Tests the "mod" block. + */ +function test_mod() { + assertEquals(42 % 5, 2, 'mod'); +} + +/** + * Tests the "constrain" block. + */ +function test_constraint() { + assertEquals(Math.min(Math.max(100, 0), 42), 42, 'constraint'); +} + +function mathRandomInt(a, b) { + if (a > b) { + // Swap a and b to ensure a is smaller. + var c = a; + a = b; + b = c; + } + return Math.floor(Math.random() * (b - a + 1) + a); +} + +/** + * Tests the "random integer" block. + */ +function test_random_integer() { + rand = mathRandomInt(5, 10); + assertEquals(rand >= 5 && rand <= 10, true, 'randRange'); + assertEquals(rand % 1 == 0, true, 'randInteger'); +} + +/** + * Tests the "random fraction" block. + */ +function test_random_fraction() { + rand = Math.random(); + assertEquals(rand >= 0 && rand <= 1, true, 'randFloat'); +} + +/** + * Describe this function... + */ +function test_atan2() { + assertEquals(Math.atan2(5, -5) / Math.PI * 180, 135, 'atan2'); + assertEquals(Math.atan2(-12, 0) / Math.PI * 180, -90, 'atan2'); +} + +/** + * Checks that the number of calls is one in order + * to confirm that a function was only called once. + */ +function check_number_of_calls(test_name) { + test_name += 'number of calls'; + assertEquals(number_of_calls, 1, test_name); +} + +/** + * Tests the "create text with" block with varying number of inputs. + */ +function test_create_text() { + assertEquals('', '', 'no text'); + assertEquals('Hello', 'Hello', 'create single'); + assertEquals(String(-1), '-1', 'create single number'); + assertEquals('K' + String(9), 'K9', 'create double text'); + assertEquals(String(4) + String(2), '42', 'create double text numbers'); + assertEquals([1,2,3].join(''), '123', 'create triple'); + assertEquals([1,true ? 0 : null,'M'].join(''), '10M', 'create order'); +} + +/** + * Creates an empty string for use with the empty test. + */ +function get_empty() { + return ''; +} + +/** + * Tests the "is empty" block". + */ +function test_empty_text() { + assertEquals(!'Google'.length, false, 'not empty'); + assertEquals(!''.length, true, 'empty'); + assertEquals(!get_empty().length, true, 'empty complex'); + assertEquals(!(true ? '' : null).length, true, 'empty order'); +} + +/** + * Tests the "length" block. + */ +function test_text_length() { + assertEquals(''.length, 0, 'zero length'); + assertEquals('Google'.length, 6, 'non-zero length'); + assertEquals((true ? 'car' : null).length, 3, 'length order'); +} + +/** + * Tests the "append text" block with different types of parameters. + */ +function test_append() { + item = 'Miserable'; + item += 'Failure'; + assertEquals(item, 'MiserableFailure', 'append text'); + item = 12; + item += String(34); + assertEquals(item, '1234', 'append number'); + item = 'Something '; + item += String(true ? 'Positive' : null); + assertEquals(item, 'Something Positive', 'append order'); +} + +/** + * Tests the "find" block with a variable. + */ +function test_find_text_simple() { + text = 'Banana'; + assertEquals(text.indexOf('an') + 1, 2, 'find first simple'); + assertEquals(text.lastIndexOf('an') + 1, 4, 'find last simple'); + assertEquals(text.indexOf('Peel') + 1, 0, 'find none simple'); +} + +/** + * Creates a string for use with the find test. + */ +function get_fruit() { + number_of_calls = (typeof number_of_calls == 'number' ? number_of_calls : 0) + 1; + return 'Banana'; +} + +/** + * Tests the "find" block with a function call. + */ +function test_find_text_complex() { + number_of_calls = 0; + assertEquals(get_fruit().indexOf('an') + 1, 2, 'find first complex'); + check_number_of_calls('find first complex'); + number_of_calls = 0; + assertEquals((true ? get_fruit() : null).indexOf('an') + 1, 2, 'find first order complex'); + check_number_of_calls('find first order complex'); + number_of_calls = 0; + assertEquals(get_fruit().lastIndexOf('an') + 1, 4, 'find last complex'); + check_number_of_calls('find last complex'); + number_of_calls = 0; + assertEquals((true ? get_fruit() : null).lastIndexOf('an') + 1, 4, 'find last order complex'); + check_number_of_calls('find last order complex'); + number_of_calls = 0; + assertEquals(get_fruit().indexOf('Peel') + 1, 0, 'find none complex'); + check_number_of_calls('find none complex'); + number_of_calls = 0; + assertEquals((true ? get_fruit() : null).indexOf('Peel') + 1, 0, 'find none order complex'); + check_number_of_calls('find none order complex'); +} + +function textRandomLetter(text) { + var x = Math.floor(Math.random() * text.length); + return text[x]; +} + +/** + * Tests the "get letter" block with a variable. + */ +function test_get_text_simple() { + text = 'Blockly'; + assertEquals(text.charAt(0), 'B', 'get first simple'); + assertEquals(text.slice(-1), 'y', 'get last simple'); + assertEquals(text.indexOf(textRandomLetter(text)) + 1 > 0, true, 'get random simple'); + assertEquals(text.charAt(2), 'o', 'get # simple'); + assertEquals(text.charAt(((true ? 3 : null) - 1)), 'o', 'get # order simple'); + assertEquals(text.slice(-3).charAt(0), 'k', 'get #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(text.slice((-(0 + 3))).charAt(0), 'k', 'get #-end order simple'); +} + +/** + * Creates a string for use with the get test. + */ +function get_Blockly() { + number_of_calls = (typeof number_of_calls == 'number' ? number_of_calls : 0) + 1; + return 'Blockly'; +} + +/** + * Tests the "get letter" block with a function call. + */ +function test_get_text_complex() { + text = 'Blockly'; + number_of_calls = 0; + assertEquals(get_Blockly().charAt(0), 'B', 'get first complex'); + check_number_of_calls('get first complex'); + number_of_calls = 0; + assertEquals((true ? get_Blockly() : null).charAt(0), 'B', 'get first order complex'); + check_number_of_calls('get first order complex'); + number_of_calls = 0; + assertEquals(get_Blockly().slice(-1), 'y', 'get last complex'); + check_number_of_calls('get last complex'); + number_of_calls = 0; + assertEquals((true ? get_Blockly() : null).slice(-1), 'y', 'get last order complex'); + check_number_of_calls('get last order complex'); + number_of_calls = 0; + assertEquals(text.indexOf(textRandomLetter(get_Blockly())) + 1 > 0, true, 'get random complex'); + check_number_of_calls('get random complex'); + number_of_calls = 0; + assertEquals(text.indexOf(textRandomLetter(true ? get_Blockly() : null)) + 1 > 0, true, 'get random order complex'); + check_number_of_calls('get random order complex'); + number_of_calls = 0; + assertEquals(get_Blockly().charAt(2), 'o', 'get # complex'); + check_number_of_calls('get # complex'); + number_of_calls = 0; + assertEquals((true ? get_Blockly() : null).charAt(((true ? 3 : null) - 1)), 'o', 'get # order complex'); + check_number_of_calls('get # order complex'); + number_of_calls = 0; + assertEquals(get_Blockly().slice(-3).charAt(0), 'k', 'get #-end complex'); + check_number_of_calls('get #-end complex'); + number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals((true ? get_Blockly() : null).slice((-(0 + 3))).charAt(0), 'k', 'get #-end order complex'); + check_number_of_calls('get #-end order complex'); +} + +/** + * Creates a string for use with the substring test. + */ +function get_numbers() { + number_of_calls = (typeof number_of_calls == 'number' ? number_of_calls : 0) + 1; + return '123456789'; +} + +/** + * Tests the "get substring" block with a variable. + */ +function test_substring_simple() { + text = '123456789'; + assertEquals(text.slice(1, 3), '23', 'substring # simple'); + assertEquals(text.slice(((true ? 2 : null) - 1), true ? 3 : null), '23', 'substring # simple order'); + assertEquals(text.slice(text.length - 3, text.length - 1), '78', 'substring #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(text.slice(text.length - (0 + 3), text.length - ((0 + 2) - 1)), '78', 'substring #-end simple order'); + assertEquals(text, text, 'substring first-last simple'); + assertEquals(text.slice(1, text.length - 1), '2345678', 'substring # #-end simple'); + assertEquals(text.slice(text.length - 7, 4), '34', 'substring #-end # simple'); + assertEquals(text.slice(0, 4), '1234', 'substring first # simple'); + assertEquals(text.slice(0, text.length - 1), '12345678', 'substring first #-end simple'); + assertEquals(text.slice(6, text.length), '789', 'substring # last simple'); + assertEquals(text.slice(text.length - 3, text.length), '789', 'substring #-end last simple'); + assertEquals(text.slice(0, text.length - 0), '123456789', 'substring all with # #-end simple'); + assertEquals(text.slice(text.length - 9, 9), '123456789', 'substring all with #-end # simple'); + // Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + assertEquals(text.slice(((0 + 1) - 1), text.length - ((0 + 1) - 1)), '123456789', 'substring all with # #-end math simple'); +} + +function subsequenceFromEndFromEnd(sequence, at1, at2) { + var start = sequence.length - 1 - at1; + var end = sequence.length - 1 - at2 + 1; + return sequence.slice(start, end); +} + +function subsequenceFromStartFromEnd(sequence, at1, at2) { + var start = at1; + var end = sequence.length - 1 - at2 + 1; + return sequence.slice(start, end); +} + +function subsequenceFromEndFromStart(sequence, at1, at2) { + var start = sequence.length - 1 - at1; + var end = at2 + 1; + return sequence.slice(start, end); +} + +function subsequenceFirstFromEnd(sequence, at2) { + var start = 0; + var end = sequence.length - 1 - at2 + 1; + return sequence.slice(start, end); +} + +function subsequenceFromStartLast(sequence, at1) { + var start = at1; + var end = sequence.length - 1 + 1; + return sequence.slice(start, end); +} + +function subsequenceFromEndLast(sequence, at1) { + var start = sequence.length - 1 - at1; + var end = sequence.length - 1 + 1; + return sequence.slice(start, end); +} + +/** + * Tests the "get substring" block with a function call. + */ +function test_substring_complex() { + number_of_calls = 0; + assertEquals(get_numbers().slice(1, 3), '23', 'substring # complex'); + check_number_of_calls('substring # complex'); + number_of_calls = 0; + assertEquals((true ? get_numbers() : null).slice(((true ? 2 : null) - 1), true ? 3 : null), '23', 'substring # complex order'); + check_number_of_calls('substring # complex order'); + number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(subsequenceFromEndFromEnd(get_numbers(), 2, 1), '78', 'substring #-end complex'); + check_number_of_calls('substring #-end complex'); + number_of_calls = 0; + assertEquals(subsequenceFromEndFromEnd((true ? get_numbers() : null), ((0 + 3) - 1), ((0 + 2) - 1)), '78', 'substring #-end order order'); + check_number_of_calls('substring #-end order order'); + number_of_calls = 0; + assertEquals(get_numbers(), text, 'substring first-last'); + check_number_of_calls('substring first-last'); + number_of_calls = 0; + assertEquals(subsequenceFromStartFromEnd(get_numbers(), 1, 1), '2345678', 'substring # #-end complex'); + check_number_of_calls('substring # #-end complex'); + number_of_calls = 0; + assertEquals(subsequenceFromEndFromStart(get_numbers(), 6, 3), '34', 'substring #-end # complex'); + check_number_of_calls('substring #-end # complex'); + number_of_calls = 0; + assertEquals(get_numbers().slice(0, 4), '1234', 'substring first # complex'); + check_number_of_calls('substring first # complex'); + number_of_calls = 0; + assertEquals(subsequenceFirstFromEnd(get_numbers(), 1), '12345678', 'substring first #-end complex'); + check_number_of_calls('substring first #-end complex'); + number_of_calls = 0; + assertEquals(subsequenceFromStartLast(get_numbers(), 6), '789', 'substring # last complex'); + check_number_of_calls('substring # last complex'); + number_of_calls = 0; + assertEquals(subsequenceFromEndLast(get_numbers(), 2), '789', 'substring #-end last complex'); + check_number_of_calls('substring #-end last complex'); + number_of_calls = 0; + assertEquals(subsequenceFromStartFromEnd(get_numbers(), 0, 0), '123456789', 'substring all with # #-end complex'); + check_number_of_calls('substring all with # #-end complex'); + number_of_calls = 0; + assertEquals(subsequenceFromEndFromStart(get_numbers(), 8, 8), '123456789', 'substring all with #-end # complex'); + check_number_of_calls('substring all with #-end # complex'); + number_of_calls = 0; + // Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + assertEquals(subsequenceFromStartFromEnd(get_numbers(), ((0 + 1) - 1), ((0 + 1) - 1)), '123456789', 'substring all with # #-end math complex'); + check_number_of_calls('substring all with # #-end math complex'); +} + +function textToTitleCase(str) { + return str.replace(/\S+/g, + function(txt) {return txt[0].toUpperCase() + txt.substring(1).toLowerCase();}); +} + +/** + * Tests the "change casing" block. + */ +function test_case() { + text = 'Hello World'; + assertEquals(text.toUpperCase(), 'HELLO WORLD', 'uppercase'); + assertEquals((true ? text : null).toUpperCase(), 'HELLO WORLD', 'uppercase order'); + text = 'Hello World'; + assertEquals(text.toLowerCase(), 'hello world', 'lowercase'); + assertEquals((true ? text : null).toLowerCase(), 'hello world', 'lowercase order'); + text = 'heLLo WorlD'; + assertEquals(textToTitleCase(text), 'Hello World', 'titlecase'); + assertEquals(textToTitleCase(true ? text : null), 'Hello World', 'titlecase order'); +} + +/** + * Tests the "trim" block. + */ +function test_trim() { + text = ' abc def '; + assertEquals(text.trim(), 'abc def', 'trim both'); + assertEquals((true ? text : null).trim(), 'abc def', 'trim both order'); + assertEquals(text.replace(/^[\s\xa0]+/, ''), 'abc def ', 'trim left'); + assertEquals((true ? text : null).replace(/^[\s\xa0]+/, ''), 'abc def ', 'trim left order'); + assertEquals(text.replace(/[\s\xa0]+$/, ''), ' abc def', 'trim right'); + assertEquals((true ? text : null).replace(/[\s\xa0]+$/, ''), ' abc def', 'trim right order'); +} + +function textCount(haystack, needle) { + if (needle.length === 0) { + return haystack.length + 1; + } else { + return haystack.split(needle).length - 1; + } +} + +/** + * Tests the "trim" block. + */ +function test_count_text() { + text = 'woolloomooloo'; + assertEquals(textCount(text, 'o'), 8, 'len 1'); + assertEquals(textCount(text, 'oo'), 4, 'len 2'); + assertEquals(textCount(text, 'loo'), 2, 'len 3'); + assertEquals(textCount(text, 'wool'), 1, 'start'); + assertEquals(textCount(text, 'chicken'), 0, 'missing'); + assertEquals(textCount(text, ''), 14, 'empty needle'); + assertEquals(textCount('', 'chicken'), 0, 'empty source'); +} + +/** + * Tests the "trim" block. + */ +function test_text_reverse() { + assertEquals(''.split('').reverse().join(''), '', 'empty string'); + assertEquals('a'.split('').reverse().join(''), 'a', 'len 1'); + assertEquals('ab'.split('').reverse().join(''), 'ba', 'len 2'); + assertEquals('woolloomooloo'.split('').reverse().join(''), 'ooloomoolloow', 'longer'); +} + +function textReplace(haystack, needle, replacement) { + needle = needle.replace(/([-()\[\]{}+?*.$\^|,:# 0, true, 'get random simple'); + assertEquals(list[1], 'Spock', 'get # simple'); + assertEquals(list[((true ? 2 : null) - 1)], 'Spock', 'get # order simple'); + assertEquals(list.slice(-3)[0], 'Kirk', 'get #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list.slice((-(0 + 3)))[0], 'Kirk', 'get #-end order simple'); +} + +/** + * Creates a list for use with the get test. + */ +function get_star_wars() { + number_of_calls = (typeof number_of_calls == 'number' ? number_of_calls : 0) + 1; + return ['Kirk', 'Spock', 'McCoy']; +} + +/** + * Tests the "get" block with a function call. + */ +function test_get_lists_complex() { + list = ['Kirk', 'Spock', 'McCoy']; + number_of_calls = 0; + assertEquals(get_star_wars()[0], 'Kirk', 'get first complex'); + check_number_of_calls('get first complex'); + number_of_calls = 0; + assertEquals((true ? get_star_wars() : null)[0], 'Kirk', 'get first order complex'); + check_number_of_calls('get first order complex'); + number_of_calls = 0; + assertEquals(get_star_wars().slice(-1)[0], 'McCoy', 'get last complex'); + check_number_of_calls('get last complex'); + number_of_calls = 0; + assertEquals((true ? get_star_wars() : null).slice(-1)[0], 'McCoy', 'get last order complex'); + check_number_of_calls('get last order complex'); + number_of_calls = 0; + assertEquals(list.indexOf(listsGetRandomItem(get_star_wars(), false)) + 1 > 0, true, 'get random complex'); + check_number_of_calls('get random complex'); + number_of_calls = 0; + assertEquals(list.indexOf(listsGetRandomItem(true ? get_star_wars() : null, false)) + 1 > 0, true, 'get random order complex'); + check_number_of_calls('get random order complex'); + number_of_calls = 0; + assertEquals(get_star_wars()[1], 'Spock', 'get # complex'); + check_number_of_calls('get # complex'); + number_of_calls = 0; + assertEquals((true ? get_star_wars() : null)[((true ? 2 : null) - 1)], 'Spock', 'get # order complex'); + check_number_of_calls('get # order complex'); + number_of_calls = 0; + assertEquals(get_star_wars().slice(-3)[0], 'Kirk', 'get #-end complex'); + check_number_of_calls('get #-end complex'); + number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals((true ? get_star_wars() : null).slice((-(0 + 3)))[0], 'Kirk', 'get #-end order complex'); + check_number_of_calls('get #-end order complex'); +} + +/** + * Tests the "get and remove" block. + */ +function test_getRemove() { + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals(list.shift(), 'Kirk', 'getremove first'); + assertEquals(list, ['Spock', 'McCoy'], 'getremove first list'); + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals((true ? list : null).shift(), 'Kirk', 'getremove first order'); + assertEquals(list, ['Spock', 'McCoy'], 'getremove first order list'); + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals(list.pop(), 'McCoy', 'getremove last'); + assertEquals(list, ['Kirk', 'Spock'], 'getremove last list'); + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals((true ? list : null).pop(), 'McCoy', 'getremove last order'); + assertEquals(list, ['Kirk', 'Spock'], 'getremove last order list'); + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals(list.indexOf(listsGetRandomItem(list, true)) + 1 == 0, true, 'getremove random'); + assertEquals(list.length, 2, 'getremove random list'); + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals(list.indexOf(listsGetRandomItem(true ? list : null, true)) + 1 == 0, true, 'getremove random order'); + assertEquals(list.length, 2, 'getremove random order list'); + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals(list.splice(1, 1)[0], 'Spock', 'getremove #'); + assertEquals(list, ['Kirk', 'McCoy'], 'getremove # list'); + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals((true ? list : null).splice(((true ? 2 : null) - 1), 1)[0], 'Spock', 'getremove # order'); + assertEquals(list, ['Kirk', 'McCoy'], 'getremove # order list'); + list = ['Kirk', 'Spock', 'McCoy']; + assertEquals(list.splice(-3, 1)[0], 'Kirk', 'getremove #-end'); + assertEquals(list, ['Spock', 'McCoy'], 'getremove #-end list'); + list = ['Kirk', 'Spock', 'McCoy']; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals((true ? list : null).splice((-(0 + 3)), 1)[0], 'Kirk', 'getremove #-end order'); + assertEquals(list, ['Spock', 'McCoy'], 'getremove #-end order list'); +} + +/** + * Tests the "remove" block. + */ +function test_remove() { + list = ['Kirk', 'Spock', 'McCoy']; + list.shift(); + assertEquals(list, ['Spock', 'McCoy'], 'remove first list'); + list = ['Kirk', 'Spock', 'McCoy']; + (true ? list : null).shift(); + assertEquals(list, ['Spock', 'McCoy'], 'remove first order list'); + list = ['Kirk', 'Spock', 'McCoy']; + list.pop(); + assertEquals(list, ['Kirk', 'Spock'], 'remove last list'); + list = ['Kirk', 'Spock', 'McCoy']; + (true ? list : null).pop(); + assertEquals(list, ['Kirk', 'Spock'], 'remove last order list'); + list = ['Kirk', 'Spock', 'McCoy']; + listsGetRandomItem(list, true); + assertEquals(list.length, 2, 'remove random list'); + list = ['Kirk', 'Spock', 'McCoy']; + listsGetRandomItem(true ? list : null, true); + assertEquals(list.length, 2, 'remove random order list'); + list = ['Kirk', 'Spock', 'McCoy']; + list.splice(1, 1); + assertEquals(list, ['Kirk', 'McCoy'], 'remove # list'); + list = ['Kirk', 'Spock', 'McCoy']; + (true ? list : null).splice(((true ? 2 : null) - 1), 1); + assertEquals(list, ['Kirk', 'McCoy'], 'remove # order list'); + list = ['Kirk', 'Spock', 'McCoy']; + list.splice(-3, 1);assertEquals(list, ['Spock', 'McCoy'], 'remove #-end list'); + list = ['Kirk', 'Spock', 'McCoy']; + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + (true ? list : null).splice((-(0 + 3)), 1);assertEquals(list, ['Spock', 'McCoy'], 'remove #-end order list'); +} + +/** + * Tests the "set" block. + */ +function test_set() { + list = ['Picard', 'Riker', 'Crusher']; + list[0] = 'Jean-Luc'; + assertEquals(list, ['Jean-Luc', 'Riker', 'Crusher'], 'set first list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null)[0] = 'Jean-Luc'; + assertEquals(list, ['Jean-Luc', 'Riker', 'Crusher'], 'set first order list'); + list = ['Picard', 'Riker', 'Crusher']; + list[list.length - 1] = 'Beverly'; + assertEquals(list, ['Picard', 'Riker', 'Beverly'], 'set last list'); + list = ['Picard', 'Riker', 'Crusher']; + var tmpList = (true ? list : null); + tmpList[tmpList.length - 1] = 'Beverly'; + assertEquals(list, ['Picard', 'Riker', 'Beverly'], 'set last order list'); + list = ['Picard', 'Riker', 'Crusher']; + var tmpX = Math.floor(Math.random() * list.length); + list[tmpX] = 'Data'; + assertEquals(list.length, 3, 'set random list'); + list = ['Picard', 'Riker', 'Crusher']; + var tmpList2 = (true ? list : null); + var tmpX2 = Math.floor(Math.random() * tmpList2.length); + tmpList2[tmpX2] = 'Data'; + assertEquals(list.length, 3, 'set random order list'); + list = ['Picard', 'Riker', 'Crusher']; + list[2] = 'Pulaski'; + assertEquals(list, ['Picard', 'Riker', 'Pulaski'], 'set # list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null)[((true ? 3 : null) - 1)] = 'Pulaski'; + assertEquals(list, ['Picard', 'Riker', 'Pulaski'], 'set # order list'); + list = ['Picard', 'Riker', 'Crusher']; + list[list.length - 1] = 'Pulaski'; + assertEquals(list, ['Picard', 'Riker', 'Pulaski'], 'set #-end list'); + list = ['Picard', 'Riker', 'Crusher']; + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + var tmpList3 = (true ? list : null); + tmpList3[tmpList3.length - (0 + 2)] = 'Pulaski'; + assertEquals(list, ['Picard', 'Pulaski', 'Crusher'], 'set #-end order list'); +} + +/** + * Tests the "insert" block. + */ +function test_insert() { + list = ['Picard', 'Riker', 'Crusher']; + list.unshift('Data'); + assertEquals(list, ['Data', 'Picard', 'Riker', 'Crusher'], 'insert first list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null).unshift('Data'); + assertEquals(list, ['Data', 'Picard', 'Riker', 'Crusher'], 'insert first order list'); + list = ['Picard', 'Riker', 'Crusher']; + list.push('Data'); + assertEquals(list, ['Picard', 'Riker', 'Crusher', 'Data'], 'insert last list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null).push('Data'); + assertEquals(list, ['Picard', 'Riker', 'Crusher', 'Data'], 'insert last order list'); + list = ['Picard', 'Riker', 'Crusher']; + var tmpX3 = Math.floor(Math.random() * list.length); + list.splice(tmpX3, 0, 'Data'); + assertEquals(list.length, 4, 'insert random list'); + list = ['Picard', 'Riker', 'Crusher']; + var tmpList4 = (true ? list : null); + var tmpX4 = Math.floor(Math.random() * tmpList4.length); + tmpList4.splice(tmpX4, 0, 'Data'); + assertEquals(list.length, 4, 'insert random order list'); + list = ['Picard', 'Riker', 'Crusher']; + list.splice(2, 0, 'Data'); + assertEquals(list, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert # list'); + list = ['Picard', 'Riker', 'Crusher']; + (true ? list : null).splice(((true ? 3 : null) - 1), 0, 'Data'); + assertEquals(list, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert # order list'); + list = ['Picard', 'Riker', 'Crusher']; + list.splice(list.length - 1, 0, 'Data'); + assertEquals(list, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert #-end list'); + list = ['Picard', 'Riker', 'Crusher']; + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + var tmpList5 = (true ? list : null); + tmpList5.splice(tmpList5.length - (0 + 2), 0, 'Data'); + assertEquals(list, ['Picard', 'Data', 'Riker', 'Crusher'], 'insert #-end order list'); +} + +/** + * Tests the "get sub-list" block with a variable. + */ +function test_sublist_simple() { + list = ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']; + assertEquals(list.slice(1, 3), ['Challenger', 'Discovery'], 'sublist # simple'); + assertEquals(list.slice(((true ? 2 : null) - 1), true ? 3 : null), ['Challenger', 'Discovery'], 'sublist # simple order'); + assertEquals(list.slice(list.length - 3, list.length - 1), ['Discovery', 'Atlantis'], 'sublist #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list.slice(list.length - (0 + 3), list.length - ((0 + 2) - 1)), ['Discovery', 'Atlantis'], 'sublist #-end simple order'); + assertEquals(list.slice(0), list, 'sublist first-last simple'); + changing_list = ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']; + list_copy = changing_list.slice(0); + listsGetRandomItem(changing_list, true); + assertEquals(list_copy, list, 'sublist first-last simple copy check'); + assertEquals(list.slice(1, list.length - 1), ['Challenger', 'Discovery', 'Atlantis'], 'sublist # #-end simple'); + assertEquals(list.slice(list.length - 3, 4), ['Discovery', 'Atlantis'], 'sublist #-end # simple'); + assertEquals(list.slice(0, 4), ['Columbia', 'Challenger', 'Discovery', 'Atlantis'], 'sublist first # simple'); + assertEquals(list.slice(0, list.length - 3), ['Columbia', 'Challenger'], 'sublist first #-end simple'); + assertEquals(list.slice(3, list.length), ['Atlantis', 'Endeavour'], 'sublist # last simple'); + assertEquals(list.slice(list.length - 4, list.length), ['Challenger', 'Discovery', 'Atlantis', 'Endeavour'], 'sublist #-end last simple'); + assertEquals(list.slice(0, list.length - 0), list, 'sublist all with # #-end simple'); + assertEquals(list.slice(list.length - 5, 5), list, 'sublist all with #-end # simple'); + // Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + assertEquals(list.slice(((0 + 1) - 1), list.length - ((0 + 1) - 1)), list, 'sublist all with # #-end math simple'); +} + +/** + * Creates a list for use with the sublist test. + */ +function get_space_shuttles() { + number_of_calls = (typeof number_of_calls == 'number' ? number_of_calls : 0) + 1; + return ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour']; +} + +/** + * Tests the "get sub-list" block with a function call. + */ +function test_sublist_complex() { + number_of_calls = 0; + assertEquals(get_space_shuttles().slice(1, 3), ['Challenger', 'Discovery'], 'sublist # start complex'); + check_number_of_calls('sublist # start complex'); + number_of_calls = 0; + assertEquals((true ? get_space_shuttles() : null).slice(((true ? 2 : null) - 1), true ? 3 : null), ['Challenger', 'Discovery'], 'sublist # start order complex'); + check_number_of_calls('sublist # start order complex'); + number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(subsequenceFromEndFromEnd(get_space_shuttles(), 2, 1), ['Discovery', 'Atlantis'], 'sublist # end complex'); + assertEquals(number_of_calls, 1, 'sublist # end complex number of calls'); + number_of_calls = 0; + assertEquals(subsequenceFromEndFromEnd((true ? get_space_shuttles() : null), ((0 + 3) - 1), ((0 + 2) - 1)), ['Discovery', 'Atlantis'], 'sublist # end order complex'); + check_number_of_calls('sublist # end order complex'); + number_of_calls = 0; + assertEquals(get_space_shuttles().slice(0), list, 'sublist first-last complex'); + check_number_of_calls('sublist first-last complex'); + number_of_calls = 0; + assertEquals(subsequenceFromStartFromEnd(get_space_shuttles(), 1, 1), ['Challenger', 'Discovery', 'Atlantis'], 'sublist # #-end complex'); + check_number_of_calls('sublist # #-end complex'); + number_of_calls = 0; + assertEquals(subsequenceFromEndFromStart(get_space_shuttles(), 2, 3), ['Discovery', 'Atlantis'], 'sublist #-end # complex'); + check_number_of_calls('sublist #-end # complex'); + number_of_calls = 0; + assertEquals(get_space_shuttles().slice(0, 4), ['Columbia', 'Challenger', 'Discovery', 'Atlantis'], 'sublist first # complex'); + check_number_of_calls('sublist first # complex'); + number_of_calls = 0; + assertEquals(subsequenceFirstFromEnd(get_space_shuttles(), 3), ['Columbia', 'Challenger'], 'sublist first #-end complex'); + check_number_of_calls('sublist first #-end complex'); + number_of_calls = 0; + assertEquals(subsequenceFromStartLast(get_space_shuttles(), 3), ['Atlantis', 'Endeavour'], 'sublist # last complex'); + check_number_of_calls('sublist # last complex'); + number_of_calls = 0; + assertEquals(subsequenceFromEndLast(get_space_shuttles(), 3), ['Challenger', 'Discovery', 'Atlantis', 'Endeavour'], 'sublist #-end last simple'); + check_number_of_calls('sublist #-end last simple'); + number_of_calls = 0; + assertEquals(subsequenceFromStartFromEnd(get_space_shuttles(), 0, 0), list, 'sublist all with # #-end complex'); + check_number_of_calls('sublist all with # #-end complex'); + number_of_calls = 0; + assertEquals(subsequenceFromEndFromStart(get_space_shuttles(), 4, 4), list, 'sublist all with #-end # complex'); + check_number_of_calls('sublist all with #-end # complex'); + number_of_calls = 0; + // Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + assertEquals(subsequenceFromStartFromEnd(get_space_shuttles(), ((0 + 1) - 1), ((0 + 1) - 1)), list, 'sublist all with # #-end math complex'); + check_number_of_calls('sublist all with # #-end math complex'); +} + +/** + * Tests the "join" block. + */ +function test_join() { + list = ['Vulcan', 'Klingon', 'Borg']; + assertEquals(list.join(','), 'Vulcan,Klingon,Borg', 'join'); + assertEquals((true ? list : null).join(','), 'Vulcan,Klingon,Borg', 'join order'); +} + +/** + * Tests the "split" block. + */ +function test_split() { + text = 'Vulcan,Klingon,Borg'; + assertEquals(text.split(','), ['Vulcan', 'Klingon', 'Borg'], 'split'); + assertEquals((true ? text : null).split(','), ['Vulcan', 'Klingon', 'Borg'], 'split order'); +} + +function listsGetSortCompare(type, direction) { + var compareFuncs = { + "NUMERIC": function(a, b) { + return parseFloat(a) - parseFloat(b); }, + "TEXT": function(a, b) { + return a.toString() > b.toString() ? 1 : -1; }, + "IGNORE_CASE": function(a, b) { + return a.toString().toLowerCase() > b.toString().toLowerCase() ? 1 : -1; }, + }; + var compare = compareFuncs[type]; + return function(a, b) { return compare(a, b) * direction; } +} + +/** + * Tests the "alphabetic sort" block. + */ +function test_sort_alphabetic() { + list = ['Vulcan', 'klingon', 'Borg']; + assertEquals(list.slice().sort(listsGetSortCompare("TEXT", 1)), ['Borg', 'Vulcan', 'klingon'], 'sort alphabetic ascending'); + assertEquals((true ? list : null).slice().sort(listsGetSortCompare("TEXT", 1)), ['Borg', 'Vulcan', 'klingon'], 'sort alphabetic ascending order'); +} + +/** + * Tests the "alphabetic sort ignore case" block. + */ +function test_sort_ignoreCase() { + list = ['Vulcan', 'klingon', 'Borg']; + assertEquals(list.slice().sort(listsGetSortCompare("IGNORE_CASE", 1)), ['Borg', 'klingon', 'Vulcan'], 'sort ignore case ascending'); + assertEquals((true ? list : null).slice().sort(listsGetSortCompare("IGNORE_CASE", 1)), ['Borg', 'klingon', 'Vulcan'], 'sort ignore case ascending order'); +} + +/** + * Tests the "numeric sort" block. + */ +function test_sort_numeric() { + list = [8, 18, -1]; + assertEquals(list.slice().sort(listsGetSortCompare("NUMERIC", -1)), [18, 8, -1], 'sort numeric descending'); + assertEquals((true ? list : null).slice().sort(listsGetSortCompare("NUMERIC", -1)), [18, 8, -1], 'sort numeric descending order'); +} + +/** + * Tests the "list reverse" block. + */ +function test_lists_reverse() { + list = [8, 18, -1, 64]; + assertEquals(list.slice().reverse(), [64, -1, 18, 8], 'reverse a copy'); + assertEquals(list, [8, 18, -1, 64], 'reverse a copy original'); + 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... + */ +function test_procedure() { + procedure_1(8, 2); + assertEquals(proc_z, 4, 'procedure with global'); + proc_w = false; + procedure_2(false); + assertEquals(proc_w, true, 'procedure no return'); + proc_w = false; + procedure_2(true); + assertEquals(proc_w, false, 'procedure return'); +} + +/** + * Describe this function... + */ +function procedure_1(proc_x, proc_y) { + proc_z = proc_x / proc_y; +} + +/** + * Describe this function... + */ +function procedure_2(proc_x) { + if (proc_x) { + return; + } + proc_w = true; +} + +/** + * Describe this function... + */ +function test_function() { + assertEquals(function_1(2, 3), -1, 'function with arguments'); + assertEquals(func_z, 'side effect', 'function with side effect'); + func_a = 'unchanged'; + func_c = 'global'; + assertEquals(function_2(2), '3global', 'function with global'); + assertEquals(func_a, 'unchanged', 'function with scope'); + assertEquals(function_3(true), true, 'function return'); + assertEquals(function_3(false), false, 'function no return'); +} + +/** + * Describe this function... + */ +function function_1(func_x, func_y) { + func_z = 'side effect'; + return func_x - func_y; +} + +/** + * Describe this function... + */ +function function_2(func_a) { + func_a = (typeof func_a == 'number' ? func_a : 0) + 1; + return String(func_a) + String(func_c); +} + +/** + * Describe this function... + */ +function function_3(func_a) { + if (func_a) { + return true; + } + return false; +} + +/** + * Describe this function... + */ +function recurse(n) { + if (n > 0) { + text = [recurse(n - 1),n,recurse(n - 1)].join(''); + } else { + text = '-'; + } + return text; +} + + +unittestResults = []; +console.log('\n====================\n\nRunning suite: Logic') +assertEquals(true, true, 'True'); +assertEquals(false, false, 'False'); +assertEquals(!false, true, 'Not true'); +assertEquals(!true, false, 'Not false'); +test_if(); +test_ifelse(); +test_equalities(); +test_and(); +test_or(); +test_ternary(); +console.log(unittest_report()); +unittestResults = null; + +unittestResults = []; +console.log('\n====================\n\nRunning suite: Loops 1') +test_repeat(); +test_repeat_ext(); +test_while(); +test_foreach(); +console.log(unittest_report()); +unittestResults = null; + +unittestResults = []; +console.log('\n====================\n\nRunning suite: Loops 2') +test_count_loops(); +test_count_by(); +console.log(unittest_report()); +unittestResults = null; + +unittestResults = []; +console.log('\n====================\n\nRunning suite: Loops 3') +test_break(); +test_continue(); +console.log(unittest_report()); +unittestResults = null; + +unittestResults = []; +console.log('\n====================\n\nRunning suite: Math') +test_arithmetic(); +test_single(); +test_trig(); +test_constant(); +test_change(); +test_number_properties(); +test_round(); +test_operations_on_list(); +test_constraint(); +test_mod(); +test_random_integer(); +test_random_fraction(); +test_atan2(); +console.log(unittest_report()); +unittestResults = null; + +unittestResults = []; +console.log('\n====================\n\nRunning suite: Text') +test_text_length(); +test_empty_text(); +test_create_text(); +test_append(); +test_find_text_simple(); +test_find_text_complex(); +test_get_text_simple(); +test_get_text_complex(); +test_substring_simple(); +test_substring_complex(); +test_case(); +test_trim(); +test_count_text(); +test_text_reverse(); +test_replace(); +console.log(unittest_report()); +unittestResults = null; + +unittestResults = []; +console.log('\n====================\n\nRunning suite: Lists') +test_create_lists(); +test_lists_empty(); +test_lists_length(); +test_find_lists_simple(); +test_find_lists_complex(); +test_get_lists_simple(); +test_get_lists_complex(); +test_getRemove(); +test_remove(); +test_set(); +test_insert(); +test_sublist_simple(); +test_sublist_complex(); +test_join(); +test_split(); +test_sort_alphabetic(); +test_sort_ignoreCase(); +test_sort_numeric(); +test_lists_reverse(); +console.log(unittest_report()); +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 = []; +console.log('\n====================\n\nRunning suite: Variables') +item = 123; +assertEquals(item, 123, 'variable'); +if2 = 123; +assertEquals(if2, 123, 'reserved variable'); +console.log(unittest_report()); +unittestResults = null; + +// Intentionally non-connected variable. +naked; + +unittestResults = []; +console.log('\n====================\n\nRunning suite: Functions') +test_procedure(); +test_function(); +assertEquals(recurse(3), '-1-2-1-3-1-2-1-', 'test recurse'); +console.log(unittest_report()); +unittestResults = null; diff --git a/tests/generators/golden/generated.lua b/tests/generators/golden/generated.lua new file mode 100644 index 000000000..9b6acfa8b --- /dev/null +++ b/tests/generators/golden/generated.lua @@ -0,0 +1,1872 @@ +function unittest_report() + -- Create test report. + local report = {} + local summary = {} + local fails = 0 + for _, v in pairs(unittestResults) do + if v["success"] then + table.insert(summary, ".") + else + table.insert(summary, "F") + fails = fails + 1 + table.insert(report, "FAIL: " .. v["title"]) + table.insert(report, v["log"]) + end + end + table.insert(report, 1, table.concat(summary)) + table.insert(report, "") + table.insert(report, "Number of tests run: " .. #unittestResults) + table.insert(report, "") + if fails > 0 then + table.insert(report, "FAILED (failures=" .. fails .. ")") + else + table.insert(report, "OK") + end + return table.concat(report, "\n") +end + +function assertEquals(actual, expected, message) + -- Asserts that a value equals another value. + assert(unittestResults ~= nil, "Orphaned assert equals: " .. message) + if type(actual) == "table" and type(expected) == "table" then + local lists_match = #actual == #expected + if lists_match then + for i, v1 in ipairs(actual) do + local v2 = expected[i] + if type(v1) == "number" and type(v2) == "number" then + if math.abs(v1 - v2) > 1e-9 then + lists_match = false + end + elseif v1 ~= v2 then + lists_match = false + end + end + end + if lists_match then + table.insert(unittestResults, {success=true, log="OK", title=message}) + return + else + -- produce the non-matching strings for a human-readable error + expected = "{" .. table.concat(expected, ", ") .. "}" + actual = "{" .. table.concat(actual, ", ") .. "}" + end + end + if actual == expected or (type(actual) == "number" and type(expected) == "number" and math.abs(actual - expected) < 1e-9) then + table.insert(unittestResults, {success=true, log="OK", title=message}) + else + table.insert(unittestResults, {success=false, log=string.format("Expected: %s\nActual: %s", tostring(expected), tostring(actual)), title=message}) + end +end + +function unittest_fail(message) + -- Always assert an error. + assert(unittestResults ~= nil, "Orphaned assert fail: " .. message) + table.insert(unittestResults, {success=false, log="Fail.", title=message}) +end + +-- Describe this function... +function test_if() + if false then + unittest_fail('if false') + end + ok = false + if true then + ok = true + end + assertEquals(ok, true, 'if true') + ok = false + if false then + unittest_fail('if/else false') + else + ok = true + end + assertEquals(ok, true, 'if/else false') + ok = false + if true then + ok = true + else + unittest_fail('if/else true') + end + assertEquals(ok, true, 'if/else true') + ok = false + if false then + unittest_fail('elseif 1') + elseif true then + ok = true + elseif true then + unittest_fail('elseif 2') + else + unittest_fail('elseif 3') + end + assertEquals(ok, true, 'elseif 4') +end + + +-- Describe this function... +function test_ifelse() + ok = false + if true then + ok = true + else + unittest_fail('ifelse true') + end + assertEquals(ok, true, 'ifelse true') + ok = false + if false then + unittest_fail('ifelse false') + else + ok = true + end + assertEquals(ok, true, 'ifelse false') +end + + +-- Describe this function... +function test_equalities() + assertEquals(2 == 2, true, 'Equal yes') + assertEquals(3 == 4, false, 'Equal no') + assertEquals(5 ~= 6, true, 'Not equal yes') + assertEquals(3 == 4, false, 'Not equal no') + assertEquals(5 < 6, true, 'Smaller yes') + assertEquals(7 < 7, false, 'Smaller no') + assertEquals(9 > 8, true, 'Greater yes') + assertEquals(10 > 10, false, 'Greater no') + assertEquals(11 <= 11, true, 'Smaller-equal yes') + assertEquals(13 <= 12, false, 'Smaller-equal no') + assertEquals(14 >= 14, true, 'Greater-equal yes') + assertEquals(15 >= 16, false, 'Greater-equal no') +end + + +-- Describe this function... +function test_and() + assertEquals(true and true, true, 'And true/true') + assertEquals(false and true, false, 'And false/true') + assertEquals(true and false, false, 'And true/false') + assertEquals(false and false, false, 'And false/false') +end + + +-- Describe this function... +function test_or() + assertEquals(true or true, true, 'Or true/true') + assertEquals(false or true, true, 'Or false/true') + assertEquals(true or false, true, 'Or true/false') + assertEquals(false or false, false, 'Or false/false') +end + + +-- Describe this function... +function test_ternary() + assertEquals(true and 42 or 99, 42, 'if true') + assertEquals(false and 42 or 99, 99, 'if true') +end + + +-- Describe this function... +function test_foreach() + log = '' + for _, x in ipairs({'a', 'b', 'c'}) do + log = log .. x + end + assertEquals(log, 'abc', 'for loop') +end + + +-- Describe this function... +function test_repeat() + count = 0 + for count2 = 1, 10 do + count = count + 1 + end + assertEquals(count, 10, 'repeat 10') +end + + +-- Describe this function... +function test_while() + while false do + unittest_fail('while 0') + end + while not true do + unittest_fail('until 0') + end + count = 1 + while count ~= 10 do + count = count + 1 + end + assertEquals(count, 10, 'while 10') + count = 1 + while not (count == 10) do + count = count + 1 + end + assertEquals(count, 10, 'until 10') +end + + +-- Describe this function... +function test_repeat_ext() + count = 0 + for count3 = 1, 10 do + count = count + 1 + end + assertEquals(count, 10, 'repeat 10') +end + + +-- Describe this function... +function test_count_by() + log = '' + for x = 1, 8, 2 do + log = log .. x + end + assertEquals(log, '1357', 'count up ints') + log = '' + for x = 8, 1, -2 do + log = log .. x + end + assertEquals(log, '8642', 'count down ints') + loglist = {} + for x = 1, 8, 1.5 do + table.insert(loglist, #loglist + 1, x) + end + assertEquals(loglist, {1, 2.5, 4, 5.5, 7}, 'count with floats') + loglist = {} + x_inc = math.abs(1 - 2) + if (1 + 0) > (8 + 0) then + x_inc = -x_inc + end + for x = 1 + 0, 8 + 0, x_inc do + table.insert(loglist, #loglist + 1, x) + end + assertEquals(loglist, {1, 2, 3, 4, 5, 6, 7, 8}, 'count up non-trivial ints') + loglist = {} + x_inc2 = 2 + if (8 + 0) > (1 + 0) then + x_inc2 = -x_inc2 + end + for x = 8 + 0, 1 + 0, x_inc2 do + table.insert(loglist, #loglist + 1, x) + end + assertEquals(loglist, {8, 6, 4, 2}, 'count down non-trivial ints') + loglist = {} + x_inc3 = math.abs(1 + 0) + if (5 + 0.5) > (1 + 0) then + x_inc3 = -x_inc3 + end + for x = 5 + 0.5, 1 + 0, x_inc3 do + table.insert(loglist, #loglist + 1, x) + end + assertEquals(loglist, {5.5, 4.5, 3.5, 2.5, 1.5}, 'count with floats') +end + + +-- Describe this function... +function test_count_loops() + log = '' + for x = 1, 8, 1 do + log = log .. x + end + assertEquals(log, '12345678', 'count up') + log = '' + for x = 8, 1, -1 do + log = log .. x + end + assertEquals(log, '87654321', 'count down') + loglist = {} + x_inc4 = 1 + if (1 + 0) > (4 + 0) then + x_inc4 = -x_inc4 + end + for x = 1 + 0, 4 + 0, x_inc4 do + table.insert(loglist, #loglist + 1, x) + end + assertEquals(loglist, {1, 2, 3, 4}, 'count up non-trivial') + loglist = {} + x_inc5 = 1 + if (3 + 1) > (1 + 0) then + x_inc5 = -x_inc5 + end + for x = 3 + 1, 1 + 0, x_inc5 do + table.insert(loglist, #loglist + 1, x) + end + assertEquals(loglist, {4, 3, 2, 1}, 'count down non-trivial') +end + + +-- Describe this function... +function test_continue() + log = '' + count = 0 + while count ~= 8 do + count = count + 1 + if count == 5 then + goto continue + end + log = log .. count + ::continue:: + end + assertEquals(log, '1234678', 'while continue') + log = '' + count = 0 + while not (count == 8) do + count = count + 1 + if count == 5 then + goto continue + end + log = log .. count + ::continue:: + end + assertEquals(log, '1234678', 'until continue') + log = '' + for x = 1, 8, 1 do + if x == 5 then + goto continue + end + log = log .. x + ::continue:: + end + assertEquals(log, '1234678', 'count continue') + log = '' + for _, x in ipairs({'a', 'b', 'c', 'd'}) do + if x == 'c' then + goto continue + end + log = log .. x + ::continue:: + end + assertEquals(log, 'abd', 'for continue') +end + + +-- Describe this function... +function test_break() + count = 1 + while count ~= 10 do + if count == 5 then + break + end + count = count + 1 + end + assertEquals(count, 5, 'while break') + count = 1 + while not (count == 10) do + if count == 5 then + break + end + count = count + 1 + end + assertEquals(count, 5, 'until break') + log = '' + for x = 1, 8, 1 do + if x == 5 then + break + end + log = log .. x + end + assertEquals(log, '1234', 'count break') + log = '' + for _, x in ipairs({'a', 'b', 'c', 'd'}) do + if x == 'c' then + break + end + log = log .. x + end + assertEquals(log, 'ab', 'for break') +end + + +-- Tests the "single" block. +function test_single() + assertEquals(math.sqrt(25), 5, 'sqrt') + assertEquals(math.abs(-25), 25, 'abs') + assertEquals(-(-25), 25, 'negate') + assertEquals(math.log(1), 0, 'ln') + assertEquals(math.log(100, 10), 2, 'log10') + assertEquals(math.exp(2), 7.38905609893065, 'exp') + assertEquals(10 ^ 2, 100, 'power10') +end + + +-- Tests the "arithmetic" block for all operations and checks +-- parenthesis are properly generated for different orders. +function test_arithmetic() + assertEquals(1 + 2, 3, 'add') + assertEquals(1 - 2, -1, 'subtract') + assertEquals(1 - (0 + 2), -1, 'subtract order with add') + assertEquals(1 - (0 - 2), 3, 'subtract order with subtract') + assertEquals(4 * 2.5, 10, 'multiply') + assertEquals(4 * (0 + 2.5), 10, 'multiply order') + assertEquals(8.2 / -5, -1.64, 'divide') + assertEquals(8.2 / (0 + -5), -1.64, 'divide order') + assertEquals(10 ^ 4, 10000, 'power') + assertEquals(10 ^ (0 + 4), 10000, 'power order') +end + + +-- Tests the "trig" block. +function test_trig() + assertEquals(math.sin(math.rad(90)), 1, 'sin') + assertEquals(math.cos(math.rad(180)), -1, 'cos') + assertEquals(math.tan(math.rad(0)), 0, 'tan') + assertEquals(math.deg(math.asin(-1)), -90, 'asin') + assertEquals(math.deg(math.acos(1)), 0, 'acos') + assertEquals(math.deg(math.atan(1)), 45, 'atan') +end + + +-- Tests the "constant" blocks. +function test_constant() + assertEquals(math.floor(math.pi * 1000), 3141, 'const pi') + assertEquals(math.floor(math.exp(1) * 1000), 2718, 'const e') + assertEquals(math.floor(((1 + math.sqrt(5)) / 2) * 1000), 1618, 'const golden') + assertEquals(math.floor(math.sqrt(2) * 1000), 1414, 'const sqrt 2') + assertEquals(math.floor(math.sqrt(1 / 2) * 1000), 707, 'const sqrt 0.5') + assertEquals(9999 < math.huge, true, 'const infinity') +end + + +function math_isPrime(n) + -- https://en.wikipedia.org/wiki/Primality_test#Naive_methods + if n == 2 or n == 3 then + return true + end + -- False if n is NaN, negative, is 1, or not whole. + -- And false if n is divisible by 2 or 3. + if not(n > 1) or n % 1 ~= 0 or n % 2 == 0 or n % 3 == 0 then + return false + end + -- Check all the numbers of form 6k +/- 1, up to sqrt(n). + for x = 6, math.sqrt(n) + 1.5, 6 do + if n % (x - 1) == 0 or n % (x + 1) == 0 then + return false + end + end + return true +end + +-- Tests the "number property" blocks. +function test_number_properties() + assertEquals(42 % 2 == 0, true, 'even') + assertEquals(42.1 % 2 == 1, false, 'odd') + assertEquals(math_isPrime(5), true, 'prime 5') + assertEquals(math_isPrime(25), false, 'prime 25') + assertEquals(math_isPrime(-31.1), false, 'prime negative') + assertEquals(math.pi % 1 == 0, false, 'whole') + assertEquals(math.huge > 0, true, 'positive') + assertEquals(-42 < 0, true, 'negative') + assertEquals(42 % 2 == 0, true, 'divisible') +end + + +-- Tests the "round" block. +function test_round() + assertEquals(math.floor(42.42 + .5), 42, 'round') + assertEquals(math.ceil(-42.42), -42, 'round up') + assertEquals(math.floor(42.42), 42, 'round down') +end + + +-- Tests the "change" block. +function test_change() + varToChange = 100 + varToChange = varToChange + 42 + assertEquals(varToChange, 142, 'change') +end + + +function math_sum(t) + local result = 0 + for _, v in ipairs(t) do + result = result + v + end + return result +end + +function math_min(t) + if #t == 0 then + return 0 + end + local result = math.huge + for _, v in ipairs(t) do + if v < result then + result = v + end + end + return result +end + +function math_max(t) + if #t == 0 then + return 0 + end + local result = -math.huge + for _, v in ipairs(t) do + if v > result then + result = v + end + end + return result +end + +function math_average(t) + if #t == 0 then + return 0 + end + return math_sum(t) / #t +end + +function math_median(t) + -- Source: http://lua-users.org/wiki/SimpleStats + if #t == 0 then + return 0 + end + local temp={} + for _, v in ipairs(t) do + if type(v) == "number" then + table.insert(temp, v) + end + end + table.sort(temp) + if #temp % 2 == 0 then + return (temp[#temp/2] + temp[(#temp/2)+1]) / 2 + else + return temp[math.ceil(#temp/2)] + end +end + +function math_modes(t) + -- Source: http://lua-users.org/wiki/SimpleStats + local counts={} + for _, v in ipairs(t) do + if counts[v] == nil then + counts[v] = 1 + else + counts[v] = counts[v] + 1 + end + end + local biggestCount = 0 + for _, v in pairs(counts) do + if v > biggestCount then + biggestCount = v + end + end + local temp={} + for k, v in pairs(counts) do + if v == biggestCount then + table.insert(temp, k) + end + end + return temp +end + +function math_standard_deviation(t) + local m + local vm + local total = 0 + local count = 0 + local result + m = #t == 0 and 0 or math_sum(t) / #t + for _, v in ipairs(t) do + if type(v) == 'number' then + vm = v - m + total = total + (vm * vm) + count = count + 1 + end + end + result = math.sqrt(total / (count-1)) + return result +end + +function math_random_list(t) + if #t == 0 then + return nil + end + return t[math.random(#t)] +end + +function first_index(t, elem) + for k, v in ipairs(t) do + if v == elem then + return k + end + end + return 0 +end + +-- Tests the "list operation" blocks. +function test_operations_on_list() + assertEquals(math_sum({3, 4, 5}), 12, 'sum') + assertEquals(math_min({3, 4, 5}), 3, 'min') + assertEquals(math_max({3, 4, 5}), 5, 'max') + assertEquals(math_average({3, 4, 5}), 4, 'average') + assertEquals(math_median({3, 4, 5, 1}), 3.5, 'median') + assertEquals(math_modes({3, 4, 3}), {3}, 'modes') + assertEquals(math_modes({3, 4, 3, 1, 4}), {3, 4}, 'modes multiple') + assertEquals(math_standard_deviation({3, 3, 3}), 0, 'standard dev') + assertEquals(first_index({3, 4, 5}, math_random_list({3, 4, 5})) > 0, true, 'random') +end + + +-- Tests the "mod" block. +function test_mod() + assertEquals(42 % 5, 2, 'mod') +end + + +-- Tests the "constrain" block. +function test_constraint() + assertEquals(math.min(math.max(100, 0), 42), 42, 'constraint') +end + + +-- Tests the "random integer" block. +function test_random_integer() + rand = math.random(5, 10) + assertEquals(rand >= 5 and rand <= 10, true, 'randRange') + assertEquals(rand % 1 == 0, true, 'randInteger') +end + + +-- Tests the "random fraction" block. +function test_random_fraction() + rand = math.random() + assertEquals(rand >= 0 and rand <= 1, true, 'randFloat') +end + + +-- Describe this function... +function test_atan2() + assertEquals(math.deg(math.atan2(5, -5)), 135, 'atan2') + assertEquals(math.deg(math.atan2(-12, 0)), -90, 'atan2') +end + + +-- Checks that the number of calls is one in order +-- to confirm that a function was only called once. +function check_number_of_calls(test_name) + test_name = test_name .. 'number of calls' + assertEquals(number_of_calls, 1, test_name) +end + + +-- Tests the "create text with" block with varying number of inputs. +function test_create_text() + assertEquals('', '', 'no text') + assertEquals(tostring('Hello'), 'Hello', 'create single') + assertEquals(tostring(-1), '-1', 'create single number') + assertEquals('K' .. 9, 'K9', 'create double text') + assertEquals(4 .. 2, '42', 'create double text numbers') + assertEquals(table.concat({1, 2, 3}), '123', 'create triple') + assertEquals(table.concat({1, true and 0 or nil, 'M'}), '10M', 'create order') +end + + +-- Creates an empty string for use with the empty test. +function get_empty() + return '' +end + + +-- Tests the "is empty" block". +function test_empty_text() + assertEquals(#'Google' == 0, false, 'not empty') + assertEquals(#'' == 0, true, 'empty') + assertEquals(#get_empty() == 0, true, 'empty complex') + assertEquals(#(true and '' or nil) == 0, true, 'empty order') +end + + +-- Tests the "length" block. +function test_text_length() + assertEquals(#'', 0, 'zero length') + assertEquals(#'Google', 6, 'non-zero length') + assertEquals(#(true and 'car' or nil), 3, 'length order') +end + + +-- Tests the "append text" block with different types of parameters. +function test_append() + item = 'Miserable' + item = item .. 'Failure' + assertEquals(item, 'MiserableFailure', 'append text') + item = 12 + item = item .. 34 + assertEquals(item, '1234', 'append number') + item = 'Something ' + item = item .. (true and 'Positive' or nil) + assertEquals(item, 'Something Positive', 'append order') +end + + +function firstIndexOf(str, substr) + local i = string.find(str, substr, 1, true) + if i == nil then + return 0 + else + return i + end +end + +function lastIndexOf(str, substr) + local i = string.find(string.reverse(str), string.reverse(substr), 1, true) + if i then + return #str + 2 - i - #substr + end + return 0 +end + +-- Tests the "find" block with a variable. +function test_find_text_simple() + text = 'Banana' + assertEquals(firstIndexOf(text, 'an'), 2, 'find first simple') + assertEquals(lastIndexOf(text, 'an'), 4, 'find last simple') + assertEquals(firstIndexOf(text, 'Peel'), 0, 'find none simple') +end + + +-- Creates a string for use with the find test. +function get_fruit() + number_of_calls = number_of_calls + 1 + return 'Banana' +end + + +-- Tests the "find" block with a function call. +function test_find_text_complex() + number_of_calls = 0 + assertEquals(firstIndexOf(get_fruit(), 'an'), 2, 'find first complex') + check_number_of_calls('find first complex') + number_of_calls = 0 + assertEquals(firstIndexOf(true and get_fruit() or nil, 'an'), 2, 'find first order complex') + check_number_of_calls('find first order complex') + number_of_calls = 0 + assertEquals(lastIndexOf(get_fruit(), 'an'), 4, 'find last complex') + check_number_of_calls('find last complex') + number_of_calls = 0 + assertEquals(lastIndexOf(true and get_fruit() or nil, 'an'), 4, 'find last order complex') + check_number_of_calls('find last order complex') + number_of_calls = 0 + assertEquals(firstIndexOf(get_fruit(), 'Peel'), 0, 'find none complex') + check_number_of_calls('find none complex') + number_of_calls = 0 + assertEquals(firstIndexOf(true and get_fruit() or nil, 'Peel'), 0, 'find none order complex') + check_number_of_calls('find none order complex') +end + + +function text_random_letter(str) + local index = math.random(string.len(str)) + return string.sub(str, index, index) +end + +function text_char_at(str, index) + return string.sub(str, index, index) +end + +-- Tests the "get letter" block with a variable. +function test_get_text_simple() + text = 'Blockly' + assertEquals(string.sub(text, 1, 1), 'B', 'get first simple') + assertEquals(string.sub(text, -1, -1), 'y', 'get last simple') + assertEquals(firstIndexOf(text, text_random_letter(text)) > 0, true, 'get random simple') + assertEquals(string.sub(text, 3, 3), 'o', 'get # simple') + assertEquals(text_char_at(text, true and 3 or nil), 'o', 'get # order simple') + assertEquals(string.sub(text, -3, -3), 'k', 'get #-end simple') + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(text_char_at(text, -(0 + 3)), 'k', 'get #-end order simple') +end + + +-- Creates a string for use with the get test. +function get_Blockly() + number_of_calls = number_of_calls + 1 + return 'Blockly' +end + + +-- Tests the "get letter" block with a function call. +function test_get_text_complex() + text = 'Blockly' + number_of_calls = 0 + assertEquals(string.sub(get_Blockly(), 1, 1), 'B', 'get first complex') + check_number_of_calls('get first complex') + number_of_calls = 0 + assertEquals(string.sub(true and get_Blockly() or nil, 1, 1), 'B', 'get first order complex') + check_number_of_calls('get first order complex') + number_of_calls = 0 + assertEquals(string.sub(get_Blockly(), -1, -1), 'y', 'get last complex') + check_number_of_calls('get last complex') + number_of_calls = 0 + assertEquals(string.sub(true and get_Blockly() or nil, -1, -1), 'y', 'get last order complex') + check_number_of_calls('get last order complex') + number_of_calls = 0 + assertEquals(firstIndexOf(text, text_random_letter(get_Blockly())) > 0, true, 'get random complex') + check_number_of_calls('get random complex') + number_of_calls = 0 + assertEquals(firstIndexOf(text, text_random_letter(true and get_Blockly() or nil)) > 0, true, 'get random order complex') + check_number_of_calls('get random order complex') + number_of_calls = 0 + assertEquals(string.sub(get_Blockly(), 3, 3), 'o', 'get # complex') + check_number_of_calls('get # complex') + number_of_calls = 0 + assertEquals(text_char_at(true and get_Blockly() or nil, true and 3 or nil), 'o', 'get # order complex') + check_number_of_calls('get # order complex') + number_of_calls = 0 + assertEquals(string.sub(get_Blockly(), -3, -3), 'k', 'get #-end complex') + check_number_of_calls('get #-end complex') + number_of_calls = 0 + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(text_char_at(true and get_Blockly() or nil, -(0 + 3)), 'k', 'get #-end order complex') + check_number_of_calls('get #-end order complex') +end + + +-- Creates a string for use with the substring test. +function get_numbers() + number_of_calls = number_of_calls + 1 + return '123456789' +end + + +-- Tests the "get substring" block with a variable. +function test_substring_simple() + text = '123456789' + assertEquals(string.sub(text, 2, 3), '23', 'substring # simple') + assertEquals(string.sub(text, true and 2 or nil, true and 3 or nil), '23', 'substring # simple order') + assertEquals(string.sub(text, -3, -2), '78', 'substring #-end simple') + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(string.sub(text, -(0 + 3), -(0 + 2)), '78', 'substring #-end simple order') + assertEquals(string.sub(text, 1, -1), text, 'substring first-last simple') + assertEquals(string.sub(text, 2, -2), '2345678', 'substring # #-end simple') + assertEquals(string.sub(text, -7, 4), '34', 'substring #-end # simple') + assertEquals(string.sub(text, 1, 4), '1234', 'substring first # simple') + assertEquals(string.sub(text, 1, -2), '12345678', 'substring first #-end simple') + assertEquals(string.sub(text, 7, -1), '789', 'substring # last simple') + assertEquals(string.sub(text, -3, -1), '789', 'substring #-end last simple') + assertEquals(string.sub(text, 1, -1), '123456789', 'substring all with # #-end simple') + assertEquals(string.sub(text, -9, 9), '123456789', 'substring all with #-end # simple') + -- Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + assertEquals(string.sub(text, 0 + 1, -(0 + 1)), '123456789', 'substring all with # #-end math simple') +end + + +-- Tests the "get substring" block with a function call. +function test_substring_complex() + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), 2, 3), '23', 'substring # complex') + check_number_of_calls('substring # complex') + number_of_calls = 0 + assertEquals(string.sub(true and get_numbers() or nil, true and 2 or nil, true and 3 or nil), '23', 'substring # complex order') + check_number_of_calls('substring # complex order') + number_of_calls = 0 + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(string.sub(get_numbers(), -3, -2), '78', 'substring #-end complex') + check_number_of_calls('substring #-end complex') + number_of_calls = 0 + assertEquals(string.sub(true and get_numbers() or nil, -(0 + 3), -(0 + 2)), '78', 'substring #-end order order') + check_number_of_calls('substring #-end order order') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), 1, -1), text, 'substring first-last') + check_number_of_calls('substring first-last') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), 2, -2), '2345678', 'substring # #-end complex') + check_number_of_calls('substring # #-end complex') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), -7, 4), '34', 'substring #-end # complex') + check_number_of_calls('substring #-end # complex') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), 1, 4), '1234', 'substring first # complex') + check_number_of_calls('substring first # complex') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), 1, -2), '12345678', 'substring first #-end complex') + check_number_of_calls('substring first #-end complex') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), 7, -1), '789', 'substring # last complex') + check_number_of_calls('substring # last complex') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), -3, -1), '789', 'substring #-end last complex') + check_number_of_calls('substring #-end last complex') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), 1, -1), '123456789', 'substring all with # #-end complex') + check_number_of_calls('substring all with # #-end complex') + number_of_calls = 0 + assertEquals(string.sub(get_numbers(), -9, 9), '123456789', 'substring all with #-end # complex') + check_number_of_calls('substring all with #-end # complex') + number_of_calls = 0 + -- Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + assertEquals(string.sub(get_numbers(), 0 + 1, -(0 + 1)), '123456789', 'substring all with # #-end math complex') + check_number_of_calls('substring all with # #-end math complex') +end + + +function text_titlecase(str) + local buf = {} + local inWord = false + for i = 1, #str do + local c = string.sub(str, i, i) + if inWord then + table.insert(buf, string.lower(c)) + if string.find(c, "%s") then + inWord = false + end + else + table.insert(buf, string.upper(c)) + inWord = true + end + end + return table.concat(buf) +end + +-- Tests the "change casing" block. +function test_case() + text = 'Hello World' + assertEquals(string.upper(text), 'HELLO WORLD', 'uppercase') + assertEquals(string.upper(true and text or nil), 'HELLO WORLD', 'uppercase order') + text = 'Hello World' + assertEquals(string.lower(text), 'hello world', 'lowercase') + assertEquals(string.lower(true and text or nil), 'hello world', 'lowercase order') + text = 'heLLo WorlD' + assertEquals(text_titlecase(text), 'Hello World', 'titlecase') + assertEquals(text_titlecase(true and text or nil), 'Hello World', 'titlecase order') +end + + +-- Tests the "trim" block. +function test_trim() + text = ' abc def ' + assertEquals(string.gsub(text, "^%s*(.-)%s*$", "%1"), 'abc def', 'trim both') + assertEquals(string.gsub(true and text or nil, "^%s*(.-)%s*$", "%1"), 'abc def', 'trim both order') + assertEquals(string.gsub(text, "^%s*(,-)", "%1"), 'abc def ', 'trim left') + assertEquals(string.gsub(true and text or nil, "^%s*(,-)", "%1"), 'abc def ', 'trim left order') + assertEquals(string.gsub(text, "(.-)%s*$", "%1"), ' abc def', 'trim right') + assertEquals(string.gsub(true and text or nil, "(.-)%s*$", "%1"), ' abc def', 'trim right order') +end + + +function text_count(haystack, needle) + if #needle == 0 then + return #haystack + 1 + end + local i = 1 + local count = 0 + while true do + i = string.find(haystack, needle, i, true) + if i == nil then + break + end + count = count + 1 + i = i + #needle + end + return count +end + +-- Tests the "trim" block. +function test_count_text() + text = 'woolloomooloo' + assertEquals(text_count(text, 'o'), 8, 'len 1') + assertEquals(text_count(text, 'oo'), 4, 'len 2') + assertEquals(text_count(text, 'loo'), 2, 'len 3') + assertEquals(text_count(text, 'wool'), 1, 'start') + assertEquals(text_count(text, 'chicken'), 0, 'missing') + assertEquals(text_count(text, ''), 14, 'empty needle') + assertEquals(text_count('', 'chicken'), 0, 'empty source') +end + + +-- Tests the "trim" block. +function test_text_reverse() + assertEquals(string.reverse(''), '', 'empty string') + assertEquals(string.reverse('a'), 'a', 'len 1') + assertEquals(string.reverse('ab'), 'ba', 'len 2') + assertEquals(string.reverse('woolloomooloo'), 'ooloomoolloow', 'longer') +end + + +function text_replace(haystack, needle, replacement) + local buf = {} + local i = 1 + while i <= #haystack do + if string.sub(haystack, i, i + #needle - 1) == needle then + for j = 1, #replacement do + table.insert(buf, string.sub(replacement, j, j)) + end + i = i + #needle + else + table.insert(buf, string.sub(haystack, i, i)) + i = i + 1 + end + end + return table.concat(buf) +end + +-- Tests the "trim" block. +function test_replace() + assertEquals(text_replace('woolloomooloo', 'oo', '123'), 'w123ll123m123l123', 'replace all instances 1') + assertEquals(text_replace('woolloomooloo', '.oo', 'X'), 'woolloomooloo', 'literal string replacement') + assertEquals(text_replace('woolloomooloo', 'abc', 'X'), 'woolloomooloo', 'not found') + assertEquals(text_replace('woolloomooloo', 'o', ''), 'wllml', 'empty replacement 1') + assertEquals(text_replace('aaaaa', 'aaaaa', ''), '', 'empty replacement 2') + assertEquals(text_replace('aaaaa', 'a', ''), '', 'empty replacement 3') + assertEquals(text_replace('', 'a', 'chicken'), '', 'empty source') +end + + +-- Checks that the number of calls is one in order +-- to confirm that a function was only called once. +function check_number_of_calls2(test_name) + test_name = test_name .. 'number of calls' + assertEquals(number_of_calls, 1, test_name) +end + + +function create_list_repeated(item, count) + local t = {} + for i = 1, count do + table.insert(t, item) + end + return t +end + +-- Tests the "create list with" and "create empty list" blocks. +function test_create_lists() + assertEquals({}, {}, 'create empty') + assertEquals({true, 'love'}, {true, 'love'}, 'create items') + assertEquals(create_list_repeated('Eject', 3), {'Eject', 'Eject', 'Eject'}, 'create repeated') + assertEquals(create_list_repeated('Eject', 0 + 3), {'Eject', 'Eject', 'Eject'}, 'create repeated order') +end + + +-- Creates an empty list for use with the empty test. +function get_empty_list() + return {} +end + + +-- Tests the "is empty" block. +function test_lists_empty() + assertEquals(#{0} == 0, false, 'not empty') + assertEquals(#{} == 0, true, 'empty') + assertEquals(#get_empty_list() == 0, true, 'empty complex') + assertEquals(#(true and {} or nil) == 0, true, 'empty order') +end + + +-- Tests the "length" block. +function test_lists_length() + assertEquals(#{}, 0, 'zero length') + assertEquals(#{'cat'}, 1, 'one length') + assertEquals(#{'cat', true, {}}, 3, 'three length') + assertEquals(#(true and {'cat', true} or nil), 2, 'two length order') +end + + +function last_index(t, elem) + for i = #t, 1, -1 do + if t[i] == elem then + return i + end + end + return 0 +end + +-- Tests the "find" block with a variable. +function test_find_lists_simple() + list = {'Alice', 'Eve', 'Bob', 'Eve'} + assertEquals(first_index(list, 'Eve'), 2, 'find first simple') + assertEquals(last_index(list, 'Eve'), 4, 'find last simple') + assertEquals(first_index(list, 'Dave'), 0, 'find none simple') +end + + +-- Creates a list for use with the find test. +function get_names() + number_of_calls = number_of_calls + 1 + return {'Alice', 'Eve', 'Bob', 'Eve'} +end + + +-- Tests the "find" block with a function call. +function test_find_lists_complex() + number_of_calls = 0 + assertEquals(first_index(get_names(), 'Eve'), 2, 'find first complex') + check_number_of_calls('find first complex') + number_of_calls = 0 + assertEquals(first_index(true and get_names() or nil, 'Eve'), 2, 'find first order complex') + check_number_of_calls('find first order complex') + number_of_calls = 0 + assertEquals(last_index(get_names(), 'Eve'), 4, 'find last complex') + check_number_of_calls('find last complex') + number_of_calls = 0 + assertEquals(last_index(true and get_names() or nil, 'Eve'), 4, 'find last order complex') + check_number_of_calls('find last order complex') + number_of_calls = 0 + assertEquals(first_index(get_names(), 'Dave'), 0, 'find none complex') + check_number_of_calls('find none complex') + number_of_calls = 0 + assertEquals(first_index(true and get_names() or nil, 'Dave'), 0, 'find none order complex') + check_number_of_calls('find none order complex') +end + + +-- Tests the "get" block with a variable. +function test_get_lists_simple() + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(list[1], 'Kirk', 'get first simple') + assertEquals(list[#list], 'McCoy', 'get last simple') + assertEquals(first_index(list, list[math.random(#list)]) > 0, true, 'get random simple') + assertEquals(list[2], 'Spock', 'get # simple') + assertEquals(list[true and 2 or nil], 'Spock', 'get # order simple') + assertEquals(list[#list + 1 - 3], 'Kirk', 'get #-end simple') + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list[#list + 1 - (0 + 3)], 'Kirk', 'get #-end order simple') +end + + +-- Creates a list for use with the get test. +function get_star_wars() + number_of_calls = number_of_calls + 1 + return {'Kirk', 'Spock', 'McCoy'} +end + + +function list_get_last(t) + return t[#t] +end + +function list_get_random(t) + return t[math.random(#t)] +end + +function list_get_from_end(t, at) + return t[#t + 1 - at] +end + +-- Tests the "get" block with a function call. +function test_get_lists_complex() + list = {'Kirk', 'Spock', 'McCoy'} + number_of_calls = 0 + assertEquals((get_star_wars())[1], 'Kirk', 'get first complex') + check_number_of_calls('get first complex') + number_of_calls = 0 + assertEquals((true and get_star_wars() or nil)[1], 'Kirk', 'get first order complex') + check_number_of_calls('get first order complex') + number_of_calls = 0 + assertEquals(list_get_last((get_star_wars())), 'McCoy', 'get last complex') + check_number_of_calls('get last complex') + number_of_calls = 0 + assertEquals(list_get_last((true and get_star_wars() or nil)), 'McCoy', 'get last order complex') + check_number_of_calls('get last order complex') + number_of_calls = 0 + assertEquals(first_index(list, list_get_random((get_star_wars()))) > 0, true, 'get random complex') + check_number_of_calls('get random complex') + number_of_calls = 0 + assertEquals(first_index(list, list_get_random((true and get_star_wars() or nil))) > 0, true, 'get random order complex') + check_number_of_calls('get random order complex') + number_of_calls = 0 + assertEquals((get_star_wars())[2], 'Spock', 'get # complex') + check_number_of_calls('get # complex') + number_of_calls = 0 + assertEquals((true and get_star_wars() or nil)[true and 2 or nil], 'Spock', 'get # order complex') + check_number_of_calls('get # order complex') + number_of_calls = 0 + assertEquals(list_get_from_end((get_star_wars()), 3), 'Kirk', 'get #-end complex') + check_number_of_calls('get #-end complex') + number_of_calls = 0 + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list_get_from_end((true and get_star_wars() or nil), 0 + 3), 'Kirk', 'get #-end order complex') + check_number_of_calls('get #-end order complex') +end + + +function list_remove_last(t) + return table.remove(t, #t) +end + +function list_remove_random(t) + return table.remove(t, math.random(#t)) +end + +function list_remove_from_end(t, at) + return table.remove(t, #t + 1 - at) +end + +-- Tests the "get and remove" block. +function test_getRemove() + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(table.remove(list, 1), 'Kirk', 'getremove first') + assertEquals(list, {'Spock', 'McCoy'}, 'getremove first list') + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(table.remove((true and list or nil), 1), 'Kirk', 'getremove first order') + assertEquals(list, {'Spock', 'McCoy'}, 'getremove first order list') + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(table.remove(list, #list), 'McCoy', 'getremove last') + assertEquals(list, {'Kirk', 'Spock'}, 'getremove last list') + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(list_remove_last((true and list or nil)), 'McCoy', 'getremove last order') + assertEquals(list, {'Kirk', 'Spock'}, 'getremove last order list') + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(first_index(list, table.remove(list, math.random(#list))) == 0, true, 'getremove random') + assertEquals(#list, 2, 'getremove random list') + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(first_index(list, list_remove_random((true and list or nil))) == 0, true, 'getremove random order') + assertEquals(#list, 2, 'getremove random order list') + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(table.remove(list, 2), 'Spock', 'getremove #') + assertEquals(list, {'Kirk', 'McCoy'}, 'getremove # list') + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(table.remove((true and list or nil), true and 2 or nil), 'Spock', 'getremove # order') + assertEquals(list, {'Kirk', 'McCoy'}, 'getremove # order list') + list = {'Kirk', 'Spock', 'McCoy'} + assertEquals(table.remove(list, #list + 1 - 3), 'Kirk', 'getremove #-end') + assertEquals(list, {'Spock', 'McCoy'}, 'getremove #-end list') + list = {'Kirk', 'Spock', 'McCoy'} + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list_remove_from_end((true and list or nil), 0 + 3), 'Kirk', 'getremove #-end order') + assertEquals(list, {'Spock', 'McCoy'}, 'getremove #-end order list') +end + + +-- Tests the "remove" block. +function test_remove() + list = {'Kirk', 'Spock', 'McCoy'} + table.remove(list, 1) + assertEquals(list, {'Spock', 'McCoy'}, 'remove first list') + list = {'Kirk', 'Spock', 'McCoy'} + table.remove((true and list or nil), 1) + assertEquals(list, {'Spock', 'McCoy'}, 'remove first order list') + list = {'Kirk', 'Spock', 'McCoy'} + table.remove(list, #list) + assertEquals(list, {'Kirk', 'Spock'}, 'remove last list') + list = {'Kirk', 'Spock', 'McCoy'} + tmp_list = (true and list or nil) + table.remove(tmp_list, #tmp_list) + assertEquals(list, {'Kirk', 'Spock'}, 'remove last order list') + list = {'Kirk', 'Spock', 'McCoy'} + table.remove(list, math.random(#list)) + assertEquals(#list, 2, 'remove random list') + list = {'Kirk', 'Spock', 'McCoy'} + tmp_list2 = (true and list or nil) + table.remove(tmp_list2, math.random(#tmp_list2)) + assertEquals(#list, 2, 'remove random order list') + list = {'Kirk', 'Spock', 'McCoy'} + table.remove(list, 2) + assertEquals(list, {'Kirk', 'McCoy'}, 'remove # list') + list = {'Kirk', 'Spock', 'McCoy'} + table.remove((true and list or nil), true and 2 or nil) + assertEquals(list, {'Kirk', 'McCoy'}, 'remove # order list') + list = {'Kirk', 'Spock', 'McCoy'} + table.remove(list, #list + 1 - 3) + assertEquals(list, {'Spock', 'McCoy'}, 'remove #-end list') + list = {'Kirk', 'Spock', 'McCoy'} + -- The order for index for #-end is addition because this will catch + -- errors in generators where most perform the operation ... - index. + tmp_list3 = (true and list or nil) + table.remove(tmp_list3, #tmp_list3 + 1 - (0 + 3)) + assertEquals(list, {'Spock', 'McCoy'}, 'remove #-end order list') +end + + +-- Tests the "set" block. +function test_set() + list = {'Picard', 'Riker', 'Crusher'} + list[1] = 'Jean-Luc' + assertEquals(list, {'Jean-Luc', 'Riker', 'Crusher'}, 'set first list') + list = {'Picard', 'Riker', 'Crusher'} + (true and list or nil)[1] = 'Jean-Luc' + assertEquals(list, {'Jean-Luc', 'Riker', 'Crusher'}, 'set first order list') + list = {'Picard', 'Riker', 'Crusher'} + list[#list] = 'Beverly' + assertEquals(list, {'Picard', 'Riker', 'Beverly'}, 'set last list') + list = {'Picard', 'Riker', 'Crusher'} + tmp_list4 = (true and list or nil) + tmp_list4[#tmp_list4] = 'Beverly' + assertEquals(list, {'Picard', 'Riker', 'Beverly'}, 'set last order list') + list = {'Picard', 'Riker', 'Crusher'} + list[math.random(#list)] = 'Data' + assertEquals(#list, 3, 'set random list') + list = {'Picard', 'Riker', 'Crusher'} + tmp_list5 = (true and list or nil) + tmp_list5[math.random(#tmp_list5)] = 'Data' + assertEquals(#list, 3, 'set random order list') + list = {'Picard', 'Riker', 'Crusher'} + list[3] = 'Pulaski' + assertEquals(list, {'Picard', 'Riker', 'Pulaski'}, 'set # list') + list = {'Picard', 'Riker', 'Crusher'} + (true and list or nil)[(true and 3 or nil)] = 'Pulaski' + assertEquals(list, {'Picard', 'Riker', 'Pulaski'}, 'set # order list') + list = {'Picard', 'Riker', 'Crusher'} + list[#list + 1 - 1] = 'Pulaski' + assertEquals(list, {'Picard', 'Riker', 'Pulaski'}, 'set #-end list') + list = {'Picard', 'Riker', 'Crusher'} + -- The order for index for #-end is addition because this will catch + -- errors in generators where most perform the operation ... - index. + tmp_list6 = (true and list or nil) + tmp_list6[#tmp_list6 + 1 - (0 + 2)] = 'Pulaski' + assertEquals(list, {'Picard', 'Pulaski', 'Crusher'}, 'set #-end order list') +end + + +-- Tests the "insert" block. +function test_insert() + list = {'Picard', 'Riker', 'Crusher'} + table.insert(list, 1, 'Data') + assertEquals(list, {'Data', 'Picard', 'Riker', 'Crusher'}, 'insert first list') + list = {'Picard', 'Riker', 'Crusher'} + table.insert((true and list or nil), 1, 'Data') + assertEquals(list, {'Data', 'Picard', 'Riker', 'Crusher'}, 'insert first order list') + list = {'Picard', 'Riker', 'Crusher'} + table.insert(list, #list + 1, 'Data') + assertEquals(list, {'Picard', 'Riker', 'Crusher', 'Data'}, 'insert last list') + list = {'Picard', 'Riker', 'Crusher'} + tmp_list7 = (true and list or nil) + table.insert(tmp_list7, #tmp_list7 + 1, 'Data') + assertEquals(list, {'Picard', 'Riker', 'Crusher', 'Data'}, 'insert last order list') + list = {'Picard', 'Riker', 'Crusher'} + table.insert(list, math.random(#list), 'Data') + assertEquals(#list, 4, 'insert random list') + list = {'Picard', 'Riker', 'Crusher'} + tmp_list8 = (true and list or nil) + table.insert(tmp_list8, math.random(#tmp_list8), 'Data') + assertEquals(#list, 4, 'insert random order list') + list = {'Picard', 'Riker', 'Crusher'} + table.insert(list, 3, 'Data') + assertEquals(list, {'Picard', 'Riker', 'Data', 'Crusher'}, 'insert # list') + list = {'Picard', 'Riker', 'Crusher'} + table.insert((true and list or nil), (true and 3 or nil), 'Data') + assertEquals(list, {'Picard', 'Riker', 'Data', 'Crusher'}, 'insert # order list') + list = {'Picard', 'Riker', 'Crusher'} + table.insert(list, #list + 1 - 1, 'Data') + assertEquals(list, {'Picard', 'Riker', 'Data', 'Crusher'}, 'insert #-end list') + list = {'Picard', 'Riker', 'Crusher'} + -- The order for index for #-end is addition because this will catch + -- errors in generators where most perform the operation ... - index. + tmp_list9 = (true and list or nil) + table.insert(tmp_list9, #tmp_list9 + 1 - (0 + 2), 'Data') + assertEquals(list, {'Picard', 'Data', 'Riker', 'Crusher'}, 'insert #-end order list') +end + + +function list_sublist_from_start_from_start(source, at1, at2) + local t = {} + local start = at1 + local finish = at2 + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +function list_sublist_from_end_from_end(source, at1, at2) + local t = {} + local start = #source + 1 - at1 + local finish = #source + 1 - at2 + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +function list_sublist_first_last(source) + local t = {} + local start = 1 + local finish = #source + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +function list_sublist_from_start_from_end(source, at1, at2) + local t = {} + local start = at1 + local finish = #source + 1 - at2 + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +function list_sublist_from_end_from_start(source, at1, at2) + local t = {} + local start = #source + 1 - at1 + local finish = at2 + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +function list_sublist_first_from_start(source, at2) + local t = {} + local start = 1 + local finish = at2 + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +function list_sublist_first_from_end(source, at2) + local t = {} + local start = 1 + local finish = #source + 1 - at2 + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +function list_sublist_from_start_last(source, at1) + local t = {} + local start = at1 + local finish = #source + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +function list_sublist_from_end_last(source, at1) + local t = {} + local start = #source + 1 - at1 + local finish = #source + for i = start, finish do + table.insert(t, source[i]) + end + return t +end + +-- Tests the "get sub-list" block with a variable. +function test_sublist_simple() + list = {'Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'} + assertEquals(list_sublist_from_start_from_start(list, 2, 3), {'Challenger', 'Discovery'}, 'sublist # simple') + assertEquals(list_sublist_from_start_from_start(list, true and 2 or nil, true and 3 or nil), {'Challenger', 'Discovery'}, 'sublist # simple order') + assertEquals(list_sublist_from_end_from_end(list, 3, 2), {'Discovery', 'Atlantis'}, 'sublist #-end simple') + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list_sublist_from_end_from_end(list, 0 + 3, 0 + 2), {'Discovery', 'Atlantis'}, 'sublist #-end simple order') + assertEquals(list_sublist_first_last(list), list, 'sublist first-last simple') + changing_list = {'Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'} + list_copy = list_sublist_first_last(changing_list) + table.remove(changing_list, math.random(#changing_list)) + assertEquals(list_copy, list, 'sublist first-last simple copy check') + assertEquals(list_sublist_from_start_from_end(list, 2, 2), {'Challenger', 'Discovery', 'Atlantis'}, 'sublist # #-end simple') + assertEquals(list_sublist_from_end_from_start(list, 3, 4), {'Discovery', 'Atlantis'}, 'sublist #-end # simple') + assertEquals(list_sublist_first_from_start(list, 4), {'Columbia', 'Challenger', 'Discovery', 'Atlantis'}, 'sublist first # simple') + assertEquals(list_sublist_first_from_end(list, 4), {'Columbia', 'Challenger'}, 'sublist first #-end simple') + assertEquals(list_sublist_from_start_last(list, 4), {'Atlantis', 'Endeavour'}, 'sublist # last simple') + assertEquals(list_sublist_from_end_last(list, 4), {'Challenger', 'Discovery', 'Atlantis', 'Endeavour'}, 'sublist #-end last simple') + assertEquals(list_sublist_from_start_from_end(list, 1, 1), list, 'sublist all with # #-end simple') + assertEquals(list_sublist_from_end_from_start(list, 5, 5), list, 'sublist all with #-end # simple') + -- Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + assertEquals(list_sublist_from_start_from_end(list, 0 + 1, 0 + 1), list, 'sublist all with # #-end math simple') +end + + +-- Creates a list for use with the sublist test. +function get_space_shuttles() + number_of_calls = number_of_calls + 1 + return {'Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'} +end + + +-- Tests the "get sub-list" block with a function call. +function test_sublist_complex() + number_of_calls = 0 + assertEquals(list_sublist_from_start_from_start(get_space_shuttles(), 2, 3), {'Challenger', 'Discovery'}, 'sublist # start complex') + check_number_of_calls('sublist # start complex') + number_of_calls = 0 + assertEquals(list_sublist_from_start_from_start(true and get_space_shuttles() or nil, true and 2 or nil, true and 3 or nil), {'Challenger', 'Discovery'}, 'sublist # start order complex') + check_number_of_calls('sublist # start order complex') + number_of_calls = 0 + -- The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list_sublist_from_end_from_end(get_space_shuttles(), 3, 2), {'Discovery', 'Atlantis'}, 'sublist # end complex') + assertEquals(number_of_calls, 1, 'sublist # end complex number of calls') + number_of_calls = 0 + assertEquals(list_sublist_from_end_from_end(true and get_space_shuttles() or nil, 0 + 3, 0 + 2), {'Discovery', 'Atlantis'}, 'sublist # end order complex') + check_number_of_calls('sublist # end order complex') + number_of_calls = 0 + assertEquals(list_sublist_first_last(get_space_shuttles()), list, 'sublist first-last complex') + check_number_of_calls('sublist first-last complex') + number_of_calls = 0 + assertEquals(list_sublist_from_start_from_end(get_space_shuttles(), 2, 2), {'Challenger', 'Discovery', 'Atlantis'}, 'sublist # #-end complex') + check_number_of_calls('sublist # #-end complex') + number_of_calls = 0 + assertEquals(list_sublist_from_end_from_start(get_space_shuttles(), 3, 4), {'Discovery', 'Atlantis'}, 'sublist #-end # complex') + check_number_of_calls('sublist #-end # complex') + number_of_calls = 0 + assertEquals(list_sublist_first_from_start(get_space_shuttles(), 4), {'Columbia', 'Challenger', 'Discovery', 'Atlantis'}, 'sublist first # complex') + check_number_of_calls('sublist first # complex') + number_of_calls = 0 + assertEquals(list_sublist_first_from_end(get_space_shuttles(), 4), {'Columbia', 'Challenger'}, 'sublist first #-end complex') + check_number_of_calls('sublist first #-end complex') + number_of_calls = 0 + assertEquals(list_sublist_from_start_last(get_space_shuttles(), 4), {'Atlantis', 'Endeavour'}, 'sublist # last complex') + check_number_of_calls('sublist # last complex') + number_of_calls = 0 + assertEquals(list_sublist_from_end_last(get_space_shuttles(), 4), {'Challenger', 'Discovery', 'Atlantis', 'Endeavour'}, 'sublist #-end last simple') + check_number_of_calls('sublist #-end last simple') + number_of_calls = 0 + assertEquals(list_sublist_from_start_from_end(get_space_shuttles(), 1, 1), list, 'sublist all with # #-end complex') + check_number_of_calls('sublist all with # #-end complex') + number_of_calls = 0 + assertEquals(list_sublist_from_end_from_start(get_space_shuttles(), 5, 5), list, 'sublist all with #-end # complex') + check_number_of_calls('sublist all with #-end # complex') + number_of_calls = 0 + -- Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + assertEquals(list_sublist_from_start_from_end(get_space_shuttles(), 0 + 1, 0 + 1), list, 'sublist all with # #-end math complex') + check_number_of_calls('sublist all with # #-end math complex') +end + + +-- Tests the "join" block. +function test_join() + list = {'Vulcan', 'Klingon', 'Borg'} + assertEquals(table.concat(list, ','), 'Vulcan,Klingon,Borg', 'join') + assertEquals(table.concat(true and list or nil, ','), 'Vulcan,Klingon,Borg', 'join order') +end + + +function list_string_split(input, delim) + local t = {} + local pos = 1 + while true do + next_delim = string.find(input, delim, pos) + if next_delim == nil then + table.insert(t, string.sub(input, pos)) + break + else + table.insert(t, string.sub(input, pos, next_delim-1)) + pos = next_delim + #delim + end + end + return t +end + +-- Tests the "split" block. +function test_split() + text = 'Vulcan,Klingon,Borg' + assertEquals(list_string_split(text, ','), {'Vulcan', 'Klingon', 'Borg'}, 'split') + assertEquals(list_string_split(true and text or nil, ','), {'Vulcan', 'Klingon', 'Borg'}, 'split order') +end + + +function list_sort(list, typev, direction) + local t = {} + for n,v in pairs(list) do table.insert(t, v) end + local compareFuncs = { + NUMERIC = function(a, b) + return (tonumber(tostring(a)) or 0) + < (tonumber(tostring(b)) or 0) end, + TEXT = function(a, b) + return tostring(a) < tostring(b) end, + IGNORE_CASE = function(a, b) + return string.lower(tostring(a)) < string.lower(tostring(b)) end + } + local compareTemp = compareFuncs[typev] + local compare = compareTemp + if direction == -1 + then compare = function(a, b) return compareTemp(b, a) end + end + table.sort(t, compare) + return t +end + +-- Tests the "alphabetic sort" block. +function test_sort_alphabetic() + list = {'Vulcan', 'klingon', 'Borg'} + assertEquals(list_sort(list,"TEXT", 1), {'Borg', 'Vulcan', 'klingon'}, 'sort alphabetic ascending') + assertEquals(list_sort(true and list or nil,"TEXT", 1), {'Borg', 'Vulcan', 'klingon'}, 'sort alphabetic ascending order') +end + + +-- Tests the "alphabetic sort ignore case" block. +function test_sort_ignoreCase() + list = {'Vulcan', 'klingon', 'Borg'} + assertEquals(list_sort(list,"IGNORE_CASE", 1), {'Borg', 'klingon', 'Vulcan'}, 'sort ignore case ascending') + assertEquals(list_sort(true and list or nil,"IGNORE_CASE", 1), {'Borg', 'klingon', 'Vulcan'}, 'sort ignore case ascending order') +end + + +-- Tests the "numeric sort" block. +function test_sort_numeric() + list = {8, 18, -1} + assertEquals(list_sort(list,"NUMERIC", -1), {18, 8, -1}, 'sort numeric descending') + assertEquals(list_sort(true and list or nil,"NUMERIC", -1), {18, 8, -1}, 'sort numeric descending order') +end + + +function list_reverse(input) + local reversed = {} + for i = #input, 1, -1 do + table.insert(reversed, input[i]) + end + return reversed +end + +-- Tests the "list reverse" block. +function test_lists_reverse() + list = {8, 18, -1, 64} + assertEquals(list_reverse(list), {64, -1, 18, 8}, 'reverse a copy') + assertEquals(list, {8, 18, -1, 64}, 'reverse a copy original') + list = {} + assertEquals(list_reverse(list), {}, 'empty list') +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... +function test_procedure() + procedure_1(8, 2) + assertEquals(proc_z, 4, 'procedure with global') + proc_w = false + procedure_2(false) + assertEquals(proc_w, true, 'procedure no return') + proc_w = false + procedure_2(true) + assertEquals(proc_w, false, 'procedure return') +end + + +-- Describe this function... +function procedure_1(proc_x, proc_y) + proc_z = proc_x / proc_y +end + + +-- Describe this function... +function procedure_2(proc_x) + if proc_x then + return + end + proc_w = true +end + + +-- Describe this function... +function test_function() + assertEquals(function_1(2, 3), -1, 'function with arguments') + assertEquals(func_z, 'side effect', 'function with side effect') + func_a = 'unchanged' + func_c = 'global' + assertEquals(function_2(2), '3global', 'function with global') + assertEquals(func_a, 'unchanged', 'function with scope') + assertEquals(function_3(true), true, 'function return') + assertEquals(function_3(false), false, 'function no return') +end + + +-- Describe this function... +function function_1(func_x, func_y) + func_z = 'side effect' + return func_x - func_y +end + + +-- Describe this function... +function function_2(func_a) + func_a = func_a + 1 + return func_a .. func_c +end + + +-- Describe this function... +function function_3(func_a) + if func_a then + return true + end + return false +end + + +-- Describe this function... +function recurse(n) + if n > 0 then + text = table.concat({recurse(n - 1), n, recurse(n - 1)}) + else + text = '-' + end + return text +end + + + +unittestResults = {} +print('\n====================\n\nRunning suite: Logic') +assertEquals(true, true, 'True') +assertEquals(false, false, 'False') +assertEquals(not false, true, 'Not true') +assertEquals(not true, false, 'Not false') +test_if() +test_ifelse() +test_equalities() +test_and() +test_or() +test_ternary() +print(unittest_report()) +unittestResults = nil + +unittestResults = {} +print('\n====================\n\nRunning suite: Loops 1') +test_repeat() +test_repeat_ext() +test_while() +test_foreach() +print(unittest_report()) +unittestResults = nil + +unittestResults = {} +print('\n====================\n\nRunning suite: Loops 2') +test_count_loops() +test_count_by() +print(unittest_report()) +unittestResults = nil + +unittestResults = {} +print('\n====================\n\nRunning suite: Loops 3') +test_break() +test_continue() +print(unittest_report()) +unittestResults = nil + +unittestResults = {} +print('\n====================\n\nRunning suite: Math') +test_arithmetic() +test_single() +test_trig() +test_constant() +test_change() +test_number_properties() +test_round() +test_operations_on_list() +test_constraint() +test_mod() +test_random_integer() +test_random_fraction() +test_atan2() +print(unittest_report()) +unittestResults = nil + +unittestResults = {} +print('\n====================\n\nRunning suite: Text') +test_text_length() +test_empty_text() +test_create_text() +test_append() +test_find_text_simple() +test_find_text_complex() +test_get_text_simple() +test_get_text_complex() +test_substring_simple() +test_substring_complex() +test_case() +test_trim() +test_count_text() +test_text_reverse() +test_replace() +print(unittest_report()) +unittestResults = nil + +unittestResults = {} +print('\n====================\n\nRunning suite: Lists') +test_create_lists() +test_lists_empty() +test_lists_length() +test_find_lists_simple() +test_find_lists_complex() +test_get_lists_simple() +test_get_lists_complex() +test_getRemove() +test_remove() +test_set() +test_insert() +test_sublist_simple() +test_sublist_complex() +test_join() +test_split() +test_sort_alphabetic() +test_sort_ignoreCase() +test_sort_numeric() +test_lists_reverse() +print(unittest_report()) +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 = {} +print('\n====================\n\nRunning suite: Variables') +item = 123 +assertEquals(item, 123, 'variable') +if2 = 123 +assertEquals(if2, 123, 'reserved variable') +print(unittest_report()) +unittestResults = nil + +local _ = -- Intentionally non-connected variable. +naked + +unittestResults = {} +print('\n====================\n\nRunning suite: Functions') +test_procedure() +test_function() +assertEquals(recurse(3), '-1-2-1-3-1-2-1-', 'test recurse') +print(unittest_report()) +unittestResults = nil diff --git a/tests/generators/golden/generated.php b/tests/generators/golden/generated.php new file mode 100644 index 000000000..0cd270bf6 --- /dev/null +++ b/tests/generators/golden/generated.php @@ -0,0 +1,1696 @@ +$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; +$list2; +$proc_z; +$func_z; +$x; +$proc_w; +$func_c; +$if2; +$i; +$loglist; +$changing_list; +$list_copy; + +function unittest_report() { + global $unittestResults; + // Create test report. + $report = array(); + $summary = array(); + $fails = 0; + for ($x = 0; $x < count($unittestResults); $x++) { + if ($unittestResults[$x][0]) { + array_push($summary, "."); + } else { + array_push($summary, "F"); + $fails++; + array_push($report, ""); + array_push($report, "FAIL: " . $unittestResults[$x][2]); + array_push($report, $unittestResults[$x][1]); + } + } + array_unshift($report, implode("", $summary)); + array_push($report, ""); + array_push($report, "Number of tests run: " . count($unittestResults)); + array_push($report, ""); + if ($fails) { + array_push($report, "FAILED (failures=" . $fails . ")"); + } else { + array_push($report, "OK"); + } + return implode("\n", $report); +} + +function assertEquals($actual, $expected, $message) { + global $unittestResults; + // Asserts that a value equals another value. + if (!is_array($unittestResults)) { + throw new Exception("Orphaned assert: " . $message); + } + if ($actual == $expected) { + array_push($unittestResults, [true, "OK", $message]); + } else { + $expected = is_array($expected) ? implode(" ", $expected) : $expected; + $actual = is_array($actual) ? implode(" ", $actual) : $actual; + array_push($unittestResults, [false, "Expected: " . $expected . "\nActual: " . $actual, $message]); + } +} + +function unittest_fail($message) { + global $unittestResults; + // Always assert an error. + if (!$unittestResults) { + throw new Exception("Orphaned assert fail: " . $message); + } + array_push($unittestResults, [false, "Fail.", $message]); +} + +// Describe this function... +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; + if (false) { + unittest_fail('if false'); + } + $ok = false; + if (true) { + $ok = true; + } + assertEquals($ok, true, 'if true'); + $ok = false; + if (false) { + unittest_fail('if/else false'); + } else { + $ok = true; + } + assertEquals($ok, true, 'if/else false'); + $ok = false; + if (true) { + $ok = true; + } else { + unittest_fail('if/else true'); + } + assertEquals($ok, true, 'if/else true'); + $ok = false; + if (false) { + unittest_fail('elseif 1'); + } else if (true) { + $ok = true; + } else if (true) { + unittest_fail('elseif 2'); + } else { + unittest_fail('elseif 3'); + } + assertEquals($ok, true, 'elseif 4'); +} + +// Describe this function... +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; + $ok = false; + if (true) { + $ok = true; + } else { + unittest_fail('ifelse true'); + } + assertEquals($ok, true, 'ifelse true'); + $ok = false; + if (false) { + unittest_fail('ifelse false'); + } else { + $ok = true; + } + assertEquals($ok, true, 'ifelse false'); +} + +// Describe this function... +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; + assertEquals(2 == 2, true, 'Equal yes'); + assertEquals(3 == 4, false, 'Equal no'); + assertEquals(5 != 6, true, 'Not equal yes'); + assertEquals(3 == 4, false, 'Not equal no'); + assertEquals(5 < 6, true, 'Smaller yes'); + assertEquals(7 < 7, false, 'Smaller no'); + assertEquals(9 > 8, true, 'Greater yes'); + assertEquals(10 > 10, false, 'Greater no'); + assertEquals(11 <= 11, true, 'Smaller-equal yes'); + assertEquals(13 <= 12, false, 'Smaller-equal no'); + assertEquals(14 >= 14, true, 'Greater-equal yes'); + assertEquals(15 >= 16, false, 'Greater-equal no'); +} + +// Describe this function... +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; + assertEquals(true && true, true, 'And true/true'); + assertEquals(false && true, false, 'And false/true'); + assertEquals(true && false, false, 'And true/false'); + assertEquals(false && false, false, 'And false/false'); +} + +// Describe this function... +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; + assertEquals(true || true, true, 'Or true/true'); + assertEquals(false || true, true, 'Or false/true'); + assertEquals(true || false, true, 'Or true/false'); + assertEquals(false || false, false, 'Or false/false'); +} + +// Describe this function... +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; + assertEquals(true ? 42 : 99, 42, 'if true'); + assertEquals(false ? 42 : 99, 99, 'if true'); +} + +// Describe this function... +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; + $log = ''; + foreach (array('a', 'b', 'c') as $x) { + $log .= $x; + } + assertEquals($log, 'abc', 'for loop'); +} + +// Describe this function... +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; + $count = 0; + for ($count2 = 0; $count2 < 10; $count2++) { + $count += 1; + } + assertEquals($count, 10, 'repeat 10'); +} + +// Describe this function... +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; + while (false) { + unittest_fail('while 0'); + } + while (!true) { + unittest_fail('until 0'); + } + $count = 1; + while ($count != 10) { + $count += 1; + } + assertEquals($count, 10, 'while 10'); + $count = 1; + while (!($count == 10)) { + $count += 1; + } + assertEquals($count, 10, 'until 10'); +} + +// Describe this function... +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; + $count = 0; + for ($count3 = 0; $count3 < 10; $count3++) { + $count += 1; + } + assertEquals($count, 10, 'repeat 10'); +} + +// Describe this function... +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; + $log = ''; + for ($x = 1; $x <= 8; $x += 2) { + $log .= $x; + } + assertEquals($log, '1357', 'count up ints'); + $log = ''; + for ($x = 8; $x >= 1; $x -= 2) { + $log .= $x; + } + assertEquals($log, '8642', 'count down ints'); + $loglist = array(); + for ($x = 1; $x <= 8; $x += 1.5) { + array_push($loglist, $x); + } + assertEquals($loglist, array(1, 2.5, 4, 5.5, 7), 'count with floats'); + $loglist = array(); + $_x_start = 1 + 0; + $_x_end = 8 + 0; + $_x_inc = abs(1 - 2); + if ($_x_start > $_x_end) { + $_x_inc = -$_x_inc; + } + for ($x = $_x_start; $_x_inc >= 0 ? $x <= $_x_end : $x >= $_x_end; $x += $_x_inc) { + array_push($loglist, $x); + } + assertEquals($loglist, array(1, 2, 3, 4, 5, 6, 7, 8), 'count up non-trivial ints'); + $loglist = array(); + $_x_start2 = 8 + 0; + $_x_end2 = 1 + 0; + $_x_inc2 = 2; + if ($_x_start2 > $_x_end2) { + $_x_inc2 = -$_x_inc2; + } + for ($x = $_x_start2; $_x_inc2 >= 0 ? $x <= $_x_end2 : $x >= $_x_end2; $x += $_x_inc2) { + array_push($loglist, $x); + } + assertEquals($loglist, array(8, 6, 4, 2), 'count down non-trivial ints'); + $loglist = array(); + $_x_start3 = 5 + 0.5; + $_x_end3 = 1 + 0; + $_x_inc3 = abs(1 + 0); + if ($_x_start3 > $_x_end3) { + $_x_inc3 = -$_x_inc3; + } + for ($x = $_x_start3; $_x_inc3 >= 0 ? $x <= $_x_end3 : $x >= $_x_end3; $x += $_x_inc3) { + array_push($loglist, $x); + } + assertEquals($loglist, array(5.5, 4.5, 3.5, 2.5, 1.5), 'count with floats'); +} + +// Describe this function... +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; + $log = ''; + for ($x = 1; $x <= 8; $x++) { + $log .= $x; + } + assertEquals($log, '12345678', 'count up'); + $log = ''; + for ($x = 8; $x >= 1; $x--) { + $log .= $x; + } + assertEquals($log, '87654321', 'count down'); + $loglist = array(); + $_x_start4 = 1 + 0; + $_x_end4 = 4 + 0; + $_x_inc4 = 1; + if ($_x_start4 > $_x_end4) { + $_x_inc4 = -$_x_inc4; + } + for ($x = $_x_start4; $_x_inc4 >= 0 ? $x <= $_x_end4 : $x >= $_x_end4; $x += $_x_inc4) { + array_push($loglist, $x); + } + assertEquals($loglist, array(1, 2, 3, 4), 'count up non-trivial'); + $loglist = array(); + $_x_start5 = 3 + 1; + $_x_end5 = 1 + 0; + $_x_inc5 = 1; + if ($_x_start5 > $_x_end5) { + $_x_inc5 = -$_x_inc5; + } + for ($x = $_x_start5; $_x_inc5 >= 0 ? $x <= $_x_end5 : $x >= $_x_end5; $x += $_x_inc5) { + array_push($loglist, $x); + } + assertEquals($loglist, array(4, 3, 2, 1), 'count down non-trivial'); +} + +// Describe this function... +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; + $log = ''; + $count = 0; + while ($count != 8) { + $count += 1; + if ($count == 5) { + continue; + } + $log .= $count; + } + assertEquals($log, '1234678', 'while continue'); + $log = ''; + $count = 0; + while (!($count == 8)) { + $count += 1; + if ($count == 5) { + continue; + } + $log .= $count; + } + assertEquals($log, '1234678', 'until continue'); + $log = ''; + for ($x = 1; $x <= 8; $x++) { + if ($x == 5) { + continue; + } + $log .= $x; + } + assertEquals($log, '1234678', 'count continue'); + $log = ''; + foreach (array('a', 'b', 'c', 'd') as $x) { + if ($x == 'c') { + continue; + } + $log .= $x; + } + assertEquals($log, 'abd', 'for continue'); +} + +// Describe this function... +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; + $count = 1; + while ($count != 10) { + if ($count == 5) { + break; + } + $count += 1; + } + assertEquals($count, 5, 'while break'); + $count = 1; + while (!($count == 10)) { + if ($count == 5) { + break; + } + $count += 1; + } + assertEquals($count, 5, 'until break'); + $log = ''; + for ($x = 1; $x <= 8; $x++) { + if ($x == 5) { + break; + } + $log .= $x; + } + assertEquals($log, '1234', 'count break'); + $log = ''; + foreach (array('a', 'b', 'c', 'd') as $x) { + if ($x == 'c') { + break; + } + $log .= $x; + } + assertEquals($log, 'ab', 'for break'); +} + +// Tests the "single" block. +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; + assertEquals(sqrt(25), 5, 'sqrt'); + assertEquals(abs(-25), 25, 'abs'); + assertEquals(-(-25), 25, 'negate'); + assertEquals(log(1), 0, 'ln'); + assertEquals(log(100) / log(10), 2, 'log10'); + assertEquals(exp(2), 7.38905609893065, 'exp'); + assertEquals(pow(10,2), 100, 'power10'); +} + +// Tests the "arithmetic" block for all operations and checks +// parenthesis are properly generated for different orders. +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; + assertEquals(1 + 2, 3, 'add'); + assertEquals(1 - 2, -1, 'subtract'); + assertEquals(1 - (0 + 2), -1, 'subtract order with add'); + assertEquals(1 - (0 - 2), 3, 'subtract order with subtract'); + assertEquals(4 * 2.5, 10, 'multiply'); + assertEquals(4 * (0 + 2.5), 10, 'multiply order'); + assertEquals(8.2 / -5, -1.64, 'divide'); + assertEquals(8.2 / (0 + -5), -1.64, 'divide order'); + assertEquals(10 ** 4, 10000, 'power'); + assertEquals(10 ** (0 + 4), 10000, 'power order'); +} + +// Tests the "trig" block. +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; + assertEquals(sin(90 / 180 * pi()), 1, 'sin'); + assertEquals(cos(180 / 180 * pi()), -1, 'cos'); + assertEquals(tan(0 / 180 * pi()), 0, 'tan'); + assertEquals(asin(-1) / pi() * 180, -90, 'asin'); + assertEquals(acos(1) / pi() * 180, 0, 'acos'); + assertEquals(atan(1) / pi() * 180, 45, 'atan'); +} + +// Tests the "constant" blocks. +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; + assertEquals(floor(M_PI * 1000), 3141, 'const pi'); + assertEquals(floor(M_E * 1000), 2718, 'const e'); + assertEquals(floor(((1 + sqrt(5)) / 2) * 1000), 1618, 'const golden'); + assertEquals(floor(M_SQRT2 * 1000), 1414, 'const sqrt 2'); + assertEquals(floor(M_SQRT1_2 * 1000), 707, 'const sqrt 0.5'); + assertEquals(9999 < INF, true, 'const infinity'); +} + +function math_isPrime($n) { + // https://en.wikipedia.org/wiki/Primality_test#Naive_methods + if ($n == 2 || $n == 3) { + return true; + } + // False if n is NaN, negative, is 1, or not whole. + // And false if n is divisible by 2 or 3. + if (!is_numeric($n) || $n <= 1 || $n % 1 != 0 || $n % 2 == 0 || $n % 3 == 0) { + return false; + } + // Check all the numbers of form 6k +/- 1, up to sqrt(n). + for ($x = 6; $x <= sqrt($n) + 1; $x += 6) { + if ($n % ($x - 1) == 0 || $n % ($x + 1) == 0) { + return false; + } + } + return true; +} + +// Tests the "number property" blocks. +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; + assertEquals(42 % 2 == 0, true, 'even'); + assertEquals(42.1 % 2 == 1, false, 'odd'); + assertEquals(math_isPrime(5), true, 'prime 5'); + assertEquals(math_isPrime(25), false, 'prime 25'); + assertEquals(math_isPrime(-31.1), false, 'prime negative'); + assertEquals(is_int(M_PI), false, 'whole'); + assertEquals(INF > 0, true, 'positive'); + assertEquals(-42 < 0, true, 'negative'); + assertEquals(42 % 2 == 0, true, 'divisible'); +} + +// Tests the "round" block. +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; + assertEquals(round(42.42), 42, 'round'); + assertEquals(ceil(-42.42), -42, 'round up'); + assertEquals(floor(42.42), 42, 'round down'); +} + +// Tests the "change" block. +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; + $varToChange = 100; + $varToChange += 42; + assertEquals($varToChange, 142, 'change'); +} + +function math_mean($myList) { + return array_sum($myList) / count($myList); +} + +function math_median($arr) { + sort($arr,SORT_NUMERIC); + return (count($arr) % 2) ? $arr[floor(count($arr)/2)] : + ($arr[floor(count($arr)/2)] + $arr[floor(count($arr)/2) - 1]) / 2; +} + +function math_modes($values) { + if (empty($values)) return array(); + $counts = array_count_values($values); + arsort($counts); // Sort counts in descending order + $modes = array_keys($counts, current($counts), true); + return $modes; +} + +function math_standard_deviation($numbers) { + $n = count($numbers); + if (!$n) return null; + $mean = array_sum($numbers) / count($numbers); + foreach($numbers as $key => $num) $devs[$key] = pow($num - $mean, 2); + return sqrt(array_sum($devs) / (count($devs) - 1)); +} + +function math_random_list($list) { + $x = rand(0, count($list)-1); + return $list[$x]; +} + +function indexOf($haystack, $needle) { + for ($index = 0; $index < count($haystack); $index++) { + if ($haystack[$index] == $needle) return $index + 1; + } + return 0; +} + +// Tests the "list operation" blocks. +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; + assertEquals(array_sum((array(3, 4, 5))), 12, 'sum'); + assertEquals(min((array(3, 4, 5))), 3, 'min'); + assertEquals(max((array(3, 4, 5))), 5, 'max'); + assertEquals(math_mean(array(3, 4, 5)), 4, 'average'); + assertEquals(math_median(array(3, 4, 5, 1)), 3.5, 'median'); + assertEquals(math_modes(array(3, 4, 3)), array(3), 'modes'); + assertEquals(math_modes(array(3, 4, 3, 1, 4)), array(3, 4), 'modes multiple'); + assertEquals(math_standard_deviation(array(3, 3, 3)), 0, 'standard dev'); + assertEquals(indexOf(array(3, 4, 5), math_random_list(array(3, 4, 5))) > 0, true, 'random'); +} + +// Tests the "mod" block. +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; + assertEquals(42 % 5, 2, 'mod'); +} + +// Tests the "constrain" block. +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; + assertEquals(min(max(100, 0), 42), 42, 'constraint'); +} + +function math_random_int($a, $b) { + if ($a > $b) { + return rand($b, $a); + } + return rand($a, $b); +} + +// Tests the "random integer" block. +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; + $rand = math_random_int(5, 10); + assertEquals($rand >= 5 && $rand <= 10, true, 'randRange'); + assertEquals(is_int($rand), true, 'randInteger'); +} + +// Tests the "random fraction" block. +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; + $rand = (float)rand()/(float)getrandmax(); + assertEquals($rand >= 0 && $rand <= 1, true, 'randFloat'); +} + +// Describe this function... +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; + assertEquals(atan2(5, -5) / pi() * 180, 135, 'atan2'); + assertEquals(atan2(-12, 0) / pi() * 180, -90, 'atan2'); +} + +// Checks that the number of calls is one in order +// to confirm that a function was only called once. +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; + $test_name .= 'number of calls'; + assertEquals($number_of_calls, 1, $test_name); +} + +// Tests the "create text with" block with varying number of inputs. +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; + assertEquals('', '', 'no text'); + assertEquals('Hello', 'Hello', 'create single'); + assertEquals(-1, '-1', 'create single number'); + assertEquals('K' . 9, 'K9', 'create double text'); + assertEquals(4 . 2, '42', 'create double text numbers'); + assertEquals(implode('', array(1,2,3)), '123', 'create triple'); + assertEquals(implode('', array(1,true ? 0 : null,'M')), '10M', 'create order'); +} + +// Creates an empty string for use with the empty test. +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; + return ''; +} + +// Tests the "is empty" block". +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; + assertEquals(empty('Google'), false, 'not empty'); + assertEquals(empty(''), true, 'empty'); + assertEquals(empty(get_empty()), true, 'empty complex'); + assertEquals(empty(true ? '' : null), true, 'empty order'); +} + +function length($value) { + if (is_string($value)) { + return strlen($value); + } else { + return count($value); + } +} + +// Tests the "length" block. +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; + assertEquals(length(''), 0, 'zero length'); + assertEquals(length('Google'), 6, 'non-zero length'); + assertEquals(length(true ? 'car' : null), 3, 'length order'); +} + +// Tests the "append text" block with different types of parameters. +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; + $item = 'Miserable'; + $item .= 'Failure'; + assertEquals($item, 'MiserableFailure', 'append text'); + $item = 12; + $item .= 34; + assertEquals($item, '1234', 'append number'); + $item = 'Something '; + $item .= true ? 'Positive' : null; + assertEquals($item, 'Something Positive', 'append order'); +} + +function text_indexOf($text, $search) { + $pos = strpos($text, $search); + return $pos === false ? 0 : $pos + 1; +} + +function text_lastIndexOf($text, $search) { + $pos = strrpos($text, $search); + return $pos === false ? 0 : $pos + 1; +} + +// Tests the "find" block with a variable. +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; + $text = 'Banana'; + assertEquals(text_indexOf($text, 'an'), 2, 'find first simple'); + assertEquals(text_lastIndexOf($text, 'an'), 4, 'find last simple'); + assertEquals(text_indexOf($text, 'Peel'), 0, 'find none simple'); +} + +// Creates a string for use with the find test. +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; + $number_of_calls += 1; + return 'Banana'; +} + +// Tests the "find" block with a function call. +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; + $number_of_calls = 0; + assertEquals(text_indexOf(get_fruit(), 'an'), 2, 'find first complex'); + check_number_of_calls('find first complex'); + $number_of_calls = 0; + assertEquals(text_indexOf(true ? get_fruit() : null, 'an'), 2, 'find first order complex'); + check_number_of_calls('find first order complex'); + $number_of_calls = 0; + assertEquals(text_lastIndexOf(get_fruit(), 'an'), 4, 'find last complex'); + check_number_of_calls('find last complex'); + $number_of_calls = 0; + assertEquals(text_lastIndexOf(true ? get_fruit() : null, 'an'), 4, 'find last order complex'); + check_number_of_calls('find last order complex'); + $number_of_calls = 0; + assertEquals(text_indexOf(get_fruit(), 'Peel'), 0, 'find none complex'); + check_number_of_calls('find none complex'); + $number_of_calls = 0; + assertEquals(text_indexOf(true ? get_fruit() : null, 'Peel'), 0, 'find none order complex'); + check_number_of_calls('find none order complex'); +} + +function text_random_letter($text) { + return $text[rand(0, strlen($text) - 1)]; +} + +// Tests the "get letter" block with a variable. +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; + $text = 'Blockly'; + assertEquals(substr($text, 0, 1), 'B', 'get first simple'); + assertEquals(substr($text, -1), 'y', 'get last simple'); + assertEquals(text_indexOf($text, text_random_letter($text)) > 0, true, 'get random simple'); + assertEquals(substr($text, 2, 1), 'o', 'get # simple'); + assertEquals(substr($text, ((true ? 3 : null) - 1), 1), 'o', 'get # order simple'); + assertEquals(substr($text, -3, 1), 'k', 'get #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(substr($text, (-(0 + 3)), 1), 'k', 'get #-end order simple'); +} + +// Creates a string for use with the get test. +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; + $number_of_calls += 1; + return 'Blockly'; +} + +// Tests the "get letter" block with a function call. +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; + $text = 'Blockly'; + $number_of_calls = 0; + assertEquals(substr(get_Blockly(), 0, 1), 'B', 'get first complex'); + check_number_of_calls('get first complex'); + $number_of_calls = 0; + assertEquals(substr(true ? get_Blockly() : null, 0, 1), 'B', 'get first order complex'); + check_number_of_calls('get first order complex'); + $number_of_calls = 0; + assertEquals(substr(get_Blockly(), -1), 'y', 'get last complex'); + check_number_of_calls('get last complex'); + $number_of_calls = 0; + assertEquals(substr(true ? get_Blockly() : null, -1), 'y', 'get last order complex'); + check_number_of_calls('get last order complex'); + $number_of_calls = 0; + assertEquals(text_indexOf($text, text_random_letter(get_Blockly())) > 0, true, 'get random complex'); + check_number_of_calls('get random complex'); + $number_of_calls = 0; + assertEquals(text_indexOf($text, text_random_letter(true ? get_Blockly() : null)) > 0, true, 'get random order complex'); + check_number_of_calls('get random order complex'); + $number_of_calls = 0; + assertEquals(substr(get_Blockly(), 2, 1), 'o', 'get # complex'); + check_number_of_calls('get # complex'); + $number_of_calls = 0; + assertEquals(substr(true ? get_Blockly() : null, ((true ? 3 : null) - 1), 1), 'o', 'get # order complex'); + check_number_of_calls('get # order complex'); + $number_of_calls = 0; + assertEquals(substr(get_Blockly(), -3, 1), 'k', 'get #-end complex'); + check_number_of_calls('get #-end complex'); + $number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(substr(true ? get_Blockly() : null, (-(0 + 3)), 1), 'k', 'get #-end order complex'); + check_number_of_calls('get #-end order complex'); +} + +// Creates a string for use with the substring test. +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; + $number_of_calls += 1; + return '123456789'; +} + +function text_get_substring($text, $where1, $at1, $where2, $at2) { + if ($where1 == 'FROM_END') { + $at1 = strlen($text) - 1 - $at1; + } else if ($where1 == 'FIRST') { + $at1 = 0; + } else if ($where1 != 'FROM_START'){ + throw new Exception('Unhandled option (text_get_substring).'); + } + $length = 0; + if ($where2 == 'FROM_START') { + $length = $at2 - $at1 + 1; + } else if ($where2 == 'FROM_END') { + $length = strlen($text) - $at1 - $at2; + } else if ($where2 == 'LAST') { + $length = strlen($text) - $at1; + } else { + throw new Exception('Unhandled option (text_get_substring).'); + } + return substr($text, $at1, $length); +} + +// Tests the "get substring" block with a variable. +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; + $text = '123456789'; + 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_END', 2, 'FROM_END', 1), '78', 'substring #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(text_get_substring($text, 'FROM_END', ((0 + 3) - 1), 'FROM_END', ((0 + 2) - 1)), '78', 'substring #-end simple order'); + assertEquals($text, $text, 'substring first-last simple'); + assertEquals(text_get_substring($text, 'FROM_START', 1, 'FROM_END', 1), '2345678', 'substring # #-end simple'); + assertEquals(text_get_substring($text, 'FROM_END', 6, 'FROM_START', 3), '34', 'substring #-end # simple'); + assertEquals(text_get_substring($text, 'FIRST', 0, 'FROM_START', 3), '1234', 'substring first # simple'); + assertEquals(text_get_substring($text, 'FIRST', 0, 'FROM_END', 1), '12345678', 'substring first #-end simple'); + assertEquals(text_get_substring($text, 'FROM_START', 6, 'LAST', 0), '789', 'substring # last simple'); + assertEquals(text_get_substring($text, 'FROM_END', 2, 'LAST', 0), '789', 'substring #-end last simple'); + assertEquals(text_get_substring($text, 'FROM_START', 0, 'FROM_END', 0), '123456789', 'substring all with # #-end simple'); + assertEquals(text_get_substring($text, 'FROM_END', 8, 'FROM_START', 8), '123456789', 'substring all with #-end # simple'); + // Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + assertEquals(text_get_substring($text, 'FROM_START', ((0 + 1) - 1), 'FROM_END', ((0 + 1) - 1)), '123456789', 'substring all with # #-end math simple'); +} + +// Tests the "get substring" block with a function call. +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; + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FROM_START', 1, 'FROM_START', 2), '23', 'substring # complex'); + check_number_of_calls('substring # complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((true ? get_numbers() : null), 'FROM_START', ((true ? 2 : null) - 1), 'FROM_START', ((true ? 3 : null) - 1)), '23', 'substring # complex order'); + check_number_of_calls('substring # complex order'); + $number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(text_get_substring((get_numbers()), 'FROM_END', 2, 'FROM_END', 1), '78', 'substring #-end complex'); + check_number_of_calls('substring #-end complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((true ? get_numbers() : null), 'FROM_END', ((0 + 3) - 1), 'FROM_END', ((0 + 2) - 1)), '78', 'substring #-end order order'); + check_number_of_calls('substring #-end order order'); + $number_of_calls = 0; + assertEquals((get_numbers()), $text, 'substring first-last'); + check_number_of_calls('substring first-last'); + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FROM_START', 1, 'FROM_END', 1), '2345678', 'substring # #-end complex'); + check_number_of_calls('substring # #-end complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FROM_END', 6, 'FROM_START', 3), '34', 'substring #-end # complex'); + check_number_of_calls('substring #-end # complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FIRST', 0, 'FROM_START', 3), '1234', 'substring first # complex'); + check_number_of_calls('substring first # complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FIRST', 0, 'FROM_END', 1), '12345678', 'substring first #-end complex'); + check_number_of_calls('substring first #-end complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FROM_START', 6, 'LAST', 0), '789', 'substring # last complex'); + check_number_of_calls('substring # last complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FROM_END', 2, 'LAST', 0), '789', 'substring #-end last complex'); + check_number_of_calls('substring #-end last complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FROM_START', 0, 'FROM_END', 0), '123456789', 'substring all with # #-end complex'); + check_number_of_calls('substring all with # #-end complex'); + $number_of_calls = 0; + assertEquals(text_get_substring((get_numbers()), 'FROM_END', 8, 'FROM_START', 8), '123456789', 'substring all with #-end # complex'); + check_number_of_calls('substring all with #-end # complex'); + $number_of_calls = 0; + // Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + assertEquals(text_get_substring((get_numbers()), 'FROM_START', ((0 + 1) - 1), 'FROM_END', ((0 + 1) - 1)), '123456789', 'substring all with # #-end math complex'); + check_number_of_calls('substring all with # #-end math complex'); +} + +// Tests the "change casing" block. +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; + $text = 'Hello World'; + assertEquals(strtoupper($text), 'HELLO WORLD', 'uppercase'); + assertEquals(strtoupper(true ? $text : null), 'HELLO WORLD', 'uppercase order'); + $text = 'Hello World'; + assertEquals(strtolower($text), 'hello world', 'lowercase'); + assertEquals(strtolower(true ? $text : null), 'hello world', 'lowercase order'); + $text = 'heLLo WorlD'; + assertEquals(ucwords(strtolower($text)), 'Hello World', 'titlecase'); + assertEquals(ucwords(strtolower(true ? $text : null)), 'Hello World', 'titlecase order'); +} + +// Tests the "trim" block. +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; + $text = ' abc def '; + assertEquals(trim($text), 'abc def', 'trim both'); + assertEquals(trim(true ? $text : null), 'abc def', 'trim both order'); + assertEquals(ltrim($text), 'abc def ', 'trim left'); + assertEquals(ltrim(true ? $text : null), 'abc def ', 'trim left order'); + assertEquals(rtrim($text), ' abc def', 'trim right'); + assertEquals(rtrim(true ? $text : null), ' abc def', 'trim right order'); +} + +// Tests the "trim" block. +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; + $text = 'woolloomooloo'; + 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('loo') === 0 ? strlen($text) + 1 : substr_count($text, 'loo'), 2, 'len 3'); + assertEquals(strlen('wool') === 0 ? strlen($text) + 1 : substr_count($text, 'wool'), 1, 'start'); + assertEquals(strlen('chicken') === 0 ? strlen($text) + 1 : substr_count($text, 'chicken'), 0, 'missing'); + assertEquals(strlen('') === 0 ? strlen($text) + 1 : substr_count($text, ''), 14, 'empty needle'); + assertEquals(strlen('chicken') === 0 ? strlen('') + 1 : substr_count('', 'chicken'), 0, 'empty source'); +} + +// Tests the "trim" block. +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; + assertEquals(strrev(''), '', 'empty string'); + assertEquals(strrev('a'), 'a', 'len 1'); + assertEquals(strrev('ab'), 'ba', 'len 2'); + assertEquals(strrev('woolloomooloo'), 'ooloomoolloow', 'longer'); +} + +// Tests the "trim" block. +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; + assertEquals(str_replace('oo', '123', 'woolloomooloo'), 'w123ll123m123l123', 'replace all instances 1'); + assertEquals(str_replace('.oo', 'X', 'woolloomooloo'), 'woolloomooloo', 'literal string replacement'); + assertEquals(str_replace('abc', 'X', 'woolloomooloo'), 'woolloomooloo', 'not found'); + assertEquals(str_replace('o', '', 'woolloomooloo'), 'wllml', 'empty replacement 1'); + assertEquals(str_replace('aaaaa', '', 'aaaaa'), '', 'empty replacement 2'); + assertEquals(str_replace('a', '', 'aaaaa'), '', 'empty replacement 3'); + assertEquals(str_replace('a', 'chicken', ''), '', 'empty source'); +} + +// Checks that the number of calls is one in order +// to confirm that a function was only called once. +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; + $test_name .= 'number of calls'; + assertEquals($number_of_calls, 1, $test_name); +} + +function lists_repeat($value, $count) { + $array = array(); + for ($index = 0; $index < $count; $index++) { + $array[] = $value; + } + return $array; +} + +// Tests the "create list with" and "create empty list" blocks. +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; + assertEquals(array(), array(), 'create empty'); + assertEquals(array(true, 'love'), array(true, 'love'), 'create items'); + assertEquals(lists_repeat('Eject', 3), array('Eject', 'Eject', 'Eject'), 'create repeated'); + assertEquals(lists_repeat('Eject', 0 + 3), array('Eject', 'Eject', 'Eject'), 'create repeated order'); +} + +// Creates an empty list for use with the empty test. +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; + return array(); +} + +// Tests the "is empty" block. +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; + assertEquals(empty((array(0))), false, 'not empty'); + assertEquals(empty((array())), true, 'empty'); + assertEquals(empty((get_empty_list())), true, 'empty complex'); + assertEquals(empty((true ? array() : null)), true, 'empty order'); +} + +// Tests the "length" block. +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; + assertEquals(length(array()), 0, 'zero length'); + assertEquals(length(array('cat')), 1, 'one length'); + assertEquals(length(array('cat', true, array())), 3, 'three length'); + assertEquals(length(true ? array('cat', true) : null), 2, 'two length order'); +} + +function lastIndexOf($haystack, $needle) { + $last = 0; + for ($index = 0; $index < count($haystack); $index++) { + if ($haystack[$index] == $needle) $last = $index + 1; + } + return $last; +} + +// Tests the "find" block with a variable. +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; + $list2 = array('Alice', 'Eve', 'Bob', 'Eve'); + assertEquals(indexOf($list2, 'Eve'), 2, 'find first simple'); + assertEquals(lastIndexOf($list2, 'Eve'), 4, 'find last simple'); + assertEquals(indexOf($list2, 'Dave'), 0, 'find none simple'); +} + +// Creates a list for use with the find test. +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; + $number_of_calls += 1; + return array('Alice', 'Eve', 'Bob', 'Eve'); +} + +// Tests the "find" block with a function call. +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; + $number_of_calls = 0; + assertEquals(indexOf(get_names(), 'Eve'), 2, 'find first complex'); + check_number_of_calls('find first complex'); + $number_of_calls = 0; + assertEquals(indexOf((true ? get_names() : null), 'Eve'), 2, 'find first order complex'); + check_number_of_calls('find first order complex'); + $number_of_calls = 0; + assertEquals(lastIndexOf(get_names(), 'Eve'), 4, 'find last complex'); + check_number_of_calls('find last complex'); + $number_of_calls = 0; + assertEquals(lastIndexOf((true ? get_names() : null), 'Eve'), 4, 'find last order complex'); + check_number_of_calls('find last order complex'); + $number_of_calls = 0; + assertEquals(indexOf(get_names(), 'Dave'), 0, 'find none complex'); + check_number_of_calls('find none complex'); + $number_of_calls = 0; + assertEquals(indexOf((true ? get_names() : null), 'Dave'), 0, 'find none order complex'); + check_number_of_calls('find none order complex'); +} + +function lists_get_random_item($list) { + return $list[rand(0,count($list)-1)]; +} + +// Tests the "get" block with a variable. +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; + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals($list2[0], 'Kirk', 'get first simple'); + assertEquals(end($list2), 'McCoy', 'get last simple'); + assertEquals(indexOf($list2, lists_get_random_item($list2)) > 0, true, 'get random simple'); + assertEquals($list2[1], 'Spock', 'get # simple'); + assertEquals($list2[((true ? 2 : null) - 1)], 'Spock', 'get # order simple'); + assertEquals(array_slice($list2, -3, 1)[0], 'Kirk', 'get #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(array_slice($list2, (-(0 + 3)), 1)[0], 'Kirk', 'get #-end order simple'); +} + +// Creates a list for use with the get test. +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; + $number_of_calls += 1; + return array('Kirk', 'Spock', 'McCoy'); +} + +// Tests the "get" block with a function call. +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; + $list2 = array('Kirk', 'Spock', 'McCoy'); + $number_of_calls = 0; + assertEquals(get_star_wars()[0], 'Kirk', 'get first complex'); + check_number_of_calls('get first complex'); + $number_of_calls = 0; + assertEquals((true ? get_star_wars() : null)[0], 'Kirk', 'get first order complex'); + check_number_of_calls('get first order complex'); + $number_of_calls = 0; + assertEquals(end(get_star_wars()), 'McCoy', 'get last complex'); + check_number_of_calls('get last complex'); + $number_of_calls = 0; + assertEquals(end(true ? get_star_wars() : null), 'McCoy', 'get last order complex'); + check_number_of_calls('get last order complex'); + $number_of_calls = 0; + assertEquals(indexOf($list2, lists_get_random_item(get_star_wars())) > 0, true, 'get random complex'); + check_number_of_calls('get random complex'); + $number_of_calls = 0; + assertEquals(indexOf($list2, lists_get_random_item(true ? get_star_wars() : null)) > 0, true, 'get random order complex'); + check_number_of_calls('get random order complex'); + $number_of_calls = 0; + assertEquals(get_star_wars()[1], 'Spock', 'get # complex'); + check_number_of_calls('get # complex'); + $number_of_calls = 0; + assertEquals((true ? get_star_wars() : null)[((true ? 2 : null) - 1)], 'Spock', 'get # order complex'); + check_number_of_calls('get # order complex'); + $number_of_calls = 0; + assertEquals(array_slice(get_star_wars(), -3, 1)[0], 'Kirk', 'get #-end complex'); + check_number_of_calls('get #-end complex'); + $number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(array_slice(true ? get_star_wars() : null, (-(0 + 3)), 1)[0], 'Kirk', 'get #-end order complex'); + check_number_of_calls('get #-end order complex'); +} + +function lists_get_remove_random_item(&$list) { + $x = rand(0,count($list)-1); + unset($list[$x]); + return array_values($list); +} + +// Tests the "get and remove" block. +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; + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(array_shift($list2), 'Kirk', 'getremove first'); + assertEquals($list2, array('Spock', 'McCoy'), 'getremove first list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(array_shift(true ? $list2 : null), 'Kirk', 'getremove first order'); + assertEquals($list2, array('Spock', 'McCoy'), 'getremove first order list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(array_pop($list2), 'McCoy', 'getremove last'); + assertEquals($list2, array('Kirk', 'Spock'), 'getremove last list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(array_pop(true ? $list2 : null), 'McCoy', 'getremove last order'); + assertEquals($list2, array('Kirk', 'Spock'), 'getremove last order list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(indexOf($list2, lists_get_remove_random_item($list2)) == 0, true, 'getremove random'); + assertEquals(length($list2), 2, 'getremove random list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(indexOf($list2, lists_get_remove_random_item(true ? $list2 : null)) == 0, true, 'getremove random order'); + assertEquals(length($list2), 2, 'getremove random order list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(array_splice($list2, 1, 1)[0], 'Spock', 'getremove #'); + assertEquals($list2, array('Kirk', 'McCoy'), 'getremove # list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(array_splice(true ? $list2 : null, ((true ? 2 : null) - 1), 1)[0], 'Spock', 'getremove # order'); + assertEquals($list2, array('Kirk', 'McCoy'), 'getremove # order list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + assertEquals(array_splice($list2, count($list2) - 3, 1)[0], 'Kirk', 'getremove #-end'); + assertEquals($list2, array('Spock', 'McCoy'), 'getremove #-end list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(array_splice(true ? $list2 : null, count(true ? $list2 : null) - (0 + 3), 1)[0], 'Kirk', 'getremove #-end order'); + assertEquals($list2, array('Spock', 'McCoy'), 'getremove #-end order list'); +} + +function lists_remove_random_item(&$list) { + unset($list[rand(0,count($list)-1)]); +} + +// Tests the "remove" block. +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; + $list2 = array('Kirk', 'Spock', 'McCoy'); + array_shift($list2); + assertEquals($list2, array('Spock', 'McCoy'), 'remove first list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + array_shift(true ? $list2 : null); + assertEquals($list2, array('Spock', 'McCoy'), 'remove first order list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + array_pop($list2); + assertEquals($list2, array('Kirk', 'Spock'), 'remove last list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + array_pop(true ? $list2 : null); + assertEquals($list2, array('Kirk', 'Spock'), 'remove last order list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + lists_remove_random_item($list2); + assertEquals(length($list2), 2, 'remove random list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + lists_remove_random_item(true ? $list2 : null); + assertEquals(length($list2), 2, 'remove random order list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + array_splice($list2, 1, 1); + assertEquals($list2, array('Kirk', 'McCoy'), 'remove # list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + array_splice(true ? $list2 : null, ((true ? 2 : null) - 1), 1); + assertEquals($list2, array('Kirk', 'McCoy'), 'remove # order list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + array_splice($list2, count($list2) - 3, 1)[0]; + assertEquals($list2, array('Spock', 'McCoy'), 'remove #-end list'); + $list2 = array('Kirk', 'Spock', 'McCoy'); + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + array_splice(true ? $list2 : null, count(true ? $list2 : null) - (0 + 3), 1)[0]; + assertEquals($list2, array('Spock', 'McCoy'), 'remove #-end order list'); +} + +function lists_set_last_item(&$list, $value) { + $list[count($list) - 1] = $value; +} + +function lists_set_from_end(&$list, $at, $value) { + $list[count($list) - $at] = $value; +} + +// Tests the "set" block. +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; + $list2 = array('Picard', 'Riker', 'Crusher'); + $list2[0] = 'Jean-Luc'; + assertEquals($list2, array('Jean-Luc', 'Riker', 'Crusher'), 'set first list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + (true ? $list2 : null)[0] = 'Jean-Luc'; + assertEquals($list2, array('Jean-Luc', 'Riker', 'Crusher'), 'set first order list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + lists_set_last_item($list2, 'Beverly'); + assertEquals($list2, array('Picard', 'Riker', 'Beverly'), 'set last list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + lists_set_last_item(true ? $list2 : null, 'Beverly'); + assertEquals($list2, array('Picard', 'Riker', 'Beverly'), 'set last order list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + $tmp_x = rand(0, count($list2)-1); + $list2[$tmp_x] = 'Data'; + assertEquals(length($list2), 3, 'set random list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + $tmp_list = &(true ? $list2 : null); + $tmp_x2 = rand(0, count($tmp_list)-1); + $tmp_list[$tmp_x2] = 'Data'; + assertEquals(length($list2), 3, 'set random order list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + $list2[2] = 'Pulaski'; + assertEquals($list2, array('Picard', 'Riker', 'Pulaski'), 'set # list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + (true ? $list2 : null)[((true ? 3 : null) - 1)] = 'Pulaski'; + assertEquals($list2, array('Picard', 'Riker', 'Pulaski'), 'set # order list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + lists_set_from_end($list2, 1, 'Pulaski'); + assertEquals($list2, array('Picard', 'Riker', 'Pulaski'), 'set #-end list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + lists_set_from_end(true ? $list2 : null, 0 + 2, 'Pulaski'); + assertEquals($list2, array('Picard', 'Pulaski', 'Crusher'), 'set #-end order list'); +} + +function lists_insert_from_end(&$list, $at, $value) { + return array_splice($list, count($list) - $at, 0, $value); +} + +// Tests the "insert" block. +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; + $list2 = array('Picard', 'Riker', 'Crusher'); + array_unshift($list2, 'Data'); + assertEquals($list2, array('Data', 'Picard', 'Riker', 'Crusher'), 'insert first list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + array_unshift(true ? $list2 : null, 'Data'); + assertEquals($list2, array('Data', 'Picard', 'Riker', 'Crusher'), 'insert first order list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + array_push($list2, 'Data'); + assertEquals($list2, array('Picard', 'Riker', 'Crusher', 'Data'), 'insert last list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + array_push(true ? $list2 : null, 'Data'); + assertEquals($list2, array('Picard', 'Riker', 'Crusher', 'Data'), 'insert last order list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + $tmp_x3 = rand(0, count($list2)-1); + array_splice($list2, $tmp_x3, 0, 'Data'); + assertEquals(length($list2), 4, 'insert random list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + $tmp_list2 = &(true ? $list2 : null); + $tmp_x4 = rand(0, count($tmp_list2)-1); + array_splice($tmp_list2, $tmp_x4, 0, 'Data'); + assertEquals(length($list2), 4, 'insert random order list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + array_splice($list2, 2, 0, 'Data'); + assertEquals($list2, array('Picard', 'Riker', 'Data', 'Crusher'), 'insert # list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + array_splice(true ? $list2 : null, ((true ? 3 : null) - 1), 0, 'Data'); + assertEquals($list2, array('Picard', 'Riker', 'Data', 'Crusher'), 'insert # order list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + lists_insert_from_end($list2, 1, 'Data'); + assertEquals($list2, array('Picard', 'Riker', 'Data', 'Crusher'), 'insert #-end list'); + $list2 = array('Picard', 'Riker', 'Crusher'); + // The order for index for #-end is addition because this will catch + // errors in generators where most perform the operation ... - index. + lists_insert_from_end(true ? $list2 : null, 0 + 2, 'Data'); + assertEquals($list2, array('Picard', 'Data', 'Riker', 'Crusher'), 'insert #-end order list'); +} + +// Tests the "get sub-list" block with a variable. +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; + $list2 = array('Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'); + 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, count($list2) - 3, count($list2) - 1 - (count($list2) - 3)), array('Discovery', 'Atlantis'), 'sublist #-end simple'); + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(array_slice($list2, count($list2) - (0 + 3), count($list2) - ((0 + 2) - 1) - (count($list2) - (0 + 3))), array('Discovery', 'Atlantis'), 'sublist #-end simple order'); + assertEquals($list2, $list2, 'sublist first-last simple'); + $changing_list = array('Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'); + $list_copy = $changing_list; + lists_remove_random_item($changing_list); + assertEquals($list_copy, $list2, 'sublist first-last simple copy check'); + assertEquals(array_slice($list2, 1, count($list2) - 1 - 1), array('Challenger', 'Discovery', 'Atlantis'), 'sublist # #-end simple'); + assertEquals(array_slice($list2, count($list2) - 3, 3 - (count($list2) - 3) + 1), array('Discovery', 'Atlantis'), 'sublist #-end # simple'); + assertEquals(array_slice($list2, 0, 3 - 0 + 1), array('Columbia', 'Challenger', 'Discovery', 'Atlantis'), 'sublist first # simple'); + assertEquals(array_slice($list2, 0, count($list2) - 3 - 0), array('Columbia', 'Challenger'), 'sublist first #-end simple'); + assertEquals(array_slice($list2, 3, count($list2) - 3), array('Atlantis', 'Endeavour'), 'sublist # last simple'); + assertEquals(array_slice($list2, count($list2) - 4, count($list2) - (count($list2) - 4)), array('Challenger', 'Discovery', 'Atlantis', 'Endeavour'), 'sublist #-end last simple'); + assertEquals(array_slice($list2, 0, count($list2) - 0 - 0), $list2, 'sublist all with # #-end simple'); + assertEquals(array_slice($list2, count($list2) - 5, 4 - (count($list2) - 5) + 1), $list2, 'sublist all with #-end # simple'); + // Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + assertEquals(array_slice($list2, ((0 + 1) - 1), count($list2) - ((0 + 1) - 1) - ((0 + 1) - 1)), $list2, 'sublist all with # #-end math simple'); +} + +// Creates a list for use with the sublist test. +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; + $number_of_calls += 1; + return array('Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'); +} + +function lists_get_sublist($list, $where1, $at1, $where2, $at2) { + if ($where1 == 'FROM_END') { + $at1 = count($list) - 1 - $at1; + } else if ($where1 == 'FIRST') { + $at1 = 0; + } else if ($where1 != 'FROM_START'){ + throw new Exception('Unhandled option (lists_get_sublist).'); + } + $length = 0; + if ($where2 == 'FROM_START') { + $length = $at2 - $at1 + 1; + } else if ($where2 == 'FROM_END') { + $length = count($list) - $at1 - $at2; + } else if ($where2 == 'LAST') { + $length = count($list) - $at1; + } else { + throw new Exception('Unhandled option (lists_get_sublist).'); + } + return array_slice($list, $at1, $length); +} + +// Tests the "get sub-list" block with a function call. +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; + $number_of_calls = 0; + assertEquals(array_slice(get_space_shuttles(), 1, 2 - 1 + 1), array('Challenger', 'Discovery'), 'sublist # start complex'); + check_number_of_calls('sublist # start complex'); + $number_of_calls = 0; + assertEquals(array_slice(true ? get_space_shuttles() : null, ((true ? 2 : null) - 1), ((true ? 3 : null) - 1) - ((true ? 2 : null) - 1) + 1), array('Challenger', 'Discovery'), 'sublist # start order complex'); + check_number_of_calls('sublist # start order complex'); + $number_of_calls = 0; + // The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(lists_get_sublist(get_space_shuttles(), 'FROM_END', 2, 'FROM_END', 1), array('Discovery', 'Atlantis'), 'sublist # end complex'); + assertEquals($number_of_calls, 1, 'sublist # end complex number of calls'); + $number_of_calls = 0; + assertEquals(lists_get_sublist(true ? get_space_shuttles() : null, 'FROM_END', ((0 + 3) - 1), 'FROM_END', ((0 + 2) - 1)), array('Discovery', 'Atlantis'), 'sublist # end order complex'); + check_number_of_calls('sublist # end order complex'); + $number_of_calls = 0; + assertEquals(get_space_shuttles(), $list2, 'sublist first-last complex'); + check_number_of_calls('sublist first-last complex'); + $number_of_calls = 0; + assertEquals(lists_get_sublist(get_space_shuttles(), 'FROM_START', 1, 'FROM_END', 1), array('Challenger', 'Discovery', 'Atlantis'), 'sublist # #-end complex'); + check_number_of_calls('sublist # #-end complex'); + $number_of_calls = 0; + assertEquals(lists_get_sublist(get_space_shuttles(), 'FROM_END', 2, 'FROM_START', 3), array('Discovery', 'Atlantis'), 'sublist #-end # complex'); + check_number_of_calls('sublist #-end # complex'); + $number_of_calls = 0; + assertEquals(array_slice(get_space_shuttles(), 0, 3 - 0 + 1), array('Columbia', 'Challenger', 'Discovery', 'Atlantis'), 'sublist first # complex'); + check_number_of_calls('sublist first # complex'); + $number_of_calls = 0; + assertEquals(lists_get_sublist(get_space_shuttles(), 'FIRST', 0, 'FROM_END', 3), array('Columbia', 'Challenger'), 'sublist first #-end complex'); + check_number_of_calls('sublist first #-end complex'); + $number_of_calls = 0; + assertEquals(lists_get_sublist(get_space_shuttles(), 'FROM_START', 3, 'LAST', 0), array('Atlantis', 'Endeavour'), 'sublist # last complex'); + check_number_of_calls('sublist # last complex'); + $number_of_calls = 0; + assertEquals(lists_get_sublist(get_space_shuttles(), 'FROM_END', 3, 'LAST', 0), array('Challenger', 'Discovery', 'Atlantis', 'Endeavour'), 'sublist #-end last simple'); + check_number_of_calls('sublist #-end last simple'); + $number_of_calls = 0; + assertEquals(lists_get_sublist(get_space_shuttles(), 'FROM_START', 0, 'FROM_END', 0), $list2, 'sublist all with # #-end complex'); + check_number_of_calls('sublist all with # #-end complex'); + $number_of_calls = 0; + assertEquals(lists_get_sublist(get_space_shuttles(), 'FROM_END', 4, 'FROM_START', 4), $list2, 'sublist all with #-end # complex'); + check_number_of_calls('sublist all with #-end # complex'); + $number_of_calls = 0; + // Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + assertEquals(lists_get_sublist(get_space_shuttles(), 'FROM_START', ((0 + 1) - 1), 'FROM_END', ((0 + 1) - 1)), $list2, 'sublist all with # #-end math complex'); + check_number_of_calls('sublist all with # #-end math complex'); +} + +// Tests the "join" block. +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; + $list2 = array('Vulcan', 'Klingon', 'Borg'); + assertEquals(implode(',', $list2), 'Vulcan,Klingon,Borg', 'join'); + assertEquals(implode(',', true ? $list2 : null), 'Vulcan,Klingon,Borg', 'join order'); +} + +// Tests the "split" block. +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; + $text = 'Vulcan,Klingon,Borg'; + assertEquals(explode(',', $text), array('Vulcan', 'Klingon', 'Borg'), 'split'); + assertEquals(explode(',', true ? $text : null), array('Vulcan', 'Klingon', 'Borg'), 'split order'); +} + +function lists_sort($list, $type, $direction) { + $sortCmpFuncs = array( + "NUMERIC" => "strnatcasecmp", + "TEXT" => "strcmp", + "IGNORE_CASE" => "strcasecmp" + ); + $sortCmp = $sortCmpFuncs[$type]; + $list2 = $list; + usort($list2, $sortCmp); + if ($direction == -1) { + $list2 = array_reverse($list2); + } + return $list2; +} + +// Tests the "alphabetic sort" block. +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; + $list2 = array('Vulcan', 'klingon', 'Borg'); + 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'); +} + +// Tests the "alphabetic sort ignore case" block. +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; + $list2 = array('Vulcan', 'klingon', 'Borg'); + 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'); +} + +// Tests the "numeric sort" block. +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; + $list2 = array(8, 18, -1); + 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'); +} + +// Tests the "list reverse" block. +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; + $list2 = array(8, 18, -1, 64); + assertEquals(array_reverse($list2), array(64, -1, 18, 8), 'reverse a copy'); + assertEquals($list2, array(8, 18, -1, 64), 'reverse a copy original'); + $list2 = array(); + 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... +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; + procedure_1(8, 2); + assertEquals($proc_z, 4, 'procedure with global'); + $proc_w = false; + procedure_2(false); + assertEquals($proc_w, true, 'procedure no return'); + $proc_w = false; + procedure_2(true); + assertEquals($proc_w, false, 'procedure return'); +} + +// Describe this function... +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; + $proc_z = $proc_x / $proc_y; +} + +// Describe this function... +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; + if ($proc_x) { + return; + } + $proc_w = true; +} + +// Describe this 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; + assertEquals(function_1(2, 3), -1, 'function with arguments'); + assertEquals($func_z, 'side effect', 'function with side effect'); + $func_a = 'unchanged'; + $func_c = 'global'; + assertEquals(function_2(2), '3global', 'function with global'); + assertEquals($func_a, 'unchanged', 'function with scope'); + assertEquals(function_3(true), true, 'function return'); + assertEquals(function_3(false), false, 'function no return'); +} + +// Describe this function... +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; + $func_z = 'side effect'; + return $func_x - $func_y; +} + +// Describe this function... +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; + $func_a += 1; + return $func_a . $func_c; +} + +// Describe this function... +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; + if ($func_a) { + return true; + } + return false; +} + +// Describe this function... +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; + if ($n > 0) { + $text = implode('', array(recurse($n - 1),$n,recurse($n - 1))); + } else { + $text = '-'; + } + return $text; +} + + +$unittestResults = array(); +print("\n====================\n\nRunning suite: Logic\n"); +assertEquals(true, true, 'True'); +assertEquals(false, false, 'False'); +assertEquals(!false, true, 'Not true'); +assertEquals(!true, false, 'Not false'); +test_if(); +test_ifelse(); +test_equalities(); +test_and(); +test_or(); +test_ternary(); +print(unittest_report()); +$unittestResults = null; + +$unittestResults = array(); +print("\n====================\n\nRunning suite: Loops 1\n"); +test_repeat(); +test_repeat_ext(); +test_while(); +test_foreach(); +print(unittest_report()); +$unittestResults = null; + +$unittestResults = array(); +print("\n====================\n\nRunning suite: Loops 2\n"); +test_count_loops(); +test_count_by(); +print(unittest_report()); +$unittestResults = null; + +$unittestResults = array(); +print("\n====================\n\nRunning suite: Loops 3\n"); +test_break(); +test_continue(); +print(unittest_report()); +$unittestResults = null; + +$unittestResults = array(); +print("\n====================\n\nRunning suite: Math\n"); +test_arithmetic(); +test_single(); +test_trig(); +test_constant(); +test_change(); +test_number_properties(); +test_round(); +test_operations_on_list(); +test_constraint(); +test_mod(); +test_random_integer(); +test_random_fraction(); +test_atan2(); +print(unittest_report()); +$unittestResults = null; + +$unittestResults = array(); +print("\n====================\n\nRunning suite: Text\n"); +test_text_length(); +test_empty_text(); +test_create_text(); +test_append(); +test_find_text_simple(); +test_find_text_complex(); +test_get_text_simple(); +test_get_text_complex(); +test_substring_simple(); +test_substring_complex(); +test_case(); +test_trim(); +test_count_text(); +test_text_reverse(); +test_replace(); +print(unittest_report()); +$unittestResults = null; + +$unittestResults = array(); +print("\n====================\n\nRunning suite: Lists\n"); +test_create_lists(); +test_lists_empty(); +test_lists_length(); +test_find_lists_simple(); +test_find_lists_complex(); +test_get_lists_simple(); +test_get_lists_complex(); +test_getRemove(); +test_remove(); +test_set(); +test_insert(); +test_sublist_simple(); +test_sublist_complex(); +test_join(); +test_split(); +test_sort_alphabetic(); +test_sort_ignoreCase(); +test_sort_numeric(); +test_lists_reverse(); +print(unittest_report()); +$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(); +print("\n====================\n\nRunning suite: Variables\n"); +$item = 123; +assertEquals($item, 123, 'variable'); +$if2 = 123; +assertEquals($if2, 123, 'reserved variable'); +print(unittest_report()); +$unittestResults = null; + +// Intentionally non-connected variable. +$naked; + +$unittestResults = array(); +print("\n====================\n\nRunning suite: Functions\n"); +test_procedure(); +test_function(); +assertEquals(recurse(3), '-1-2-1-3-1-2-1-', 'test recurse'); +print(unittest_report()); +$unittestResults = null; diff --git a/tests/generators/golden/generated.py b/tests/generators/golden/generated.py new file mode 100644 index 000000000..603a4ddd2 --- /dev/null +++ b/tests/generators/golden/generated.py @@ -0,0 +1,1524 @@ +from numbers import Number +import math +import random +import sys + +unittestResults = None +test_name = None +naked = None +proc_x = None +proc_y = None +func_x = None +func_y = None +func_a = None +n = None +ok = None +log = None +count = None +varToChange = None +rand = None +item = None +text = None +number_of_calls = None +list2 = None +proc_z = None +func_z = None +x = None +proc_w = None +func_c = None +if2 = None +i = None +loglist = None +changing_list = None +list_copy = None + +def unittest_report(): + # Create test report. + report = [] + summary = [] + fails = 0 + for (success, log, message) in unittestResults: + if success: + summary.append(".") + else: + summary.append("F") + fails += 1 + report.append("") + report.append("FAIL: " + message) + report.append(log) + report.insert(0, "".join(summary)) + report.append("") + report.append("Number of tests run: %d" % len(unittestResults)) + report.append("") + if fails: + report.append("FAILED (failures=%d)" % fails) + else: + report.append("OK") + return "\n".join(report) + +def assertEquals(actual, expected, message): + # Asserts that a value equals another value. + if unittestResults == None: + raise Exception("Orphaned assert equals: " + message) + if actual == expected: + unittestResults.append((True, "OK", message)) + else: + unittestResults.append((False, "Expected: %s\nActual: %s" % (expected, actual), message)) + +def fail(message): + # Always assert an error. + if unittestResults == None: + raise Exception("Orphaned assert equals: " + message) + unittestResults.append((False, "Fail.", message)) + +"""Describe this function... +""" +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 + if False: + fail('if false') + ok = False + if True: + ok = True + assertEquals(ok, True, 'if true') + ok = False + if False: + fail('if/else false') + else: + ok = True + assertEquals(ok, True, 'if/else false') + ok = False + if True: + ok = True + else: + fail('if/else true') + assertEquals(ok, True, 'if/else true') + ok = False + if False: + fail('elseif 1') + elif True: + ok = True + elif True: + fail('elseif 2') + else: + fail('elseif 3') + assertEquals(ok, True, 'elseif 4') + +"""Describe this function... +""" +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 + ok = False + if True: + ok = True + else: + fail('ifelse true') + assertEquals(ok, True, 'ifelse true') + ok = False + if False: + fail('ifelse false') + else: + ok = True + assertEquals(ok, True, 'ifelse false') + +"""Describe this function... +""" +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 + assertEquals(2 == 2, True, 'Equal yes') + assertEquals(3 == 4, False, 'Equal no') + assertEquals(5 != 6, True, 'Not equal yes') + assertEquals(3 == 4, False, 'Not equal no') + assertEquals(5 < 6, True, 'Smaller yes') + assertEquals(7 < 7, False, 'Smaller no') + assertEquals(9 > 8, True, 'Greater yes') + assertEquals(10 > 10, False, 'Greater no') + assertEquals(11 <= 11, True, 'Smaller-equal yes') + assertEquals(13 <= 12, False, 'Smaller-equal no') + assertEquals(14 >= 14, True, 'Greater-equal yes') + assertEquals(15 >= 16, False, 'Greater-equal no') + +"""Describe this function... +""" +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 + assertEquals(True and True, True, 'And true/true') + assertEquals(False and True, False, 'And false/true') + assertEquals(True and False, False, 'And true/false') + assertEquals(False and False, False, 'And false/false') + +"""Describe this function... +""" +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 + assertEquals(True or True, True, 'Or true/true') + assertEquals(False or True, True, 'Or false/true') + assertEquals(True or False, True, 'Or true/false') + assertEquals(False or False, False, 'Or false/false') + +"""Describe this function... +""" +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 + assertEquals(42 if True else 99, 42, 'if true') + assertEquals(42 if False else 99, 99, 'if true') + +"""Describe this function... +""" +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 + log = '' + for x in ['a', 'b', 'c']: + log = str(log) + str(x) + assertEquals(log, 'abc', 'for loop') + +"""Describe this function... +""" +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 + count = 0 + for count2 in range(10): + count = (count if isinstance(count, Number) else 0) + 1 + assertEquals(count, 10, 'repeat 10') + +"""Describe this function... +""" +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 + while False: + fail('while 0') + while not True: + fail('until 0') + count = 1 + while count != 10: + count = (count if isinstance(count, Number) else 0) + 1 + assertEquals(count, 10, 'while 10') + count = 1 + while not count == 10: + count = (count if isinstance(count, Number) else 0) + 1 + assertEquals(count, 10, 'until 10') + +"""Describe this function... +""" +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 + count = 0 + for count3 in range(10): + count = (count if isinstance(count, Number) else 0) + 1 + assertEquals(count, 10, 'repeat 10') + +def upRange(start, stop, step): + while start <= stop: + yield start + start += abs(step) + +def downRange(start, stop, step): + while start >= stop: + yield start + start -= abs(step) + +"""Describe this function... +""" +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 + log = '' + for x in range(1, 9, 2): + log = str(log) + str(x) + assertEquals(log, '1357', 'count up ints') + log = '' + for x in range(8, 0, -2): + log = str(log) + str(x) + assertEquals(log, '8642', 'count down ints') + loglist = [] + for x in upRange(1, 8, 1.5): + loglist.append(x) + assertEquals(loglist, [1, 2.5, 4, 5.5, 7], 'count with floats') + loglist = [] + x_start = float(1 + 0) + x_end = float(8 + 0) + x_inc = float(1 - 2) + for x in (x_start <= x_end) and upRange(x_start, x_end, 1 - 2) or downRange(x_start, x_end, 1 - 2): + loglist.append(x) + assertEquals(loglist, [1, 2, 3, 4, 5, 6, 7, 8], 'count up non-trivial ints') + loglist = [] + x_start2 = float(8 + 0) + x_end2 = float(1 + 0) + for x in (x_start2 <= x_end2) and upRange(x_start2, x_end2, 2) or downRange(x_start2, x_end2, 2): + loglist.append(x) + assertEquals(loglist, [8, 6, 4, 2], 'count down non-trivial ints') + loglist = [] + x_start3 = float(5 + 0.5) + x_end3 = float(1 + 0) + x_inc2 = float(1 + 0) + for x in (x_start3 <= x_end3) and upRange(x_start3, x_end3, 1 + 0) or downRange(x_start3, x_end3, 1 + 0): + loglist.append(x) + assertEquals(loglist, [5.5, 4.5, 3.5, 2.5, 1.5], 'count with floats') + +"""Describe this function... +""" +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 + log = '' + for x in range(1, 9): + log = str(log) + str(x) + assertEquals(log, '12345678', 'count up') + log = '' + for x in range(8, 0, -1): + log = str(log) + str(x) + assertEquals(log, '87654321', 'count down') + loglist = [] + x_start4 = float(1 + 0) + x_end4 = float(4 + 0) + for x in (x_start4 <= x_end4) and upRange(x_start4, x_end4, 1) or downRange(x_start4, x_end4, 1): + loglist.append(x) + assertEquals(loglist, [1, 2, 3, 4], 'count up non-trivial') + loglist = [] + x_start5 = float(3 + 1) + x_end5 = float(1 + 0) + for x in (x_start5 <= x_end5) and upRange(x_start5, x_end5, 1) or downRange(x_start5, x_end5, 1): + loglist.append(x) + assertEquals(loglist, [4, 3, 2, 1], 'count down non-trivial') + +"""Describe this function... +""" +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 + log = '' + count = 0 + while count != 8: + count = (count if isinstance(count, Number) else 0) + 1 + if count == 5: + continue + log = str(log) + str(count) + assertEquals(log, '1234678', 'while continue') + log = '' + count = 0 + while not count == 8: + count = (count if isinstance(count, Number) else 0) + 1 + if count == 5: + continue + log = str(log) + str(count) + assertEquals(log, '1234678', 'until continue') + log = '' + for x in range(1, 9): + if x == 5: + continue + log = str(log) + str(x) + assertEquals(log, '1234678', 'count continue') + log = '' + for x in ['a', 'b', 'c', 'd']: + if x == 'c': + continue + log = str(log) + str(x) + assertEquals(log, 'abd', 'for continue') + +"""Describe this function... +""" +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 + count = 1 + while count != 10: + if count == 5: + break + count = (count if isinstance(count, Number) else 0) + 1 + assertEquals(count, 5, 'while break') + count = 1 + while not count == 10: + if count == 5: + break + count = (count if isinstance(count, Number) else 0) + 1 + assertEquals(count, 5, 'until break') + log = '' + for x in range(1, 9): + if x == 5: + break + log = str(log) + str(x) + assertEquals(log, '1234', 'count break') + log = '' + for x in ['a', 'b', 'c', 'd']: + if x == 'c': + break + log = str(log) + str(x) + assertEquals(log, 'ab', 'for break') + +"""Tests the "single" block. +""" +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 + assertEquals(math.sqrt(25), 5, 'sqrt') + assertEquals(math.fabs(-25), 25, 'abs') + assertEquals(-(-25), 25, 'negate') + assertEquals(math.log(1), 0, 'ln') + assertEquals(math.log10(100), 2, 'log10') + assertEquals(math.exp(2), 7.38905609893065, 'exp') + assertEquals(math.pow(10,2), 100, 'power10') + +"""Tests the "arithmetic" block for all operations and checks +parenthesis are properly generated for different orders. +""" +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 + assertEquals(1 + 2, 3, 'add') + assertEquals(1 - 2, -1, 'subtract') + assertEquals(1 - (0 + 2), -1, 'subtract order with add') + assertEquals(1 - (0 - 2), 3, 'subtract order with subtract') + assertEquals(4 * 2.5, 10, 'multiply') + assertEquals(4 * (0 + 2.5), 10, 'multiply order') + assertEquals(8.2 / -5, -1.64, 'divide') + assertEquals(8.2 / (0 + -5), -1.64, 'divide order') + assertEquals(10 ** 4, 10000, 'power') + assertEquals(10 ** (0 + 4), 10000, 'power order') + +"""Tests the "trig" block. +""" +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 + assertEquals(math.sin(90 / 180.0 * math.pi), 1, 'sin') + assertEquals(math.cos(180 / 180.0 * math.pi), -1, 'cos') + assertEquals(math.tan(0 / 180.0 * math.pi), 0, 'tan') + assertEquals(math.asin(-1) / math.pi * 180, -90, 'asin') + assertEquals(math.acos(1) / math.pi * 180, 0, 'acos') + assertEquals(math.atan(1) / math.pi * 180, 45, 'atan') + +"""Tests the "constant" blocks. +""" +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 + assertEquals(math.floor(math.pi * 1000), 3141, 'const pi') + assertEquals(math.floor(math.e * 1000), 2718, 'const e') + assertEquals(math.floor(((1 + math.sqrt(5)) / 2) * 1000), 1618, 'const golden') + assertEquals(math.floor(math.sqrt(2) * 1000), 1414, 'const sqrt 2') + assertEquals(math.floor(math.sqrt(1.0 / 2) * 1000), 707, 'const sqrt 0.5') + assertEquals(9999 < float('inf'), True, 'const infinity') + +def math_isPrime(n): + # https://en.wikipedia.org/wiki/Primality_test#Naive_methods + # If n is not a number but a string, try parsing it. + if not isinstance(n, Number): + try: + n = float(n) + except: + return False + if n == 2 or n == 3: + return True + # False if n is negative, is 1, or not whole, or if n is divisible by 2 or 3. + if n <= 1 or n % 1 != 0 or n % 2 == 0 or n % 3 == 0: + return False + # Check all the numbers of form 6k +/- 1, up to sqrt(n). + for x in range(6, int(math.sqrt(n)) + 2, 6): + if n % (x - 1) == 0 or n % (x + 1) == 0: + return False + return True + +"""Tests the "number property" blocks. +""" +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 + assertEquals(42 % 2 == 0, True, 'even') + assertEquals(42.1 % 2 == 1, False, 'odd') + assertEquals(math_isPrime(5), True, 'prime 5') + assertEquals(math_isPrime(25), False, 'prime 25') + assertEquals(math_isPrime(-31.1), False, 'prime negative') + assertEquals(math.pi % 1 == 0, False, 'whole') + assertEquals(float('inf') > 0, True, 'positive') + assertEquals(-42 < 0, True, 'negative') + assertEquals(42 % 2 == 0, True, 'divisible') + +"""Tests the "round" block. +""" +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 + assertEquals(round(42.42), 42, 'round') + assertEquals(math.ceil(-42.42), -42, 'round up') + assertEquals(math.floor(42.42), 42, 'round down') + +"""Tests the "change" block. +""" +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 + varToChange = 100 + varToChange = (varToChange if isinstance(varToChange, Number) else 0) + 42 + assertEquals(varToChange, 142, 'change') + +def math_mean(myList): + localList = [e for e in myList if isinstance(e, Number)] + if not localList: return + return float(sum(localList)) / len(localList) + +def math_median(myList): + localList = sorted([e for e in myList if isinstance(e, Number)]) + if not localList: return + if len(localList) % 2 == 0: + return (localList[len(localList) // 2 - 1] + localList[len(localList) // 2]) / 2.0 + else: + return localList[(len(localList) - 1) // 2] + +def math_modes(some_list): + modes = [] + # Using a lists of [item, count] to keep count rather than dict + # to avoid "unhashable" errors when the counted item is itself a list or dict. + counts = [] + maxCount = 1 + for item in some_list: + found = False + for count in counts: + if count[0] == item: + count[1] += 1 + maxCount = max(maxCount, count[1]) + found = True + if not found: + counts.append([item, 1]) + for counted_item, item_count in counts: + if item_count == maxCount: + modes.append(counted_item) + return modes + +def math_standard_deviation(numbers): + n = len(numbers) + if n == 0: return + mean = float(sum(numbers)) / n + variance = sum((x - mean) ** 2 for x in numbers) / n + return math.sqrt(variance) + +def first_index(my_list, elem): + try: index = my_list.index(elem) + 1 + except: index = 0 + return index + +"""Tests the "list operation" blocks. +""" +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 + assertEquals(sum([3, 4, 5]), 12, 'sum') + assertEquals(min([3, 4, 5]), 3, 'min') + assertEquals(max([3, 4, 5]), 5, 'max') + assertEquals(math_mean([3, 4, 5]), 4, 'average') + assertEquals(math_median([3, 4, 5, 1]), 3.5, 'median') + assertEquals(math_modes([3, 4, 3]), [3], 'modes') + assertEquals(math_modes([3, 4, 3, 1, 4]), [3, 4], 'modes multiple') + assertEquals(math_standard_deviation([3, 3, 3]), 0, 'standard dev') + assertEquals(first_index([3, 4, 5], random.choice([3, 4, 5])) > 0, True, 'random') + +"""Tests the "mod" block. +""" +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 + assertEquals(42 % 5, 2, 'mod') + +"""Tests the "constrain" block. +""" +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 + assertEquals(min(max(100, 0), 42), 42, 'constraint') + +"""Tests the "random integer" block. +""" +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 + rand = random.randint(5, 10) + assertEquals(rand >= 5 and rand <= 10, True, 'randRange') + assertEquals(rand % 1 == 0, True, 'randInteger') + +"""Tests the "random fraction" block. +""" +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 + rand = random.random() + assertEquals(rand >= 0 and rand <= 1, True, 'randFloat') + +"""Describe this function... +""" +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 + assertEquals(math.atan2(5, -5) / math.pi * 180, 135, 'atan2') + assertEquals(math.atan2(-12, 0) / math.pi * 180, -90, 'atan2') + +"""Checks that the number of calls is one in order +to confirm that a function was only called once. +""" +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 + test_name = str(test_name) + 'number of calls' + assertEquals(number_of_calls, 1, test_name) + +"""Tests the "create text with" block with varying number of inputs. +""" +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 + assertEquals('', '', 'no text') + assertEquals('Hello', 'Hello', 'create single') + assertEquals(str(-1), '-1', 'create single number') + assertEquals('K' + str(9), 'K9', 'create double text') + assertEquals(str(4) + str(2), '42', 'create double text numbers') + assertEquals(''.join([str(x2) for x2 in [1, 2, 3]]), '123', 'create triple') + assertEquals(''.join([str(x3) for x3 in [1, 0 if True else None, 'M']]), '10M', 'create order') + +"""Creates an empty string for use with the empty test. +""" +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 + return '' + +"""Tests the "is empty" block". +""" +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 + assertEquals(not len('Google'), False, 'not empty') + assertEquals(not len(''), True, 'empty') + assertEquals(not len(get_empty()), True, 'empty complex') + assertEquals(not len('' if True else None), True, 'empty order') + +"""Tests the "length" block. +""" +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 + assertEquals(len(''), 0, 'zero length') + assertEquals(len('Google'), 6, 'non-zero length') + assertEquals(len('car' if True else None), 3, 'length order') + +"""Tests the "append text" block with different types of parameters. +""" +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 + item = 'Miserable' + item = str(item) + 'Failure' + assertEquals(item, 'MiserableFailure', 'append text') + item = 12 + item = str(item) + str(34) + assertEquals(item, '1234', 'append number') + item = 'Something ' + item = str(item) + str('Positive' if True else None) + assertEquals(item, 'Something Positive', 'append order') + +"""Tests the "find" block with a variable. +""" +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 + text = 'Banana' + assertEquals(text.find('an') + 1, 2, 'find first simple') + assertEquals(text.rfind('an') + 1, 4, 'find last simple') + assertEquals(text.find('Peel') + 1, 0, 'find none simple') + +"""Creates a string for use with the find test. +""" +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 + number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1 + return 'Banana' + +"""Tests the "find" block with a function call. +""" +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 + number_of_calls = 0 + assertEquals(get_fruit().find('an') + 1, 2, 'find first complex') + check_number_of_calls('find first complex') + number_of_calls = 0 + assertEquals((get_fruit() if True else None).find('an') + 1, 2, 'find first order complex') + check_number_of_calls('find first order complex') + number_of_calls = 0 + assertEquals(get_fruit().rfind('an') + 1, 4, 'find last complex') + check_number_of_calls('find last complex') + number_of_calls = 0 + assertEquals((get_fruit() if True else None).rfind('an') + 1, 4, 'find last order complex') + check_number_of_calls('find last order complex') + number_of_calls = 0 + assertEquals(get_fruit().find('Peel') + 1, 0, 'find none complex') + check_number_of_calls('find none complex') + number_of_calls = 0 + assertEquals((get_fruit() if True else None).find('Peel') + 1, 0, 'find none order complex') + check_number_of_calls('find none order complex') + +def text_random_letter(text): + x = int(random.random() * len(text)) + return text[x]; + +"""Tests the "get letter" block with a variable. +""" +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 + text = 'Blockly' + assertEquals(text[0], 'B', 'get first simple') + assertEquals(text[-1], 'y', 'get last simple') + assertEquals(text.find(text_random_letter(text)) + 1 > 0, True, 'get random simple') + assertEquals(text[2], 'o', 'get # simple') + assertEquals(text[int((3 if True else None) - 1)], 'o', 'get # order simple') + assertEquals(text[-3], 'k', 'get #-end simple') + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(text[-int(0 + 3)], 'k', 'get #-end order simple') + +"""Creates a string for use with the get test. +""" +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 + number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1 + return 'Blockly' + +"""Tests the "get letter" block with a function call. +""" +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 + text = 'Blockly' + number_of_calls = 0 + assertEquals(get_Blockly()[0], 'B', 'get first complex') + check_number_of_calls('get first complex') + number_of_calls = 0 + assertEquals((get_Blockly() if True else None)[0], 'B', 'get first order complex') + check_number_of_calls('get first order complex') + number_of_calls = 0 + assertEquals(get_Blockly()[-1], 'y', 'get last complex') + check_number_of_calls('get last complex') + number_of_calls = 0 + assertEquals((get_Blockly() if True else None)[-1], 'y', 'get last order complex') + check_number_of_calls('get last order complex') + number_of_calls = 0 + assertEquals(text.find(text_random_letter(get_Blockly())) + 1 > 0, True, 'get random complex') + check_number_of_calls('get random complex') + number_of_calls = 0 + assertEquals(text.find(text_random_letter((get_Blockly() if True else None))) + 1 > 0, True, 'get random order complex') + check_number_of_calls('get random order complex') + number_of_calls = 0 + assertEquals(get_Blockly()[2], 'o', 'get # complex') + check_number_of_calls('get # complex') + number_of_calls = 0 + assertEquals((get_Blockly() if True else None)[int((3 if True else None) - 1)], 'o', 'get # order complex') + check_number_of_calls('get # order complex') + number_of_calls = 0 + assertEquals(get_Blockly()[-3], 'k', 'get #-end complex') + check_number_of_calls('get #-end complex') + number_of_calls = 0 + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals((get_Blockly() if True else None)[-int(0 + 3)], 'k', 'get #-end order complex') + check_number_of_calls('get #-end order complex') + +"""Creates a string for use with the substring test. +""" +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 + number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1 + return '123456789' + +"""Tests the "get substring" block with a variable. +""" +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 + text = '123456789' + 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[-3 : -1], '78', 'substring #-end simple') + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(text[-int(0 + 3) : -int((0 + 2) - 1) or sys.maxsize], '78', 'substring #-end simple order') + assertEquals(text[ : ], text, 'substring first-last simple') + assertEquals(text[1 : -1], '2345678', 'substring # #-end simple') + assertEquals(text[-7 : 4], '34', 'substring #-end # simple') + assertEquals(text[ : 4], '1234', 'substring first # simple') + assertEquals(text[ : -1], '12345678', 'substring first #-end simple') + assertEquals(text[6 : ], '789', 'substring # last simple') + assertEquals(text[-3 : ], '789', 'substring #-end last simple') + assertEquals(text[ : ], '123456789', 'substring all with # #-end simple') + assertEquals(text[-9 : 9], '123456789', 'substring all with #-end # simple') + # Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + assertEquals(text[int((0 + 1) - 1) : -int((0 + 1) - 1) or sys.maxsize], '123456789', 'substring all with # #-end math simple') + +"""Tests the "get substring" block with a function call. +""" +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 + number_of_calls = 0 + assertEquals(get_numbers()[1 : 3], '23', 'substring # complex') + check_number_of_calls('substring # complex') + number_of_calls = 0 + assertEquals((get_numbers() if True else None)[int((2 if True else None) - 1) : int(3 if True else None)], '23', 'substring # complex order') + check_number_of_calls('substring # complex order') + number_of_calls = 0 + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(get_numbers()[-3 : -1], '78', 'substring #-end complex') + check_number_of_calls('substring #-end complex') + number_of_calls = 0 + assertEquals((get_numbers() if True else None)[-int(0 + 3) : -int((0 + 2) - 1) or sys.maxsize], '78', 'substring #-end order order') + check_number_of_calls('substring #-end order order') + number_of_calls = 0 + assertEquals(get_numbers()[ : ], text, 'substring first-last') + check_number_of_calls('substring first-last') + number_of_calls = 0 + assertEquals(get_numbers()[1 : -1], '2345678', 'substring # #-end complex') + check_number_of_calls('substring # #-end complex') + number_of_calls = 0 + assertEquals(get_numbers()[-7 : 4], '34', 'substring #-end # complex') + check_number_of_calls('substring #-end # complex') + number_of_calls = 0 + assertEquals(get_numbers()[ : 4], '1234', 'substring first # complex') + check_number_of_calls('substring first # complex') + number_of_calls = 0 + assertEquals(get_numbers()[ : -1], '12345678', 'substring first #-end complex') + check_number_of_calls('substring first #-end complex') + number_of_calls = 0 + assertEquals(get_numbers()[6 : ], '789', 'substring # last complex') + check_number_of_calls('substring # last complex') + number_of_calls = 0 + assertEquals(get_numbers()[-3 : ], '789', 'substring #-end last complex') + check_number_of_calls('substring #-end last complex') + number_of_calls = 0 + assertEquals(get_numbers()[ : ], '123456789', 'substring all with # #-end complex') + check_number_of_calls('substring all with # #-end complex') + number_of_calls = 0 + assertEquals(get_numbers()[-9 : 9], '123456789', 'substring all with #-end # complex') + check_number_of_calls('substring all with #-end # complex') + number_of_calls = 0 + # Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end. + assertEquals(get_numbers()[int((0 + 1) - 1) : -int((0 + 1) - 1) or sys.maxsize], '123456789', 'substring all with # #-end math complex') + check_number_of_calls('substring all with # #-end math complex') + +"""Tests the "change casing" block. +""" +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 + text = 'Hello World' + assertEquals(text.upper(), 'HELLO WORLD', 'uppercase') + assertEquals((text if True else None).upper(), 'HELLO WORLD', 'uppercase order') + text = 'Hello World' + assertEquals(text.lower(), 'hello world', 'lowercase') + assertEquals((text if True else None).lower(), 'hello world', 'lowercase order') + text = 'heLLo WorlD' + assertEquals(text.title(), 'Hello World', 'titlecase') + assertEquals((text if True else None).title(), 'Hello World', 'titlecase order') + +"""Tests the "trim" block. +""" +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 + text = ' abc def ' + assertEquals(text.strip(), 'abc def', 'trim both') + assertEquals((text if True else None).strip(), 'abc def', 'trim both order') + assertEquals(text.lstrip(), 'abc def ', 'trim left') + assertEquals((text if True else None).lstrip(), 'abc def ', 'trim left order') + assertEquals(text.rstrip(), ' abc def', 'trim right') + assertEquals((text if True else None).rstrip(), ' abc def', 'trim right order') + +"""Tests the "trim" block. +""" +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 + text = 'woolloomooloo' + assertEquals(text.count('o'), 8, 'len 1') + assertEquals(text.count('oo'), 4, 'len 2') + assertEquals(text.count('loo'), 2, 'len 3') + assertEquals(text.count('wool'), 1, 'start') + assertEquals(text.count('chicken'), 0, 'missing') + assertEquals(text.count(''), 14, 'empty needle') + assertEquals(''.count('chicken'), 0, 'empty source') + +"""Tests the "trim" block. +""" +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 + assertEquals(''[::-1], '', 'empty string') + assertEquals('a'[::-1], 'a', 'len 1') + assertEquals('ab'[::-1], 'ba', 'len 2') + assertEquals('woolloomooloo'[::-1], 'ooloomoolloow', 'longer') + +"""Tests the "trim" block. +""" +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 + assertEquals('woolloomooloo'.replace('oo', '123'), 'w123ll123m123l123', 'replace all instances 1') + assertEquals('woolloomooloo'.replace('.oo', 'X'), 'woolloomooloo', 'literal string replacement') + assertEquals('woolloomooloo'.replace('abc', 'X'), 'woolloomooloo', 'not found') + assertEquals('woolloomooloo'.replace('o', ''), 'wllml', 'empty replacement 1') + assertEquals('aaaaa'.replace('aaaaa', ''), '', 'empty replacement 2') + assertEquals('aaaaa'.replace('a', ''), '', 'empty replacement 3') + assertEquals(''.replace('a', 'chicken'), '', 'empty source') + +"""Checks that the number of calls is one in order +to confirm that a function was only called once. +""" +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 + test_name = str(test_name) + 'number of calls' + assertEquals(number_of_calls, 1, test_name) + +"""Tests the "create list with" and "create empty list" blocks. +""" +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 + assertEquals([], [], 'create empty') + assertEquals([True, 'love'], [True, 'love'], 'create items') + assertEquals(['Eject'] * 3, ['Eject', 'Eject', 'Eject'], 'create repeated') + assertEquals(['Eject'] * (0 + 3), ['Eject', 'Eject', 'Eject'], 'create repeated order') + +"""Creates an empty list for use with the empty test. +""" +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 + return [] + +"""Tests the "is empty" block. +""" +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 + assertEquals(not len([0]), False, 'not empty') + assertEquals(not len([]), True, 'empty') + assertEquals(not len(get_empty_list()), True, 'empty complex') + assertEquals(not len([] if True else None), True, 'empty order') + +"""Tests the "length" block. +""" +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 + assertEquals(len([]), 0, 'zero length') + assertEquals(len(['cat']), 1, 'one length') + assertEquals(len(['cat', True, []]), 3, 'three length') + assertEquals(len(['cat', True] if True else None), 2, 'two length order') + +def last_index(my_list, elem): + try: index = len(my_list) - my_list[::-1].index(elem) + except: index = 0 + return index + +"""Tests the "find" block with a variable. +""" +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 + list2 = ['Alice', 'Eve', 'Bob', 'Eve'] + assertEquals(first_index(list2, 'Eve'), 2, 'find first simple') + assertEquals(last_index(list2, 'Eve'), 4, 'find last simple') + assertEquals(first_index(list2, 'Dave'), 0, 'find none simple') + +"""Creates a list for use with the find test. +""" +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 + number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1 + return ['Alice', 'Eve', 'Bob', 'Eve'] + +"""Tests the "find" block with a function call. +""" +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 + number_of_calls = 0 + assertEquals(first_index(get_names(), 'Eve'), 2, 'find first complex') + check_number_of_calls('find first complex') + number_of_calls = 0 + assertEquals(first_index(get_names() if True else None, 'Eve'), 2, 'find first order complex') + check_number_of_calls('find first order complex') + number_of_calls = 0 + assertEquals(last_index(get_names(), 'Eve'), 4, 'find last complex') + check_number_of_calls('find last complex') + number_of_calls = 0 + assertEquals(last_index(get_names() if True else None, 'Eve'), 4, 'find last order complex') + check_number_of_calls('find last order complex') + number_of_calls = 0 + assertEquals(first_index(get_names(), 'Dave'), 0, 'find none complex') + check_number_of_calls('find none complex') + number_of_calls = 0 + assertEquals(first_index(get_names() if True else None, 'Dave'), 0, 'find none order complex') + check_number_of_calls('find none order complex') + +"""Tests the "get" block with a variable. +""" +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 + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals(list2[0], 'Kirk', 'get first simple') + assertEquals(list2[-1], 'McCoy', 'get last simple') + assertEquals(first_index(list2, random.choice(list2)) > 0, True, 'get random simple') + assertEquals(list2[1], 'Spock', 'get # simple') + assertEquals(list2[int((2 if True else None) - 1)], 'Spock', 'get # order simple') + assertEquals(list2[-3], 'Kirk', 'get #-end simple') + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list2[-int(0 + 3)], 'Kirk', 'get #-end order simple') + +"""Creates a list for use with the get test. +""" +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 + number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1 + return ['Kirk', 'Spock', 'McCoy'] + +"""Tests the "get" block with a function call. +""" +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 + list2 = ['Kirk', 'Spock', 'McCoy'] + number_of_calls = 0 + assertEquals(get_star_wars()[0], 'Kirk', 'get first complex') + check_number_of_calls('get first complex') + number_of_calls = 0 + assertEquals((get_star_wars() if True else None)[0], 'Kirk', 'get first order complex') + check_number_of_calls('get first order complex') + number_of_calls = 0 + assertEquals(get_star_wars()[-1], 'McCoy', 'get last complex') + check_number_of_calls('get last complex') + number_of_calls = 0 + assertEquals((get_star_wars() if True else None)[-1], 'McCoy', 'get last order complex') + check_number_of_calls('get last order complex') + number_of_calls = 0 + assertEquals(first_index(list2, random.choice(get_star_wars())) > 0, True, 'get random complex') + check_number_of_calls('get random complex') + number_of_calls = 0 + assertEquals(first_index(list2, random.choice(get_star_wars() if True else None)) > 0, True, 'get random order complex') + check_number_of_calls('get random order complex') + number_of_calls = 0 + assertEquals(get_star_wars()[1], 'Spock', 'get # complex') + check_number_of_calls('get # complex') + number_of_calls = 0 + assertEquals((get_star_wars() if True else None)[int((2 if True else None) - 1)], 'Spock', 'get # order complex') + check_number_of_calls('get # order complex') + number_of_calls = 0 + assertEquals(get_star_wars()[-3], 'Kirk', 'get #-end complex') + check_number_of_calls('get #-end complex') + number_of_calls = 0 + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals((get_star_wars() if True else None)[-int(0 + 3)], 'Kirk', 'get #-end order complex') + check_number_of_calls('get #-end order complex') + +def lists_remove_random_item(myList): + x = int(random.random() * len(myList)) + return myList.pop(x) + +"""Tests the "get and remove" block. +""" +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 + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals(list2.pop(0), 'Kirk', 'getremove first') + assertEquals(list2, ['Spock', 'McCoy'], 'getremove first list') + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals((list2 if True else None).pop(0), 'Kirk', 'getremove first order') + assertEquals(list2, ['Spock', 'McCoy'], 'getremove first order list') + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals(list2.pop(), 'McCoy', 'getremove last') + assertEquals(list2, ['Kirk', 'Spock'], 'getremove last list') + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals((list2 if True else None).pop(), 'McCoy', 'getremove last order') + assertEquals(list2, ['Kirk', 'Spock'], 'getremove last order list') + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals(first_index(list2, lists_remove_random_item(list2)) == 0, True, 'getremove random') + assertEquals(len(list2), 2, 'getremove random list') + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals(first_index(list2, lists_remove_random_item(list2 if True else None)) == 0, True, 'getremove random order') + assertEquals(len(list2), 2, 'getremove random order list') + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals(list2.pop(1), 'Spock', 'getremove #') + assertEquals(list2, ['Kirk', 'McCoy'], 'getremove # list') + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals((list2 if True else None).pop(int((2 if True else None) - 1)), 'Spock', 'getremove # order') + assertEquals(list2, ['Kirk', 'McCoy'], 'getremove # order list') + list2 = ['Kirk', 'Spock', 'McCoy'] + assertEquals(list2.pop(-3), 'Kirk', 'getremove #-end') + assertEquals(list2, ['Spock', 'McCoy'], 'getremove #-end list') + list2 = ['Kirk', 'Spock', 'McCoy'] + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals((list2 if True else None).pop(-int(0 + 3)), 'Kirk', 'getremove #-end order') + assertEquals(list2, ['Spock', 'McCoy'], 'getremove #-end order list') + +"""Tests the "remove" block. +""" +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 + list2 = ['Kirk', 'Spock', 'McCoy'] + list2.pop(0) + assertEquals(list2, ['Spock', 'McCoy'], 'remove first list') + list2 = ['Kirk', 'Spock', 'McCoy'] + (list2 if True else None).pop(0) + assertEquals(list2, ['Spock', 'McCoy'], 'remove first order list') + list2 = ['Kirk', 'Spock', 'McCoy'] + list2.pop() + assertEquals(list2, ['Kirk', 'Spock'], 'remove last list') + list2 = ['Kirk', 'Spock', 'McCoy'] + (list2 if True else None).pop() + assertEquals(list2, ['Kirk', 'Spock'], 'remove last order list') + list2 = ['Kirk', 'Spock', 'McCoy'] + lists_remove_random_item(list2) + assertEquals(len(list2), 2, 'remove random list') + list2 = ['Kirk', 'Spock', 'McCoy'] + lists_remove_random_item(list2 if True else None) + assertEquals(len(list2), 2, 'remove random order list') + list2 = ['Kirk', 'Spock', 'McCoy'] + list2.pop(1) + assertEquals(list2, ['Kirk', 'McCoy'], 'remove # list') + list2 = ['Kirk', 'Spock', 'McCoy'] + (list2 if True else None).pop(int((2 if True else None) - 1)) + assertEquals(list2, ['Kirk', 'McCoy'], 'remove # order list') + list2 = ['Kirk', 'Spock', 'McCoy'] + list2.pop(-3) + assertEquals(list2, ['Spock', 'McCoy'], 'remove #-end list') + list2 = ['Kirk', 'Spock', 'McCoy'] + # The order for index for #-end is addition because this will catch + # errors in generators where most perform the operation ... - index. + (list2 if True else None).pop(-int(0 + 3)) + assertEquals(list2, ['Spock', 'McCoy'], 'remove #-end order list') + +"""Tests the "set" block. +""" +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 + list2 = ['Picard', 'Riker', 'Crusher'] + list2[0] = 'Jean-Luc' + assertEquals(list2, ['Jean-Luc', 'Riker', 'Crusher'], 'set first list') + list2 = ['Picard', 'Riker', 'Crusher'] + (list2 if True else None)[0] = 'Jean-Luc' + assertEquals(list2, ['Jean-Luc', 'Riker', 'Crusher'], 'set first order list') + list2 = ['Picard', 'Riker', 'Crusher'] + list2[-1] = 'Beverly' + assertEquals(list2, ['Picard', 'Riker', 'Beverly'], 'set last list') + list2 = ['Picard', 'Riker', 'Crusher'] + (list2 if True else None)[-1] = 'Beverly' + assertEquals(list2, ['Picard', 'Riker', 'Beverly'], 'set last order list') + list2 = ['Picard', 'Riker', 'Crusher'] + tmp_x = int(random.random() * len(list2)) + list2[tmp_x] = 'Data' + assertEquals(len(list2), 3, 'set random list') + list2 = ['Picard', 'Riker', 'Crusher'] + tmp_list = (list2 if True else None) + tmp_x2 = int(random.random() * len(tmp_list)) + tmp_list[tmp_x2] = 'Data' + assertEquals(len(list2), 3, 'set random order list') + list2 = ['Picard', 'Riker', 'Crusher'] + list2[2] = 'Pulaski' + assertEquals(list2, ['Picard', 'Riker', 'Pulaski'], 'set # list') + list2 = ['Picard', 'Riker', 'Crusher'] + (list2 if True else None)[int((3 if True else None) - 1)] = 'Pulaski' + assertEquals(list2, ['Picard', 'Riker', 'Pulaski'], 'set # order list') + list2 = ['Picard', 'Riker', 'Crusher'] + list2[-1] = 'Pulaski' + assertEquals(list2, ['Picard', 'Riker', 'Pulaski'], 'set #-end list') + list2 = ['Picard', 'Riker', 'Crusher'] + # The order for index for #-end is addition because this will catch + # errors in generators where most perform the operation ... - index. + (list2 if True else None)[-int(0 + 2)] = 'Pulaski' + assertEquals(list2, ['Picard', 'Pulaski', 'Crusher'], 'set #-end order list') + +"""Tests the "insert" block. +""" +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 + list2 = ['Picard', 'Riker', 'Crusher'] + list2.insert(0, 'Data') + assertEquals(list2, ['Data', 'Picard', 'Riker', 'Crusher'], 'insert first list') + list2 = ['Picard', 'Riker', 'Crusher'] + (list2 if True else None).insert(0, 'Data') + assertEquals(list2, ['Data', 'Picard', 'Riker', 'Crusher'], 'insert first order list') + list2 = ['Picard', 'Riker', 'Crusher'] + list2.append('Data') + assertEquals(list2, ['Picard', 'Riker', 'Crusher', 'Data'], 'insert last list') + list2 = ['Picard', 'Riker', 'Crusher'] + (list2 if True else None).append('Data') + assertEquals(list2, ['Picard', 'Riker', 'Crusher', 'Data'], 'insert last order list') + list2 = ['Picard', 'Riker', 'Crusher'] + tmp_x3 = int(random.random() * len(list2)) + list2.insert(tmp_x3, 'Data') + assertEquals(len(list2), 4, 'insert random list') + list2 = ['Picard', 'Riker', 'Crusher'] + tmp_list2 = (list2 if True else None) + tmp_x4 = int(random.random() * len(tmp_list2)) + tmp_list2.insert(tmp_x4, 'Data') + assertEquals(len(list2), 4, 'insert random order list') + list2 = ['Picard', 'Riker', 'Crusher'] + list2.insert(2, 'Data') + assertEquals(list2, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert # list') + list2 = ['Picard', 'Riker', 'Crusher'] + (list2 if True else None).insert(int((3 if True else None) - 1), 'Data') + assertEquals(list2, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert # order list') + list2 = ['Picard', 'Riker', 'Crusher'] + list2.insert(-1, 'Data') + assertEquals(list2, ['Picard', 'Riker', 'Data', 'Crusher'], 'insert #-end list') + list2 = ['Picard', 'Riker', 'Crusher'] + # The order for index for #-end is addition because this will catch + # errors in generators where most perform the operation ... - index. + (list2 if True else None).insert(-int(0 + 2), 'Data') + assertEquals(list2, ['Picard', 'Data', 'Riker', 'Crusher'], 'insert #-end order list') + +"""Tests the "get sub-list" block with a variable. +""" +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 + list2 = ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'] + 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[-3 : -1], ['Discovery', 'Atlantis'], 'sublist #-end simple') + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(list2[-int(0 + 3) : -int((0 + 2) - 1) or sys.maxsize], ['Discovery', 'Atlantis'], 'sublist #-end simple order') + assertEquals(list2[ : ], list2, 'sublist first-last simple') + changing_list = ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'] + list_copy = changing_list[ : ] + lists_remove_random_item(changing_list) + assertEquals(list_copy, list2, 'sublist first-last simple copy check') + assertEquals(list2[1 : -1], ['Challenger', 'Discovery', 'Atlantis'], 'sublist # #-end simple') + assertEquals(list2[-3 : 4], ['Discovery', 'Atlantis'], 'sublist #-end # simple') + assertEquals(list2[ : 4], ['Columbia', 'Challenger', 'Discovery', 'Atlantis'], 'sublist first # simple') + assertEquals(list2[ : -3], ['Columbia', 'Challenger'], 'sublist first #-end simple') + assertEquals(list2[3 : ], ['Atlantis', 'Endeavour'], 'sublist # last simple') + assertEquals(list2[-4 : ], ['Challenger', 'Discovery', 'Atlantis', 'Endeavour'], 'sublist #-end last simple') + assertEquals(list2[ : ], list2, 'sublist all with # #-end simple') + assertEquals(list2[-5 : 5], list2, 'sublist all with #-end # simple') + # Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + assertEquals(list2[int((0 + 1) - 1) : -int((0 + 1) - 1) or sys.maxsize], list2, 'sublist all with # #-end math simple') + +"""Creates a list for use with the sublist test. +""" +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 + number_of_calls = (number_of_calls if isinstance(number_of_calls, Number) else 0) + 1 + return ['Columbia', 'Challenger', 'Discovery', 'Atlantis', 'Endeavour'] + +"""Tests the "get sub-list" block with a function call. +""" +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 + number_of_calls = 0 + assertEquals(get_space_shuttles()[1 : 3], ['Challenger', 'Discovery'], 'sublist # start complex') + check_number_of_calls('sublist # start complex') + number_of_calls = 0 + assertEquals((get_space_shuttles() if True else None)[int((2 if True else None) - 1) : int(3 if True else None)], ['Challenger', 'Discovery'], 'sublist # start order complex') + check_number_of_calls('sublist # start order complex') + number_of_calls = 0 + # The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index. + assertEquals(get_space_shuttles()[-3 : -1], ['Discovery', 'Atlantis'], 'sublist # end complex') + assertEquals(number_of_calls, 1, 'sublist # end complex number of calls') + number_of_calls = 0 + assertEquals((get_space_shuttles() if True else None)[-int(0 + 3) : -int((0 + 2) - 1) or sys.maxsize], ['Discovery', 'Atlantis'], 'sublist # end order complex') + check_number_of_calls('sublist # end order complex') + number_of_calls = 0 + assertEquals(get_space_shuttles()[ : ], list2, 'sublist first-last complex') + check_number_of_calls('sublist first-last complex') + number_of_calls = 0 + assertEquals(get_space_shuttles()[1 : -1], ['Challenger', 'Discovery', 'Atlantis'], 'sublist # #-end complex') + check_number_of_calls('sublist # #-end complex') + number_of_calls = 0 + assertEquals(get_space_shuttles()[-3 : 4], ['Discovery', 'Atlantis'], 'sublist #-end # complex') + check_number_of_calls('sublist #-end # complex') + number_of_calls = 0 + assertEquals(get_space_shuttles()[ : 4], ['Columbia', 'Challenger', 'Discovery', 'Atlantis'], 'sublist first # complex') + check_number_of_calls('sublist first # complex') + number_of_calls = 0 + assertEquals(get_space_shuttles()[ : -3], ['Columbia', 'Challenger'], 'sublist first #-end complex') + check_number_of_calls('sublist first #-end complex') + number_of_calls = 0 + assertEquals(get_space_shuttles()[3 : ], ['Atlantis', 'Endeavour'], 'sublist # last complex') + check_number_of_calls('sublist # last complex') + number_of_calls = 0 + assertEquals(get_space_shuttles()[-4 : ], ['Challenger', 'Discovery', 'Atlantis', 'Endeavour'], 'sublist #-end last simple') + check_number_of_calls('sublist #-end last simple') + number_of_calls = 0 + assertEquals(get_space_shuttles()[ : ], list2, 'sublist all with # #-end complex') + check_number_of_calls('sublist all with # #-end complex') + number_of_calls = 0 + assertEquals(get_space_shuttles()[-5 : 5], list2, 'sublist all with #-end # complex') + check_number_of_calls('sublist all with #-end # complex') + number_of_calls = 0 + # Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end. + assertEquals(get_space_shuttles()[int((0 + 1) - 1) : -int((0 + 1) - 1) or sys.maxsize], list2, 'sublist all with # #-end math complex') + check_number_of_calls('sublist all with # #-end math complex') + +"""Tests the "join" block. +""" +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 + list2 = ['Vulcan', 'Klingon', 'Borg'] + assertEquals(','.join(list2), 'Vulcan,Klingon,Borg', 'join') + assertEquals(','.join(list2 if True else None), 'Vulcan,Klingon,Borg', 'join order') + +"""Tests the "split" block. +""" +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 + text = 'Vulcan,Klingon,Borg' + assertEquals(text.split(','), ['Vulcan', 'Klingon', 'Borg'], 'split') + assertEquals((text if True else None).split(','), ['Vulcan', 'Klingon', 'Borg'], 'split order') + +def lists_sort(my_list, type, reverse): + def try_float(s): + try: + return float(s) + except: + return 0 + key_funcs = { + "NUMERIC": try_float, + "TEXT": str, + "IGNORE_CASE": lambda s: str(s).lower() + } + key_func = key_funcs[type] + list_cpy = list(my_list) + return sorted(list_cpy, key=key_func, reverse=reverse) + +"""Tests the "alphabetic sort" block. +""" +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 + list2 = ['Vulcan', 'klingon', 'Borg'] + 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') + +"""Tests the "alphabetic sort ignore case" block. +""" +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 + list2 = ['Vulcan', 'klingon', 'Borg'] + 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') + +"""Tests the "numeric sort" block. +""" +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 + list2 = [8, 18, -1] + 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') + +"""Tests the "list reverse" block. +""" +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 + list2 = [8, 18, -1, 64] + assertEquals(list(reversed(list2)), [64, -1, 18, 8], 'reverse a copy') + assertEquals(list2, [8, 18, -1, 64], 'reverse a copy original') + list2 = [] + 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... +""" +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 + procedure_1(8, 2) + assertEquals(proc_z, 4, 'procedure with global') + proc_w = False + procedure_2(False) + assertEquals(proc_w, True, 'procedure no return') + proc_w = False + procedure_2(True) + assertEquals(proc_w, False, 'procedure return') + +"""Describe this function... +""" +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 + proc_z = proc_x / proc_y + +"""Describe this function... +""" +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 + if proc_x: + return + proc_w = True + +"""Describe this 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 + assertEquals(function_1(2, 3), -1, 'function with arguments') + assertEquals(func_z, 'side effect', 'function with side effect') + func_a = 'unchanged' + func_c = 'global' + assertEquals(function_2(2), '3global', 'function with global') + assertEquals(func_a, 'unchanged', 'function with scope') + assertEquals(function_3(True), True, 'function return') + assertEquals(function_3(False), False, 'function no return') + +"""Describe this function... +""" +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 + func_z = 'side effect' + return func_x - func_y + +"""Describe this function... +""" +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 + func_a = (func_a if isinstance(func_a, Number) else 0) + 1 + return str(func_a) + str(func_c) + +"""Describe this function... +""" +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 + if func_a: + return True + return False + +"""Describe this function... +""" +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 + if n > 0: + text = ''.join([str(x5) for x5 in [recurse(n - 1), n, recurse(n - 1)]]) + else: + text = '-' + return text + + +unittestResults = [] +print('\n====================\n\nRunning suite: Logic') +assertEquals(True, True, 'True') +assertEquals(False, False, 'False') +assertEquals(not False, True, 'Not true') +assertEquals(not True, False, 'Not false') +test_if() +test_ifelse() +test_equalities() +test_and() +test_or() +test_ternary() +print(unittest_report()) +unittestResults = None + +unittestResults = [] +print('\n====================\n\nRunning suite: Loops 1') +test_repeat() +test_repeat_ext() +test_while() +test_foreach() +print(unittest_report()) +unittestResults = None + +unittestResults = [] +print('\n====================\n\nRunning suite: Loops 2') +test_count_loops() +test_count_by() +print(unittest_report()) +unittestResults = None + +unittestResults = [] +print('\n====================\n\nRunning suite: Loops 3') +test_break() +test_continue() +print(unittest_report()) +unittestResults = None + +unittestResults = [] +print('\n====================\n\nRunning suite: Math') +test_arithmetic() +test_single() +test_trig() +test_constant() +test_change() +test_number_properties() +test_round() +test_operations_on_list() +test_constraint() +test_mod() +test_random_integer() +test_random_fraction() +test_atan2() +print(unittest_report()) +unittestResults = None + +unittestResults = [] +print('\n====================\n\nRunning suite: Text') +test_text_length() +test_empty_text() +test_create_text() +test_append() +test_find_text_simple() +test_find_text_complex() +test_get_text_simple() +test_get_text_complex() +test_substring_simple() +test_substring_complex() +test_case() +test_trim() +test_count_text() +test_text_reverse() +test_replace() +print(unittest_report()) +unittestResults = None + +unittestResults = [] +print('\n====================\n\nRunning suite: Lists') +test_create_lists() +test_lists_empty() +test_lists_length() +test_find_lists_simple() +test_find_lists_complex() +test_get_lists_simple() +test_get_lists_complex() +test_getRemove() +test_remove() +test_set() +test_insert() +test_sublist_simple() +test_sublist_complex() +test_join() +test_split() +test_sort_alphabetic() +test_sort_ignoreCase() +test_sort_numeric() +test_lists_reverse() +print(unittest_report()) +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 = [] +print('\n====================\n\nRunning suite: Variables') +item = 123 +assertEquals(item, 123, 'variable') +if2 = 123 +assertEquals(if2, 123, 'reserved variable') +print(unittest_report()) +unittestResults = None + +# Intentionally non-connected variable. +naked + +unittestResults = [] +print('\n====================\n\nRunning suite: Functions') +test_procedure() +test_function() +assertEquals(recurse(3), '-1-2-1-3-1-2-1-', 'test recurse') +print(unittest_report()) +unittestResults = None diff --git a/tests/generators/lists.xml b/tests/generators/lists.xml index 32fb6aae7..f046d3a46 100644 --- a/tests/generators/lists.xml +++ b/tests/generators/lists.xml @@ -3,25 +3,25 @@ Lists - + - + - + - + - + - + - + @@ -57,7 +57,7 @@ - + @@ -134,7 +134,7 @@ - test create + test create lists Tests the "create list with" and "create empty list" blocks. @@ -298,7 +298,7 @@ - test empty + test lists empty Tests the "is empty" block. @@ -391,7 +391,7 @@ - test length + test lists length Tests the "length" block. @@ -525,7 +525,7 @@ - test find simple + test find lists simple Tests the "find" block with a variable. @@ -697,7 +697,7 @@ - test find complex + test find lists complex Tests the "find" block with a function call. @@ -1067,7 +1067,7 @@ - test get simple + test get lists simple Tests the "get" block with a variable. @@ -1391,7 +1391,7 @@ - test get complex + test get lists complex Tests the "get" block with a function call. @@ -8138,7 +8138,7 @@ - test reverse + test lists reverse Tests the "list reverse" block. diff --git a/tests/generators/loops2.xml b/tests/generators/loops2.xml index 0f0411c67..39cd1cffc 100644 --- a/tests/generators/loops2.xml +++ b/tests/generators/loops2.xml @@ -3,7 +3,7 @@ Loops 2 - + @@ -580,7 +580,7 @@ - test count + test count loops log diff --git a/tests/generators/run_generators_in_browser.js b/tests/generators/run_generators_in_browser.js new file mode 100644 index 000000000..4983b3e62 --- /dev/null +++ b/tests/generators/run_generators_in_browser.js @@ -0,0 +1,145 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2018 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Node.js script to run generator tests in Firefox, via webdriver. + */ +var webdriverio = require('webdriverio'); +var fs = require('fs'); + +/** + * Run the generator for a given language and save the results to a file. + * @param {Thenable} browser A Thenable managing the processing of the browser + * tests. + * @param {string} filename Where to write the output file. + * @param {Function} codegenFn The function to run for code generation for this + * language. + * @return the Thenable managing the processing of the browser tests. + */ +function runLangGeneratorInBrowser(browser, filename, codegenFn) { + return browser + .pause(5000) + .then(function() { + this.execute(codegenFn) + }) + .pause(10000) + .getValue("#importExport") + .then(function(result) { + fs.writeFile(filename, result, function(err) { + if (err) { + return console.log(err); + } + }); + }); +} + +/** + * Runs the generator tests in Firefox. It uses webdriverio to + * launch Firefox and load index.html. Outputs a summary of the test results + * to the console and outputs files for later validation. + * @return the Thenable managing the processing of the browser tests. + */ +function runGeneratorsInBrowser() { + var options = { + desiredCapabilities: { + browserName: 'firefox' + } + }; + + var url = 'file://' + __dirname + '/index.html'; + var prefix = 'tests/generators/tmp/generated' + console.log('Starting webdriverio...'); + return webdriverio + .remote(options) + .init() + .then(function() { + console.log('Initialized.\nLoading url: ' + url); + }) + .url(url) + .then(function() { + console.log('about to load'); + this.execute(function() { + checkAll(); + loadSelected(); + }) + }) + .pause(10000) + .then(function() { + return runLangGeneratorInBrowser(this, prefix + '.js', function() { + toJavaScript(); + }); + }) + .then(function() { + return runLangGeneratorInBrowser(this, prefix + '.py', function() { + toPython(); + }); + }) + .then(function() { + return runLangGeneratorInBrowser(this, prefix + '.dart', function() { + toDart(); + }); + }) + .then(function() { + return runLangGeneratorInBrowser(this, prefix + '.lua', function() { + toLua(); + }); + }) + .then(function() { + return runLangGeneratorInBrowser(this, prefix + '.php', function() { + toPhp(); + }); + }) + .pause(10000) + .catch(function(e) { + console.error('Error: ', e); + + if (require.main === module) { + // .catch() doesn't seem to work in the calling code, + // even if the error is rethrown. To ensure the script + // exit code is non-zero, shutdown the process here. + process.exit(1); + } + + // WARNING: Catching this outside of runJsUnitTestsInBrowser() is not + // working. However, killing the process doesn't seem good, either. + throw e; + }); +} + +module.exports = runGeneratorsInBrowser; + +if (require.main === module) { + try { + runGeneratorsInBrowser() + .catch(function(e) { + // TODO: Never called during errors. Fix. + console.error('Error: ' + e); + process.exit(1); + }) + .endAll() + .then(function() { + console.log('JSUnit tests completed'); + process.exit(0); + }); + } catch(e) { + console.error('Uncaught error: ', e); + process.exit(1); + } +} diff --git a/tests/generators/text.xml b/tests/generators/text.xml index 597b3931d..68dcf15d3 100644 --- a/tests/generators/text.xml +++ b/tests/generators/text.xml @@ -3,28 +3,28 @@ Text - + - + - + - + - + - + - + @@ -39,10 +39,10 @@ - + - + @@ -114,7 +114,7 @@ - test create + test create text Tests the "create text with" block with varying number of inputs. @@ -333,7 +333,7 @@ - test empty + test empty text Tests the "is empty" block". @@ -425,7 +425,7 @@ - test length + test text length Tests the "length" block. @@ -643,7 +643,7 @@ - test find simple + test find text simple Tests the "find" block with a variable. @@ -775,7 +775,7 @@ - test find complex + test find text complex Tests the "find" block with a function call. @@ -1145,7 +1145,7 @@ - test get simple + test get text simple Tests the "get letter" block with a variable. @@ -1432,7 +1432,7 @@ - test get complex + test get text complex Tests the "get letter" block with a function call. @@ -4108,7 +4108,7 @@ - test count + test count text Tests the "trim" block. @@ -4318,7 +4318,7 @@ - test reverse + test text reverse Tests the "trim" block. diff --git a/tests/run_all_tests.sh b/tests/run_all_tests.sh index ae6b8ca3b..f63646fb6 100755 --- a/tests/run_all_tests.sh +++ b/tests/run_all_tests.sh @@ -49,7 +49,7 @@ run_test_command () { fi } -# Setup the environment (Chrome, Selenium, etc.) +# Set up the environment (Chrome, Selenium, etc.) run_test_command "test_setup" "tests/scripts/test_setup.sh" # Lint the codebase. @@ -59,8 +59,11 @@ run_test_command "eslint" "eslint ." run_test_command "jsunit" "node tests/jsunit/run_jsunit_tests_in_browser.js" # TODO: Make sure jsunit output is captured. Child process? -# Attempt advanced compilation of a Blockly app. -run_test_command "compile" "tests/compile/compile.sh" +# Run generator tests inside a browser and check the results. +run_test_command "generators" "tests/scripts/run_generators.sh" + +# # Attempt advanced compilation of a Blockly app. +# run_test_command "compile" "tests/compile/compile.sh" # End of tests. diff --git a/tests/scripts/run_generators.sh b/tests/scripts/run_generators.sh new file mode 100755 index 000000000..9d556acad --- /dev/null +++ b/tests/scripts/run_generators.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# ANSI colors +BOLD_GREEN='\033[1;32m' +BOLD_RED='\033[1;31m' +ANSI_RESET='\033[0m' +SUCCESS_PREFIX="${BOLD_GREEN}SUCCESS:${ANSI_RESET}" +FAILURE_PREFIX="${BOLD_RED}FAILED:${ANSI_RESET}" + +TMP_DIR="tests/generators/tmp/" +GOLDEN_DIR="tests/generators/golden/" + +FAILURE_COUNT=0 +check_result() { + local suffix=$1 # One of: js, py, dart, lua, php + local tmp_filename="${TMP_DIR}generated.$suffix" + + if [ -f $tmp_filename ]; then + local golden_filename="${GOLDEN_DIR}generated.$suffix" + if [ -f $golden_filename ]; then + if cmp --silent $tmp_filename $golden_filename; then + echo -e "$SUCCESS_PREFIX $suffix: $tmp_filename matches $golden_filename" + else + echo -e "$FAILURE_PREFIX $suffix: $tmp_filename does not match $golden_filename" + FAILURE_COUNT=$((FAILURE_COUNT+1)) + fi + else + echo "File $golden_filename not found!" + FAILURE_COUNT=$((FAILURE_COUNT+1)) + fi + else + echo "File $tmp_filename not found!" + FAILURE_COUNT=$((FAILURE_COUNT+1)) + fi +} + + +mkdir $TMP_DIR + +node tests/generators/run_generators_in_browser.js +generator_suffixes=( "js" "py" "dart" "lua" "php" ) +for i in "${generator_suffixes[@]}" +do + check_result "$i" +done + + +# Clean up. +rm -r $TMP_DIR + +if [ "$FAILURE_COUNT" -eq "0" ]; then + echo -e "${BOLD_GREEN}All generator tests passed.${ANSI_RESET}" + exit 0 +else + echo -e "${BOLD_RED}Failures in ${FAILURE_COUNT} generator tests.${ANSI_RESET}" + exit 1 +fi