Archive for the ‘feature request’ Category
testing, states, comparison
Repeatable test means that you can build up the _same_ starting state and run the _same_ test cases with the _same_ test tools configured the _same_ way. Even if you have random simulations, you should be able to reset the random seed.
It can happen that you cannot use the same starting state in your project, because it is around a terabyte (a database containing transactions and their history). You can’t step twice into the same database : ) Some sort of justification can be that this big state is an aggregate state. So a given test case depends only on its close environment. In this case though, the locality of these environments should be documented.
It can happen that the schema of the database changes and because of this, some of the numerous test cases are modified during the regression tests. But not all the ones that depend on the old schema (or on the schema in general). Years later nobody knows what the hell is going on when testing with those old cases. Either about the way they should be fixed.
By the way, don’t represent the cases in MS Access databases. In case you want to understand the evolution of a test case (e.g. along with the evolution of the database schema) by looking through the versioned history of their representation, that’s quite time consuming because there aren’t any good tools to diff MS Access databases.
I’m not sure though, that teaching people comparable textual representations worth it in contrast to not comparable wysiwyg editor based information forms. A solution can be a wysiwyg solution with predictable and _not_ verbose export functionality. For example pg_dump and pgadmin as GUI:
% pg_dump -s | grep -v ^-- > dbscm1.sql % psql -q => create table zfoo (a serial primary key, c numeric check (c > 0)); NOTICE: CREATE TABLE will create implicit sequence "zfoo_a_seq" for "serial" column "zfoo.a" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "zfoo_pkey" for table "zfoo" => \q % pg_dump -s | grep -v ^-- > dbscm2.sql % diff dbscm1.sql dbscm2.sql 270a271,278 > CREATE TABLE zfoo ( > a serial NOT NULL, > c numeric, > CONSTRAINT zfoo_c CHECK ((c > (0)::numeric)) > ); > > > 340a349,353 > ALTER TABLE ONLY zfoo > ADD CONSTRAINT zfoo_pkey PRIMARY KEY (a); > > > %
common lisp GUI-application shipment&delivery on windows
First of all, here’s the lisp I’ve used:
% clisp --version | grep -v ^Machine GNU CLISP 2.48 (2009-07-28) (built on stnt067 [192.168.0.1]) Software: GNU C 3.4.5 (mingw-vista special r3) gcc -mno-cygwin -O2 -W -Wswitch -Wcomment -Wpointer-arith -Wimplicit -Wreturn-ty pe -Wmissing-declarations -Wno-sign-compare -Wno-format-nonliteral -O2 -fexpensi ve-optimizations -falign-functions=4 -D_WIN32 -DUNICODE -DDYNAMIC_FFI -I. -lint l -lreadline -ltermcap -lavcall -lcallback -luser32 -lws2_32 -lole32 -loleaut32 -luuid -liconv -lsigsegv SAFETY=0 HEAPCODES STANDARD_HEAPCODES GENERATIONAL_GC SPVW_BLOCKS SPVW_MIXED TRI VIALMAP_MEMORY libsigsegv 2.6 libiconv 1.11 libreadline 5.2 Features: (READLINE REGEXP SYSCALLS I18N LOOP COMPILER CLOS MOP CLISP ANSI-CL COMMON-LISP LISP=CL INTERPRETER SOCKETS GENERIC-STREAMS LOGICAL-PATHNAMES SCREEN FFI GETTEXT UNICODE BASE-CHAR=CHARACTER PC386 WIN32) C Modules: (clisp i18n syscalls regexp readline) Installation directory: C:\Program Files\clisp-2.48\ User language: ENGLISH %
I have also MingW (5.1.6) and MSYS (1.0.1) installed, Witchs Hat icon downloaded, CLisp dlls copied from the base subdirectory under the installation path. This is the development tree in clean form:
% find . ./bootstrapper.cc ./bootstrapper.rc ./clisp-dlls ./clisp-dlls/libiconv-2.dll ./clisp-dlls/libintl-8.dll ./clisp-dlls/readline5.dll ./Makefile ./message.lisp ./witchs-hat.ico %
Under clisp-dlls, there are the mentioned dlls of CLisp. The file message.lisp contains the program you’d like to run (or ship or whatever). Finally, the bootstrapper files are up to provide an exe with company info, icon, copyright, etc. as an entry to the lisp program. The important bit here is that you don’t want a command prompt window popping up before startup.
Let’s see the files:
% cat message.lisp
(use-package "FFI")
(def-call-out messagebox
(:name "MessageBoxA") (:library "user32.dll")
(:arguments (hwnd int) (text c-string) (capt c-string) (type uint))
(:return-type int)
(:language :stdc))
(defun main ()
(messagebox 0 "Your hacking starts... NOW!" "Demo MsgBox" 0)
(quit))
% cat -A Makefile
all:^Imsgbox-app.exe msgbox-app.img$
^Imkdir -p shipment$
^Icp msgbox-app.exe shipment$
^Icp msgbox-app.img shipment$
^Icp clisp-dlls/* shipment$
$
msgbox-app.img:^Imsgbox-app.img.exe$
^Icp $< $@$
$
msgbox-app.img.exe:^Imessage.lisp$
^Iclisp -q -norc -x \$
"(load \"message.lisp\") \$
(ext:saveinitmem #P\"./msgbox-app.img.exe\" \$
:executable t \$
:norc t \$
:init-function #'main)"$
$
bootstrapper.res:^Ibootstrapper.rc witchs-hat.ico$
^Iwindres $< -O coff -o $@$
^I$
msgbox-app.exe:^Ibootstrapper.cc bootstrapper.res$
^Ig++ -mwindows $^ -o $@$
$
clean:$
^Irm -rf msgbox-app.exe bootstrapper.res \$
^Imsgbox-app.img msgbox-app.img.exe shipment$
% cat bootstrapper.rc
ID ICON "witchs-hat.ico"
1 VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904E4"
BEGIN
VALUE "CompanyName", "MsgBox Products"
VALUE "FileDescription", "Demo MsgBox"
VALUE "FileVersion", "1.0"
VALUE "InternalName", "msgbox-app"
VALUE "LegalCopyright", "Grault"
VALUE "OriginalFilename", "msgbox-app.exe"
VALUE "ProductName", "Demo MsgBox"
VALUE "ProductVersion", "1.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1252
END
END
% cat bootstrapper.cc
#include <windows.h>
int WinMain(HINSTANCE a0, HINSTANCE a1, LPSTR a2, int a3)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
CreateProcess("msgbox-app.img", "",
NULL,NULL,TRUE,CREATE_NO_WINDOW,NULL,
NULL,&si,&pi);
// version and company details are in the bootstrapper exe
// it's kinda better to show these e.g. in process explorer
// and image file as a subprocess
// feel free to comment the following line to leave img only
WaitForSingleObject(pi.hProcess, INFINITE);
return 0;
}
%
These are the files, and here are the results of a make:
% make
windres bootstrapper.rc -O coff -o bootstrapper.res
g++ -mwindows bootstrapper.cc bootstrapper.res -o msgbox-app.exe
clisp -q -norc -x \
"(load \"message.lisp\") \
(ext:saveinitmem #P\"./msgbox-app.img.exe\" \
:executable t \
:norc t \
:init-function #'main)"
;; Loading file message.lisp ...
;; Loaded file message.lisp
T
;; Wrote the memory image into .\msgbox-app.img.exe (5,088,157 bytes)
Bytes permanently allocated: 92,512
Bytes currently in use: 2,188,704
Bytes available until next GC: 544,546
2188704 ;
544546 ;
92512 ;
1 ;
52160 ;
156001
cp msgbox-app.img.exe msgbox-app.img
mkdir -p shipment
cp msgbox-app.exe shipment
cp msgbox-app.img shipment
cp clisp-dlls/* shipment
% find
.
./bootstrapper.cc
./bootstrapper.rc
./bootstrapper.res
./clisp-dlls
./clisp-dlls/libiconv-2.dll
./clisp-dlls/libintl-8.dll
./clisp-dlls/readline5.dll
./Makefile
./message.lisp
./msgbox-app.exe
./msgbox-app.img
./msgbox-app.img.exe
./shipment
./shipment/libiconv-2.dll
./shipment/libintl-8.dll
./shipment/msgbox-app.exe
./shipment/msgbox-app.img
./shipment/readline5.dll
./witchs-hat.ico
Here’s a picture how this all looks like on a Windows Server 2003 Standard Edition without any kind of lisp installed. And the entries in Process Explorer.
Obviously one can develop a much more sophisticated bootstrapper. This one represents only the possibility of releasing software written in Lisp. Assembling these output files together into an installer could be the next step : ))
And finally, you can get either the binaries or the source files by sending a mail to:
% echo gra.rtebsrpehbf.ferfh@gyhnet | rev | tr '[a-z]' '[n-za-m]'
manipulate k-th column in file with sed & friends
$ echo $0 bash $
Which means that all the stuff below holds at least when using Bash. One of the important features in it is “Process Substitution”. Not so efficient (due to extra bash processes spawned), but I just don’t care at the moment..
The first use case is to manipulate the k-th column of a file. Let’s see our test file:
$ cat -A if1.txt a^Ib^Ic^Id^Ie^If^Ig^Ih$ b^Ic^Id^Ie^If^Ig^Ih^Ia$ c^Id^Ie^If^Ig^Ih^Ia^Ib$ d^Ie^If^Ig^Ih^Ia^Ib^Ic$ e^If^Ig^Ih^Ia^Ib^Ic^Id$ f^Ig^Ih^Ia^Ib^Ic^Id^Ie$ g^Ih^Ia^Ib^Ic^Id^Ie^If$ h^Ia^Ib^Ic^Id^Ie^If^Ig$ $ cat if1.txt a b c d e f g h b c d e f g h a c d e f g h a b d e f g h a b c e f g h a b c d f g h a b c d e g h a b c d e f h a b c d e f g $
The problem is to search and replace with sed, but only in a given column.
The first solution is done by using paste, cut.
$ paste <(cut -f-4 if1.txt) <(cut -f5 if1.txt | sed 's/h/x/g') <(cut -f6- if1.txt) a b c d e f g h b c d e f g h a c d e f g h a b d e f g x a b c e f g h a b c d f g h a b c d e g h a b c d e f h a b c d e f g $
The second one uses the bash language and its read command which is able to fill an array with values read from a line.
$ cat if1.txt | while read -a line; do
> line[4]=$(echo ${line[4]} | sed 's/h/x/')
> echo -e ${line[*]} | sed 's/\ /\t/g'
> done
a b c d e f g h
b c d e f g h a
c d e f g h a b
d e f g x a b c
e f g h a b c d
f g h a b c d e
g h a b c d e f
h a b c d e f g
$
Note that this multiline command can be written into a single line as well (obviously by removing the secondary prompt characters).
Now what if you want to do computations based on other columns. Here’s the same approach for this (removing 2nd and 4th columns and introducing a new 3rd one which should be the sum of the two deleted ones):
$ cat -A if2.txt
a^I1^Id^I2$
b^I3^Ie^I4$
c^I5^If^I6$
$ cat if2.txt
a 1 d 2
b 3 e 4
c 5 f 6
$ paste <(cut -f1,3 if2.txt) <(cut -f2,4 if2.txt | sed 's/$/ + p/' | dc)
a d 3
b e 7
c f 11
$ cat if2.txt | while read -a line; do
> echo -e ${line[0]}\\t${line[2]}\\t$(echo ${line[1]} ${line[3]} + p | dc)
> done
a d 3
b e 7
c f 11
$
use cases in calendar programs
1. Normal todo type entry. E.g. mail a contract to someone. Not recurrent in any sense. It’s good to know how much time spent between the registration and the check.
2. Calendar type entry. E.g. there’s a recurrent event you plan to participate on. You don’t have impact on scheduling that event. Good to track whether you were there or not. This should contain exact time.
3. My special type 1. E.g. you want to wash your car every two weeks. Therefore, in case of success a new entry should be inserted with the same content but date. That should be two weeks after completion. Good to know the distance between planned & real execution.
4. My special type 2. The same as before, except the next entry should be two weeks after planned date.
5. My special type 3 aka Moving type. E.g. you want to read a book with 12 chapters. 1 chapter every week. Kinda special type 4, but with changing labels.
statistics in calendar programs
One of my most wanted features in calendar programs looks like as follows. Ability to design recurrent events with the possibility to show whether it was successful or not. Later show statistics on the ratio of successful planned events. For example Outlook’s calendar program allows to design recurrent events but without a check sign. Outlook’s tasks facility provides a check box when recurrent task is designed but without the ability to skip elements. One have to check the previous to gain access to following items. Events have only date field, there’s no time definition.
