Include Unit Code at the bottom of your class files

One of the important things in software development is to do unit testing - that is a set of tests the programmer can do on a piece of code to be assured it is most likely working the way one wants it to.

Surprisingly it is rare to find unit test code as part of a source code file. If it is created at all (horror), it is usually tucked away on some developers disk someplace or simply thrown away!

What I have found helpful for myself as well as others working the same code, is to place a comment at the end of the program with the unit test code.

This way at least the people following on will have a something they can cut and paste into a progress client/webspeed script lab that can run the code and see if it behaves as expected.

Here we have a very simple program with it's unit test code. Don't be deceived that because one has a more complicated program unit testing shouldn't be done - if anything it means that more of it needs to be done.

This is a simple object that contains all the routines needed to create an alert object. The users can subscribe to certain types of alerts (report done, script didn't run, security warning, etc.) and be made aware of them when something happens.

(Why don't I just use publish and subscribe? Because often users are on web applications not on the same progress process that threw the alert. In fact, often I have scripts that run and if they have an error it goes into the alert system instead of a simple email message as there is a screen that is used to show alerts.)

Anyhow, on to the point....



class AlertMngr:

  define temp-table AlertResultSet like Alert.
  
  /***********************************************************************/

  method public logical SubscribeAlert
  (input Login as character,
   input AlertType as character):
   
   define variable S as class strings no-undo.
   
   find AlertSubscription exclusive-lock
   where AlertSubscription.Login = Login
   no-error.
   
   if not available AlertSubscription then do:
     
     create AlertSubscription.
     AlertSubscription.Login = Login.
     AlertSubscription.Alerts = "".
     
   end. /* if */
   
   S = new strings().

   AlertSubscription.Alerts = S:AddListUnique(AlertSubscription.Alerts, AlertType, ",").

   delete object S.
   
   return true.
   
  end. /* SubscribeAlert */
  
  /***********************************************************************/
  
  method public logical UnsubscribeAlert
  (input Login as character,
   input AlertName as character):
   
   define variable S as class strings no-undo.
   
   find AlertSubscription exclusive-lock
   where AlertSubscription.Login = Login
   no-error.

   if not available AlertSubscription then return false.
   
   S = new strings().
   AlertSubscription.Alerts = S:DeleteAll(AlertSubscription.Alerts, AlertName, ",").
   delete object S.  
   
   return true.
  
  end. /* UnsubscribeAlert */

  /***********************************************************************/
  
  method public logical SendAlert
  (input AlertName as character,
   input Priority as integer,
   input Msg as character,
   input CreationProgram as character):
  
   create Alert.
   Alert.CreateDate = today.
   Alert.CreateTime = time.
   Alert.Comment = Msg.
   Alert.AlertName = AlertName.
   Alert.Priority = Priority.
   Alert.CreationProgram = CreationProgram.
   
  end. /* SendAlert */

  /***********************************************************************/
  
  method public logical AlertList
  (input Login as character,
   input MaxDate as date,
   output table AlertResultSet):
   
    for each AlertSubscription no-lock
      where AlertSubscription.Login = Login,
      
      each Alert no-lock
        where Alert.CreateDate >= MaxDate
        and can-do (AlertSubscription.Alerts, Alert.AlertName):

        create AlertResultSet.
        buffer-copy Alert to AlertResultSet.
          
    end. /* for each */
   
  end.  /* AlertList */

  /***********************************************************************/
  
  method public logical PurgeAlertsByDate (input ClearDate as date):
  
    for each Alert exclusive-lock
      where Alert.CreateDate <= ClearDate:
    
      delete Alert.
      
    end. /* for each */
    
  end. /* method */
  
  /***********************************************************************/
  
  method public logical ClearAlertSubscription (input Login as character):
  
    find AlertSubscription exclusive-lock
    where AlertSubscription.Login = Login
    no-error.
    
    if available AlertSubscription then do:
      delete AlertSubscription.
      return true.
    end.
    
    return false.
    
  end. /* method */
end.

/* UNIT TESTING CODE

define variable v as class AlertMngr no-undo.
define temp-table t like alert.

v = new AlertMngr().
v:PurgeAlertsByDate(TODAY).
{&OUT} v:SubscribeAlert ("scott", "Alert1").
{&OUT} v:SubscribeAlert ("scott", "Alert2").
{&OUT} v:SubscribeAlert ("scott", "Alert3").
{&OUT} v:UnsubscribeAlert ("scott", "Alert2").
{&OUT} v:UnsubscribeAlert ("scott", "Alert4").

{&OUT} v:SubscribeAlert ("craig", "Alert1").
v:ClearAlertSubscription("craig").

v:SendAlert("alert1", 1, "Test1", "me").
v:SendAlert("alert2", 1, "Test2", "me").
v:SendAlert("alert1", 1, "Test3", "me").
v:SendAlert("alert4", 1, "Test4", "me").

v:AlertList ("scott", today, output table T).

for each T no-lock:
  display T.
end.

delete object v.



*/