Computation Syntax

Operands

An operand is any element defined in the model, called with its unique identifier (ID).

Measures

Measure IDs may be prefixed with B. to distinguish between the base measure and the derived measure.

Adding and dividing measures values:

<Computation targetArtefactTypes="FUNCTION" result="(TOPD+TOPT)/(DOPD+DOPT)" />

Using both base and derived measures (B.SLOC and SLOC respectively) in the same calculation:

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="LC - B.SLOC + (-04 - SLOC)" />
</Measure>
Indicators

Indicators are prefixed with I.. Computations with indicators use the rank of the indicator, as defined in the indicator's associated scale.

Sum the values of the ranks of several indicators:

<Computation targetArtefactTypes="FUNCTION" result="I.SDOC+I.DFCX+I.CFCX" />

Using the rank of the root indicator for the artefact with the RANK keyword:

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="RANK + LC" />
</Measure>

Using the rank of the root indicator for the artefact with the LEVEL keyword:

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="LEVEL + LC" />
</Measure>
Rules

Rules are prefixed with R. The following example shows a computation which retrieves the number of times the rule R_COMPOUNDIF was violated for the current artefact:

<Computation targetArtefactTypes="PACKAGE" result="R.R_COMPOUNDIF" />

Tip

Using R.RULE_ID is the same as writing the following query:

<Computation targetArtefactTypes="PACKAGE" result="COUNT RULE.OCCURRENCES FROM NODE WHERE MEASUREID=RULE_ID" />

Query syntax is introduced later in this chapter, in the section called “Queries”.

Operators

+

Add operands

Take the value of LC and add 10:

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="LC + 10" />
</Measure>
-

Subtract operands / use the opposite of an operand

Take the value of LC, subtract SLOC:

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="LC - SLOC" />
</Measure>

Using the opposite value of an operand:

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="0.1 * -LC + 2 * -SLOC * 3" />
</Measure>
*

Multiply operands

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="LC * SLOC * 6.0" />
</Measure>
/

Divide operands

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="LC + 2 / 2" />
</Measure>
OR or ||

Allows evaluating operands as boolean conditions. An operand evaluates to true if its value is > 0. OR returns true if at least one operand evaluates to true

AND or &amp;&amp;

Allows evaluating operands as boolean conditions. An operand evaluates to true if its value is > 0. AND returns true if both operands evaluate to true

Tip

The operator precedence in computation is as follows:

Table 5.1. Operator Precedence

1

- (as opposite or operand)

2

/, *

3

+, - (as subtraction)

4

<=, >=, !=, =, >, <

5

OR, ||

6

AND, &amp;&amp;


You can use parentheses to override operator precedence, if needed.

Note

When a computation gives an error, the measure will be assigned the default value (-1 in the example below) instead of the result of the computation:

<Measure measureId="COMR" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="LC / 0" />
</Measure>

Tip

When a measure is assigned its default value because of an error, the Measures tab of the Explorer will display the measure status as Error. When this happens for an indicator, the indicator is displayed in red in the Indicator Tree.

Functions

Mathematical Functions

MIN(value[,value,value...])

Determines the minimum in a set of values

Use the lower of three indicators:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="MIN(I.TESTABILITY, I.CHANGEABILITY, I.ANALISABILITY)" />
</Measure>

Using nested MIN and MAX functions:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="MIN(MAX(SLOC+(BLANK/2),1000),MAX(LC,1000))+2" />
</Measure>
FMIN(<Computation> min, <Computation> max, <Computation> value [, <Computation> value, <Computation> value...])

Calculate the filtered minimum of comma-separated values. When using the FMIN() function, only the values within min and max are used to calculate a MIN(). To specify infinity as a bound, leave the value of min or max empty. If no values match the filter, the default value is returned.

FMIN(,,-2,4,11) 
is equivalent to: FMIN(-Infinity,+Infinity,-2,4,11)
is equivalent to: MIN(-2,4,11)
FMIN(0,10,-2,4,11)
is equivalent to: MIN(4,11)
FMIN(0,1,-2,4,11)
is equivalent to: MIN(), which evaluates to null 
and leads to using the default value of the measure and marking 
it in the indicator tree with the status ERROR.
FMIN(2,,1,I.LC)
is equivalent to: FMIN(2,+Infinity,1,I.lC)
is equivalent to: MIN(I.LC)
resolves to: I.LC if LC >= 2, else default value
MAX(value[,value,value...])

