[Pkg-jed-commit] r808 - in jed-extra/trunk: debian tests utils

Guenter Milde milde-guest at alioth.debian.org
Thu Jul 26 14:31:29 UTC 2007


tags 429893 pending
thanks

Author: milde-guest
Date: 2007-07-26 14:31:28 +0000 (Thu, 26 Jul 2007)
New Revision: 808

Added:
   jed-extra/trunk/tests/ch_table-lat1-decimal.txt
   jed-extra/trunk/tests/ch_table-utf8-decimal.txt
   jed-extra/trunk/tests/py-code-example.py
   jed-extra/trunk/tests/pymode-test.sl
   jed-extra/trunk/tests/rst-test.sl
   jed-extra/trunk/tests/structured_text-test.sl
   jed-extra/trunk/tests/test.py
   jed-extra/trunk/tests/testreport-jed-extra2.2.txt
   jed-extra/trunk/tests/unittesttest.sl
   jed-extra/trunk/tests/utf8helper-autoconvert-test.sl
   jed-extra/trunk/tests/utf8helper-test.sl
   jed-extra/trunk/utils/do-unittests.sl
Modified:
   jed-extra/trunk/debian/README.Debian
   jed-extra/trunk/debian/README.Maintainer
   jed-extra/trunk/debian/changelog
   jed-extra/trunk/debian/contents.txt
   jed-extra/trunk/debian/rules
   jed-extra/trunk/tests/ch_table-test.sl
   jed-extra/trunk/tests/datutils-test.sl
   jed-extra/trunk/tests/ishell-test.sl
   jed-extra/trunk/tests/listing-test.sl
   jed-extra/trunk/tests/test-browse_url.sl
   jed-extra/trunk/tests/test-calc.sl
   jed-extra/trunk/tests/test-console_keys.sl
   jed-extra/trunk/tests/test-css1.sl
   jed-extra/trunk/tests/test-dict-cli.sl
   jed-extra/trunk/tests/test-dict-curl.sl
Log:
* new release 2.4-1 from new upstream release 2.4
* updated and new unit tests


Modified: jed-extra/trunk/debian/README.Debian
===================================================================
--- jed-extra/trunk/debian/README.Debian	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/debian/README.Debian	2007-07-26 14:31:28 UTC (rev 808)
@@ -31,16 +31,15 @@
 different look-and-feel), a complete automatic setup is not possible.
 
 In order to make full use of the modes, additional configuration is needed.
-Users are advised to study the documentation at the source files and
+Users are advised to study the documentation in the source files and
 add activation code to their ~/.jed/jed.rc. The ``examples`` subdir contains
-some generic examples|templates for this task.
+generic examples that could also serve as templates for this task.
 
 Versions
 --------
 
 The version numbering scheme for the jed-extra package follows the versions
-on Jedmodes. All modes in versions 2.x should be SLang-2 compatible (while
-most modes are still backwards compatible to SLang-1).
+on Jedmodes. 
 
 Support for UTF8 is still experimental.
 

Modified: jed-extra/trunk/debian/README.Maintainer
===================================================================
--- jed-extra/trunk/debian/README.Maintainer	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/debian/README.Maintainer	2007-07-26 14:31:28 UTC (rev 808)
@@ -36,7 +36,7 @@
 it can be fetched non-interactively. 
 
 Unfortunately, the standard URL for a Sourceforge release cannot serve as
-such a canonocal site, as it requires user interaction to select a mirror.
+such a canonical site, as it requires user interaction to select a mirror.
 Therefore alternatively a fixed mirror URL for a Jedmodes-CVS release or a
 URL for a pre-release source archive on the Jedmodes home site is used.
 
@@ -51,7 +51,7 @@
 
 
 Considering the interference with JED, 4 types of modes can be distinguished
-cf. the list in "contents.txt":
+(cf. the list in "contents.txt"):
 
 A: Additions
 ~~~~~~~~~~~~
@@ -76,9 +76,8 @@
 
 * example: help.sl (hyperhelp), man.sl (hyperman), recent.sl
 
--> install in libdir/drop-in *added* in the config file (a sysadmin can
-   revert this default activation, a normal user can delete the libdir from
-   the jed-library-path)
+-> install in libdir/drop-in *added* in the config file 
+   ( cf. `Where should the modes go?`_)
 
 
 E: Enhancements
@@ -141,11 +140,12 @@
 * Some modes are drop-in replacements. Placing them in the
   jed_library_path would either
    
-  a) make their use obligatory for all users if the libdir is *added*, or
+  a) make their use obligatory for all users if the libdir is *added* 
+     (i.e. prepended), or
   b) prevent their use if the libdir is *appended*.
 
   Drop-ins should therefore go to ``/usr/share/jed/jed-extra/drop-in/``,
-  added (i.e. prepended) to the library path in 50jed-extra.sl.
+  added to the library path in 50jed-extra.sl.
   
   * The default behaviour would be to use the drop-ins if jed-extra
     is installed.

