Module: deuce-test-suite Synopsis: Test suite for the Deuce editor Author: Hugh Greene Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND // -=- Auxilliary definitions -=- define constant $insertion-line-indices :: = vector(0, 1, 2); define constant $insertion-indices :: = vector (pair(-1, "before start"), pair(0, "at start"), pair(3, "in middle"), pair(6, "at end"), pair(7, "after end")); define constant $insert-results-format = vector ("%sLine 1\nLine 2\nLine 3\nLine 4\nLine 5", "Lin%se 1\nLine 2\nLine 3\nLine 4\nLine 5", "Line 1%s\nLine 2\nLine 3\nLine 4\nLine 5", "Line 1\n%sLine 2\nLine 3\nLine 4\nLine 5", "Line 1\nLin%se 2\nLine 3\nLine 4\nLine 5", "Line 1\nLine 2%s\nLine 3\nLine 4\nLine 5", "Line 1\nLine 2\n%sLine 3\nLine 4\nLine 5", "Line 1\nLine 2\nLin%se 3\nLine 4\nLine 5", "Line 1\nLine 2\nLine 3%s\nLine 4\nLine 5"); define function make-result-vector (str :: ) => (results :: ) map(rcurry(format-to-string, str), $insert-results-format) end function; define constant $insert-into-line-characters = vector("\n", "X"); define constant $insert-into-line-strings = vector ("", "\n", "ABC", "\nABC", "A\nBC", "ABC\n", "A\nB\nC\n", "A\n\n\nBC"); // -=- Tests and Suites -=- // ---*** This _doesn't_ test that moving BPs get moved correctly :-( // I'm not sure that we can easily check they get moved to the right // place, but we _could_ at least check that they're on a line in the // buffer and at a valid index for that line. Could also check that // node-{start,end}-bps are indeed at the start/end of lines which // have no line-{previous,next}. define function test-insert! (thing :: type-union(, , ), results :: ) => () let result-index :: = 0; let thing-without-newlines = select ( thing.object-class ) => if ( thing == '\n' ) 'N' else thing end; => map(method (c) if ( c == '\n' ) 'N' else c end; end, thing); otherwise => thing end; let check-message = format-to-string("Insert %=", thing); for (line-index :: in $insertion-line-indices) let check-message = format-to-string ("%s at line %=", check-message, line-index); for (idx :: in $insertion-indices) let (index, index-description) = values(head(idx), tail(idx)); let check-message = format-to-string ("%s, %s", check-message, index-description); reset-testing-buffer-state(); dynamic-bind(*buffer* = *testing-buffer*) // Get the "line-index"th line in the buffer. We can't just // iterate over a collection of *line1-{1,2,3}*, as these // global variables get rebound every time the buffer state is // reset. let buffer-lines :: = testing-lines(); let insertion-lines :: = vector(buffer-lines[0], buffer-lines[1], buffer-lines[2]); let line :: = insertion-lines[line-index]; // Check contents after insertion (or check for ). if (index = -1 | index = 7) check-condition (check-message, , insert!(make-bp(line, index), thing)); else insert!(make-bp(line, index), thing); check-equal (check-message, as(, *buffer*), results[result-index]); result-index := result-index + 1; end if; // Check buffer structure. check-true ("Buffer line link structure okay after insertion", last-line-from (first(buffer-lines), in-buffer?: #t) == last(buffer-lines)); // If the following fails, you can add ", verbose?: #t" after // "*buffer*" below to get some useful(?) diagnostics. check-true ("Buffer BPs okay after insertion", check-buffer-bps(*buffer*)); end dynamic-bind; end for; end for; end function; define test insert-character-into-line-test () for (str-index from 0 below size($insert-into-line-characters)) let char-str :: = $insert-into-line-characters[str-index]; let results = make-result-vector(char-str); // Note the extra "[0]" here, as compared with the next test. // It extracts the first from a . test-insert!(char-str[0], results); end for; end test; define test insert-string-into-line-test () for (str-index from 0 below size($insert-into-line-strings)) let string :: = $insert-into-line-strings[str-index]; let results :: = make-result-vector(string); test-insert!(string, results); end for; end test; define test insert-interval-test () let intervals :: = vector(); reset-testing-buffer-state(); dynamic-bind(*buffer* = *testing-buffer*) intervals := map(copy-interval, testing-intervals()); end dynamic-bind; for (interval in intervals) test-insert!(interval, make-result-vector(as(, interval))); end for; end test; define suite insertion-suite () test insert-character-into-line-test; test insert-string-into-line-test; test insert-interval-test; end suite; /* Things to test ... insert! for insert! for See insert-into-line. insert! for Check inserting at {start,middle,end}-of-{line,section}. Check for empty, single-line and multi-line intervals. [At the moment, we seem to be assuming that to-be-inserted intervals contain no s, just s. If/when we do, check for inserting intervals spanning 2 and 3 sections.] [I assume that later we may want to be able to insert "section breaks", if the interval spans sections. I expect we'd have to create fresh sections and add the lines to them.] [What happens if we insert an interval into the middle of itself?!? If it's something bad, maybe we'd better catch that! A: We don't expect to, since we normally only insert from the clipboard or kill-ring. We could check for this but it would be expensive.] insert-into-line for , Check inserting at -1, 0, middle-of-line, end-of-line, past-end. Check for '\n' and non-'\n' characters. Check lines with and without moving-bps. [Why doesn't the bp-relocating code need to check that the bps are s? Are all bps inserted into s guaranteed to be moving?] insert-into-line for , [What is the "insert-moving!(nbp, '\n')" in the ">1-'\n's" clause for?] Check inserting at -1, 0, middle-of-line, end-of-line, past-end. Check for strings containing 0, 1 and n '\n's; the string "\n"; and a string with 2/3 consecutive '\n's. Check lines with and without moving-bps. [Why doesn't the bp-relocating code need to check that the bps are s? Are all bps inserted into s guaranteed to be moving?] insert-into-line for , XXX [Won't bother testing these for now.] [What if you insert a which contains (begins/ends with?) a '\n'? Will you get the same effect as if you had inserted each character separately, given that the method treats '\n' specially?] split-for-insertion [This is tested within the insert-into-line tests.] Check inserting at -1, 0, middle-of-line, end-of-line, past-end. Check splitting first, middle and last line in a section. insert-moving! [Hardly worth testing.] Check that the bp points to the inserted object (and that it's == to the original argument)? */