Determines the maximum in a set of values

Use a measure if it is above a threshold, else use the threshold itself:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="MAX(10,VG)" />
</Measure>

Use the value of the higher of two measures:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="MAX(LC,SLOC)" />
</Measure>

Prevent a division by 0:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="LC / MAX(STAT, 1)" />
</Measure>
FMAX(<Computation> min, <Computation> max, <Computation> value [, <Computation> value, <Computation> value...])

Calculates the filtered maximum of comma-separated values. When using the FMAX() function, only the values within min and max are used to calculate a MAX(). To specify infinity as a bound, leave the value of min or max empty. If no values match the filter, the default value is returned.

ABS(operand)

Determines the absolute value for an operand

Retrieve the variation of a measure:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="ABS(DELTA_VALUE(LC))" />
</Measure>
AVR(value[,value,value...])

Computes the average for a set of values

Calculate the average of three indicators:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="AVR(I.TESTABILITY, I.CHANGEABILITY, I.ANALISABILITY)" />
</Measure>
EXP(<Computation>)

Calculates the exponential of a value

LN(<Computation> value)

Calculates the natural logarithm of a value

LOG(<Computation> value, <Computation> base)

Calculates the logarithm of a value

POW(<Computation> value, <Computation> power)

Calculates a power

SQRT(<Computation> value)

Calculates a square root

ROUND(<Computation> value)

Rounds a number up or down to the nearest integer

FLOOR(<Computation> value)

Rounds a number down to the nearest integer

CEIL(<Computation> value)

Rounds a number up to the nearest integer

CENTROID(<Computation> value [| <computation> weight], ...)

Calculates the centroid of comma-separated pairs of value|weight. If no weight is specified, it is set to 1.

Calculate the centroid of 3 with weight 3 and 2 with weight 100 (=2.03) (this translates to (3x3 + 2x100) / (100+3)):

<Measure measureId="MATH_CENTROID_3_3_2_100" defaultValue="-1">
	<Computation targetArtefactTypes="APPLICATION" result="CENTROID(3|3,2|100)"/>
</Measure>
FCENTROID(<Computation> min, <Computation> max, <Computation> value [| <computation> weight], ...)

Calculates the filtered centroid of comma-separated pairs of value|weight. When using the FCENTROID() function, only the values within min and max are used to calculate a CENTROID(). To specify infinity as a bound, leave the value of min or max empty. If no values match the filter, the default value is returned.

Calculate the filtered centroid of TESTABILITY/STABILITY/MAINTAINABILITY:

Given the scale:

  • level: UNKNOWN, rank: -1

  • level: LEVELA, rank: 0

  • level: LEVELB, rank: 1

  • level: LEVELC, rank: 2

and given that I.TESTABILITY is UNKNOWN, I.STABILITY is LEVELB, I.MAINTAINABILITY is LEVELC

<Measure measureId="MATH_FCENTROID" defaultValue="-1">
	<Computation targetArtefactTypes="APPLICATION" result="FCENTROID(0,,I.TESTABILITY|3,I.STABILITY|2,I.MAINTAINABILITY)"/>
</Measure>

I.TESTABILITY is filtered out as it is not between the specified minimum and maximum.

The value is then computed as CENTROID(I.STABILITY|2,I.MAINTAINABILITY), which is (1x2 + 2) / (2+1).

FSUM(<Computation> min, <Computation> max, <Computation> value [, <Computation> value, <Computation> value...])

Calculates the filtered sum of comma-separated values. When using the FSUM() function, only the values within min and max are used to calculate a sum. To specify infinity as a bound, leave the value of min or max empty. If no values match the filter, the default value is returned.

FSUM(,,1,2.5,2>1,3)
is evaluated as: 1 + 2.5 + 1 + 3
FSUM(2,4,1,2.5,2>1,3)
is evaluated as: 2.5 + 3
FSUM(6,,-1,I.LC,LC)
resolves to: I.LC if >= 6 or LC if >= 6

Conditional and Level-Related Functions

IF(cond,val_yes,val_no)

Assigns different values based on the result of a condition. Note that nested IF constructions are allowed, and an IF block can contain OR or AND operators. A condition is simply a computation that returns 1 if true and 0 if false. For example, result="SLOC>50" returns 1 if the artefact's SLOC is greater than 50, or 0 otherwise.

Set a measure to 6 if SLOC is above a threshold, else set it to 4:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="2+IF(SLOC>50,4,2)" />
</Measure>

