REBOL [
	Title:   "Generates Red/System byte! tests"
	Author:  "Peter W A Wood"
	File: 	 %make-integer-auto-test.r
	Version: 0.2.0
	Tabs:	 4
	Rights:  "Copyright (C) 2011-2015 Peter W A Wood. All rights reserved."
	License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt"
]

rand: func [
	"returns a random number between 0 and 255"
	/local i
][
	i: random 256
	i: i - 1
]

;; initialisations 
tests: copy ""                          ;; string to hold generated tests
test-number: 0                          ;; number of the generated test
make-dir %auto-tests/
file-out: %auto-tests/byte-auto-test.reds

;; create a block of values to be used in the binary ops tests
test-values: [
	#"^(00)"					; zero
	#"^(FF)"					; max
	#"^(01)"
	#"^(02)"
	#"^(03)"
	#"^(05)"
	#"^(F0)"
	#"^(FD)"
	#"^(FE)"
]
loop 3 [append test-values to char! rand]

;; function to format a char as a #"^(xx)"
hex-char: func [
	c [char!]
	/local 
		i  ;; issue
][
	i: to-hex to integer! c
	to string! reduce [ {#"^^(} i/7 i/8 {)"}]
]

;; create blocks of operators to be applied
test-binary-ops: [
	+
	-
	*
	/
	//
	or
	xor
	and
]

test-no-zeroes: [         ;; zero not allowed as operand2
	/ 
	//
]

test-comparison-ops: [
	=
	<>
	<
	>
	>=
	=<
]

test-comparison-values: [
	-1
	0
	+1
]

;; create test file with header
append tests "Red/System [^(0A)"
append tests {  Title:   "Red/System auto-generated byte! tests"^(0A)}
append tests {	Author:  "Peter W A Wood"^(0A)}
append tests {  File: 	 %byte-auto-test.reds^(0A)}
append tests {  License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"^(0A)}
append tests "]^(0A)^(0A)"
append tests join ";make-length:" 
			[length? read %make-byte-auto-test.r "^(0A)^(0A)"]
append tests "^(0A)^(0A)comment {"
append tests "  This file is generated by make-byte-auto-test.r^(0A)"
append tests "  Do not edit this file directly.^(0A)"
append tests "}^(0A)^(0A)"
append tests "#include %../../../../../quick-test/quick-test.reds^(0A)^(0A)"
append tests {~~~start-file~~~ "Auto-generated tests for bytes"^(0A)^(0A)}
append tests {===start-group=== "Auto-generated tests for bytes"^(0A)^(0A)}

write file-out tests
tests: copy ""

;; binary operator tests - in global context
foreach op test-binary-ops [
	foreach operand1 test-values [
		foreach operand2 test-values [
			;; only write a test if REBOL produces a result
			if attempt [expected: do reduce [operand1 op operand2]][

				;; don't write tests for certain ops with zero second operand
				if not all [
					operand2 = 0
					find test-no-zeroes op 
				][
					expected: to char! expected
					;; test with literal values
					test-number: test-number + 1
					append tests join {  --test-- "byte-auto-} [test-number {"^(0A)}]
					append tests "  --assert "
					append tests reform [hex-char expected " = (" hex-char operand1 op hex-char operand2 ")^(0A)"]
                	
					;; test with variables
					test-number: test-number + 1
					append tests join {  --test-- "byte-auto-} [test-number {"^(0A)}]
					append tests join "      ba-b1: " [hex-char operand1 "^(0A)"]
					append tests join "      ba-b2: " [hex-char operand2 "^(0A)"]
					append tests rejoin ["      ba-b3:  ba-b1 " op " ba-b2^(0A)"]
					append tests "  --assert "
					append tests reform [hex-char expected " = ba-b3 ^(0A)"]
                	
					;; test with "complex expression"
					test-number: test-number + 1
					expected: expected + #"a"
					append tests join {  --test-- "byte-auto-} [test-number {"^(0A)}]
					append tests "  --assert "
					append tests reform [hex-char expected { = ( #"a" + (} hex-char operand1 op hex-char operand2 "))^(0A)"]
                	
					;; write tests to file
					write/append file-out tests
					tests: copy ""
				]
			]
		recycle
		]
	]
]

;; comparison tests
foreach op test-comparison-ops [
	foreach operand1 test-values [
		foreach operand2 test-comparison-values [
			;; only write a test if REBOL produces a result
			if all [
				attempt [operand2: operand1 + operand2]
				none <> attempt [expected: do reduce [operand1 op operand2]]
			][
				test-number: test-number + 1
				append tests join {  --test-- "byte-auto-} [test-number {"^(0A)}]
				append tests "  --assert "
				append tests reform [expected " = (" hex-char operand1 op hex-char operand2 ")^(0A)"]

				;; write tests to file
				write/append file-out tests
				tests: copy ""
			]
		]
	]
]

;; write file epilog
append tests "^(0A)===end-group===^(0A)^(0A)"
append tests {~~~end-file~~~^(0A)^(0A)}

write/append file-out tests
      
print ["Number of assertions generated" test-number]
