@ -7,24 +7,59 @@
( in-suite all-tests )
( in-suite all-tests )
;; These two examples show the 'full' call to the fiveAm test
;;; HAD TO REVERT BACK TO FULL PACKAGE NAMES
;; functions. This is just for reference. The 'namespace' is already
;;; ========================================
;; 'imported' in 'package.lisp'.
;; (fiveam:test sum-1
;;; BELOW EXPLAINS HOW YOU CAN OMIT PACKAGE NAMES FROM FUNCTION
;; (fiveam:is (= 3 (+ 1 2))))
;;; CALLS. BUT, I'VE ADDED THE 'RATIFY' PACKAGE SINCE THEN AND I WAS
;;; GETTING NAMING CONFLICTS (WITH 'TEST'). SO, I'VE HAD TO USE THE
;;; FULL 'FIVEAM:TEST' FUNCTION CALLS. I'VE KEPT THE NOT FOR FUTURE
;;; REFERENCE AND ADDED THIS AS EXTRA CONTEXT FOR WHEN/HOW TO OMIT
;;; PACKAGE NAMES.
;; (fiveam:run!)
;;; THIS BIT KINDA OUT-OF-DATE...
;; How you would normally create the tests -- with fiveAM already
;;; These two examples show the 'full' call to the fiveAm test
;; set-up in 'package.lisp' and not needing to be explicit about it
;;; functions. This is just for reference. The 'namespace' is already
;; here. This is similar to 'using static' in C#.
;;; 'imported' in 'package.lisp'.
;;; (fiveam:test sum-1
;;; (fiveam:is (= 3 (+ 1 2))))
;;; (fiveam:run!)
;;; How you would normally create the tests -- with fiveAM already
;;; set-up in 'package.lisp' and not needing to be explicit about it
;;; here. This is similar to 'using static' in C#.
( defun test-quasi ( )
( defun test-quasi ( )
( run! 'all-tests ) )
( run! 'all-tests ) )
( test factory-1-light-reading-data
;;; REST API Used Here is Temporary
:description "Validates the (reading) data produced by `FACTORY1'."
;;; ===============================
;;; This REST API is a temporary one -- it's part of an artwork for
;;; the Return to Ritherdon project. The intention is to retire the
;;; API when the exhibition ends. So, these tests might fail because
;;; the API is no longer active.
;;; DEVICE STATUS TESTS
;;; ===================
;;; These tests are checking the 'shape' of the data returned by the
;;; HTTP (REST) request matches what is expected. These tests are
;;; expecting JSON data which looks similar to:
;;; ((:ID . 79) (:STATUS . "off") (:TIME . "2021-07-01T16:00:001")).
;;; ID: The row Id. in the database.
;;; STATUS: The current power state of the device (I.E. on or off).
;;; TIME: The timestamp when the status was recorded.
;;; Usually, these updates are logged when each device is either just
;;; finished powering up or as they are about to power down.
( fiveam:test factory-1-light-status-data
:description "Validates the (status) data produced by `FACTORY1'."
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/1" ) ) )
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/1" ) ) )
;; Data should look something like:
;; Data should look something like:
;; ((:ID . 79) (:STATUS . "off") (:TIME . "2021-07-01T16:00:001")).
;; ((:ID . 79) (:STATUS . "off") (:TIME . "2021-07-01T16:00:001")).
@ -33,14 +68,14 @@
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; :id number
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; row :id number
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
( test factory-2-light-reading -data
( fiveam:test factory-2-light-status -data
:description "Validates the (reading ) data produced by `FACTORY2'."
:description "Validates the (status ) data produced by `FACTORY2'."
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/2" ) ) )
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/2" ) ) )
;; Data should look something like:
;; Data should look something like:
;; ((:ID . 79) (:STATUS . "off") (:TIME . "2021-07-01T16:00:001")).
;; ((:ID . 79) (:STATUS . "off") (:TIME . "2021-07-01T16:00:001")).
@ -49,14 +84,14 @@
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; :id number
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; row :id number
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
( test factory-3-light-reading -data
( fiveam:test factory-3-light-status -data
:description "Validates the (reading ) data produced by `FACTORY3'."
:description "Validates the (status ) data produced by `FACTORY3'."
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/3" ) ) )
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/3" ) ) )
;; Ritherdon has a third welding booth but it was not included in
;; Ritherdon has a third welding booth but it was not included in
;; the art project so no light sensor was installed. Therefore,
;; the art project so no light sensor was installed. Therefore,
@ -69,8 +104,138 @@
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; :id number
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; row :id number
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
( fiveam:test gallery-1-status-data
:description "Validates the (status) data produced by `GALLERY1'."
;; Data should still take the same shape as others:
;; ((:ID . 1) (:STATUS . "off") (:TIME . "2021-04-26T20:42:19.400868"))
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/4" ) ) )
( is ( = 3 ( length data ) ) )
( is ( equal t ( consp data ) ) )
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; row :id number
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
( fiveam:test gallery-2-status-data
:description "Validates the (status) data produced by `GALLERY2'."
;; Data should still take the same shape as others:
;; ((:ID . 1) (:STATUS . "off") (:TIME . "2021-04-26T20:42:19.400868"))
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/5" ) ) )
( is ( = 3 ( length data ) ) )
( is ( equal t ( consp data ) ) )
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; row :id number
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
( fiveam:test gallery-3-status-data
:description "Validates the (status) data produced by `GALLERY3'."
;; This corresponds to 'factory3' -- no light sensor in welding
;; booth 3 in Ritherdon. Therefore, no data to send. Because of
;; this, the data returned here should be the 'seed data' unless
;; I've manually updated it as part of another test.
;; Data should still take the same shape as others:
;; ((:ID . 1) (:STATUS . "off") (:TIME . "2021-04-26T20:42:19.400868")).
( let ( ( data ( ritherdon-rest:parse-request "/status/latest/6" ) ) )
( is ( = 3 ( length data ) ) )
( is ( equal t ( consp data ) ) )
( is ( equal ' :id ( first ( nth 0 data ) ) ) )
( is ( equal ' :status ( first ( nth 1 data ) ) ) )
( is ( equal ' :time ( first ( nth 2 data ) ) ) )
( is ( equal t ( typep ( cdr ( car data ) ) 'integer ) ) ) ; row :id number
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( > ( cdr ( car data ) ) 0 ) )
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( typep ( cdr ( car ( cdr data ) ) ) 'string ) ) ) ; :status value
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( is ( equal t ( or ( string-equal ( cdr ( car ( cdr data ) ) ) "off" )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
( string-equal ( cdr ( car ( cdr data ) ) ) "on" ) ) ) ) ) )
;;; LIGHT READINGS TESTS
;;; ====================
;;; Theses tests check the 'shape' of the light meter readings
;;; returned by the HTTP (REST) requests. They make sure the data
;;; matches what's expected. These tests are expecting JSON data along
;;; the lines of:
;;; ((:ID . 1855109) (:READING . 16) (:TIME . "2021-07-02T13:42:16"))
;;; ID: The row Id. in the database.
;;; READING: The amount of light recorded.
;;; TIME: The timestamp when the reading was taken.
;;; Because of how the light meters work, they do not always take
;;; light meter readings at consistent intervals. But, both devices
;;; aim to take a reading for as long as they are on. Also, Ritherdon
;;; has three welding booths and the system has the capacity to record
;;; all three booths. The Return to Ritherdon project decided on only
;;; recording two of the booths so 'factory3' should only return it
;;; seed data -- unless I've manually updated it (for another test
;;; most likely).
( fiveam:test factory-1-reading-data ; Had to add fiveam here because
; of naming conflict with ratify
; package. Comment at top of file
; explaining further.
:description "Validates the (light reading) data produced by `FACTORY1'."
;; ((:ID . 1855109) (:READING . 16) (:TIME . "2021-07-02T13:42:16"))
( let ( ( data ( ritherdon-rest:parse-request "/readings/latest/1" ) ) )
( is-true ( = 3 ( length data ) ) )
( is-true ( consp data ) )
( is ( equal ' :id ( caar data ) ) )
( is ( equal ' :reading ( caadr data ) ) )
( is ( equal ' :time ( caaddr data ) ) )
( is-true ( > ( cdar data ) 0 ) ) ; Db Id numbers start at 0.
( is-true ( typep ( cdadr data ) 'integer ) ) ; reading can be <=> 0.
;; Returns the date-time if data could be parsed. Returns `NIL' if
;; it could not. Don't need to check if string. If system can't
;; parse it doesn't matter what form the date-time is in.
( is-false ( equal ( ratify:datetime-p ( cdaddr data ) ) nil ) ) ) ) ; time value.
( fiveam:test factory-2-reading-data
:description "Validates the (light reading) data produced by `FACTORY2'."
;; ((:ID . 1855109) (:READING . 16) (:TIME . "2021-07-02T13:42:16"))
( let ( ( data ( ritherdon-rest:parse-request "/readings/latest/2" ) ) )
( is-true ( = 3 ( length data ) ) )
( is-true ( consp data ) )
( is ( equal ' :id ( caar data ) ) )
( is ( equal ' :reading ( caadr data ) ) )
( is ( equal ' :time ( caaddr data ) ) )
( is-true ( > ( cdar data ) 0 ) ) ; Db Id numbers start at 0.
( is-true ( typep ( cdadr data ) 'integer ) ) ; reading can be <=> 0.
;; Returns the date-time if data could be parsed. Returns `NIL' if
;; it could not. Don't need to check if string. If system can't
;; parse it doesn't matter what form the date-time is in.
( is-false ( equal ( ratify:datetime-p ( cdaddr data ) ) nil ) ) ) ) ; time value.
( fiveam:test factory-3-reading-data
:description "Validates the (light reading) data produced by `FACTORY3'."
;; ((:ID . 1855109) (:READING . 16) (:TIME . "2021-07-02T13:42:16"))
( let ( ( data ( ritherdon-rest:parse-request "/readings/latest/3" ) ) )
( is-true ( = 3 ( length data ) ) )
( is-true ( consp data ) )
( is ( equal ' :id ( caar data ) ) )
( is ( equal ' :reading ( caadr data ) ) )
( is ( equal ' :time ( caaddr data ) ) )
( is-true ( > ( cdar data ) 0 ) ) ; Db Id numbers start at 0.
( is-true ( typep ( cdadr data ) 'integer ) ) ; reading can be <=> 0.
;; This device is not active so the seed data should be
;; returned. This data should not be produce `NIL' when Ratify
;; tries to parse it (not a valid timestamp). If the timestamp can
;; be parsed it most likely means I've updated the latest reading
;; data (manually most likely) which should result in this failing
;; because Ratify will return the parsed timestamp and not `NIL'.
( is ( equal ( ratify:datetime-p ( cdaddr data ) ) nil ) ) ) ) ; time value.