False into the ELSE part of the IF statement to avoid using the default value:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="IF(2/0, 5, 10)" />
</Measure>
=> will return 10 instead of -1

Set a measure to 6 if SLOC is above a value and below another one, else set it to 4:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="2+IF(SLOC>50 AND SLOC<100,4,2)" />
</Measure>

A nested IF construction:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="2+IF(I.LC>IF(SLOC>300,SLOC,MAX(250,300)),98,8)" />
</Measure>
CASE(measureId,case1:value1,case2:value2[,...][,DEFAULT:value])

Assigns different values to a measure based on the value of another measure. A fallback can be specified by using the DEFAULT case.

Assign a value for EASE_OF_USE based on the value of FEEDBACK:

<Measure measureId="EASE_OF_USE" defaultValue="-1">
	<Computation targetArtefactTypes="APPLICATION" result="CASE(FEEDBACK,C.BAD:0,C.GOOD:50,C.EXCELLENT:80,DEFAULT:-1)" />
</Measure>
NOT(computation)

Returns 0 if the result of the computation is greater than or equal to 1, or 1 otherwise.

Set OLD_LARGE_FILE to 1 if the file is neither new nor under 500 lines

<Measure measureId="OLD_LARGE_FILE" defaultValue="-1">
	<Computation targetArtefactTypes="FILE" result="NOT(IS_NEW_ARTEFACT() AND LC<500)" />
</Measure>
RANK(scale_id,level_id)

Provides a way to retrieve rank values from your model.

Retriev rank values, given the following scale:

<Scale scaleId="SCALE_LINE">
	<ScaleLevel levelId="LEVELA" bounds="];10]"  rank="0" />
	<ScaleLevel levelId="LEVELB" bounds="]10;30]" rank="1" />
	<ScaleLevel levelId="LEVELC" bounds="]30;60]" rank="2" />
	<ScaleLevel levelId="LEVELD" bounds="]60;100]" rank="4" />
	<ScaleLevel levelId="LEVELE" bounds="]100;[" rank="8" />
</Scale>

You can use the RANK function as follows to find the rank of LEVELD. The example below returns 4:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="RANK(SCALE_LINE,LEVELD)" />
</Measure>

Using RANK is useful when combined with conditions. The examples below are equivalent:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="IF(I.LC>4,1,0)" />
</Measure>
<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="IF(I.LC>RANK(SCALE_LINE,LEVELD),1,0)" />
</Measure>
<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="IF(I.LC>LEVELD,1,0)" />
</Measure>

In the last example, we use the short syntax for the RANK function: >LEVELD is only valid when used after an indicator. The rank retrieved is the rank of level LEVELD for the scale of the current artefact type for the indicator LC.

FIND_RANK(scale_id,measure_id)

Provides a way to retrieve a rank from your model by passing a measure and a scale.

The FIND_RANK() function is mostly useful when using dynamic scales (see the section called “Dynamic Scales”). The example below assigns to TEST_COVERAGE_RANK the value of the rank for the value of COVERAGE on the scale DYN_SCALE_OK_KO:

<Measure measureId="OBJECTIVE" targetArtefactTypes="APPLICATION;FODLER;FILE;CLASS" defaultValue="-1" />
<Measure measureId="COVERAGE" targetArtefactTypes="APPLICATION;FODLER;FILE;CLASS" defaultValue="-1" />

<Scale scaleId="DYN_SCALE_OK_KO">
	<ScaleLevel levelId="DYN_OK" bounds="[;APP(OBJECTIVE)]"  rank="0" />
	<ScaleLevel levelId="DYN_KO" bounds="[APP(OBJECTIVE);]" rank="1" />
</Scale>

<Scale scaleId="SCALE_OK_KO">
	<ScaleLevel levelId="OK" bounds="[1;1]"  rank="0" />
	<ScaleLevel levelId="KO" bounds="[0;0]" rank="1" />
</Scale>

<Measure measureId="TEST_COVERAGE_RANK">
	<Computation targetArtefactTypes="APPLICATION" result="FIND_RANK(DYN_SCALE_OK_KO,COVERAGE)" />
</Measure>

<Indicator indicatorId="TEST_COVERAGE" measureId="TEST_COVERAGE_RANK" scaleId="SCALE_OK_KO" />
APP(measure_id)

Retrieves the value of a measure at application level