Modified: jed-extra/trunk/debian/changelog
===================================================================
--- jed-extra/trunk/debian/changelog	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/debian/changelog	2007-07-26 14:31:28 UTC (rev 808)
@@ -1,3 +1,16 @@
+jed-extra (2.4-1) unstable; urgency=low
+  
+  * New upstream release:
+     * new diffmode.sl: diff frontend; mode for viewing, editing and 
+                        selective applying of patches,
+     * new utf8helper.sl: Functions and hooks to (auto)convert between 
+                          'latin1' and 'utf8' encodings.
+     * pymode.sl: added missing autoload (closes: #429893),
+     * structured_text.sl: allow UTF-8 multi-byte chars in 
+       `Text_List_Patterns' (closes #431418).
+
+ -- Guenter Milde <milde at users.sf.net>  Mon, 23 Jul 2007 14:28:56 +0200
+
 jed-extra (2.3.2-3) unstable; urgency=low
 
   * Debconf templates and debian/control reviewed by the debian-l10n-

Modified: jed-extra/trunk/debian/contents.txt
===================================================================
--- jed-extra/trunk/debian/contents.txt	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/debian/contents.txt	2007-07-26 14:31:28 UTC (rev 808)
@@ -43,21 +43,22 @@
 O   dabbrev        Complete the current word looking for similar word-beginnings
 U   datutils       Convenience functions for several Data_Types
 X   diagnose       Diagnostic functions for SLang programmers
-#X   dict           A dict client.
-X   ding           Ding dictionary lookup function and mode
+X   dict           A dict client.
+X   diffmode       Unified diff mode viewer and editor
+E   ding           Ding dictionary lookup function and mode
 A   dictmode       dict dictionary lookup (including thesaurus)
 A   dict-backend   backends for dictmode
 A   email          mode for editing emails
 X   ffap           Find File At Point
 E   filelist       A special mode for file listings (ls, locate)
-#X   fileview       configurable file viewing function
+X   fileview       configurable file viewing function
 E   filter-buffer  Filter buffer  show/hide lines that match a pattern
 A   gdbmrecent     another recent mode
 A   gnuplot        Mode for the Gnuplot plotting program
 A   grep           JED interface to the `grep` command
 #O   history        Save the content of the minibuffer across jed sessions
 O   home-lib       Initialize libraries for jed extensions easily
-#X   howto          howto-reader
+X   howto          howto-reader
 D   hyperhelp      Hypertext help browser.
 D   hyperman       hypertextish man pager
 X   info           Info reader for JED
@@ -66,7 +67,7 @@
 A   jedasp         Try to simulate MS IIS Active Server Pages with JED
 #X   jedgtk         slgtk dialogs for JED
 #X   jedmodes       Utilities for the publication of modes at Jedmodes
-#X   jedscape       html browser
+X   jedscape       html browser
 #X   kcomplete      keyword completion from the syntax table
 A   keywords       Create keyword lists for syntax tables
 O   kp_keydefs     keydefs for the numeric keypad (now included in x-keydefs)
@@ -118,6 +119,7 @@
 U   txtutils       Tools for text processing (marking, string processing, formatting)
 X   unittest       Framework for unit testing of S-Lang scripts
 E   uri            Let jed handle Universal Ressource Indicators (URIs)
+E   utf8helper     Converting latin-1 <-> utf8.
 E   vi             vi editor emulation mode
 A   view           A generic view mode for readonly buffers
 U   window         Window management routines

Modified: jed-extra/trunk/debian/rules
===================================================================
--- jed-extra/trunk/debian/rules	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/debian/rules	2007-07-26 14:31:28 UTC (rev 808)
@@ -9,6 +9,12 @@
 
 include /usr/share/dpatch/dpatch.make
 
+# Variables
+# =========
+
+# File Sorting
+# ------------
+
 CONTENTS_FILE = debian/contents.txt
 
 ADDITION = $(shell awk '/^A/ { print $$2"/*"; }' $(CONTENTS_FILE))
@@ -23,21 +29,39 @@
 
 dh_inst_excl = -X.html -X.otl -X.example -X.template -XREADME
 
-# upstream version
+
+# Source download
+# ---------------
+
+WGET = wget -N
+# URL of the upstream source package
 UPSTREAM_VERSION ?= $(shell perl -ne '/([\d.]+)-?/; print $$1; exit' < debian/changelog)
-WGET = wget -N
+UPSTREAM_PACKAGE = jedmodes-$(UPSTREAM_VERSION).tgz
+UPSTREAM_PACKAGE_CHECKSUM = jedmodes-$(UPSTREAM_VERSION).md5sum
+# pre-release (source tarball from the jedmodes home site)
+PRERELEASE_URL = http://jedmodes.sourceforge.net/cvs/
+# officially released CVS tarball from the SF FRS
+RELEASE_URL = http://osdn.dl.sourceforge.net/sourceforge/jedmodes/
+# local copy
+LOCAL_RELEASE_URL = file:~/.jed/jedmodes/src/
 
+# # choose source:
+UPSTREAM_URL = $(RELEASE_URL)
+# UPSTREAM_URL = $(PRERELEASE_URL)
+# UPSTREAM_URL = $(LOCAL_RELEASE_URL)
+
+# Rules
+# =====
+
 get-orig-source:
-	# pre-release (source tarball from the jedmodes home site)
-	# wget http://jedmodes.sourceforge.net/cvs/jedmodes-$(UPSTREAM_VERSION).tgz
-	# officially released CVS tarball from the sf FRS
-	$(WGET) http://osdn.dl.sourceforge.net/sourceforge/jedmodes/jedmodes-$(UPSTREAM_VERSION).tgz
+	# get and check the jedmodes tarball
+	$(WGET) $(UPSTREAM_URL)$(UPSTREAM_PACKAGE)
 	# Check the md5sum of the upstream tarball
-	$(WGET) http://jedmodes.sourceforge.net/cvs/jedmodes-$(UPSTREAM_VERSION).md5sum
-	cat jedmodes-$(UPSTREAM_VERSION).md5sum | md5sum -c || exit 1
+	$(WGET) $(PRERELEASE_URL)$(UPSTREAM_PACKAGE_CHECKSUM)
+	cat $(UPSTREAM_PACKAGE_CHECKSUM) | md5sum -c || exit 1
+	
+	mv $(UPSTREAM_PACKAGE) jed-extra_$(UPSTREAM_VERSION).orig.tar.gz
 
-	mv jedmodes-$(UPSTREAM_VERSION).tgz jed-extra_$(UPSTREAM_VERSION).orig.tar.gz
-
 	# additional modes from other sources
 	mkdir --parents jedmodes-$(UPSTREAM_VERSION)/boxquote
 	cd jedmodes-$(UPSTREAM_VERSION)/boxquote; \

Added: jed-extra/trunk/tests/ch_table-lat1-decimal.txt
===================================================================
--- jed-extra/trunk/tests/ch_table-lat1-decimal.txt	                        (rev 0)
+++ jed-extra/trunk/tests/ch_table-lat1-decimal.txt	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,29 @@
+[ 10]	0	1	2	3	4	5	6	7	8	9	
+
+   0										TAB
+  10	NL			
+						
+  20								ESC		
+  30			 	!	"	#	$	%	&	'
+  40	(	)	*	+	,	-	.	/	0	1
+  50	2	3	4	5	6	7	8	9	:	;
+  60	<	=	>	?	@	A	B	C	D	E
+  70	F	G	H	I	J	K	L	M	N	O
+  80	P	Q	R	S	T	U	V	W	X	Y
+  90	Z	[	\	]	^	_	`	a	b	c
+ 100	d	e	f	g	h	i	j	k	l	m
+ 110	n	o	p	q	r	s	t	u	v	w
+ 120	x	y	z	{	|	}	~		€	
+ 130	‚	ƒ	„	…	†	‡	ˆ	‰	Š	‹
+ 140	Œ		Ž			‘	’	“	”	•
+ 150	–	—	˜	™	š	›	œ		ž	Ÿ
+ 160	 	¡	¢	£	¤	¥	¦	§	¨	©
+ 170	ª	«	¬	­	®	¯	°	±	²	³
+ 180	´	µ	¶	·	¸	¹	º	»	¼	½
+ 190	¾	¿	À	Á	Â	Ã	Ä	Å	Æ	Ç
+ 200	È	É	Ê	Ë	Ì	Í	Î	Ï	Ð	Ñ
+ 210	Ò	Ó	Ô	Õ	Ö	×	Ø	Ù	Ú	Û
+ 220	Ü	Ý	Þ	ß	à	á	â	ã	ä	å
+ 230	æ	ç	è	é	ê	ë	ì	í	î	ï
+ 240	ð	ñ	ò	ó	ô	õ	ö	÷	ø	ù
+ 250	ú	û	ü	ý	þ	ÿ

Modified: jed-extra/trunk/tests/ch_table-test.sl
===================================================================
--- jed-extra/trunk/tests/ch_table-test.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/ch_table-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -1,4 +1,4 @@
-% ch_table-testª.sl: 
+% ch_table-test.sl: 
 % 
 % Copyright (c) 2006 Günter Milde
 % Released under the terms of the GNU General Public License (ver. 2 or later)
@@ -77,6 +77,10 @@
 test_function("ch_table->string2int", "100000", 2);
 test_last_result(32);
 
+#if (_slang_utf8_ok)
+#stop
+#endif
+
 % ct_status_line: undefined  Undocumented
 %  static define ct_status_line()
 % test_function("ch_table->ct_status_line");

Added: jed-extra/trunk/tests/ch_table-utf8-decimal.txt
===================================================================
--- jed-extra/trunk/tests/ch_table-utf8-decimal.txt	                        (rev 0)
+++ jed-extra/trunk/tests/ch_table-utf8-decimal.txt	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,29 @@
+[ 10]	0	1	2	3	4	5	6	7	8	9	
+
+   0										TAB
+  10	NL			
+						
+  20								ESC		
+  30			 	!	"	#	$	%	&	'
+  40	(	)	*	+	,	-	.	/	0	1
+  50	2	3	4	5	6	7	8	9	:	;
+  60	<	=	>	?	@	A	B	C	D	E
+  70	F	G	H	I	J	K	L	M	N	O
+  80	P	Q	R	S	T	U	V	W	X	Y
+  90	Z	[	\	]	^	_	`	a	b	c
+ 100	d	e	f	g	h	i	j	k	l	m
+ 110	n	o	p	q	r	s	t	u	v	w
+ 120	x	y	z	{	|	}	~		€	
+ 130	‚	ƒ	„	…	†	‡	ˆ	‰	Š	‹
+ 140	Œ		Ž			‘	’	“	”	•
+ 150	–	—	˜	™	š	›	œ		ž	Ÿ
+ 160	 	¡	¢	£	¤	¥	¦	§	¨	©
+ 170	ª	«	¬	­	®	¯	°	±	²	³
+ 180	´	µ	¶	·	¸	¹	º	»	¼	½
+ 190	¾	¿	À	Á	Â	Ã	Ä	Å	Æ	Ç
+ 200	È	É	Ê	Ë	Ì	Í	Î	Ï	Ð	Ñ
+ 210	Ò	Ó	Ô	Õ	Ö	×	Ø	Ù	Ú	Û
+ 220	Ü	Ý	Þ	ß	à	á	â	ã	ä	å
+ 230	æ	ç	è	é	ê	ë	ì	í	î	ï
+ 240	ð	ñ	ò	ó	ô	õ	ö	÷	ø	ù
+ 250	ú	û	ü	ý	þ	ÿ

Modified: jed-extra/trunk/tests/datutils-test.sl
===================================================================
--- jed-extra/trunk/tests/datutils-test.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/datutils-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -1,4 +1,4 @@
-% Test the functions in datutils.sl 
+% Test the functions in datutils.sl  Test datutils.sl
 % 
 % Copyright (c) 2006 Günter Milde
 % Released under the terms of the GNU General Public License (ver. 2 or later)
@@ -10,22 +10,495 @@
 
 require("unittest");
 
-% Fixture: provide some test data
-variable lst = {1,2,3,4};
-variable strlist = {"hello", "world"};
 
-% Test the public functions
+% Fixture
+% -------
 
-% list2array with optional arg
-test_function("list2array", lst, Integer_Type);
-test_function("list2array", strlist, String_Type);
-% list2array without otional arg
-test_function("list2array", lst);
-test_function("list2array", strlist);
+require("datutils");
 
-% test the result
-$1 = where([1,2,3,4] == list2array(lst));
-test_equal(length(lst), length($1));
+private variable testbuf = "*bar*";
+private variable teststring = "a test line";
+private variable intlist = {1,2,3,4}, intarray = [1,2,3,4];
+private variable strlist = {"hello", "world"}, strarray = ["hello", "world"];
 
-popup_buffer("*test report*", 1.0);
+static define setup()
+{
+   sw2buf(testbuf);
+   insert(teststring);
+}
+
+static define teardown()
+{
+   sw2buf(testbuf);
+   set_buffer_modified_flag(0);
+   close_buffer(testbuf);
+}
+
+% Test functions
+% --------------
+
+% define null_fun() {}
+static define test_null_fun()
+{
+   null_fun();
+   test_equal(23, null_fun(23));
+}
+
+
+% array_max: library function
+% 
+%  SYNOPSIS
+%   Return the maximal value of an array
+% 
+%  USAGE
+%   result = array_max(Array_Type a)
+% 
+%  DESCRIPTION
+%   The `array_max' function examines the elements of a numeric array and
+%   returns the value of the largest element.
+% 
+%  EXAMPLE
+% 
+%    array_max([1,2,30,4] == 30
+% 
+% 
+%  NOTES
+%  `max' is a slang intrinsic since 1.4.6. (but must be activated manually)
+% 
+%  SEE ALSO
+%   array_sum, array_product, max, min
+static define test_array_max()
+{
+   test_equal(6, array_max([1,2,6,3]));
+   test_equal(12, array_max([1.4, 12, 3, 5.7]));
+   test_equal(-1, array_max([-12, -3,-1]));
+   test_equal(-1, array_max([-1]));
+}
+
+% array_sum: library function
+% 
+%  SYNOPSIS
+%   Return the sum of the array elements
+% 
+%  USAGE
+%   result = array_sum(a)
+% 
+%  DESCRIPTION
+%   Sum up the values of a numeric array and return the result.
+% 
+%  NOTES
+%  `sum' is a slang intrinsic since 1.4.6. (but must be activated manually)
+% 
+%  SEE ALSO
+%   array_max, array_product, sum
+static define test_array_sum()
+{
+   test_equal(1+2+3+4+5, array_sum([1:5]));
+}
+
+% array_product: library function
+% 
+%  SYNOPSIS
+%   Return the product of the array elements
+% 
+%  USAGE
+%   result = array_product(a)
+% 
+%  DESCRIPTION
+%   Multiply the values of a numeric array and return the result.
+% 
+%  SEE ALSO
+%   array_sum, array_max
+static define test_array_product()
+{
+   test_equal(2*3*4*5, array_product([2:5]));
+   test_equal(2, array_product([2]));
+}
+
+
+% list2array: library function
+%   Convert a list to an array
+%
+%  EXAMPLE
+%   `list2array' enables the use of lists in places that require an
+%   array, e.g.:
+% 
+%    message(strjoin(list2array({"hello", "world"}, String_Type), " "));
+%    23 + list2array({1, 2, 3}) == [24, 25, 26]
+static define test_list2array()
+{
+   % list2array with optional arg
+   test_equal(intarray, list2array(intlist, Integer_Type));
+   test_equal(strarray, list2array(strlist, String_Type));
+   % list2array without otional arg
+   test_equal(intarray, list2array(intlist));
+   test_equal(strarray, list2array(strlist));
+   % examples
+   test_equal("hello world", strjoin(list2array({"hello", "world"}), " "));
+   test_equal(23 + list2array({1, 2, 3}), [24, 25, 26]);
+   
+}
+
+
+% array_append: library function
+% 
+%  SYNOPSIS
+%   Append a value to an array or concatenate `a' and `b'
+% 
+%  USAGE
+%   Array = array_append(a, b)
+% 
+%  DESCRIPTION
+%  `array_append' provides a means to use 1d-arrays like lists. It
+%  concatenates `a' and `b'. 
+%   
+%  The arguments may be of any type and will be converted to Array_Type (if
+%  the not already are) before the concatenation.
+% 
+%  EXAMPLE
+%  The following statemants are all TRUE:
+% 
+%    array_append(1,2)          == [1,2]
+%    array_append(1, [2,3,4])   == [1,2,3,4]
+%    array_append([1,2], [3,4]) == [1,2,3,4]
+%    array_append([1,2,3], 4)   == [1,2,3,4]
+% 
+% 
+%  NOTES
+%  For arrays with 1000 values, it becomes time-consuming (0.13 s),
+%  for 2000 values annoying (0.5 s) and for 5000 values prohibitive (3 s)
+%  (CPU-time on a AMD-Duron 700MHz under Linux)
+% 
+%  SEE ALSO
+%   list_append
+static define test_array_append()
+{
+   test_equal(array_append(1,2)          , [1,2]);
+   test_equal(array_append(1, [2,3,4])   , [1,2,3,4]);
+   test_equal(array_append([1,2], [3,4]) , [1,2,3,4]);
+   test_equal(array_append([1,2,3], 4)   , [1,2,3,4]);
+}
+
+
+#stop
+   
+% pop2array: library function
+% 
+%  SYNOPSIS
+%   Return N stack-items as an array of type `type'
+% 
+%  USAGE
+%   Array_Type pop2array(N=_stkdepth, [type])
+% 
+%  DESCRIPTION
+%  Return an array that consists of the N topmost stack elements.
+%  The top element becomes element arr[N-1].
+%  If `type' is not given, autodetermine it (fall back to `Any_Type'
+%  if the element types differ).
+% 
+%  NOTES
+%  Attention: dont use `pop2array' in a function call with optional
+%  arguments , i.e. not
+% 
+%    show(pop2array())
+% 
+%  but
+% 
+%    $1 = pop2array(); 
+%    show($1);
+% 
+% 
+%  SEE ALSO
+%   array, pop2list, push_array
+static define test_pop2array()
+{
+   Arr  pop2array(N=_stkdepth, [type]);
+}
+
+% array: library function
+% 
+%  SYNOPSIS
+%   Return an array containing the arguments
+% 
+%  USAGE
+%   Array_Type array([args])
+% 
+%  DESCRIPTION
+%   Pack the arguments into an array and return it.
+%   The type is autodetermined (defaulting to `Any_Type'
+%   if the element types differ).
+% 
+%  NOTES
+%  If you know the datatype of the arguments, you can save resources pushing
+%  the arguments first and using `pop2array' with the datatype argument.
+% 
+%      (arg1, ...., argN);
+%      a = pop2array(N, datatype)
+% 
+%  instead of (the simpler)
+% 
+%      a = array(arg1, ...., argN);
+% 
+% 
+%  SEE ALSO
+%   pop2array, push_array, list2array
+static define test_array()
+{
+   Arr  = array([args]);
+}
+
+
+% array_delete: library function
+% 
+%  SYNOPSIS
+%   Delete the element(s) at position(s) `N'
+% 
+%  USAGE
+%   Array_Type array_delete(Array_Type a, Integer_Type N)
+% 
+%  USAGE
+%   Array_Type array_delete(Array_Type a, Array_Type N)
+% 
+%  DESCRIPTION
+%  Return a slice of all positions not in `N'.
+%  This provides a means to use 1d-arrays like lists.
+% 
+%  EXAMPLE
+% 
+%    array_delete([1,2,3,4], 0)      == [2,3,4]
+%    array_delete([1,2,3,4], [0,1])  == [3,4]
+%    array_delete([1,2,3,4], [0,-1]) == [2,3]
+%    array_delete([1,2,3,4], -1)     == [1,2,3]
+% 
+% 
+%  NOTES
+%  For arrays with 1000 values, it becomes time-consuming (0.09 s),
+%  for 2000 values annoying (0.32 s) and for 5000 values prohibitive (1.83 s).
+%  With SLang 2, consider using the new List_Type instead.
+% 
+%  SEE ALSO
+%   array_append, where, list_delete
+static define test_array_delete()
+{
+   Arr  = array_delete(Arr  a, i N);
+}
+
+
+% array_value_exists: library function
+% 
+%  SYNOPSIS
+%   Return the number of occurences of `value' in array `a'
+% 
+%  USAGE
+%   Integer_Type array_value_exists(a, value)
+% 
+%  DESCRIPTION
+%   Count, how many times `value' is present in array `a'. 
+%   For normal arrays, this is equal to
+% 
+%      length(where(a == value))
+% 
+%   while special care is taken to get meaningfull results with arrays of
+%   `Any_Type'.
+% 
+%  SEE ALSO
+%   where, wherefirst, wherelast, assoc_value_exists
+static define test_array_value_exists()
+{
+   i = array_value_exists(a, value);
+}
+
+% array_repeat: library function
+% 
+%  SYNOPSIS
+%   Repeat an array `N' times
+% 
+%  USAGE
+%   Array_Type array_repeat(a, N)
+% 
+%  DESCRIPTION
+%  Concatenate an array N-1 times to itself and return the result.
+% 
+%  SEE ALSO
+%   string_repeat, array_append
+static define test_array_repeat()
+{
+   Arr  = array_repeat(a, N);
+}
+
+% array_transpose: library function
+% 
+%  SYNOPSIS
+%   Swap the axes of a 2d array
+% 
+%  USAGE
+%   Array_Type array_transpose(a)
+% 
+%  DESCRIPTION
+%   Swap rows and columns of a 2dimensional array.
+% 
+%  SEE ALSO
+%   array_info, reshape
+static define test_array_transpose()
+{
+   Arr  = array_transpose(a);
+}
+
+% assoc_value_exists: library function
+% 
+%  SYNOPSIS
+%   Return the number of occurences of `value' in `ass'
+% 
+%  USAGE
+%   Integer_Type assoc_value_exists(Assoc_Type ass, value)
+% 
+%  DESCRIPTION
+%   Count, how many times `value' is present in the associative 
+%   array `ass'. 
+% 
+%  SEE ALSO
+%   array_value_exists, assoc_key_exists, assoc_get_key, assoc_get_values
+static define test_assoc_value_exists()
+{
+   i = assoc_value_exists(Ass ass, value);
+}
+
+% assoc_get_key: library function
+% 
+%  SYNOPSIS
+%   Return the key of a value of an Associative Array
+% 
+%  USAGE
+%   String_Type key = assoc_get_key(ass, value)
+% 
+%  DESCRIPTION
+%   Reverse the usual lookup of an hash table (associative array). Return the
+%   first key whose value is equal to `value'.
+% 
+%  NOTES
+%   Of course, this function is far slower than the corresponding ass[key].
+% 
+%  SEE ALSO
+%   assoc_value_exists
+static define test_assoc_get_key()
+{
+   Str key = assoc_get_key(ass, value);
+}
+
+% push_list: library function
+% 
+%  SYNOPSIS
+%   Push the list elements on the stack
+% 
+%  USAGE
+%   push_list(List_Type lst)
+% 
+%  DESCRIPTION
+%   Push all elements of a list to the stack. 
+%   Very convenient for converting a list to an argument list.
+% 
+%  EXAMPLE
+% 
+%    variable args = {"foo ", "bar ", "uffe "};
+%    variable str = strjoin(push_list(args));
+% 
+% 
+%  SEE ALSO
+%   pop2list, push_array
+static define test_push_list()
+{
+   push_list(List_Type = lst);
+}
+
+% pop2list: library function
+% 
+%  SYNOPSIS
+%   Return list with N topmost stack-items
+% 
+%  USAGE
+%   List_Type lst = pop2list(N=_stkdepth)
+% 
+%  DESCRIPTION
+%  Return a list that consists of the N topmost stack elements. The default
+%  is to return all elements currently on the stack.
+%  The top element becomes lst[N-1].
+% 
+%  EXAMPLE
+%  Together with `push_list', this is a convenient way to manipulate or
+%  pass on an argument list. Compared to `__pop_args'/`__push_args', 
+%  it has the advantage that the args are easily accessible via the normal
+%  index syntax and list functions:
+% 
+%    define silly() % ([args])
+%    {
+%       variable args = pop2list(_NARGS);
+%       list_append(args, "42", -1);
+%       args[1] = 3;
+%       show(push_list(args));
+%    }      
+% 
+% 
+%  NOTES
+%  Attention: dont use `pop2list' in a function call with optional
+%  arguments.
+% 
+%  SEE ALSO
+%   push_list, pop2array, _stkdepth
+static define test_pop2list()
+{
+   List_Type lst = pop2list(N=_stkdepth);
+}
+
+% array2list: library function
+% 
+%  SYNOPSIS
+%   Convert an array to a list
+% 
+%  USAGE
+%   List_Type array2list(a)
+% 
+%  DESCRIPTION
+%   Return a list of the  elements of `a'.
+% 
+%  EXAMPLE
+% 
+%    array2list([1, 2, 3]) == {1, 2, 3}
+% 
+% 
+%  SEE ALSO
+%   list2array, push_array, pop2list
+static define test_array2list()
+{
+   List_Type = array2list(a);
+}
+
+% list_concat: library function
+% 
+%  SYNOPSIS
+%   Concatenate 2 lists
+% 
+%  USAGE
+%   list_concat(l1, l2)
+% 
+%  DESCRIPTION
+%   Concatenate 2 lists by appending the elements of `l2' to `l1'.
+% 
+%  NOTES
+%   As this function uses a foreach loop over `l2', it can also be an 
+%   Array_Type object.
+% 
+%  SEE ALSO
+%   list_append, list_insert, push_list
+static define test_list_concat()
+{
+   list_concat(l1, = l2);
+}
+
+% define list_inject(l1, l2, i)
+static define test_list_inject()
+{
+   list_inject();
+}
+
+sw2buf("*test report*");
 view_mode();

Modified: jed-extra/trunk/tests/ishell-test.sl
===================================================================
--- jed-extra/trunk/tests/ishell-test.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/ishell-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -3,7 +3,6 @@
 % currently, this tests function calls for errors but does only a partial
 % test of advertised functionality
 
-
 % ishell.sl: Interactive shell mode (based on ashell.sl by J. E. Davis)
 
 % custom_variable("Ishell_default_output_placement", ">");
@@ -24,17 +23,17 @@
 autoload("get_buffer", "txtutils");
 
 private variable cmd = "echo 'hello world'";
-% the setting of ADD_NEWLINE has influence of the return value of 
+private variable testbuf = "*bar*";
+% the setting of ADD_NEWLINE has influence of the return value of
 % functions saving the buffer (e.g. using bufsubstring()) and processing the
 % resulting file
 private variable add_newline_before = ADD_NEWLINE;
 
 static define mode_setup()
 {
-   ADD_NEWLINE = 0; 
+   ADD_NEWLINE = 0;
 }
 
-
 static define mode_teardown()
 {
    ADD_NEWLINE = add_newline_before;
@@ -42,32 +41,31 @@
 
 static define setup()
 {
-   popup_buffer("*bar*");
+   popup_buffer(testbuf);
    insert("bar bar");
 }
-       
+
 static define teardown()
 {
-   sw2buf("*bar*");
+   sw2buf(testbuf);
    set_buffer_modified_flag(0);
-   close_buffer("*bar*");
+   close_buffer(testbuf);
 }
 
-
 % ishell_mode(cmd=Ishell_Default_Shell); Open a process and attach it to the current buffer.
 % test_function("ishell_mode");
 static define test_ishell_mode()
 {
    ishell_mode(); % attach a shell to the buffer
    % test the attached shell
-   % 
+   %
    % to test the proper working, we would need a way to synchronize the
    % assynchron working (i.e. wait for a response from the command.)
-   % 
+   %
    % Maybe input_pending() can be (ab)used in conjunction with an output handler
    % pushing a string back on the input-stream (ungetkey()). (Maybe a special
    % blocal "Ishell_output_filter"?)
-   
+
    usleep(2000);  % wait for the startup
    insert("pwd");
    ishell_send_input();
@@ -77,7 +75,6 @@
    usleep(1000);  % wait for the result
 }
 
-
 static define test_ishell()
 {
    ishell(); % Interactive shell
@@ -100,7 +97,6 @@
    terminal("logout");
 }
 
-
 % shell_command(cmd="", output_handling=0); Run a shell command
 static define test_shell_command_0()
 {
@@ -120,13 +116,13 @@
 
 static define test_shell_command_1() % insert at point
 {
-   shell_command(cmd, 1); 
+   shell_command(cmd, 1);
    test_equal(get_buffer(), "bar barhello world\n");
 }
 
 static define test_shell_command_2() % replace region/buffer at point
 {
-   shell_command(cmd, 2); 
+   shell_command(cmd, 2);
    test_equal(get_buffer(), "hello world\n");
 }
 
@@ -146,6 +142,21 @@
    shell_command(cmd, -1); % ignore output
 }
 
+static define test_shell_command_no_output()
+{
+   variable modename1, modename2;
+   (modename1, ) = what_mode();
+   if (bufferp("*shell-output*"))
+     {
+        sw2buf("*shell-output*");
+        set_buffer_modified_flag(0);
+        close_buffer();
+     }
+   shell_command(" "); % null-command -> no output
+   test_equal(whatbuf(), testbuf, "output buffer should close if empty");
+   (modename2, ) = what_mode();
+   test_equal(modename1, modename2, "must not change modename");
+}
 
 % shell_cmd_on_region_or_buffer: library function  Undocumented
 static define test_shell_cmd_on_region_or_buffer()
@@ -155,14 +166,12 @@
    test_equal(shell_cmd_on_region_or_buffer("cat", 3), "bar bar");
 }
 
-  
 % shell_cmd_on_region(cmd="", output_handling=0, postfile_args=""); Save region to a temp file and run a command on it
 static define test_shell_cmd_on_region()
 {
    test_equal(shell_cmd_on_region("cat", 3), "bar bar");
 }
 
-
 % filter_region(cmd=NULL); Filter the region through a shell command
 static define test_filter_region()
 {

Modified: jed-extra/trunk/tests/listing-test.sl
===================================================================
--- jed-extra/trunk/tests/listing-test.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/listing-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -269,9 +269,8 @@
 {
    listing_mode();
    listing->tag_all();
-   !if (is_equal(["three", "test", "lines"], listing_list_tags()))
-     throw AssertionError,
-     "listing_list_tags() should return the tagged lines as String array";
+   test_equal(["three", "test", "lines"], listing_list_tags(),
+     "listing_list_tags() should return the tagged lines as String array");
    !if (3 == listing->tags_length)
      throw AssertionError, "there should be 3 tagged lines";
 }
@@ -279,18 +278,16 @@
 {
    listing_mode();
    listing->tag_all();
-   !if (is_equal(["lines"], listing_list_tags(0)))
-     throw AssertionError,
-     "listing_list_tags(0) should return the current line as String array";
+   test_equal(["lines"], listing_list_tags(0),
+     "listing_list_tags(0) should return the current line as String array");
    !if (3 == listing->tags_length)
      throw AssertionError, "there should be 3 tagged lines";
 }
 static define test_listing_list_tags_1_non_tagged()
 {
    listing_mode();
-   !if (is_equal(["lines"], listing_list_tags(1)))
-     throw AssertionError,
-     "listing_list_tags(1) should return the tagged lines as String array";
+   test_equal(["lines"], listing_list_tags(1),
+     "listing_list_tags(1) should return the tagged lines as String array");
    !if (0 == listing->tags_length)
      throw AssertionError, "there should be no tagged line";
 }
@@ -298,9 +295,8 @@
 {
    listing_mode();
    listing->tag_all();
-   !if (is_equal(["three", "test", "lines"], listing_list_tags(1)))
-     throw AssertionError,
-     "listing_list_tags(1) should return the tagged lines as String array";
+   test_equal(["three", "test", "lines"], listing_list_tags(1),
+     "listing_list_tags(1) should return the tagged lines as String array");
    !if (3 == listing->tags_length)
      throw AssertionError, "there should be 3 tagged lines";
 }
@@ -308,9 +304,8 @@
 {
    listing_mode();
    listing->tag_all();
-   !if (is_equal(["three", "test", "lines"], listing_list_tags(2, 1)))
-     throw AssertionError,
-     "listing_list_tags should return the tagged lines as String array";
+   test_equal(["three", "test", "lines"], listing_list_tags(2, 1),
+     "listing_list_tags should return the tagged lines as String array");
    !if (0 == listing->tags_length)
      throw AssertionError, "all lines should be untagged";
 }
@@ -318,9 +313,8 @@
 {
    listing_mode();
    listing->tag_all();
-   !if (is_equal(["three", "test", "lines"], listing_list_tags(2, 2)))
-     throw AssertionError,
-     "listing_list_tags should return the tagged lines as String array";
+   test_equal(["three", "test", "lines"], listing_list_tags(2, 2),
+     "listing_list_tags should return the tagged lines as String array");
    !if (bobp and eobp)
      {
         testmessage("buffer content: '%s'", get_buffer());

Added: jed-extra/trunk/tests/py-code-example.py
===================================================================
--- jed-extra/trunk/tests/py-code-example.py	                        (rev 0)
+++ jed-extra/trunk/tests/py-code-example.py	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,18 @@
+import sys 
+from os.path import dirname, exists, \
+                    lexists 
+# a comment 
+def unindent(self, 
+             indent=None): 
+    """Return unindeted list of lines
+    
+    Unindents by the least (or given) indentation level"""
+    if indent is None:
+        indent = self.min_indent()
+    else:         
+        indent = 0
+    par = [line[indent:] 
+           for line in self]
+    return PylitParagraph(par)
+
+print 3j, 3.4j, 4J, 4.5J,  3.3e2j, 3L, 3l

Added: jed-extra/trunk/tests/pymode-test.sl
===================================================================
--- jed-extra/trunk/tests/pymode-test.sl	                        (rev 0)
+++ jed-extra/trunk/tests/pymode-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,677 @@
+% pymode-test.sl:  Test pymode.sl
+% 
+% Copyright (c) 2006 Günter Milde
+% Released under the terms of the GNU General Public License (ver. 2 or later)
+%
+% Versions:
+% 0.1 2006-03-03 
+
+require("unittest");
+
+% test availability of public functions (comment to skip)
+test_true(is_defined("python_shell"), "public fun python_shell undefined");
+test_true(is_defined("python_mode"), "public fun python_mode undefined");
+
+% Fixture
+% -------
+
+require("pymode");
+
+private variable testbuf = "*pymode test*";
+private variable teststring = strjoin(
+   ["import sys",
+    "from os.path import dirname, exists, \\",
+    "                lexists",
+    "# a comment",
+    "def unindent(self,",
+    "    indent=None):",
+    "    \"\"\"Return unindented list of lines",
+    "",   
+    "    Unindents by the least (or given) indentation level\"\"\"",
+    "    if indent is None:",
+    "        indent = self.min_indent()",
+    "    else:",
+    "        indent = 0",
+    "    par = [line[indent:] ",
+    "           for line in self]",
+    "    return PylitParagraph(par)",
+    ""
+    ], "\n");
+% show_string(teststring);
+
+private variable literal_strings__teststring = strjoin(
+   ["''' 'in' ''' out",
+    "\"\"\" \"in\" \"\"\" out",
+    "''' in ",
+    "in ''' out",
+    "\"\"\" in ",
+    "in \"\"\" out",
+    "''' in \"\"\" in ''' out",
+    "\"\"\" in ",
+    "''' in",
+    "\"\"\" out ''' in ''' out",
+    "' in \"\"\" in \\\' in \" in ' out",
+    "\" in ''' in \\\" in ' in \" out",
+    "\" ' in",
+    "out '''",
+    " in \"\"\" in "], "\n");
+% show_string(literal_strings__teststring);
+
+static define setup()
+{
+   sw2buf(testbuf);
+   insert(teststring);
+}
+
+static define teardown()
+{
+   sw2buf(testbuf);
+   set_buffer_modified_flag(0);
+   close_buffer(testbuf);
+}
+
+% Test functions
+% --------------
+
+% test whether the point is inside a long string literal (""" """ or ''' ''')
+% static define in_literal_string()
+static define test_in_literal_string()
+{
+   erase_buffer();
+   insert(literal_strings__teststring);
+   bob;
+   while (fsearch("in"))
+     {
+        test_true(python->in_literal_string(),
+           sprintf("inside string literal: %d %s", 
+              what_line, line_as_string()));
+        go_right(2);
+     }
+   bob;
+   while (fsearch("out"))
+     {
+        test_true(not(python->in_literal_string()),
+           sprintf("outside string literal: %d %s", 
+              what_line, line_as_string()));
+        go_right(3);
+     }
+}
+
+% define py_is_continuation_line()
+% recognize continuation lines (after \, inside """ """, (), [], and {})
+static define test_py_is_continuation_line()
+{
+   variable continuation_lines = [3, 6, 8, 9, 15];
+   bob();
+   do
+     {
+        % vshow("line %d: continues at %d", 
+        %    what_line, py_is_continuation_line());
+        if (wherefirst(what_line() == continuation_lines) != NULL)
+          test_true(python->is_continuation_line(),
+             sprintf("line %d '%s' is a continuation line", 
+                what_line(), line_as_string()));
+        else
+          test_true(not(python->is_continuation_line()),
+             sprintf("line %d '%s' is no continuation line", 
+                what_line(), line_as_string()));
+     }
+   while (down_1());
+}
+
+static define test_py_is_indented_code_line()
+{
+   % line-numbers of indented code lines in the teststring
+   variable indented_code_lines = [7, 10, 11, 12, 13, 14, 16];
+   
+   bob();
+   do
+     {
+        % testmessage(sprintf("\n  line %d: continues at %d", 
+        %    what_line, python->is_continuation_line()));
+        if (wherefirst(what_line() == indented_code_lines) != NULL)
+          test_true(python->is_indented_code_line(),
+             sprintf("line %d '%s' is an indented_code line", 
+                what_line(), line_as_string()));
+        else
+          test_true(not(python->is_indented_code_line()),
+             sprintf("line %d '%s' is no indented_code line", 
+                what_line(), line_as_string()));
+     }
+   while (down_1());
+}
+
+% Determine the buffer-local indentation level
+% 
+% Try the blocal variable "Py_Indent_Level", 
+%     the first indented code line, or
+%     the global Py_Indent_Level.
+% store in blocal variable
+static define test_get_indent_level()
+{
+   test_equal(python->get_indent_level(), 4, "default is 4 spaces");
+   goto_line(2);
+   insert("\t");
+   test_equal(python->get_indent_level(), 4, "value should be cached");
+}
+
+static define test_get_indent_level_tab()
+{
+   goto_line(2);
+   insert("\t");
+   % () = get_y_or_n("continue");
+   test_equal(python->get_indent_level(), 0, "tab use should return 0");
+   
+}
+
+static define test_get_indent_level_default()
+{
+   erase_buffer();
+   test_equal(python->get_indent_level(), Py_Indent_Level , 
+      "should return Py_Indent_Level if there are no indented code lines");
+}
+
+% get the width of the expanded indent string (indent_level or TAB)
+static define test_get_indent_width()
+{
+   test_equal(python->get_indent_width(), 4, 
+      "should return get_indent_level() if it is > 0");
+   define_blocal_var("Py_Indent_Level", 0);
+   test_equal(python->get_indent_width(), TAB,
+      "should return TAB if indent-level is 0 (tab use)");
+}
+
+% static define check_indentation()
+% Test whether code indentation mixes tabs and spaces
+% Leave point at the first non-white char in the offending line
+static define test_check_indentation()
+{
+   test_equal(' ', python->check_indentation(),
+      "false alarm: is there really a tab in '" + line_as_string() + "' ?");
+   % tab in continuation line
+   goto_line(3); 
+   bol();
+   insert("\t");
+   test_equal(' ', python->check_indentation(),
+      "should ignore tab in continuation line");
+   % tab in code line
+   goto_line(7);
+   insert("\t");
+   eob();
+   test_equal(0, python->check_indentation(),
+      "should find tab in indented code line");
+   test_equal(what_line(), 7, "should place point in first offending line");
+   % convert spaces to tabs:
+   bob();
+   replace("    ", "\t");
+   define_blocal_var("Py_Indent_Level", 0);
+   test_equal('\t', python->check_indentation(),
+      "false alarm: is there really a space in " + line_as_string());
+}
+
+% static define calculate_indent_col()
+% Parse last line(s) to estimate the correct indentation for the current line
+% 
+% Used in py_indent_line, indent_line_hook (for indent_line() and
+% newline_and_indent(), and electric_colon()
+static define test_calculate_indent()
+{
+   variable i=1, indent, indents = [0,0,0,0,0,13,4,4,0,4,8,4,8,8,11,4,0];
+   
+   bob();
+   foreach indent (indents)
+     {
+        test_equal(indent, python->calculate_indent(),
+           sprintf("wrong estimate in line %d", i));
+        go_down_1();
+        i++;
+     }
+}
+
+% define py_indent_line()
+static define test_py_indent_line()
+{
+   bob();
+   % indent by given amount
+   py_indent_line(7);
+   bol_skip_white();
+   test_equal(what_column()-1, 7, "should indent to given amount");
+   test_equal(bfind("\t"), 0, 
+      "must not use tabs for indentation if indent-level != 0");
+
+   % Indent to calculated column
+   % no indent
+   py_indent_line();
+   bol_skip_white();
+   test_equal(what_column()-1, 0, "should remove spurious indentation");
+   % indented line (1 level)
+   () = fsearch("if indent is None:");
+   bol_trim();
+   py_indent_line();
+   bol_skip_white();
+   test_equal(what_column()-1, Py_Indent_Level, "should indent to previous line");
+   % more variants are tested via test_calculate_indent_col()
+   
+   % indent with tabs
+   define_blocal_var("Py_Indent_Level", 0);
+   py_indent_line(2*TAB);
+   bol_skip_white();
+   test_equal(what_column()-1, 2*TAB, 
+      "should indent to given amount also if using tabs");
+   test_equal(bfind(" "), 0, 
+      "must not use spaces indentation if indent-level == 0 and width is multiple of TAB");
+}
+
+
+%\function{python->py_shift_line_right}
+%Increase the indentation level of the current line
+static define test_py_shift_line_right()
+{
+   % define_blocal_var("Py_Indent_Level", 4); % calculated from teststring
+   TAB = 8;
+   bob;
+   % Indent one level
+   variable i;
+   foreach i ([0,1,2,3])
+      {
+         bol_trim();
+         whitespace(i);
+         python->py_shift_line_right();
+         bol_skip_white();
+         test_equal(what_column()-1, Py_Indent_Level,
+            sprintf("should indent from %d to next Py_Indent_Level", i));
+      }
+   % Indent one more level
+   foreach i ([4,5,6,7])
+      {
+         bol_trim();
+         whitespace(i);
+         python->py_shift_line_right();
+         bol_skip_white();
+         test_equal(what_column()-1, 2*Py_Indent_Level,
+            sprintf("should indent from %d to next Py_Indent_Level", i));
+      }
+   % Indent with spaces (test now, as TAB is 2*Py_Indent_Level)
+   test_equal(0, bfind("\t"), "should indent with spaces");
+   
+   % Indent several levels at once with prefix argument
+   bol_trim(); 
+   set_prefix_argument(3);
+   python->py_shift_line_right();
+   bol_skip_white();
+   test_equal(what_column()-1, 3*Py_Indent_Level, 
+      "should indent by prefix-arg * Py_Indent_Level");
+}
+
+static define test_py_shift_line_right_with_tabs()
+{
+   bob;
+   % Indent with tabs if get_indent_level returns 0
+   define_blocal_var("Py_Indent_Level", 0);
+   python->py_shift_line_right();
+   test_equal(what_column(), TAB+1,
+      "should indent by TAB");
+   test_true(blooking_at("\t"), "should indent with tabs");
+}
+
+% py_shift_region_right: undefined
+%   Increase the indentation level of the region
+static define test_py_shift_region_right()
+{
+   bob();
+   push_mark();
+   python->py_shift_region_right();
+   bol_skip_white();
+   test_equal(what_column()-1, Py_Indent_Level, 
+      "should indent by Py_Indent_Level");
+   test_equal(count_narrows(), 0, "still narrowed");
+   test_equal(markp(), 0, "mark left");
+}
+
+% py_shift_right: undefined
+%   Increase code indentation level
+%   If a `prefix_argument' is set, indent the number of levels
+%   given in the prefix argument.
+static define test_py_shift_right()
+{
+   bob();
+   set_prefix_argument(3);
+   py_shift_right();
+   bol_skip_white();
+   test_equal(what_column()-1, 3*Py_Indent_Level, 
+      "should indent by 3*Py_Indent_Level");
+}
+
+% define py_shift_line_left()
+static define test_py_shift_line_left()
+{
+   % set indent leve because we fiddle with the teststring!
+   define_blocal_var("Py_Indent_Level", 4); 
+   TAB = 8;
+   bob;
+   % Unindent to bol
+   variable i;
+   foreach i ([1,2,3,4])
+      {
+         bol_trim();
+         whitespace(i);
+         python->py_shift_line_left();
+         bol_skip_white();
+         test_equal(what_column()-1, 0,
+            sprintf("should unindent from %d to bol", i));
+      }
+   % Unindent to first level
+   foreach i ([5,6,7,8])
+      {
+         bol_trim();
+         whitespace(i);
+         python->py_shift_line_left();
+         bol_skip_white();
+         test_equal(what_column()-1, 4,
+            sprintf("should unindent from %d to first Py_Indent_Level", i));
+      }
+   % test the saveguard error
+   bol_trim();
+   variable err = test_for_exception("python->py_shift_line_left");
+   if (orelse{err == NULL}{err.error != RunTimeError})
+     throw AssertionError, 
+     "should abort if there is not enough indentation";
+}
+
+% define py_shift_region_left()
+static define test_py_shift_region_left()
+{
+   bol_trim();
+   whitespace(Py_Indent_Level);
+   push_mark();
+   python->py_shift_region_left();
+   bol_skip_white();
+   test_equal(what_column()-1, 0, "should dedent by Py_Indent_Level");
+   test_equal(count_narrows(), 0, "still narrowed");
+   test_equal(markp(), 0, "mark left");
+}
+
+% define py_shift_left() {
+%\synopsis{Decrease code indentation level}
+static define test_py_shift_left()
+{
+   bol_trim();
+   whitespace(Py_Indent_Level);
+   py_shift_left();
+   bol_skip_white();
+   test_equal(what_column()-1, 0, "should dedent by Py_Indent_Level");
+   bol_trim();
+   whitespace(3*Py_Indent_Level);
+   set_prefix_argument(3);
+   py_shift_left();
+   bol_skip_white();
+   test_equal(what_column()-1, 0, "should dedent by 3*Py_Indent_Level");
+}
+
+% public  define py_untab()
+%   Convert tabs to `Py_Indent_Level' spaces or
+%   spaces to tabs (with prefix argument)
+%   Replace all hard tabs ("\\t") with spaces 
+%  NOTES
+%   Other than `untab', `py_untab' acts on the whole buffer, not on a
+%   region.
+static define test_py_untab()
+{
+   % spaces to tabs (with prefix argument)
+   set_prefix_argument(1);
+   py_untab();
+   bob();
+   test_equal('\t', python->check_indentation(),
+      "there should be only tabs in code indentation"
+      +"(if the indents are a multipel of TAB)");
+   test_equal(0, python->get_indent_level,
+      "set local indent level to 0 (indent with tabs)");
+   % tabs to spaces
+   py_untab();
+   bob();
+   test_equal(0, fsearch("\t"), "there should be no tabs in the buffer");
+   test_equal(TAB, python->get_indent_level,
+      "set local indent level to TAB");
+}
+
+% static define reindent_buffer()
+%   Reindent buffer using `Py_Indent_Level'
+%  DESCRIPTION
+%   Reformat current buffer to consistent indentation levels. using the current
+%   relative indentation and the value of get_indent_width().
+%   Abort if the current indentation violates the Python syntax.
+static define test_reindent_buffer()
+{
+   define_blocal_var("Py_Indent_Level", 0);
+   TAB=8;
+   python->reindent_buffer();
+   test_equal('\t', python->check_indentation(),
+      "there should be only tabs in code indentation");
+   % reindent with given value
+   python->reindent_buffer(4);
+   test_equal(4, python->get_indent_level,
+      "should set local indent level to 4");
+   test_equal(0, fsearch("\t"), "there should be no tabs in the buffer");
+   % mark_buffer();
+   % show(bufsubstr());
+   % show(teststring);
+   mark_buffer();
+   test_equal(bufsubstr(), teststring, "should be back to original indent");
+}
+
+static define test_reindent_buffer_zero_TAB()
+{
+   TAB=0;
+   % reindent_buffer should set TAB to 4 to prevent indent by 0 spaces!
+   python->reindent_buffer(0);
+   test_equal('\t', python->check_indentation(),
+      "there should be only tabs in code indentation");
+   % reindent with given value
+   python->reindent_buffer(4);
+   test_equal(4, python->get_indent_level,
+      "should set local indent level to 4");
+   test_equal(0, fsearch("\t"), "there should be no tabs in the buffer");
+   mark_buffer();
+   test_equal(bufsubstr(), teststring, "should be back to original indent");
+}
+
+% static define reindent_block()
+% reindent the current block or all blocks that overlap with a visible region
+static define test_reindent_block()
+{
+   eob();
+   insert("def ulf():\n");
+   insert("    quatsch()\n");
+   insert("    batch()\n");
+   insert("\n");
+   insert("# last comment\n");
+   
+   define_blocal_var("Py_Indent_Level", 0);
+   % call reindent_block on last line
+   set_buffer_modified_flag(0);
+   python->reindent_block();
+   test_equal(0, buffer_modified(), 
+      "should do nothing if on non-indented line that doesnot start a block");
+   % call on last block
+   () = bsearch("quatsch");
+   python->reindent_block();
+   bol();
+   test_true(looking_at_char('\t'), "should indent block with tabs");
+   % this should move the point into the first block
+   test_equal(0, python->check_indentation(), "now tabs and spaces are mixed");
+   python->reindent_block();
+   % as there are only 2 blocks, indentation should be clean again
+   test_equal('\t', python->check_indentation(), "should be only tabs");
+}
+
+% Magic keys
+% ----------
+
+% define electric_colon()
+% dedent a line one level, if it is the start of a new block
+static define test_electric_colon()
+{
+   insert("\n   else");
+   python->electric_colon();
+   bol_skip_white();
+   test_equal(what_column(), 1);
+   insert("\n   elise"); % not a subblock starter
+   python->electric_colon();
+   bol_skip_white();
+   test_equal(what_column(), 4);
+}
+
+
+% define electric_delim(ch)
+% Currently not used due to unsolved problems
+static define test_electric_delim()
+{
+   python->electric_delim(')');
+}
+
+% define py_backspace_key()
+% shift line right if we are at the first non-white space in an indented
+% line,  normal action else
+static define test_py_backspace_key()
+{
+   variable line, col;
+   % inside code: just delete prev char
+   bob;
+   () = fsearch("self.min_indent");
+   line = what_line(), col = what_column();
+   python->py_backspace_key();
+   test_equal(col-1, what_column(), "should delete prev char normally");
+   % goto first non-white char
+   bol_skip_white();
+   col = what_column();
+   python->py_backspace_key();
+   test_equal(col-Py_Indent_Level, what_column, 
+      "should dedent line if at first non-white space");
+   bol;
+   python->py_backspace_key();
+   test_equal(line-1, what_line(), "should del prev newline if at bol");
+}
+
+% define py_exec()
+% Run python interpreter on current region or the whole buffer.
+% Display output in *python-output* buffer window.
+static define test_py_exec()
+{
+   bob();
+   insert("print 2 + 2 #");
+   py_exec();
+   % () = get_y_or_n("continue");
+   test_true(bufferp("*python output*"), 
+      "should open output buffer (if there is output from python)");
+   close_buffer("*python output*");
+}
+
+% public define python_shell()
+% attach python session to buffer
+static define test_python_shell_interactive()
+{
+   python_shell();
+   testmessage("test interactive!");
+}
+
+% define py_help_on_word()
+% #ifdef MSWINDOWS
+% static define test_py_help_on_word()
+% {
+%    py_help_on_word();
+% }
+% #endif
+
+% define get_import_lines()
+% find lines with global imports (import ... and  from ... import ...)
+static define test_get_import_lines()
+{
+   % get the teststring up to the comment (minus the newline)
+   variable import_lines = teststring[[:is_substr(teststring, "#")-2]];
+   
+   test_equal(import_lines, python->get_import_lines());
+   erase_buffer();
+   test_equal("", python->get_import_lines());
+}
+
+% py_help: undefined
+% 
+%  SYNOPSIS
+%   Run python's help feature on topic
+% 
+%  USAGE
+%    Void py_help([String topic])
+% 
+%  DESCRIPTION
+%    Call python help on topic and display the help text in a window.
+%    If the topic is not given, ask in the minibuffer.
+% 
+%  NOTES
+%    Only tested on UNIX
+% 
+%  SEE ALSO
+%   py_mode
+static define test_py_help()
+{
+   py_help("string.whitespace");
+   test_true(bufferp("*python-help*"), 
+      "should open help buffer");
+   test_true(fsearch("string.whitespace"),
+      "should display help on 'string.whitespace'");
+   close_buffer("*python-help*");
+}
+
+
+% define py_help_for_word_hook(word)
+% (add "." to word chars);
+static define test_python_help_for_word_hook()
+{
+   insert(" string.whitespace");
+   python->python_help_for_word_hook("dummy");
+   test_true(bufferp("*python-help*"), 
+      "should open help buffer");
+   setbuf("*python-help*");
+   bob();
+   test_true(fsearch("string.whitespace"),
+      "should display help on 'string.whitespace'");
+   % () = get_y_or_n("continue");
+   close_buffer("*python-help*");
+}
+
+% define py_browse_module_doc() % (module=NULL)
+static define test_py_browse_module_doc_interactive()
+{
+   message("should open help for module 'os' in browser");
+   py_browse_module_doc("os");
+   testmessage("needs interactive testing (opens external browser)");
+}
+
+% python_mode: library function
+% 
+%  SYNOPSIS
+%   Mode for editing Python files.
+% 
+%  USAGE
+%   Void python_mode()
+% 
+%  DESCRIPTION
+%  A major mode for editing scripts written in Python (www.python.org).
+% 
+%  The following keys have python specific bindings:
+% 
+%   Backspace   deletes to previous indentation level
+%   : (colon)   dedents appropriately
+%   (the next assume `_Reserved_Key_Prefix' == "^C")
+%   ^C#         comments region or current line
+%   ^C>         shifts line or region right
+%   ^C<         shifts line or region left
+%   ^C^C        executes the region, or the buffer if region not marked.
+%   ^C|         executes the region
+% 
+% 
+%  SEE ALSO
+%   Py_Indent_Level, Py_Use_Tabs, py_reindent, python->py_untab
+static define test_python_mode()
+{
+   python_mode();
+}

Added: jed-extra/trunk/tests/rst-test.sl
===================================================================
--- jed-extra/trunk/tests/rst-test.sl	                        (rev 0)
+++ jed-extra/trunk/tests/rst-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,298 @@
+% rst-test.sl:  Test rst.sl
+% 
+% Copyright (c) 2006 Günter Milde
+% Released under the terms of the GNU General Public License (ver. 2 or later)
+%
+% Versions:
+% 0.1 2006-03-03 
+
+require("unittest");
+
+% Customization
+% -------------
+% 
+% Set 
+%   Unittest_Skip_Patterns = [Unittest_Skip_Patterns, "long"];  
+% to skip long running tests.
+
+% test availability of public functions (comment to skip)
+test_true(is_defined("rst_mode"), "public fun rst_mode undefined");
+
+% Fixture
+% -------
+
+require("rst");
+
+private variable testfile = make_tmp_file("rst-testfile.txt");
+private variable testbuf = path_basename(testfile);
+private variable teststring = "a test line";
+
+static define setup()
+{
+   () = find_file(testfile);
+   insert(teststring);
+   save_buffer();
+}
+
+static define teardown()
+{
+   sw2buf(testbuf);
+   set_buffer_modified_flag(0);
+   close_buffer(testbuf);
+   test_true(delete_file(testfile), "cleanup failed");
+}
+
+% private namespace: `rst'
+
+
+% Test functions
+% --------------
+
+% static define rst_export() % (to, outfile=path_sans_extname(whatbuf())+"."+to)
+static define test_rst_export_long()
+{
+   variable to = "html";
+   variable outfile = path_sans_extname(buffer_filename()) + "." + to;
+
+   rst->rst_export(to);
+   
+   test_true(delete_file(outfile), "should create output file");
+}
+
+% public  define rst_to_html()
+static define test_rst_to_html_long()
+{
+   variable outfile = path_sans_extname(buffer_filename()) + ".html";
+   rst_to_html();
+
+   test_true(delete_file(outfile), "should create html output");
+}
+
+% public  define rst_to_latex() % (outfile=path_sans_extname(whatbuf())+".tex")
+static define test_rst_to_latex_long()
+{
+   variable outfile = path_sans_extname(buffer_filename()) + ".tex";
+
+   rst_to_latex();
+   
+   test_true(delete_file(outfile), "should create latex output");
+}
+
+% public  define rst_to_pdf() % (outfile=path_sans_extname(whatbuf())+".pdf")
+static define test_rst_to_pdf_long()
+{
+   testmessage("rst2pdf still not working");
+   return;
+   
+   variable outfile = path_sans_extname(buffer_filename()) + ".pdf";
+
+   rst_to_pdf();
+   
+   test_true(delete_file(outfile), "should create pdf output");
+}
+
+% static define command_help(cmd)
+static define test_command_help()
+{
+   rst->command_help("ls foo");
+   test_equal(whatbuf(), "*rst export help*", "should open help buffer");
+   close_buffer("*rst export help*");
+}
+
+% static define set_export_cmd(export_type)
+static define test_set_export_cmd_html_long()
+{
+   variable testcmd = " --option", old_cmd = Rst2Html_Cmd;
+   buffer_keystring(testcmd + "\r");
+   rst->set_export_cmd("html");
+   test_equal(Rst2Html_Cmd, old_cmd + testcmd);
+   Rst2Html_Cmd = old_cmd;}
+
+static define test_set_export_cmd_tex_long()
+{
+   variable testcmd = " --option", old_cmd = Rst2Latex_Cmd;
+   buffer_keystring(testcmd + "\r");
+   rst->set_export_cmd("tex");
+   test_equal(Rst2Latex_Cmd, old_cmd + testcmd);
+   Rst2Latex_Cmd = old_cmd;
+}
+
+static define test_set_export_cmd_pdf_long()
+{
+   variable testcmd = " --option", old_cmd = Rst2Pdf_Cmd;
+   buffer_keystring(testcmd + "\r");
+   rst->set_export_cmd("pdf");
+   test_equal(Rst2Pdf_Cmd, old_cmd + testcmd);
+   Rst2Pdf_Cmd = old_cmd;
+}
+
+% public  define rst_view_html() % (browser=Browse_Url_Browser))
+% Needs interactive testing.
+static define test_rst_view_html_interactive()
+{
+   rst_view_html();
+}
+
+% static define markup(type)
+static define test_markup()
+{
+   rst->markup("strong");
+   test_equal("a test **line**", line_as_string(), "should mark up last word");
+}
+
+
+% static define block_markup(type)
+static define test_block_markup()
+{
+   insert("\n   strong");
+   rst->block_markup("strong");
+   test_equal("**strong**", line_as_string(), 
+      "should mark up last word and (re) indent");
+}
+
+% static define insert_directive(directive_type)
+static define test_insert_directive()
+{
+   rst->insert_directive("test");
+   test_equal(".. test:: ", line_as_string(), 
+      "should insert directive on a line on its own");
+}
+
+
+% static define section_header() % ([underline_character]) % as string
+static define test_section_header()
+{
+   variable ul_string = string_repeat("+", strlen(teststring));
+   
+   rst->section_header(ul_string[[0]]);
+   go_up_1();
+   test_equal(ul_string, line_as_string(), 
+      "should underline with given character");
+   
+   insert(ul_string + "\t");
+   rst->section_header(ul_string[[0]]);
+   test_true(eobp(), "should replace existing section markup");
+   go_up_1();
+   test_equal(ul_string, line_as_string(), 
+      "should adapt length of underline");
+   
+   ul_string = string_repeat("-", strlen(teststring));
+   rst->section_header(ul_string[[0]]);
+   test_true(eobp(), "should replace existing section markup");
+   go_up_1();
+   test_equal(ul_string, line_as_string(), 
+      "should change section markup");
+}
+
+   
+static define test_section_header_replace()
+{
+   variable ul_string = string_repeat("+", strlen(teststring));
+   newline();
+   insert(ul_string + " " + ul_string);
+   bob();
+   rst->section_header(ul_string[[0]]);
+   go_up_1();
+   test_equal(ul_string, line_as_string(), 
+      "should insert section markup");
+   eob();
+   test_equal(ul_string + " " + ul_string, line_as_string(),
+      "should keep next line if it is not section markup");
+}
+
+
+static define test_section_header_numeric()
+{
+   variable level, ul_string;
+   
+   for (level = 0; level < strlen(rst->Underline_Chars); level++)
+     {
+        ul_string = string_repeat(rst->Underline_Chars[[level]], 
+           strlen(teststring));
+        rst->section_header(level);
+        go_up_1();
+        test_equal(ul_string, line_as_string(), 
+           "should underline with given level, replacing existing markup");
+     }
+}
+
+  
+  
+#ifexists list_routines
+
+% public  define rst_list_routines_extract (nRegexp)
+static define test_rst_list_routines_extract()
+{
+   test_equal("", rst_list_routines_extract(0),
+      "should return empty string if not on a section header");
+   
+   variable adornment = string_repeat("+", strlen(teststring));
+   % testmessage("\n" + line_as_string);
+   insert("\n" + adornment);
+   % testmessage("\n" + line_as_string);
+   bol();
+   test_equal("+ a test line", rst_list_routines_extract(0),
+      "should return section header preceded by adornment character");
+
+   delete_line();
+   insert("------");
+   bol();
+   test_equal("", rst_list_routines_extract(0),
+      "should return empty string if underline too short");
+
+   newline();
+   insert("\n\n------");
+   bol();
+   test_equal("", rst_list_routines_extract(0),
+      "should return empty string if on a transition");
+
+   newline();
+   insert("\n\n::");
+   bol();
+   test_equal("", rst_list_routines_extract(0),
+      "should return empty string if on a literal block marker");
+
+   newline();
+   insert("\n\nsubsection");
+   insert(  "\n----------");
+   bol();
+   test_equal("  - subsection", rst_list_routines_extract(0),
+      "should return sub section header");
+
+}
+
+% public  define rst_list_routines_done()
+static define test_rst_list_routines_done()
+{
+   rst_list_routines_done();
+}
+
+#endif
+
+
+% static define new_popup(menu, popup)
+static define test_new_popup()
+{
+   variable popup = rst->new_popup("Global", "test");
+   test_equal("Global.test", popup, "should return identifier of popup");
+   menu_delete_item(popup);
+}
+
+% static define rst_menu(menu)
+static define test_rst_menu()
+{
+   % simple test for errors while executing, 
+   % TODO: test of functionality
+   variable popup = "Global.test";
+   menu_append_popup("Global", "test");
+   rst->rst_menu(popup);
+   menu_delete_item(popup);
+}
+
+% public define rst_mode()
+static define test_rst_mode()
+{
+   % simple test for errors while executing, 
+   % TODO: test of functionality
+   rst_mode();
+}

Added: jed-extra/trunk/tests/structured_text-test.sl
===================================================================
--- jed-extra/trunk/tests/structured_text-test.sl	                        (rev 0)
+++ jed-extra/trunk/tests/structured_text-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,250 @@
+% structured_text-test.sl:  Test structured_text.sl
+% 
+% Copyright (c) 2006 Günter Milde
+% Released under the terms of the GNU General Public License (ver. 2 or later)
+%
+% Versions:
+% 0.1 2006-03-03 
+
+require("unittest");
+
+% test availability of public functions (comment to skip)
+test_true(is_defined("structured_text_hook"), "public fun structured_text_hook undefined");
+
+% Fixture
+% -------
+
+require("structured_text");
+
+private variable testbuf = "*bar*";
+private variable teststring = "a test line";
+private variable enumerated_list = ["1. das ist es",
+                                    "2.  auch noch",
+                                    " 3. drittens",
+                                    "45.\tlast"];
+private variable itemize_list = ["* so",
+                                 "+ geht's",
+                                 "*  auch",
+                                 "-  nicht",
+                                 "+\tbesser"];
+
+private define insert_lists()
+{
+   insert(strjoin(enumerated_list, "\n")+"\n"+strjoin(itemize_list, "\n"));
+}
+  
+static define setup()
+{
+   sw2buf(testbuf);
+   insert(teststring);
+}
+
+static define teardown()
+{
+   sw2buf(testbuf);
+   set_buffer_modified_flag(0);
+   close_buffer(testbuf);
+}
+
+% Test functions
+% --------------
+
+% line_is_list: library function
+% 
+%  SYNOPSIS
+%   Return length of a list marker
+% 
+%  USAGE
+%    line_is_list()
+% 
+%  DESCRIPTION
+%  Check if the current line starts with a list marker matching one of the
+%  regular expressions defined in `Rst_List_Patterns'.
+%  Return length of the list marker (excluding leading whitespace)
+% 
+%  Leaves the editing point at first non-whitespace or eol
+% 
+%  NOTES
+%  Thanks to JED for the regular expressions variant
+% 
+%  SEE ALSO
+%   line_is_empty, Text_List_Patterns
+static define test_line_is_list()
+{
+   test_equal(line_is_list(), 0, "text line is no list");
+   erase_buffer();
+   insert_lists();
+   bob();
+   do
+     test_true(line_is_list(), "should recognize list line");
+   while (down_1());
+   % should return the length of the list marker:
+   bob();
+   variable len, 
+     marker_lengths = [3, %   "1. das ist es",
+                       4, %   "2.  auch noch",
+                       3, %   " 3. drittens",
+                       4, %   "45.\tlast"
+                       2, %   "* so",
+                       2, %   "+ geht's",
+                       3, %   "*  auch",
+                       3, %   "-  nicht",
+                       2]; %   "+\tbesser"              
+   
+   foreach len (marker_lengths)
+     {
+        test_equal(line_is_list(), len, 
+           sprintf("should return list marker length (%d) '%s'",  
+              len, get_line()));
+        go_down_1();
+     }
+}
+
+% define line_is_blank()
+static define test_line_is_blank()
+{
+   test_equal(line_is_blank(), 0, "text is not blank");
+   erase_buffer();
+   insert("\n   \n\t\t\n\n  \t\n\n");
+   bob();
+   do
+     test_true(line_is_blank(), sprintf("line %d is blank", what_line));
+   while (down_1());
+}
+
+% TODO: the remainder is still raw testscript_wizard output
+#stop
+
+% st_is_paragraph_separator: library function
+% 
+%  SYNOPSIS
+%   paragraph separator hook for structured text
+% 
+%  USAGE
+%   st_is_paragraph_separator()
+% 
+%  DESCRIPTION
+%  Return 1 if the current line separates a paragraph, i.e. it
+%  is empty or a list item
+% 
+%  NOTES
+%  Actually, this misses an important difference between empty lines and
+%  first lines of a list item: While an empty line must not be filled
+%  when reformatting, a list item should.
+%  This is why Emacs has 2 Variables, paragraph-separator and paragraph-start.
+% 
+%  SEE ALSO
+%   line_is_empty, line_is_list
+static define test_st_is_paragraph_separator()
+{
+   st_is_paragraph_separator();
+}
+
+% define st_backward_paragraph()
+static define test_st_backward_paragraph()
+{
+   st_backward_paragraph();
+}
+
+% define st_mark_paragraph()
+static define test_st_mark_paragraph()
+{
+   st_mark_paragraph();
+}
+
+% st_indent: library function
+% 
+%  SYNOPSIS
+%   indent-line for structured text
+% 
+%  USAGE
+%   st_indent()
+% 
+%  DESCRIPTION
+%  Indent the current line,  taking care of list markers as defined in
+%  `Text_List_Patterns'.
+% 
+%  NOTES
+%   Expanded from example in hooks.txt
+% 
+%  SEE ALSO
+%   st_is_paragraph_separator, line_is_list, Text_List_Patterns
+static define test_st_indent()
+{
+   st_indent();
+}
+
+% st_newline_and_indent: library function
+% 
+%  SYNOPSIS
+%   newline_and_indent for structured text
+% 
+%  USAGE
+%    st_newline_and_indent ()
+% 
+%  DESCRIPTION
+%  Indent to level of preceding line
+% 
+%  NOTES
+%  We need a separate definition, as by default newline_and_indent()  uses the
+%  indent_hook (which structured_text.sl sets to st_indent (considering list
+%  markers) while with Enter we want more likely to start a new list topic.
+% 
+%  SEE ALSO
+%   st_indent, st_indent_relative
+static define test_st_newline_and_indent()
+{
+   st_newline_and_indent();
+}
+
+% define st_format_paragraph();  % forward definition
+static define test_st_format_paragraph()
+{
+   st_format_paragraph();
+}
+
+% define st_format_paragraph()
+static define test_st_format_paragraph()
+{
+   st_format_paragraph();
+}
+
+% structured_text_hook: library function
+% 
+%  SYNOPSIS
+%   Formatting hook for "ASCII markup"
+% 
+%  USAGE
+%   structured_text_hook()
+% 
+%  DESCRIPTION
+%   This function calls a list of buffer hooks (see Help>Browse-Docs>Hooks)
+%   suitable for proper indenting and paragraph formatting of documents using
+%   "ASCII markup".
+%   
+%   Paragraphs are separated by blank lines and indented to the same column
+%   as the first line of the paragraph.
+%   
+%   List items that start with a special list marker (e.g. '* ' or '3.') are
+%   considered paragraphs as well, even when not preceded by an empty line.
+%   Continuation lines are indented to the column that matches the start of the
+%   list text.%  
+% 
+%  EXAMPLE
+%   To enable the structured text formatting in `text_mode', set an alias:
+% 
+%    define text_mode_hook() { structured_text_hook(); }
+% 
+% 
+%  NOTES
+%   `rst_mode' calls `structured_text_hook' by default.
+% 
+%  SEE ALSO
+%   st_indent, st_backward_paragraph, st_mark_paragraph
+static define test_structured_text_hook()
+{
+   structured_text_hook();
+}
+
+sw2buf("*test report*");
+view_mode();

Modified: jed-extra/trunk/tests/test-browse_url.sl
===================================================================
--- jed-extra/trunk/tests/test-browse_url.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/test-browse_url.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -1,4 +1,4 @@
-% test-browse_url.sl: Test browse_url.sl
+% test-browse_url.sl: Test browse_url.sl with unittest.sl
 % 
 % Copyright (c) 2006 Günter Milde
 % Released under the terms of the GNU General Public License (ver. 2 or later)
@@ -8,20 +8,19 @@
 
 require("unittest");
 
-variable results;    % list with return value(s)
-variable test_url = "http://jedmodes.sourceforge.net/mode/cua/index.php";
+variable test_url = "http://www.example.org";
 
 % find_url(url=read_mini, cmd = Browse_Url_Download_Cmd); Find a file by URL
 %  public define find_url() %(url=read_mini, cmd = Browse_Url_Download_Cmd)
-results = test_function("find_url", test_url);
-test_return_value(results, {});
+test_function("find_url", test_url);
+test_last_result();
 test_equal(whatbuf(), test_url);
 delbuf(test_url);
 
 % view_url(Str url=read_mini, Str cmd= Browse_Url_Viewer); View an ASCII rendering of a URL
 %  public define view_url() %(url=read_mini, cmd= Browse_Url_Viewer)
-results = test_function("view_url", test_url);
-test_return_value(results, {});
+test_function("view_url", test_url);
+test_last_result();
 test_equal(whatbuf(), "*"+test_url+"*");
 delbuf("*"+test_url+"*");
 
@@ -29,8 +28,8 @@
 % browse_url_x(Str url=ask, Str cmd=Browse_Url_X_Browser); Open a URL in a browser
 testmessage("\n  browse_url_x() needs interactive testing,");
 testmessage("\n  (opens a document in an external browser with system())");
-% results = test_function("browse_url_x", test_url);
-% test_return_value(results, {});
+%  test_function("browse_url_x", test_url);
+% test_last_result();
 %   browse_url_x(): OK ()
 
 % public define browse_url() %(url=read_mini, cmd=Browse_Url_Browser)
@@ -38,6 +37,6 @@
 testmessage("\n  browse_url() needs interactive testing,");
 testmessage("\n  (opens a document in an external browser with system())");
 % (commented out to prevent side effects)
-% results = test_function("browse_url", test_url);
-% test_return_value(results, {});
+% test_function("browse_url", test_url);
+% test_last_result();
 %  browse_url(http://jedmodes.sourceforge.net/mode/cua/index.php): OK ()

Modified: jed-extra/trunk/tests/test-calc.sl
===================================================================
--- jed-extra/trunk/tests/test-calc.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/test-calc.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -8,9 +8,6 @@
 
 
 require("unittest");
-
-variable results;    % list of return value(s)
-
 % private namespace: `calc'
 
 % Open the calc buffer
@@ -18,15 +15,15 @@
 
 % calc: library function  Undocumented
 %  public define calc ()
-results = test_function("calc");
-test_return_value(results, {});
+test_function("calc");
+test_last_result();
 test_equal(whatbuf(), "Calculator");
 
 
 % calc2: library function  Undocumented
 %  public define calc2 ()
-results = test_function("calc2");
-test_return_value(results, {});
+test_function("calc2");
+test_last_result();
 
 % clean up and abort (TODO test remaining functions)
 sw2buf("Calculator");
@@ -37,125 +34,125 @@
 
 % calc_select_expression_buf: undefined  Undocumented
 %  static define calc_select_expression_buf ()
-results = test_function("calc->calc_select_expression_buf");
-test_return_value(results, {});
+test_function("calc->calc_select_expression_buf");
+test_last_result();
 
 % history_next: undefined  Undocumented
 %  static define history_next ()
-results = test_function("calc->history_next");
-test_return_value(results, {});
+test_function("calc->history_next");
+test_last_result();
 
 % history_prev: undefined  Undocumented
 %  static define history_prev ()
-results = test_function("calc->history_prev");
-test_return_value(results, {});
+test_function("calc->history_prev");
+test_last_result();
 
 % calc_next_expression: undefined  Undocumented
 %  public define calc_next_expression ()
-results = test_function("calc_next_expression");
-test_return_value(results, {});
+test_function("calc_next_expression");
+test_last_result();
 
 % calc_format_binary: undefined  Undocumented
 %  static define calc_format_binary (val)
-results = test_function("calc->calc_format_binary");
-test_return_value(results, {});
+test_function("calc->calc_format_binary");
+test_last_result();
 
 % calc_display_value: undefined  Undocumented
 %  static define calc_display_value(val, linepref);
-results = test_function("calc->calc_display_value");
-test_return_value(results, {});
+test_function("calc->calc_display_value");
+test_last_result();
 
 % calc_display_value: undefined  Undocumented
 %  static define calc_display_value(val, linepref)
-results = test_function("calc->calc_display_value");
-test_return_value(results, {});
+test_function("calc->calc_display_value");
+test_last_result();
 
 % calc_display_stack: undefined  Undocumented
 %  static define calc_display_stack ()
-results = test_function("calc->calc_display_stack");
-test_return_value(results, {});
+test_function("calc->calc_display_stack");
+test_last_result();
 
 % calc_display_variables: undefined  Undocumented
 %  public define calc_display_variables ()
-results = test_function("calc_display_variables");
-test_return_value(results, {});
+test_function("calc_display_variables");
+test_last_result();
 
 % calc_result_window: undefined  Undocumented
 %  public define calc_result_window ()
-results = test_function("calc_result_window");
-test_return_value(results, {});
+test_function("calc_result_window");
+test_last_result();
 
 % calc_make_calculation: undefined  Undocumented
 %  public define calc_make_calculation ()
-results = test_function("calc_make_calculation");
-test_return_value(results, {});
+test_function("calc_make_calculation");
+test_last_result();
 
 % calc_find_max_id: undefined  Undocumented
 %  static define calc_find_max_id ()
-results = test_function("calc->calc_find_max_id");
-test_return_value(results, {});
+test_function("calc->calc_find_max_id");
+test_last_result();
 
 % calc_read_file: undefined  Undocumented
 %  public define calc_read_file ()
-results = test_function("calc_read_file");
-test_return_value(results, {});
+test_function("calc_read_file");
+test_last_result();
 
 % calc_write_file: undefined  Undocumented
 %  public define calc_write_file ()
-results = test_function("calc_write_file");
-test_return_value(results, {});
+test_function("calc_write_file");
+test_last_result();
 
 % calc_float_format: undefined  Undocumented
 %  public define calc_float_format ()
-results = test_function("calc_float_format");
-test_return_value(results, {});
+test_function("calc_float_format");
+test_last_result();
 
 % calc_help: undefined  Undocumented
 %  public define calc_help ()
-results = test_function("calc_help");
-test_return_value(results, {});
+test_function("calc_help");
+test_last_result();
 
 % calc_prepare_keymap: undefined  Undocumented
 %  static define calc_prepare_keymap ()
-results = test_function("calc->calc_prepare_keymap");
-test_return_value(results, {});
+test_function("calc->calc_prepare_keymap");
+test_last_result();
 
 % calc_reset_buffer: undefined  Undocumented
 %  public define calc_reset_buffer()
-results = test_function("calc_reset_buffer");
-test_return_value(results, {});
+test_function("calc_reset_buffer");
+test_last_result();
 
 % init_menu: undefined  Undocumented
 %  static define init_menu (menu)
-results = test_function("calc->init_menu");
-test_return_value(results, {});
+test_function("calc->init_menu");
+test_last_result();
 
 % calc_start: undefined  Undocumented
 %  static define calc_start ()
-results = test_function("calc->calc_start");
-test_return_value(results, {});
+test_function("calc->calc_start");
+test_last_result();
 
 % calc_mode_dec: undefined  Undocumented
 %  public define calc_mode_dec()
-results = test_function("calc_mode_dec");
-test_return_value(results, {});
+test_function("calc_mode_dec");
+test_last_result();
 
 % calc_mode_hex: undefined  Undocumented
 %  public define calc_mode_hex()
-results = test_function("calc_mode_hex");
-test_return_value(results, {});
+test_function("calc_mode_hex");
+test_last_result();
 
 % calc_mode_oct: undefined  Undocumented
 %  public define calc_mode_oct()
-results = test_function("calc_mode_oct");
-test_return_value(results, {});
+test_function("calc_mode_oct");
+test_last_result();
 
 % calc_mode_bin: undefined  Undocumented
 %  public define calc_mode_bin()
-results = test_function("calc_mode_bin");
-test_return_value(results, {});
+test_function("calc_mode_bin");
+test_last_result();
 
 % calc_mode_all: undefined  Undocumented
 %  public define calc_mode_all()
-results = test_function("calc_mode_all");
-test_return_value(results, {});
+test_function("calc_mode_all");
+test_last_result();

Modified: jed-extra/trunk/tests/test-console_keys.sl
===================================================================
--- jed-extra/trunk/tests/test-console_keys.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/test-console_keys.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -9,22 +9,22 @@
 
 require("unittest");
 
-variable results;    % list of return value(s)
 
 
-results = test_function("evalfile", "console_keys");
-test_return_value(results, {1});
 
+test_function("evalfile", "console_keys");
+test_last_result(1);
+
 testmessage("\n  console_keys.sl needs interactive testing in a Linux console");
 #stop
 
 % define set_console_keys()
 % set_console_keys: undefined  Undocumented
-results = test_function("set_console_keys");
-test_return_value(results, {});
+test_function("set_console_keys");
+test_last_result();
 
 % define restore_console_keys()
 % restore_console_keys: undefined  Undocumented
-results = test_function("restore_console_keys");
-test_return_value(results, {});
+test_function("restore_console_keys");
+test_last_result();
 

Modified: jed-extra/trunk/tests/test-css1.sl
===================================================================
--- jed-extra/trunk/tests/test-css1.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/test-css1.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -9,20 +9,20 @@
 
 require("unittest");
 
-variable results;    % list of return value(s)
+
 sw2buf("*scratch*");
 
 
 % public define css1_mode() {
 % css1_mode: library function  Undocumented
-results = test_function("css1_mode");
-test_return_value(results, {});
+test_function("css1_mode");
+test_last_result();
 test_equal(get_mode_name(), "css1");
 
 no_mode();
 
 % test the automatic mode setting at loading a file
-results = test_function("find_file", "test.css"); % new file, empty buffer
+test_function("find_file", "test.css"); % new file, empty buffer
 test_equal(get_mode_name(), "css1");
 if (bufferp("test.css"))
   delbuf("test.css");

Modified: jed-extra/trunk/tests/test-dict-cli.sl
===================================================================
--- jed-extra/trunk/tests/test-dict-cli.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/test-dict-cli.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -15,9 +15,6 @@
 require("dict-cli");
 
 % fixture
-private variable results;    % list of return value(s)
-
-
 private variable word = "line";
 private variable host = "dict.org";    % public dict server
 % private variable host = "localhost"; % local dict server
@@ -32,20 +29,20 @@
 
 % define dict_define(word, database, host)
 % dict_define: library function  Undocumented
-results = test_function("dict_define", word, database, host);
-test_return_value(results, {});
+test_function("dict_define", word, database, host);
+test_last_result();
 erase_buffer();
 
 % define dict_match(word, strategy, database, host)
 % dict_match: library function  Undocumented
-results = test_function("dict_match", word, strategy, database, host);
-test_return_value(results, {});
+test_function("dict_match", word, strategy, database, host);
+test_last_result();
 erase_buffer();
 
 % define dict_show(what, host)
 % dict_show: library function  Undocumented
-results = test_function("dict_show", what, host);
-test_return_value(results, {});
+test_function("dict_show", what, host);
+test_last_result();
 erase_buffer();
 
 sw2buf("*test report*");

Modified: jed-extra/trunk/tests/test-dict-curl.sl
===================================================================
--- jed-extra/trunk/tests/test-dict-curl.sl	2007-07-24 19:58:26 UTC (rev 807)
+++ jed-extra/trunk/tests/test-dict-curl.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -14,16 +14,13 @@
 
 require("unittest");
 
-testmessage("at my site, dict-curl crashs ('Speicherzugriffsfehler') Jed" +
-   "Jed Version: 0.99.18, S-Lang Version: 2.0.6, slang-curl 0.1.1-5");
+% testmessage("at my site, dict-curl crashs ('Speicherzugriffsfehler') Jed" +
+%    "Jed Version: 0.99.18, S-Lang Version: 2.0.6, slang-curl 0.1.1-5");
+% throw AssertionError, "() = evalfile(\"dict-curl\"); crashs Jed";
 
-throw AssertionError, "() = evalfile(\"dict-curl\"); crashs Jed";
-
 () = evalfile("dict-curl");
 
 % fixture
-private variable results;    % list of return value(s)
-
 private variable word = "line";
 private variable host = "dict.org";    % public dict server
 % private variable host = "localhost"; % local dict server
@@ -38,20 +35,19 @@
 
 % define dict_define(word, database, host)
 % dict_define: library function  Undocumented
-results = test_function("dict_define", word, database, host);
-test_return_value(results, {});
+test_function("dict_define", word, database, host);test_last_result();
 erase_buffer();
 
 % define dict_match(word, strategy, database, host)
 % dict_match: library function  Undocumented
-results = test_function("dict_match", word, strategy, database, host);
-test_return_value(results, {});
+test_function("dict_match", word, strategy, database, host);
+test_last_result();
 erase_buffer();
 
 % define dict_show(what, host)
 % dict_show: library function  Undocumented
-results = test_function("dict_show", what, host);
-test_return_value(results, {});
+test_function("dict_show", what, host);
+test_last_result();
 erase_buffer();
 
 sw2buf("*test report*");

Added: jed-extra/trunk/tests/test.py
===================================================================
--- jed-extra/trunk/tests/test.py	                        (rev 0)
+++ jed-extra/trunk/tests/test.py	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1 @@
+print 2 + 2

Added: jed-extra/trunk/tests/testreport-jed-extra2.2.txt
===================================================================
--- jed-extra/trunk/tests/testreport-jed-extra2.2.txt	                        (rev 0)
+++ jed-extra/trunk/tests/testreport-jed-extra2.2.txt	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,128 @@
+
+test_files in '/home/milde/.jed/lib' matching '^unit-tests$': testing 1 file 
+test_files in '/home/milde/.jed/lib/unit-tests' matching '\C\<test\>.*.sl$': testing 13 files 
+ garbage on stack: 1
+ ch_table-test.sl: 
+  ch_table->int2string(32, 10):  => ("32") OK
+  ch_table->int2string(32, 16):  => ("20") OK
+  ch_table->int2string(32, 8):  => ("40") OK
+  ch_table->int2string(32, 2):  => ("100000") OK
+  ch_table->string2int("32", 10):  => (32) OK
+  ch_table->string2int("20", 16):  => (32) OK
+  ch_table->string2int("40", 8):  => (32) OK
+  ch_table->string2int("100000", 2):  => (32) OK
+  _ch_table_test->test_ch_table():  OK
+  _ch_table_test->test_ct_down():  OK
+  _ch_table_test->test_ct_insert_and_close():  OK
+  _ch_table_test->test_special_chars():  OK
+ 0 errors
+ csvutils-test.sl:  only basic test, arguments not tested completely
+  _csvutils_test->test_buffer_compress():  OK
+  _csvutils_test->test_compute_columns():  OK
+  _csvutils_test->test_format_table():  OK
+  _csvutils_test->test_get_lines():  OK
+  _csvutils_test->test_get_table():  OK
+  _csvutils_test->test_goto_max_column():  OK
+  _csvutils_test->test_insert_table():  OK
+  _csvutils_test->test_list2table():  OK
+  _csvutils_test->test_max_column():  OK
+  _csvutils_test->test_strchop2d():  OK
+  _csvutils_test->test_strjoin2d():  OK
+ 0 errors
+ cuamark-test.sl: 
+  _cuamark_test->test_cua_copy_region():  OK
+  _cuamark_test->test_cua_insert_clipboard(): 
+  E: ""=="a test line" failed. The teststring should be reinserted
+  _cuamark_test->test_cua_kill_region(): 
+  E: "a test linea test line"=="a test line" failed. yp_yank should reinsert the kill
+  _cuamark_test->test_cua_mark():  OK
+ 
+ 2 errors
+ cuamouse-test.sl: 
+  _cuamouse_test->test_click_in_region():  OK
+  _cuamouse_test->test_click_in_region_after():  OK
+  _cuamouse_test->test_click_in_region_after_eol():  OK
+  _cuamouse_test->test_click_in_region_before():  OK
+  _cuamouse_test->test_click_in_region_no_region():  OK
+  _cuamouse_test->test_copy_region_to_clipboard():  OK
+  _cuamouse_test->test_cuamouse_2click_hook():  => (1) OK
+  _cuamouse_test->test_cuamouse_insert():  => (1) OK
+ 0 errors
+ datutils-test.sl: 
+  list2array(List_Type with 4 elements, Integer_Type):  => (Integer_Type[4]) OK
+  list2array(List_Type with 2 elements, String_Type):  => (String_Type[2]) OK
+  list2array(List_Type with 4 elements):  => (Integer_Type[4]) OK
+  list2array(List_Type with 2 elements):  => (String_Type[2]) OK
+ 0 errors
+ ishell-test.sl: 
+  _ishell_test->test_filter_region():  OK
+  _ishell_test->test_ishell():  OK
+  _ishell_test->test_ishell_mode():  OK
+  _ishell_test->test_shell_cmd_on_region():  OK
+  _ishell_test->test_shell_cmd_on_region_or_buffer():  OK
+  _ishell_test->test_shell_command_0():  OK
+  _ishell_test->test_shell_command_1():  OK
+  _ishell_test->test_shell_command_2():  OK
+  _ishell_test->test_shell_command_3():  OK
+  _ishell_test->test_shell_command_4():  OK
+  _ishell_test->test_shell_command_ignore():  OK
+  _ishell_test->test_shell_command_named_buffer():  OK
+  _ishell_test->test_terminal():  OK
+ 0 errors
+ listing-test.sl: 
+  _listing_test->test_get_confirmation_abort(): E: 'False Assertion' in /home/milde/.jed/lib/unit-tests/listing-test.sl:129 key 'q' should throw UserBreakError 
+  _listing_test->test_get_confirmation_all():  OK
+  _listing_test->test_get_confirmation_no():  OK
+  _listing_test->test_get_confirmation_with_default():  OK
+  _listing_test->test_get_confirmation_wrong_key(): E: 'False Assertion' in /home/milde/.jed/lib/unit-tests/listing-test.sl:144 three wrong keys should throw UserBreakError not Run-Time Error 
+  _listing_test->test_get_confirmation_yes():  OK
+  _listing_test->test_line_is_tagged():  OK
+  _listing_test->test_listing_list_tags():  OK
+  _listing_test->test_listing_list_tags_0():  OK
+  _listing_test->test_listing_list_tags_1_non_tagged():  OK
+  _listing_test->test_listing_list_tags_1_tagged():  OK
+  _listing_test->test_listing_list_tags_2_1():  OK
+  _listing_test->test_listing_list_tags_2_2():  OK
+  _listing_test->test_listing_mode():  OK
+  _listing_test->test_null_fun():  OK
+  _listing_test->test_tag():  OK
+  _listing_test->test_tag_all():  OK
+  _listing_test->test_tag_matching():  OK
+  _listing_test->test_tags_length():  OK
+  _listing_test->test_tags_length_0():  OK
+  _listing_test->test_tags_length_1():  OK
+  _listing_test->test_tags_length_2():  OK
+ 
+ 2 errors
+ test-browse_url.sl: 
+  find_url("http://www.example.org"):  OK
+  view_url("http://www.example.org"):  OK
+  browse_url_x() needs interactive testing,
+  (opens a document in an external browser with system())
+  browse_url() needs interactive testing,
+  (opens a document in an external browser with system())
+ 0 errors
+ test-calc.sl: 
+  calc():  OK
+  calc2():  OK
+ 0 errors
+ test-console_keys.sl: 
+  evalfile("console_keys"):  => (1) OK
+  console_keys.sl needs interactive testing in a Linux console
+ 0 errors
+ test-css1.sl: 
+  css1_mode():  OK
+  find_file("test.css"):  => (0) OK
+ 0 errors
+ test-dict-cli.sl: 
+  dict_define("line", "!", "dict.org"):  OK
+  dict_match("line", ".", "!", "dict.org"):  OK
+  dict_show("db", "dict.org"):  OK
+ 0 errors
+ test-dict-curl.sl: 
+  dict_define("line", "!", "dict.org"):  OK
+  dict_match("line", ".", "!", "dict.org"):  OK
+  dict_show("db", "dict.org"):  OK
+ 0 errors
+13 files, 4 errors 
+1 file, 4 errors 
\ No newline at end of file

Added: jed-extra/trunk/tests/unittesttest.sl
===================================================================
--- jed-extra/trunk/tests/unittesttest.sl	                        (rev 0)
+++ jed-extra/trunk/tests/unittesttest.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,178 @@
+% unittesttest.sl: test the SLang unittest framework
+% 
+% This self-testing is quite verbose and out of line with the remaining unit
+% tests so it deliberately named not to match the "-test"
+% Unittest_File_Pattern.
+% 
+% Copyright (c) 2006 Günter Milde
+% Released under the terms of the GNU General Public License (ver. 2 or later)
+%
+% Versions:
+% 0.1 2006-03-03 
+% 0.3 2006-09-25  * adapted to unittest version 0.3
+%                 * undo Error_Count increase in case of correct behaviour
+%                   of the test functions
+
+require("unittest");
+require("sprint_var");
+
+static variable results, err, a=1, b=3, last_error_count;
+
+
+testmessage("\n\nAssertions");
+% ----------
+
+% here, we put the AssertionError in a try-catch phrase to keep on
+% evaluating the unittest test script
+try (err)
+{
+   if (a != b)
+     throw AssertionError, "$a != $b"$;
+   % this code should not be reached:
+   testmessage("E: AssertionError not thrown ");
+   unittest->Error_Count++;
+}
+catch AssertionError:
+{
+   testmessage("OK: wrong assertion threw AssertionError.");
+}
+
+
+
+testmessage("\n\nTruth and Equality\n");
+% ------------------------------------
+
+testmessage("\ntest_true(): true args must not show in the report");
+test_true(1+1 == 2, "# 1+1 should be 2, test_true failed");
+
+last_error_count = unittest->Error_Count;
+test_true(1+1 == 3);
+if (unittest->Error_Count == last_error_count + 1)
+{
+   testmessage("\n OK: 1+1 == 3 is FALSE, so test_true() works fine");
+   unittest->Error_Count--;
+}
+
+testmessage("\ntest_equal(): this should not show in the report");
+test_equal(1+1, 2, "# test_equal failed: 1+1 should be 2");
+
+last_error_count = unittest->Error_Count;
+test_equal(1+1, 3);
+if (unittest->Error_Count == last_error_count + 1)
+{
+   testmessage("\n OK: 1+1 != 3, so test_equal() works fine");
+   unittest->Error_Count--;
+}
+
+
+testmessage("\n\nStack hygiene\n");
+% -------------------------------
+
+testmessage("\n empty stack, so there should be no response");
+test_stack();
+testmessage("\n now push 2 values on stack");
+42, "baa";
+
+last_error_count = unittest->Error_Count;
+test_stack();
+if (unittest->Error_Count == last_error_count + 1)
+{
+   testmessage("\n OK: garbage on stack detected");
+   unittest->Error_Count--;
+}
+
+testmessage("\n\ntest for exceptions:\n");
+% ----------------------------------------
+
+private define zero_division()
+{
+   return 23/0;
+}
+
+testmessage("\n non defined function:");
+err = test_for_exception("foo");
+testmessage("\n  result: %S %s", typeof(err), sprint_variable(err));
+
+testmessage("\n no exception:");
+err = test_for_exception("what_line");
+testmessage("\n  result: " + sprint_variable(err));
+
+testmessage("\n zero division:");
+err = test_for_exception(&zero_division);
+testmessage("\n  result: " + sprint_error(err));
+
+
+testmessage("\n\nFunction testing:\n");
+% -------------------------------------
+
+testmessage(" working cases");
+test_function("sprintf", "%d", 8);
+test_last_result("8");
+test_function("eval", "3+4");
+test_last_result(7);
+test_function(&bol);
+test_last_result();
+
+testmessage(" catching bugs");
+last_error_count = unittest->Error_Count;
+test_function("sprintf", "%d", 8);
+test_last_result("8");
+if (unittest->Error_Count == last_error_count + 1)
+{
+   testmessage("\n OK: catched wrong return value");
+   unittest->Error_Count--;
+}
+
+last_error_count = unittest->Error_Count;
+test_function("non_defined");
+if (unittest->Error_Count == last_error_count + 1)
+{
+   testmessage("\n OK: catched non defined function");
+   unittest->Error_Count--;
+}
+
+last_error_count = unittest->Error_Count;
+test_function("message", NULL);
+if (unittest->Error_Count == last_error_count + 1)
+{
+   testmessage("\n OK: catched wrong usage");
+   unittest->Error_Count--;
+}
+
+last_error_count = unittest->Error_Count;
+test_function("zero_division");
+if (unittest->Error_Count == last_error_count + 1)
+{
+   testmessage("\n OK: catched buggy function");
+   unittest->Error_Count--;
+}
+
+last_error_count = unittest->Error_Count;
+test_function(&what_line);
+test_last_result();
+if (unittest->Error_Count == last_error_count + 1)
+{
+   testmessage("\n OK: catched unexpected return value");
+   unittest->Error_Count--;
+}
+
+
+testmessage("\n\nRun a test script:\n");
+% ------------------------------------
+
+% () = test_file(path_concat(path_dirname(__FILE__), "datutils-test.sl"));
+% () = test_file("uffe.sl");  % not present
+
+testmessage("\n\nRun a test suite:\n");
+% ------------------------------------
+
+() = test_files("fooli/"); % invalid dir
+() = test_files("/home/milde/.jed/lib/test/*datutils*.sl");
+
+testmessage("\n\nRun a test suite and exit Jed:\n");
+% --------------------------------------------------
+
+testmessage("\n skipped");
+% () = test_files_and_exit("/home/milde/.jed/lib/test/*datutils*.sl");
+
+message("Done");

Added: jed-extra/trunk/tests/utf8helper-autoconvert-test.sl
===================================================================
--- jed-extra/trunk/tests/utf8helper-autoconvert-test.sl	                        (rev 0)
+++ jed-extra/trunk/tests/utf8helper-autoconvert-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,100 @@
+%  utf8helper-test.sl:  Test utf8helper.sl
+% 
+% Copyright (c) 2006 Guenter Milde
+% Released under the terms of the GNU General Public License (ver. 2 or later)
+%
+% Versions:
+% 1.1 2007-06-02 
+
+require("unittest");
+
+% Fixture
+% -------
+
+require("utf8helper");
+
+% testbufs[_slang_utf8_ok] is in active encoding
+private variable   teststrings,
+  testbufs = ["ch_table-lat1-decimal.txt", 
+              "ch_table-utf8-decimal.txt"],
+  base_dir = path_dirname(__FILE__),
+  read_autoconvert = UTF8Helper_Read_Autoconvert,
+  write_autoconvert = UTF8Helper_Write_Autoconvert;
+
+% set the _jed_*_hooks
+UTF8Helper_Read_Autoconvert = 1;
+UTF8Helper_Write_Autoconvert = 1;
+() = evalfile("utf8helper");
+
+
+static define setup()
+{
+   teststrings = array_map(String_Type, 
+      &strread_file, base_dir + "/" + testbufs);
+}
+
+static define teardown()
+{
+   variable buf;
+   foreach buf (testbufs)
+     {
+        !if (bufferp(buf))
+          continue;
+        sw2buf(buf);
+        set_buffer_modified_flag(0);
+        close_buffer();
+     }
+   UTF8Helper_Read_Autoconvert = read_autoconvert;
+   UTF8Helper_Write_Autoconvert = write_autoconvert;
+}
+
+% Test functions
+% --------------
+
+
+static define test_read_autoconvert()
+{
+   % do autoconvert the test buffers:
+   UTF8Helper_Read_Autoconvert = 1;
+
+   % load file in "wrong" encoding
+   () = find_file(base_dir + "/" + testbufs[not(_slang_utf8_ok)]);
+   % should autoconvert:
+   if (_slang_utf8_ok)
+     test_equal(get_blocal("encoding"), "utf8");
+   else
+     test_equal(get_blocal("encoding"), "latin1");
+   mark_buffer();
+   % testbufs[_slang_utf8_ok] is in active encoding
+   test_equal(bufsubstr(), teststrings[_slang_utf8_ok],
+      "should autoconvert to native encoding");
+}
+
+static define test_read_autoconvert_false()
+{
+   % do not autoconvert the test buffers:
+   UTF8Helper_Read_Autoconvert = 0;
+
+   % testbufs[_slang_utf8_ok] is in active encoding
+   % load file in "wrong" encoding
+   () = find_file(base_dir + "/" + testbufs[not(_slang_utf8_ok)]);
+   mark_buffer();
+   test_equal(bufsubstr(), teststrings[not(_slang_utf8_ok)],
+      "should not autoconvert to native encoding");
+}
+
+static define test_read_autoconvert_interactive()
+{
+   % do not autoconvert the test buffers:
+   UTF8Helper_Read_Autoconvert = -1;
+
+   % testbufs[_slang_utf8_ok] is in active encoding
+   % load file in "wrong" encoding
+   () = find_file(base_dir + "/" + testbufs[not(_slang_utf8_ok)]);
+   update_sans_update_hook(1);
+   flush("Press any key to continue");
+   () = getkey();
+   testmessage("\n    buffer encoding is '%S'", get_blocal("encoding"));
+   
+   
+}

Added: jed-extra/trunk/tests/utf8helper-test.sl
===================================================================
--- jed-extra/trunk/tests/utf8helper-test.sl	                        (rev 0)
+++ jed-extra/trunk/tests/utf8helper-test.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,153 @@
+%  utf8helper-test.sl:  Test utf8helper.sl
+% 
+% Copyright (c) 2006 Guenter Milde
+% Released under the terms of the GNU General Public License (ver. 2 or later)
+%
+% Versions:
+% 1.1 2007-06-02 
+
+require("unittest");
+
+% test availability of public functions (comment to skip)
+test_true(is_defined("latin1_to_utf8"), "public fun latin1_to_utf8 undefined");
+test_true(is_defined("utf8_to_latin1"), "public fun utf8_to_latin1 undefined");
+test_true(is_defined("strtrans_latin1_to_utf8"), "public fun strtrans_latin1_to_utf8 undefined");
+test_true(is_defined("strtrans_utf8_to_latin1"), "public fun strtrans_utf8_to_latin1 undefined");
+
+% Fixture
+% -------
+
+require("utf8helper");
+
+% testbufs[_slang_utf8_ok] is in active encoding
+private variable testbufs = ["ch_table-lat1-decimal.txt", 
+                             "ch_table-utf8-decimal.txt"],
+  teststrings = String_Type[length(testbufs)],
+  base_dir = path_dirname(__FILE__);
+
+static define setup()
+{
+   % do not autoconvert the test buffers:
+   UTF8Helper_Read_Autoconvert = 0;
+   
+   variable i=0, buf;
+   foreach buf (testbufs)
+     {
+        % load file
+        () = find_file(base_dir + "/" + buf);
+        % extract teststring
+        mark_buffer();
+        teststrings[i] = bufsubstr();
+        i++;
+     }
+}
+
+static define teardown()
+{
+   variable buf;
+   foreach buf (testbufs)
+     {
+        sw2buf(buf);
+        set_buffer_modified_flag(0);
+        close_buffer();
+     }
+}
+
+% Test functions
+% --------------
+
+% public define latin1_to_utf8()
+static define test_latin1_to_utf8()
+{
+   % transform buffer;
+   sw2buf(testbufs[0]);
+   latin1_to_utf8();
+   test_equal(get_blocal_var("encoding"), "utf8", 
+      "should set blocal var 'encoding'");
+   mark_buffer();
+   variable str = bufsubstr();
+   test_equal(str, teststrings[1]);
+   test_unequal(str, teststrings[0]);
+}
+
+% public define utf8_to_latin1 ()
+static define test_utf8_to_latin1()
+{
+   sw2buf(testbufs[1]);
+   utf8_to_latin1();
+   test_equal(get_blocal_var("encoding"), "latin1",
+      "should set blocal var 'encoding'");
+   mark_buffer();
+   variable str = bufsubstr();
+   test_unequal(str, teststrings[1]);
+   test_equal(str, teststrings[0]);
+}
+
+% public define strtrans_latin1_to_utf8(str)
+static define test_strtrans_latin1_to_utf8()
+{
+   test_unequal(strtrans_latin1_to_utf8(teststrings[0]), teststrings[0]);
+   test_equal(strtrans_latin1_to_utf8(teststrings[0]), teststrings[1]);
+}
+
+% public define strtrans_utf8_to_latin1(str)
+static define test_strtrans_utf8_to_latin1()
+{
+   test_unequal(strtrans_latin1_to_utf8(teststrings[1]), teststrings[1]);
+   test_equal(strtrans_utf8_to_latin1(teststrings[1]), teststrings[0]);
+}
+
+% scan for non-printable characters in current buffer
+% static define has_invalid_chars()
+static define test_has_invalid_chars()
+{
+   sw2buf(testbufs[not(_slang_utf8_ok)]); % testbuffer in other encoding
+   test_true(utf8helper->has_invalid_chars());
+}
+
+static define test_has_invalid_chars_false()
+{
+   sw2buf(testbufs[_slang_utf8_ok]); % testbuffer in active encoding
+   test_equal(0, utf8helper->has_invalid_chars());
+}
+
+#stop 
+
+#if (_slang_utf8_ok)
+
+% define insert_after_char(char)
+static define test_insert_after_char()
+{
+   insert_after_char();
+}
+
+% define stroke() { insert_after_char(0x336); }
+static define test_stroke()
+{
+   stroke();
+}
+
+% define underline() { insert_after_char(0x332); }
+static define test_underline()
+{
+   underline();
+}
+
+% define double_underline() { insert_after_char(0x333); }
+static define test_double_underline()
+{
+   double_underline();
+}
+
+% define overline() { insert_after_char(0x305); }
+static define test_overline()
+{
+   overline();
+}
+
+% define double_overline() { insert_after_char(0x33f); }
+static define test_double_overline()
+{
+   double_overline();
+}
+#endif

Added: jed-extra/trunk/utils/do-unittests.sl
===================================================================
--- jed-extra/trunk/utils/do-unittests.sl	                        (rev 0)
+++ jed-extra/trunk/utils/do-unittests.sl	2007-07-26 14:31:28 UTC (rev 808)
@@ -0,0 +1,21 @@
+% do-unittests.sl: run the unit-tests in the /tests/ subdir
+%  
+%   run the tests with e.g. `jed -n -l ./do-unittests.sl`
+%               
+% Copyright (c) 2006 Günter Milde
+% Released under the terms of the GNU General Public License (ver. 2 or later)
+%
+% Versions:
+% 0.1 2006-03-03  initial try
+
+
+% eval unittest.sl from the extra section
+require("extra/unittest.sl");
+
+% ignore interactive tests
+% 
+% TODO
+
+% test-run the 
+test_files_and_exit("../tests");
+




More information about the Pkg-jed-commit mailing list