Search code examples
karate

Karate Schema JSON Validation with incremental 'key name'


Into my json schema i need to manage keys with 'incremental' name :

For example :

  [
   {
        "id": 9396,
        "value": "toto",
        "attribut": "blue",
        "occur1": null,
        "occur2": null,
        "occur3": null,
        "occur4": null,
        "occur5": null,
        "occur6": null,
        "occur7": null,
        "occur8": {
            "occurenceId": 105498,
            "year": "2023",
            "quantity": 707
        },
        "occur9": {
            "occurenceId": 105499,
            "year": "2023",
            "quantity": 371
        },
        "occur10": {
            "occurenceId": 105500,
            "year": "2023",
            "quantity": 875
        },
        "occur11": null,
        "occur12": null
    },
    {
        "id": 9417,
        "value": "momo",
        "attribut": "red",
        "occur1": {
            "occurenceId": 105502,
            "year": "2023",
            "quantity": 85
        },
        "occur2": null,
        "occur3": {
            "occurenceId": 105503,
            "year": "2023",
            "quantity": 432
        },
        "occur4": null,
        "occur5": null,
        "occur6": null,
        "occur7": null,
        "occur8": null,
        "occur9": null,
        "occur10": null,
        "occur11": null,
        "occur12": null
    }
 ]

How to manage each key "occur" from occur1 to occur12 wihtout writing each lines with its own schema ?

I tried only by keeping the complete structure :

 * def MyStruct =
  """
  { 
    id: '#number',
    value: '#number',
    attribut: '#string',
    occur1: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur2: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur3: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur4: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur5: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur6: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur7: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur8: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur9: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur10: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur11: '##({occurenceId: '#number', year: '#string', quantity: '#number' })',
    occur12: '##({occurenceId: '#number', year: '#string', quantity: '#number' })'
  }

but i would like to know if it is possible to define dynamically the key 'occur(i)' to get something more elegant and flexible if tomorrow i need to increase the number of occurencies.

Thanks


Solution

  • I think I have a much cleaner solution for you. It should give you hints to come up with the final approach you are comfortable with.

    * def response = 
    """
    {
      id: 9417,
      value: 'momo',
      attribut: 'red',
      occur1: {
        occurenceId: 105502,
        year: '2023',
        quantity: 85
      },
      occur2: null,
      occur3: {
        occurenceId: 105503,
        year: '2023',
        quantity: 432
      },
      occur4: null,
      occur5: null
    }
    """    
    * def items = []
    * karate.forEach(response, (k, v) => { if (k.startsWith('occur') && v) items.push(v) })
    * match each items == { occurenceId: '#number', year: '#string', quantity: '#number' }
    

    For some similar ideas, see: https://stackoverflow.com/a/76912833/143475