Compute the percentage of lines of code present in the current artefact using the entire application as the reference, with APP():

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="(LC*100)/APP(LC)" />
</Measure>
PARENT(measure_id, [type]) , ANCESTOR(measure_id, [type])

Retrieve the value of a measure for an artefact's parent or ancestor containing this measure. The concept is similar to that of the APP() function, but PARENT() only checks the artefact's direct parent and ANCESTOR() goes up the tree until finding an artefact (of the optionally specified type) that has the requested measure ID.

Mark a method as risky if the parent class has changed, using PARENT():

<Measure measureId="RISKY" defaultValue="-1">
	<Computation targetArtefactTypes="FUNCTION" result="PARENT(CHANGED,CLASS)" />
</Measure>

Set an artefact as critical if one of its containing folder is critical:

<Measure measureId="IS_CRITICAL" defaultValue="-1">
	<Computation targetArtefactTypes="FOLDER;CLASS;FUNCTION" result="ANCESTOR(IS_CRITICAL,FOLDER)" />
</Measure>
FPARENT(min,max,measure_id, [type]) , FANCESTOR(min,max,measure_id, [type])

Provide the same function as PARENT and ANCESTOR but allow filtering for values to take into account. Note that if min or max are omitted, they are automatically replaced by -Infinity and +Infinity respectively.

Filtering with FPARENT():

IF(FPARENT(RANK(SCALE_LINE,LEVELG), RANK(SCALE_LINE,LEVELG), I.LC),1,2)
=> resolves as: IF(PARENT(I.LC)=RANK(SCALE_LINE,LEVELG),1,2)
=> return 1 if PARENT(I.LC) = LEVELG, otherwise 2

Filtering with FANCESTOR():

FANCESTOR(500,, LC, FOLDER)
=> returns LC for the first folder ancestor where LC >= 500
IS_DP_OK(data_provider_name)

Provides a way to find out if a Data Provider was executed successfully or not during the analysis. If the Data Provider was not executed or failed, the function returns 0. If the Data Provider was executed successfully, then the function returns 1.

Find out if the Checkstyle Data Provider was executed successfully with IS_DP_OK:

<Measure measureId="RAN_CHECKSTYLE" defaultValue="-1">
	<Computation targetArtefactTypes="APPLICATION" result="IS_DP_OK(Checkstyle)" />
</Measure>
DP_STATUS(data_provider_name)

Provides finer information about the execution status of a Data Provider than IS_DP_OK():

Find out the status of the execution of Checkstyle during the analysis:

<Measure measureId="CHECKSTYLE_STATUS" defaultValue="-1">
	<Computation targetArtefactTypes="APPLICATION" result="DP_STATUS(Checkstyle)" />
</Measure>
  • returns -1 if the DP was not run

  • returns 0 if the DP was successful

  • returns 1 if the DP returned some warnings

  • returns 2 if the DP reported errors

  • returns 3 if the DP stopped with a fatal error

IS_META_PROJECT()

Allows determining if the project is a meta-project, i.e. an aggregation of results from other Squore projects, and allows you to compute results differently if needed. The function returns 0 for regular projects and 1 for meta-projects. For more information about meta-projects, consult the section called “Wizard Contept”.

IS_APPROVED_TEMPLATE()

Returns 1 when the project uses an approved ruleset template, or 0 when it does not. Approved ruleset templates can be created by model managers using the Analysis Model Editor. Refer to the Getting Started Guide for more information about ruleset edition.

IS_ARTEFACT_TYPE(artefact_type)

Provides a way to check if an artefact is of a specific type. If the artefact is of the specified type, the function returns 1, else it returns 0.

Check if the artefact is a CHANGE_REQUEST:

<ArtefactType id="ISSUE" heirs="BUG;CHANGE_REQUEST;HOTLINE;REGRESSION" />
<Measure measureId="IS_CR" defaultValue="-1">
	<Computation targetArtefactTypes="ISSUE" result="IS_ARTEFACT_TYPE(CHANGE_REQUEST)" />
</Measure>
IS_NEW_ARTEFACT()

Tests whether the artefact is new in the current version of the project. It returns 1 if true, 0 if false.

Define a measure whose value is set to 1 when the artefact is new, else 0:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="IS_NEW_ARTEFACT()" />
</Measure>

Use IS_NEW_ARTEFACT as a condition operator:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="IF(IS_NEW_ARTEFACT(),3,4)" />
</Measure>

Note: IF(IS_NEW_ARTEFACT(),val_yes,val_no) is equivalent to IF(IS_NEW_ARTEFACT()>0,val_yes,val_no)

