Forum Discussion

cvback66's avatar
cvback66
New Contributor
2 years ago

Groovy Script Library - Problem creating class from working script

I am making a class in a Groovy Script Library. 

The original script which works fine:

random = new Random()
Date randomDate(Range<Date> range) {
def res = range.from + random.nextInt(range.to - range.from + 1)
}
def start = Date.parse('yyyy-MM-dd', '2015-01-01')
def end = Date.parse('yyyy-MM-dd', '2017-12-31')
log.info randomDate(start..end).format('yyyy-MM-dd')

 

The class:

class DOB {
String dob (){
random = new Random()
Date randomDate(Range<Date> range) {
def res = range.from + random.nextInt(range.to - range.from + 1)
}
def start = Date.parse('yyyy-MM-dd', '2015-01-01')
def end = Date.parse('yyyy-MM-dd', '2017-12-31')
log.info randomDate(start..end).format('yyyy-MM-dd')
}
}

 

When I import the class in a Groovy script, I get the following error.

Mon May 16 13:46:49 CDT 2022: ERROR: BUG! exception in phase 'semantic analysis' in source unit 'Script26.groovy' The lookup for DOB caused a failed compilation. There should not have been any compilation from this call.

 

From the Error Log:

C:\Program Files\SmartBear\bin\DOB.groovy: 6: Method definition not expected here @ line 6, column 3.
Date randomDate(Range<Date> range) {

 

Is this due some variation in how SmartBear supports Groovy in the script library files?

3 Replies

  • ChrisAdams's avatar
    ChrisAdams
    Champion Level 2

    Hi,

     

    The code for your class had some bugs in it.

    Below is a simple implementation of a class that achieves what you want...

     

    package groovyScripts.play;  // Change this to your package name.
    
    class DOB {
    
        //Define our range.
        def start = Date.parse('yyyy-MM-dd', '2015-01-01')
        def end = Date.parse('yyyy-MM-dd', '2017-12-31')
        def random = new Random();
    
        def DOB() {
            // Constructor for the object.
            // nothing to do here, but constructors are useful for one-time set up tasks.
    
        }
    
    
        Date randomDate() {
            // This is the method we will call to get a random date.
            Range<Date> range = (this.start..this.end);
    	def res = range.from + random.nextInt(range.to - range.from + 1)
    
            return res;
        }
    
    }

     

     

    Then, in your groovy script, you can create the object and call the mehtod...

     

    def dobObject = new groovyScripts.play.DOB();  // remember to update the package
    
    log.info(dobObject.randomDate());

     

     

    Here's a more refined example of the class, which uses the constructor to set-up the object..

     

    package groovyScripts.play;
    
    class DOB {
    
        //Define our properties.
        def start = null;
        def end = null;
        def random = null;
        Range<Date> range = null;
    
        def DOB() {
            // Constructor for the object.
            // Let's set up what we can up front.
            this.start = Date.parse('yyyy-MM-dd', '2015-01-01')
            this.end = Date.parse('yyyy-MM-dd', '2017-12-31')
            this.random = new Random();       
            this.range = (this.start..this.end);
        }
    
    
        Date randomDate() {
    
    	    def res = this.range.from + this.random.nextInt(this.range.to - this.range.from + 1)
    
            return res;
        }
    
    }

     

     

    You can even 'overload' the constructor so that you can pass in the range, should you want to override the defaults....

    Here's the updated class...

     

    package groovyScripts.play;
    
    class DOB {
    
        //Define our range.
        def start = null;
        def end = null;
        def random = null;
        Range<Date> range = null;
    
        def DOB() {
            // Constructor for the object.
            // Let's set up what we can up front.
            this.start = Date.parse('yyyy-MM-dd', '2015-01-01')
            this.end = Date.parse('yyyy-MM-dd', '2017-12-31')
            this.random = new Random();       
            this.range = (this.start..this.end);
        }
    
        def DOB(start, end) {
            // Overloaded Constructor for the object.
            // Let's set up the object with passed in values.
            this.start = Date.parse('yyyy-MM-dd', start);
            this.end = Date.parse('yyyy-MM-dd', end);
            this.random = new Random();       
            this.range = (this.start..this.end);
        }
    
        Date randomDate() {
    
    	    def res = this.range.from + this.random.nextInt(this.range.to - this.range.from + 1)
    
            return res;
        }
    
    }

     

     

    Usage example....

     

    // Use the defaults in the class....
    def dobObject = new groovyScripts.play.DOB();
    log.info(dobObject.randomDate());
    
    // Let's override the defaults....
    def dobObject2 = new groovyScripts.az.play.DOB('1990-01-01',  '1990-12-31');
    log.info(dobObject2.randomDate());

     

     

    • cvback66's avatar
      cvback66
      New Contributor

      Thanks, Chris.

      I could not get past the errors with your solutions but they did inspire me to rethink my approach and to simplify.  I end up with:

      class DOB {
      String db (){
      def start = Date.parse('yyyy-MM-dd', '2015-01-01')
      def end = Date.parse('yyyy-MM-dd', '2017-12-31')
      def random = new Random()
      def DOB = (start + random.nextInt(end - start + 1)).format('yyyy-MM-dd')
      return DOB
      }
      }

       

      Thanks, again.

  • nmrao's avatar
    nmrao
    Champion Level 3

    One more thing is that there are changes in date related stuff in  Java 8 and I believe that ReadyAPI uses Java 8 or higher version.