Home > other >  Calculate values from json file
Calculate values from json file

Time:11-04

I have a script

#!/bin/bash

#create path to redirect output.json to same directory as output.txt
path=$(dirname $1)

#create variables for name line, test lines and result line
firstline=$(cat $1 | head -n  1 | cut -d "[" -f2 | cut -d "]" -f1)
testname=$(echo $firstline)

tests=$(cat $1 | tail -n  3 | head -n -2)

results=$(cat $1 | tail -n1)

#create main JSON variable
json=$(jq -n --arg tn "$testname" '{testname:$tn,tests:[],summary:{}}')

#test's names, status, duration and updating JSON variable
IFS=$'\n'
for i in $tests
do
    if [[ $i == not* ]]
    then
        stat=false
    else
        stat=true
    fi

    if [[ $i =~ expecting(. ?)[0-9] ]]
    then
        var=${BASH_REMATCH[0]}
        name=${var%,*}
    fi

    if [[ $i =~ [0-9]*ms ]]
    then
        test_duration=${BASH_REMATCH[0]}
    fi

    json=$(echo $json | jq \
        --arg na "$name" \
        --arg st "$stat" \
        --arg dur "$test_duration" \
        '.tests  = [{name:$na,status:$st|test("true"),duration:$dur}]')
done

#final success, failed, rating, duration and finishing JSON variable

IFS=$'\n'
for l in $results
do
    if [[ $l =~ [0-9]  ]]
    then
        success=${BASH_REMATCH[0]}
    fi

    if [[ $l =~ ,.[0-9]  ]]
    then
        v=${BASH_REMATCH[0]}
        failed=${v:2}
    fi

    if [[ $l =~ [0-9] .[0-9] % ]] || [[ $l =~ [0-9] % ]]
    then
        va=${BASH_REMATCH[0]}
        rating=${va%%%}
    fi

    if [[ $l =~ [0-9]*ms ]]
    then
        duration=${BASH_REMATCH[0]}
    fi

    json=$(echo $json | jq \
                --arg suc "$success" \
                --arg fa "$failed" \
                --arg rat "$rating" \
            --arg dur "$duration" \
            '.summary  = {success:$suc|tonumber,failed:$fa|tonumber,rating:$rat|tonumber,duration:$dur}')
done

#redirect variable's output to file
echo $json | jq "." > $path"/output.json"

Output.json looks like:

{
  "testname": "Behave test",
  "tests": [
    {
      "name": "some text",
      "status": true,
      "duration": "7ms"
    },
    {
      "name": "some text",
      "status": false,
      "duration": "27ms"
    }
  ],
  "summary": {
    "success": 1,
    "failed": 1,
    "rating": 50,
    "duration": "34ms"
  }
}

Output is much more than in my example above. My question is, how I can calculate "summary" values and put it to json?

  • "success" - tests with status true;
  • "failed" - tests with status false;
  • "rating" - success / total, and it can be float or int
  • "duration" - sum of "duration" field

I will be very grateful for help.

CodePudding user response:

This adds (or replaces) a .summary field which is calculated by reduceing the .tests array to an object, initialized as {success: 0, failed: 0}. For each array item, either .success or .failed is incremented, depending on the current array item's boolean .state field. The .rating field is incremented unconditionally, thus counting the total number of items which is later used to calculate the true rating. As for the duration, the array item's .duration field is converted into a number by chopping off the ms suffix, and added to the summary's (numeric) .duration field. After the reduction, the rating is corrected by dividing the the success count by it (and multiplied by 100 for convenience). The ? // 0 part catches division by zero issues, in case the .tests array was empty. Finally, the .duration field is re-equipped with the ms suffix.

.summary = (reduce .tests[] as $t ({success: 0, failed: 0};
  (if $t.status then .success else .failed end, .rating)  = 1
  | .duration  = ($t.duration | rtrimstr("ms") | tonumber)
) | .rating = (100 * (.success / .rating)? // 0) | .duration |= "\(.//0)ms")
{
  "testname": "Behave test",
  "tests": [
    {
      "name": "some text",
      "status": true,
      "duration": "7ms"
    },
    {
      "name": "some text",
      "status": false,
      "duration": "27ms"
    }
  ],
  "summary": {
    "success": 1,
    "failed": 1,
    "rating": 50,
    "duration": "34ms"
  }
}

Demo

  • Related