IS_RELAXED_ARTEFACT()

Provides a way to find out an artefact's relaxation status. It returns 1 if the artefact is relaxed and 0 if it is not.

LINKS(<linkTypeId> [, OUT|IN|IN_OUT] [, CONDITION])

Returns the number of links for an artefact. It requires defining the type of link to consider (linkTypeId) and optionally allows to specify an extra parameter to refine which link directions to consider:

  • OUT considers only outbound links (links from this artefact to other artefacts)

  • IN considers only inbound links (links from other artefacts to this artefact)

  • IN_OUT considers all links for this artefact and is the default value if none is specified

The function also allows defining a condition to filter out unwanted links when counting. The condition is verified against the target artefacts according to the specified link direction. In order for the condition to be taken into account, the link type and its supported IN and OUT artefacts must be declared in the analysis model, see the section called “Artefact Links” for more details.

Find the number of failing tests (link type: BLOCKS) for each requirement and requirement folder:

<Measure measureId="NUM_FAILING_TESTS" defaultValue="-1">
	<Computation targetArtefactTypes="REQUIREMENT" result="LINKS(BLOCKS,IN)" />
	<Computation targetArtefactTypes="REQUIREMENT_FOLDER" result="SUM REQUIREMENT.NUM_FAILING_TESTS FROM TREE" />
</Measure>

Find the number of failing tests for each requirement, excluding failing tests on relaxed code:

<Link id="BLOCKS" srcArtefactTypes="CODE" dstArtefactTypes="REQUIREMENT" />
	<Measure measureId="NUM_FAILING_TESTS_COND" defaultValue="-1">
	<Computation targetArtefactTypes="REQUIREMENT" result="LINKS(BLOCKS,IN, NOT(IS_RELAXED_ARTEFACT())" />
</Measure>
LINKS_AGGREGATE(<aggregationType>, <computation>, <linkTypeId> [, OUT|IN|IN_OUT] [, CONDITION] [, default computation])

Allows aggregating metrics from linked artefacts. The function's parameters are:

  • aggregationType (mandatory) defines how the values for the metrics are aggregated. The supported values are:

    • MIN

    • MAX

    • OCC

    • AVG

    • DEV

    • SUM

    • MED

    • MOD

  • computation (mandatory) is the computation to perform when encountering the desired type of link.

  • linkTypeId (mandatory) is desired type of link to aggregate data from. The link type and its supported IN and OUT artefacts must be declared in the analysis model, see the section called “Artefact Links” for more details.

  • The link direction, which is one of:

    • OUT considers only outbound links (links from this artefact to other artefacts)

    • IN considers only inbound links (links from other artefacts to this artefact)

    • IN_OUT considers all links for this artefact and is the default value if none is specified

  • A computation used as a condition to filter out unwanted artefacts

  • A default computation that is used to return a value in case no link exists

Find out the average code coverage for code implementing requirements where tests are failing. Only consider code artefacts where there is test coverage. If there are no failing tests, set the metric to 0:

<Link id="BLOCKS" srcArtefactTypes="CODE" dstArtefactTypes="REQUIREMENT" />
<Measure measureId="TCOV_FAILING_TESTS" defaultValue="-1" type="PERCENT">
	<Computation targetArtefactTypes="REQUIREMENT" result="LINKS_AGGREGATE(AVG, TCOV, BLOCKS,IN, TCOV != -1, 0)" />
</Measure>

Temporal Functions

PREVIOUS_VALUE(measureId)

Retrieves the previous value of a measure or indicator (measureId). This function returns 0 when no previous value can be found.

Use the value of LC from the previous analysis:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="PREVIOUS_VALUE(LC)" />
</Measure>
DELTA_VALUE(measureId)

Computes the difference between the current value of a measure or indicator (measureId) and its previous value. This function returns 0 if no delta can be calculated.

Obtaining the difference in ranking between two analyses for an artefact:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="DELTA_VALUE(RANK)" />
</Measure>

Compute a delta of opened/closed bugs since the previous analysis:

<Measure measureId="SPRINT_PROGRESS" defaultValue="-1">
<Computation targetArtefactTypes="SPRINT" result="DELTA_VALUE(NB_OPEN_CR)" />
</Measure>
PREVIOUS_INFO(infoId)

