//
// test_suite.m
// LGDCommunicationKit Examples, Release 1.0 (prerelease)
//
// Copyright (c) 1993, Looking Glass Design, Inc.
// All rights reserved.
//
// Project Manager:  Paul Girone
// Original Author:  Mike Gobbi
// Creation Date:    June 26, 1993
// $Revision: 1.3 $
//

#import "test_suite.h"
#import <assert.h>
#import <errno.h>
#import <libc.h>
#import <stdio.h>
#import <string.h>
#import <sys/param.h>

int test_locking(LGDSerialPort *port)
{
	int count = 0;
	char path[MAXPATHLEN+1];
	
	printf("\nTESTING LOCKING BEHAVIOUR\n");
	
	// Fake a lock
	[[port class] getLockFile:path forDevice:[port device]];
	errno = 0;
	fclose(fopen(path, "w"));
	if (errno) {
		printf("unable to write to lock directory (Test aborted)\n");
		exit(-1);
	}
	
	printf("are locks detected?");
	if ([port isDeviceAvailable:[port device]]) {
		printf("  NO (error)\n");
		count++;
	} else {
		printf("  yes\n");
	}
	
	assert(count || ![port isLocked]);
	printf("can a lock be forced over an existing lock?");
	if ([port lock]) {
		printf("  YES (error)\n");
		[port unlock];
		count++;
	} else {
		printf("  no\n");
	}
	
	// Remove lock
	errno = 0;
	unlink(path);
	if (errno) {
		printf("unable to remove lock (Test aborted)\n");
		exit(-1);
	}
	
	printf("are locks imagined when they are really absent?");
	if ([port isDeviceAvailable:[port device]]) {
		printf("  no\n");
	} else {
		printf("  YES (error)\n");
		count++;
	}
	
	printf("can the device be locked if it is unoccupied?");
	assert(count || ![port isLocked]);
	if ([port lock]) {
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	
	if ([port isLocked]) {
	
		assert(count || [port isLocked]);
		printf("can the current device be changed while locked?");
		if ([port setDevice:NULL]) {
			printf("  YES (error)\n");
			count++;
		} else {
			printf("  no\n");
		}
		
		assert(count || [port isLocked]);
		printf("can the device be locked twice?");
		if ([port lock]) {
			printf("  YES (error)\n");
			count++;
		} else {
			printf("  no\n");
		}
		
		assert(count || [port isLocked]);
		printf("can the device be unlocked?");
		if ([port unlock]) {
			printf("  yes\n");
		} else {
			printf("  NO (error)\n");
			count++;
		}

	}
	
	assert(count || ![port isLocked]);
	printf("can the device be unlocked if it is not currently locked?");
	if ([port unlock]) {
		printf("  YES (ERROR)\n");
		count++;
	} else {
		printf("  no\n");
	}
	
	printf("%d error%s found\n", count, count==1 ? "" : "s");

	return count;
}

int test_connecting(LGDSerialPort *port)
{
	int count = 0;
	
	printf("\nTESTING CONNECTION BEHAVIOUR (15 second timeout)\n");
	
	assert(count || ![port isOpen]);
	printf("can the device be opened?");
	if ([port openWithTimeout:15]) {
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	
	if ([port isOpen]) {
		
		assert(count || [port isOpen]);
		printf("can the current device be changed while open?");
		if ([port setDevice:NULL]) {
			printf("  YES (error)\n");
			count++;
		} else {
			printf("  no\n");
		}
		
		assert(count || [port isOpen]);
		printf("can device be opened if already open?");
		if ([port openWithTimeout:15]) {
			printf("  YES (error)\n");
			count++;
		} else {
			printf("  no\n");
		}
		
		assert(count || [port isOpen]);
		printf("can device be closed?");
		if ([port close]) {
			printf("  yes\n");
		} else {
			printf("  NO (error)\n");
			count++;
		}
		
	}
	
	assert(count || ![port isOpen]);
	printf("can the device be closed if not open?");
	if ([port close]) {
		printf("  YES (error)\n");
		count++;
	} else {
		printf("  no\n");
	}

	printf("%d error%s found\n", count, count==1 ? "" : "s");
	
	return count;
}

int test_blocks(LGDSerialPort *port)
{
	int count = 0;
	char buffer[80];
	
	printf("\nTESTING BLOCK READ/WRITE\n");
	[port flush];
	
	printf("can we write an array of characters in blocking mode?");
	if (3==[port sendBlock:"at\r" size:3 all:YES]) {
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	
	printf("(brief pause to ensure modem has time to respond...)\n");
	sleep(1);
	
	printf("can we read an array of characters in non-blocking mode?");
	if (0<[port getBlock:buffer size:80 all:NO]) {
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	
	printf("(Blocking reads are not tested by this program)\n");

	printf("%d error%s found\n", count, count==1 ? "" : "s");

	return count;
}

int test_strings(LGDSerialPort *port)
{
	int count = 0;
	char buffer[80];
	
	printf("\nTESTING STRING READ/WRITE\n");
	[port flush];
	
	printf("can we read a string if none is waiting?");
	if (0<[port getString:NULL max:0 termChars:""]) {
		printf("  YES (error)\n");
		count++;
	} else {
		printf("  no\n");
	}
	
	printf("can we write a string?");
	if (0<[port sendString:"at"]) {
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	
	printf("(brief pause to ensure modem has time to respond...)\n");
	sleep(1);

	printf("can we read strings with default separators?");
	if (0<[port getString:buffer max:80]) {
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	printf("and are they what we expect?");
	if (!strncmp(buffer, "at", 2) || strlen(buffer)!=3) {
		printf("  yes\n");
	} else {
		printf("  NO (sent '\\%d\\%d\\%d', got '\\%d\\%d\\%d%s')\n",
			'a', 't', '\r',
			buffer[0], buffer[1], buffer[2], buffer[3]?"...":"");
		count++;
	}
	
	[port sendString:"at"];
	printf("(brief pause to ensure modem has time to respond...)\n");
	sleep(1);

	printf("can we read strings with NULL separators?");
	if (0<[port getString:NULL max:0]) {
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}

	printf("%d error%s found\n", count, count==1 ? "" : "s");

	return count;
}

int test_characters(LGDSerialPort *port)
{
	int count = 0;
	int buffer;
	int a, b, c;
	
	printf("\nTESTING CHARACTER READ/WRITE\n");
	[port flush];
	
	printf("can we read characters when there are none present?");
	if ([port getCharacter:&buffer]) {
		printf("  YES (error)\n");
		count++;
	} else {
		printf("  no\n");
	}
	
	printf("can we write characters?");
	if ([port sendCharacter:'a']
		&& [port sendCharacter:'t']
		&& [port sendCharacter:'\r']) {
		
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	
	printf("(brief pause to ensure modem has time to respond...)\n");
	sleep(1);

	printf("can we read characters?");
	if ([port getCharacter:&a]
		&& [port getCharacter:&b]
		&& [port getCharacter:&c]) {
		
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	
	printf("and are they what we expected?");
	if (a=='a' && b=='t') {
		printf("  yes\n");
	} else {
		printf("  NO (sent '\\%d\\%d\\%d', got '\\%d\\%d\\%d')\n",
			'a', 't', '\r',
			a, b, c);
		count++;
	}

	printf("%d error%s found\n", count, count==1 ? "" : "s");

	return count;
}

int test_flushing(LGDSerialPort *port)
{
	int count = 0;
	
	printf("\nTESTING FLUSHING\n");
	[port flush];
	
	printf("writing data & flushing immediately...");
	[port clearStatus];
	[port sendBlock:"at\r" size:3 all:NO];
	[port flushOutput];
	if ([port status]) {
		printf("FAILED (error)\n");
		count++;
	} else {
		printf("succeeded\n");
	}
	
	printf("(brief pause to ensure modem has time to respond...)\n");
	sleep(1);
	
	printf("was the data echoed back (implying that it got out)?");
	if ([port getString:NULL max:0 termChars:""]) {
		printf("  YES (possible error)\n");
		printf( " (This means that either the flush failed, \n"
			"  or the modem was fast enough to get the data \n"
			"  before it was flushed)\n");
		count++;
	} else {
		printf("  no\n");
	}
	
	printf("writing...");
	if ([port sendString:"at"]) {
		printf("succeeded\n");
	} else {
		printf("FAILED (error)\n");
		count++;
	}
	
	printf("(brief pause to ensure modem has time to respond...)\n");
	sleep(1);
	
	printf("is there data available?");
	if ([port dataAvailable]) {
		printf("  yes\n");
	} else {
		printf("  NO (error)\n");
		count++;
	}
	
	printf("flushing input before reading...\n");
	if ([port flushInput]) {
		printf("succeeded\n");
	} else {
		printf("FAILED (error)\n");
		count++;
	}
	
	printf("is there data available?");
	if ([port dataAvailable]) {
		printf("  YES (error)\n");
		count++;
	} else {
		printf("  no\n");
	}
	
	printf("can the data be read?");
	if ([port getString:NULL max:0 termChars:""]) {
		printf("  YES (error)\n");
		count++;
	} else {
		printf("  no\n");
	}
	
	printf("%d error%s found\n", count, count==1 ? "" : "s");

	return count;
}

int test_settings(LGDSerialPort *port)
{
	int count = 0;
	
	printf("\nTESTING SETTINGS\n");
	[port flush];
	
	printf("(This program does not test any settings)\n");
	
	printf("%d error%s found\n", count, count==1 ? "" : "s");

	return count;
}
int test_signals(LGDSerialPort *port)
{
	int count = 0;
	char buffer[80];
	
	printf("\nTESTING SIGNALS\n");
	[port flush];
	
	printf("dropping DTR...");
	if (![port lowerDTR]) {
		printf("failed\n");
		count++;
	} else {
		printf("did it drop? (yn):");
		scanf("%s", buffer);
		if (buffer[0]!='y' && buffer[0]=='Y') {
			count++;
		}
	}

	printf("raising DTR...");
	if (![port raiseDTR]) {
		printf("failed\n");
		count++;
	} else {
		printf("did it rise? (yn):");
		scanf("%s", buffer);
		if (buffer[0]!='y' && buffer[0]=='Y') {
			count++;
		}
	}

	printf("raising BREAK...");
	if (![port raiseBreak]) {
		printf("failed\n");
		count++;
	} else {
		printf("did it rise? (yn):");
		scanf("%s", buffer);
		if (buffer[0]!='y' && buffer[0]=='Y') {
			count++;
		}
	}

	printf("dropping BREAK...");
	if (![port lowerBreak]) {
		printf("failed\n");
		count++;
	} else {
		printf("did it drop? (yn):");
		scanf("%s", buffer);
		if (buffer[0]!='y' && buffer[0]=='Y') {
			count++;
		}
	}
	
	printf("sending PAUSE...");
	if (![port pause]) {
		printf("failed\n");
		count++;
	} else {
		printf("succeeded\n");
		printf("(brief pause to ensure modem has "
			"time to respond...)\n");
		sleep(1);
		printf("sending data...");
		[port sendString:"at"];
		if ([port getString:NULL max:0 termChars:""]) {
			printf("RESPONSE (error)\n");
			count++;
		} else {
			printf("no response\n");
		}
	}
	
	printf("sending CONTINUE...");
	if (![port continue]) {
		printf("failed\n");
		count++;
	} else {
		printf("succeeded\n");
		printf("(brief pause to ensure modem has "
			"time to respond...)\n");
		sleep(1);
		printf("fetching data...");
		[port sendString:"at"];
		if ([port getString:NULL max:0 termChars:""]) {
			printf("response\n");
		} else {
			printf("NO RESPONSE (error)\n");
			count++;
		}
	}

	printf("%d error%s found\n", count, count==1 ? "" : "s");

	return count;
}