Retrieves the value of some artefact information (infoId) in the previous version so it can be compared with the current artefact information (This is useful when combined with the EQUALS() or MATCHES() functions, as described in the section called “String Matching Functions”).

FIRST_VALUE(measureId [, <computation> min] [, <computation> max])

Returns the first value ever assigned to a metric (measureId) in the current project, optionally within specific bounds (min, max).

Compute a delta of opened/closed bugs since the beginning of a sprint:

<Measure measureId="SPRINT_PROGRESS" defaultValue="-1">
	<Computation targetArtefactTypes="SPRINT" result="FIRST_VALUE(NB_OPEN_CR)-NB_OPEN_CR" />
</Measure>
AGGREGATE(aggregationType, measureId, [, <computation> minNb] [, <computation> maxNb] [, <computation> min] [, <computation> max])

Returns the aggregated value of the previous values of a metric (measureId). You can optionally configure the minimun and maximum (minNb, maxNb) number of valid data points to be aggregated, and specify bounds (min, max) for the values to consider for aggregation. The aggregation type (aggregationType) is a mandatory parameter, and must be one of MIN, MAX, OCC, AVG, DEV, SUM, MED or MOD.

Count the number of new issues reported based on the number of new issues opened daily:

<Measure measureId="NEW_ISSUES_TALLY" defaultValue="-1">
	<Computation targetArtefactTypes="SPRINT" result="AGGREGATE(SUM, NEW_CR)" />
</Measure>

Compute the average number of issues opened daily:

<Measure measureId="ISSUE_DISCOVERY_RATE" defaultValue="-1">
	<Computation targetArtefactTypes="SPRINT" result="AGGREGATE(AVG, NEW_CR)" />
</Measure>
LEAST_SQUARE_FIT(<computation> degree, measureId, <computation> date, [, <computation> minNb] [, <computation> maxNb] [, <computation> min] [, <computation> max])

Returns the interpolated or extrapolated value from the previous values of a metric (measureId) at a specific date (date). You can optionally configure the minimun and maximum (minNb, maxNb) number of valid data points to be taken into account, and specify bounds (min, max) for the values to consider for extrapolation. The date (date) and degree (degree) of the polynomial extrapolation are mandatory parameters.

Compute the value of WP_PCT at the next milestone using exactly 3 data points

<Measure measureId="WP_PCT_NEXT_1" defaultValue="-1"  >
	<Computation targetArtefactTypes="WORK_PRODUCT" result="LEAST_SQUARE_FIT(1, WP_PCT, DATE_MILESTONE(NEXT), 3, 3)" />
</Measure>

Date Functions

Note

Squore computes and stores dates internally as the number of milliseconds since January 1st 1970 in UTC.

For version dates and project attributes, users can set a date using the following levels of precision:

  • Date "1979-07-28" is saved as July 28th 1979 at midnight UTC

  • Date/Time "1979-07-28T13:58:25" is saved as July 28th 1979 at 13:58:25 UTC

  • Date/Time in a specific timezone (new in 18.0) "1979-07-28T13:58:25+0800" is saved as July 28th 1979 at 13:58:25 UTC+8

There are various ways to display dates in the web interface. See the description of the format attribute in the section called “Measures” for more information.

DATE(<year_param>, <month_param>, <day_param>)

Converts year/month/day numbers to a date in milliseconds.

Convert to the date 28th July 1979:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="DATE(1979,07,28)" />
</Measure>

Convert to a date using measure IDs:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="DATE(YEAR_START+2,MONTH_START+MONTHS_SPENT,TARGET_DAY)" />
</Measure>
DAYS(<param>)

Allows passing a number as a number of days in milliseconds

Find the number of days since the start of the project (the project attribute PROJECT_START_DATE) until today:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="TO_DAYS(TODAY()-PROJECT_START_DATE)" />
</Measure>

Find the number of working days since the start of the project (the project attribute PROJECT_START_DATE) until today:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="TO_DAYS(DURATION_WITHOUT_WEEKEND(PROJECT_START_DATE, TODAY()))" />
</Measure>

Add 4 days to May 19th 2012 to obtain May 23rd 2012:

<Measure measureId="EXAMPLE" defaultValue="-1">
	<Computation targetArtefactTypes="CODE" result="DATE(2012,05,19)+DAYS(4)" />
</Measure>
TO_DAYS(<duration>)

Returns the number of days between two dates, given a duration in milliseconds

Calculate the age of a change request:

<Measure measureId="AGE" defaultValue="-1">
	<Computation targetArtefactTypes="CR" result="TO_DAYS(APP(PRESENT_DAY)-CREATE_TIME)" />
</Measure>
TODAY()

Retrieves today's date at midnight UTC

NOW()

Retrieve today's exact date and time (at the time of the analysis)

VERSION_DATE()

Retrieves the version's date and time. By default, this is the same value as the time of the analysis (NOW()), but users are allowed to specify a different date different from the current one.

Calculate whether an issue expires within a week of the analysis:

<Measure measureId="EXPIRES_THIS_WEEK" defaultValue="-1">
	<Computation targetArtefactTypes="BUG;CR" result="IF(EXPIRY_DATE - DAYS(7) < VERSION_DATE(),1,0)" />
</Measure>
TRUNCATE_DATE(<date>, <unit>)

Returns a date truncated to the specified precision unit and is useful when calculating date differences. The supported units are:

  • YEAR

  • QUARTER

  • MONTH

  • SEMI_MONTH

  • WEEK_SUNDAY (use when the first day of the week is Sunday)

  • WEEK_MONDAY (use when the first day of the week is Monday)

  • DAY

  • AM_PM

  • HOUR

  • MINUTE

  • SECOND

  • MILLISECOND

Truncate a date down to year precision:

<!-- Sat, 28 Jul 1979 11:14:04 GMT -->
<Constant id="EXACT_DATE" value="302008444000" />

<!-- Returns 283996800000 (aka: Mon, 01 Jan 1979 00:00:00 GMT) -->
<Measure measureId="TRUNCATE_TO_YEAR" defaultValue="-1">
	<Computation targetArtefactTypes="ISSUE" result="TRUNCATE_DATE(EXACT_DATE, YEAR)" />
</Measure>

Find out how much time it took to solve an issue. This example highlights how using TRUNCATE_DATE() can bring more precision depending on how you want to handle periods under 24 hours as one day or two days.

<!-- Date opened: Sat, 28 Jul 1979 07:47:47 GMT -->
<Constant id="TIME_OPENED" value="301996067000" />

<!-- Date closed 1: Sat, 28 Jul 1979 12:02:25 GMT -->
<Constant id="TIME_CLOSED_1" value="302011345000" />

<!-- Date closed 2: Sun, 29 Jul 1979 04:56:04 GMT -->
<Constant id="TIME_CLOSED_2" value="302072164000" />


<Measure measureId="TRUNCATE_TO_RETURN_ZERO" defaultValue="-1">
	<Computation targetArtefactTypes="ISSUE" result="TRUNCATE_DATE(TIME_CLOSED_1, DAY) - TRUNCATE_DATE(TIME_OPENED, DAY)" />
</Measure>

<Measure measureId="TRUNCATE_TO_RETURN_ONE" defaultValue="-1">
	<Computation targetArtefactTypes="ISSUE" result="TRUNCATE_DATE(TIME_CLOSED_2, DAY) - TRUNCATE_DATE(TIME_OPENED, DAY)" />
</Measure>

<Measure measureId="TO_DAYS_RETURNS_ONE" defaultValue="-1">
	<Computation targetArtefactTypes="ISSUE" result="DAYS(TIME_CLOSED_1 - TIME_OPENED)" />
</Measure>

<Measure measureId="TO_DAYS_RETURNS_ONE_ALSO" defaultValue="-1">
	<Computation targetArtefactTypes="ISSUE" result="DAYS(TIME_CLOSED_2 - TIME_OPENED)" />
</Measure>
DURATION_WITHOUT_WEEKEND(<computation> startDateTime, <computation> endDateTime)

Returns the difference between startDateTime and endDateTime with Saturdays and Sundays removed. The function uses the GMT timezone and returns a result in milliseconds.

Milestone Functions

HAS_MILESTONE([milestoneId or keyword] [, date])

Checks if a milestone with the specified milestoneId exists in the project. The function returns 0 if no milestone is found, 1 if a milestone is found.

Find if we are at the last milestone of the project:

IS_LAST_MILESTONE=IF(HAS_MILESTONE(),0,1)
DATE_MILESTONE([milestoneId or keyword] [, date])

Returns the date associated to a milestone.

Find if the date for the milestone BETA_RELEASE has been modified between June 2015 and now:

DATE_HAS_SLIPPED=(DATE_MILESTONE(BETA_RELEASE)-DATE_MILESTONE(BETA_RELEASE, DATE(2015,06,01))) != 0

Compute the date difference between the previous and next milestones:

MILESTONE_DURATION=DATE_MILESTONE(NEXT) - DATE_MILESTONE(PREVIOUS)

Find the date slip for the next milestone between now and the previous anlaysis:

DATE_SLIP=DATE_MILESTONE(NEXT) - DATE_MILESTONE(NEXT, VERSION_DATE(PREVIOUS))

Find the amount of time left until the next milestone:

DEADLINE=DATE_MILESTONE(NEXT) - VERSION_DATE()
GOAL(measureId [, milestoneId or keyword] [, date])

Returns the goal for a metric at the specified milestone.

Find the goal for requirement stability set for the milestone PROTOTYPE as of June 2016:

REQ_STABILITY_GOAL=GOAL(REQ_STABILITY, PROTOTYPE, DATE(2016,06,01))

Find the delta between the goal for TEST between the previous and next milestones:

DELTA=GOAL(TEST) - GOAL(TEST, PREVIOUS)

Find the delta between the goal for TEST for the next milestone set for the previous analysis and now:

DELTA=GOAL(TEST) - GOAL(TEST, NEXT, VERSION_DATE(PREVIOUS))

Find the delta between the current value of TEST and the goal for TEST at the next milestone:

DELTA=GOAL(TEST) - TEST

Tip

You can use keywords instead of using a milestone ID. You can retrieve information about the next, previous, first or last milestones in the project by using:

  • NEXT

  • NEXT+STEP where STEP is a number indicating how many milestones to jump ahead

  • PREVIOUS

  • PREVIOUS-STEP where STEP is a number indicating how many milestones to jump backward

  • FIRST

  • LAST

Note

In all milestone functions, if no milestone ID and no keyword is specified, then NEXT is used by default.

All milestone functions accept a date parameter. The date is used to execute the function in that date context. If no date is specified, then the context used to execute the function is the analysis date.

String Matching Functions

Note

The examples in this section are based on an artefact with the following data:

<I n="LANGUAGES" v="Java, C#, C++, C"/>
<I n="AUTHOR" v="gabriel"/>
<I n="URL" v="http://www.my_url.com"/> [^]
<I n="ONE_LANGUAGE" v="JaVa"/>
INFO(info_tag)

Retrieves the textual information info_tag for an artefact.

ARTEFACT_NAME()

Retrieves an artefact's name

EQUALS('haystack','needle'[, forceIgnoreCase])

Checks if two strings are equal and returns 1 if they are

Case-insensitive search:

EQUALS(INFO(AUTHOR), 'gabriel')
=> 1

Case-sensitive search:

EQUALS(INFO(LANGUAGES), 'Java, C#, C++, C', 0)
=> 1
CONTAINS('haystack','needle'[, forceIgnoreCase])

Checks if a string contains another string and returns 1 if it does

Case-insensitive search:

CONTAINS(INFO(LANGUAGES), 'C++')
=> 1

Case-sensitive search:

CONTAINS(INFO(LANGUAGES), 'Cobol', 0)
=> 0

use two infos as search parameters:

CONTAINS(INFO(LANGUAGES), INFO(ONE_LANGUAGE), 1)
=> 1
STARTS_WITH('haystack','needle'[, forceIgnoreCase])

Checks if a string starts with another string and returns 1 if it does

Check if the URL starts with HTTP:

STARTS_WITH(INFO(URL), 'HTTP')
=> 1
STARTS_WITH(INFO(URL), 'HTTPS')
=> 0
ENDS_WITH('haystack','needle'[, forceIgnoreCase])

Checks if a string ends with another string and returns 1 if it does

Check if the URL ends with COM (case-sensitive):

ENDS_WITH(INFO(URL), '.COM', 0)
=> 0
MATCHES('string','regexp'[, forceIgnoreCase])

Checks if a string matches a pattern and returns 1 if it does

Check various regular expressions for the language field:

MATCHES(INFO(LANGUAGES), 'J.*', 0)
=> 1
MATCHES(INFO(LANGUAGES), '.*(, C\+\+).*', 0)
=> 1
MATCHES(INFO(LANGUAGES), '.*(, C\+\+\+).*', 0)
=> 0

Tip

forceIgnoreCase is an optional boolean set to 1 by default. If you want to perform a case-sensitive search, use 0, instead.

Note

You can also retrieve the previous value of textual information for an artefact using the PREVIOUS_INFO() function, as described in the section called “Temporal Functions”