Initial commit
This commit is contained in:
commit
01c833b44f
5 changed files with 433 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
artist.txt
|
||||
.idea/
|
||||
target/
|
134
automation/pom.xml
Normal file
134
automation/pom.xml
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.usi.sq</groupId>
|
||||
<artifactId>sq-2021-1</artifactId>
|
||||
<version>1.0</version>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<junit.platform.version>1.7.0-M1</junit.platform.version>
|
||||
<junit.jupiter.version>5.6.2</junit.jupiter.version>
|
||||
<junit.vintage.version>5.6.2</junit.vintage.version>
|
||||
<junit.version>4.13</junit.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<!-- attached to Maven test phase -->
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.pitest</groupId>
|
||||
<artifactId>pitest-maven</artifactId>
|
||||
<version>1.5.2</version>
|
||||
<configuration>
|
||||
<targetClasses>
|
||||
<param>org.usi.sq*</param>
|
||||
</targetClasses>
|
||||
<targetTests>
|
||||
<param>org.usi.sq*</param>
|
||||
<param>*</param>
|
||||
</targetTests>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.pitest</groupId>
|
||||
<artifactId>pitest-junit5-plugin</artifactId>
|
||||
<version>0.12</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<version>${junit.vintage.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<!-- select non-aggregate reports -->
|
||||
<report>report</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-report-plugin</artifactId>
|
||||
<version>3.0.0-M5</version>
|
||||
<configuration>
|
||||
<!-- place configuration here if required-->
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jxr-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,71 @@
|
|||
package org.usi.sq.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CollectionUtils {
|
||||
|
||||
private static final double EPSILON = 1e-6;
|
||||
|
||||
/**
|
||||
* Implementation of insertion sort. Insertion sort can be used in cases
|
||||
* where the input list is almost sorted or small. The list implementation
|
||||
* should provide fast indexed access. Due to its quadratic worst-case
|
||||
* runtime complexity, other sorting algorithms should be used in the
|
||||
* general case.
|
||||
*
|
||||
* @param list the list to be sorted in-place
|
||||
* @param <T> the type of the elements in the list (need to be comparable)
|
||||
* @throws IllegalArgumentException if called with null pointer
|
||||
*/
|
||||
static <T extends Comparable<T>> void sort(List<T> list){
|
||||
if(list == null)
|
||||
throw new IllegalArgumentException("Sort must not be called with " +
|
||||
"null");
|
||||
for(int i = 1; i < list.size(); i++){
|
||||
T key = list.get(i);
|
||||
int j = 0;
|
||||
for(j = i-1; j >= 0; j--){
|
||||
T elem = list.get(j);
|
||||
if(elem.compareTo(key) > 0){ // check if elem > key
|
||||
list.set(j+1, elem);
|
||||
} else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
list.set(j+1,key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method computes the arithmetic mean of values in a subarray of
|
||||
* the array passed as an argument. It returns {@code Double.NaN} if the
|
||||
* length of the subarray is zero.
|
||||
*
|
||||
* @param values values for which the mean should be computed
|
||||
* @param begin the first of the considered subarray
|
||||
* @param length the length of the subarray
|
||||
* @return the arithmetic mean or {@code Double.NaN} if length is zero
|
||||
* @throws IllegalArgumentException if values is null or the subarray length
|
||||
* exceeds the length of the array {@code values}
|
||||
*/
|
||||
public static double mean(int[] values, int begin, int length){
|
||||
if(length == 0)
|
||||
return Double.NaN;
|
||||
if(values == null)
|
||||
throw new IllegalArgumentException("mean must not be called with " +
|
||||
"null.");
|
||||
if(begin + length > values.length)
|
||||
throw new IllegalArgumentException("Boundary mismatch: the " +
|
||||
"specified length of the subarray exceeds the length of " +
|
||||
"the array.");
|
||||
int sum = 0;
|
||||
for (int i = begin; i < begin + length; i++){
|
||||
sum += values[i];
|
||||
}
|
||||
double mean = (double)sum/length;
|
||||
return mean;
|
||||
}
|
||||
|
||||
}
|
200
automation/src/main/java/org/usi/sq/util/StringUtils.java
Normal file
200
automation/src/main/java/org/usi/sq/util/StringUtils.java
Normal file
|
@ -0,0 +1,200 @@
|
|||
package org.usi.sq.util;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class StringUtils {
|
||||
|
||||
|
||||
private static final String EMPTY = "";
|
||||
private static final Map<Character, Integer > HEX_VALUES = new HashMap<>();
|
||||
static {
|
||||
HEX_VALUES.put('0', 0);
|
||||
HEX_VALUES.put('1', 1);
|
||||
HEX_VALUES.put('2', 2);
|
||||
HEX_VALUES.put('3', 3);
|
||||
HEX_VALUES.put('4', 4);
|
||||
HEX_VALUES.put('5', 5);
|
||||
HEX_VALUES.put('6', 6);
|
||||
HEX_VALUES.put('7', 7);
|
||||
HEX_VALUES.put('8', 8);
|
||||
HEX_VALUES.put('9', 9);
|
||||
HEX_VALUES.put('A', 10);
|
||||
HEX_VALUES.put('B', 11);
|
||||
HEX_VALUES.put('C', 12);
|
||||
HEX_VALUES.put('D', 13);
|
||||
HEX_VALUES.put('E', 14);
|
||||
HEX_VALUES.put('F', 15);
|
||||
HEX_VALUES.put('a', 10);
|
||||
HEX_VALUES.put('b', 11);
|
||||
HEX_VALUES.put('c', 12);
|
||||
HEX_VALUES.put('d', 13);
|
||||
HEX_VALUES.put('e', 14);
|
||||
HEX_VALUES.put('f', 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of this method has been adapted from StringUtils in
|
||||
* Apache Commons Lang. The following documentation is taken from the
|
||||
* original implementation.
|
||||
*
|
||||
* <p>Removes one newline from end of a String if it's there,
|
||||
* otherwise leave it alone. A newline is "{@code \n}",
|
||||
* "{@code \r}", or "{@code \r\n}".</p>
|
||||
*
|
||||
* <p>NOTE: This method changed in 2.0.
|
||||
* It now more closely matches Perl chomp.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.chomp(null) = null
|
||||
* StringUtils.chomp("") = ""
|
||||
* StringUtils.chomp("abc \r") = "abc "
|
||||
* StringUtils.chomp("abc\n") = "abc"
|
||||
* StringUtils.chomp("abc\r\n") = "abc"
|
||||
* StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
|
||||
* StringUtils.chomp("abc\n\r") = "abc\n"
|
||||
* StringUtils.chomp("abc\n\rabc") = "abc\n\rabc"
|
||||
* StringUtils.chomp("\r") = ""
|
||||
* StringUtils.chomp("\n") = ""
|
||||
* StringUtils.chomp("\r\n") = ""
|
||||
* </pre>
|
||||
*
|
||||
* @param str the String to chomp a newline from, may be null
|
||||
* @return String without newline, {@code null} if null String input
|
||||
*/
|
||||
public static String chomp(final String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (str.length() == 1) {
|
||||
final char ch = str.charAt(0);
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
return EMPTY;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
int lastIdx = str.length() - 1;
|
||||
final char last = str.charAt(lastIdx);
|
||||
|
||||
if (last == '\n') {
|
||||
if (str.charAt(lastIdx - 1) == '\r') {
|
||||
lastIdx--;
|
||||
}
|
||||
} else if (last != '\r') {
|
||||
lastIdx++;
|
||||
}
|
||||
return str.substring(0, lastIdx);
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of this method has been adapted from StringUtils in
|
||||
* Apache Commons Lang.
|
||||
* The following documentation has been slightly adapted from the original documentation.
|
||||
*
|
||||
* <p>Joins the string representations of the elements in the provided {@code List}
|
||||
* into a single String containing the provided list of elements. The string representation
|
||||
* of an element is retrieved via {@code Object.toString()}.</p>
|
||||
*
|
||||
* <p>No delimiter is added before or after the list.
|
||||
* Null objects or empty strings within the array are represented by
|
||||
* empty strings.</p>
|
||||
*
|
||||
* <pre>
|
||||
* StringUtils.join(null, *) = null
|
||||
* StringUtils.join([], *) = ""
|
||||
* StringUtils.join([null], *) = ""
|
||||
* StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
|
||||
* StringUtils.join(["a", "b", "c"], null) = "abc"
|
||||
* StringUtils.join([null, "", "a"], ';') = ";;a"
|
||||
* </pre>
|
||||
*
|
||||
* @param list the {@code List} of values to join together, may be null
|
||||
* @param separator the separator character to use
|
||||
* @param startIndex the first index to start joining from. It is
|
||||
* an error to pass in a start index past the end of the list
|
||||
* @param endIndex the index to stop joining from (exclusive). It is
|
||||
* an error to pass in an end index past the end of the list
|
||||
* @return the joined String, {@code null} if null list input
|
||||
* @since 3.8
|
||||
*/
|
||||
public static String join(final List<?> list, final String separator, final int startIndex, final int endIndex) {
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
final int noOfItems = endIndex - startIndex;
|
||||
if (noOfItems <= 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
final List<?> subList = list.subList(startIndex, endIndex);
|
||||
return join(subList.iterator(), separator);
|
||||
}
|
||||
public static String join(final Iterator<?> iterator, final String separator) {
|
||||
|
||||
// handle null, zero and one elements before building a buffer
|
||||
if (iterator == null) {
|
||||
return null;
|
||||
}
|
||||
if (!iterator.hasNext()) {
|
||||
return EMPTY;
|
||||
}
|
||||
final Object first = iterator.next();
|
||||
if (!iterator.hasNext()) {
|
||||
return Objects.toString(first, "");
|
||||
}
|
||||
|
||||
// two or more elements
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
if (first != null) {
|
||||
buf.append(first);
|
||||
}
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
if (separator != null) {
|
||||
buf.append(separator);
|
||||
}
|
||||
final Object obj = iterator.next();
|
||||
if (obj != null) {
|
||||
buf.append(obj);
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a reimplementation of the C function cgi_decode presented in
|
||||
* "Software Testing and Analysis: Process, Principles, and Techniques" by
|
||||
* Pezzè and Young.
|
||||
* It decodes a CGI-encoded string. For more information, please refer to the original
|
||||
* implementation.
|
||||
*
|
||||
* @param encoded a CGI-encoded string
|
||||
* @return {@code Optional.empty()} in case of an error (malformed input),
|
||||
* otherwise {@code Optional.of(result)}, where result is the decoded string
|
||||
*/
|
||||
public static Optional<String> cgiDecode(String encoded){
|
||||
StringBuilder decodedBuilder = new StringBuilder();
|
||||
boolean ok = true;
|
||||
for(int encodedI = 0; encodedI < encoded.length(); encodedI++){
|
||||
char c = encoded.charAt(encodedI);
|
||||
if(c == '+'){
|
||||
decodedBuilder.append(' ');
|
||||
} else if(c == '%'){
|
||||
Integer digitHigh = HEX_VALUES.get(encoded.charAt(++encodedI));
|
||||
Integer digitLow = HEX_VALUES.get(encoded.charAt(++encodedI));
|
||||
if(digitHigh == null || digitLow == null){
|
||||
ok = false;
|
||||
} else {
|
||||
decodedBuilder.append((char)(16*digitHigh + digitLow));
|
||||
}
|
||||
} else {
|
||||
decodedBuilder.append(c);
|
||||
}
|
||||
}
|
||||
if(ok){
|
||||
return Optional.of(decodedBuilder.toString());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.usi.sq.util;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
class CollectionUtilsTest {
|
||||
private static final double EPSILON = 1e-6;
|
||||
|
||||
@Test
|
||||
void testMean_Normal() {
|
||||
int[] values = new int[]{1,2,3,4};
|
||||
|
||||
double actual = CollectionUtils.mean(values,0,4);
|
||||
assertEquals(2.5, actual, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMean_ZeroLength() {
|
||||
int[] values = new int[]{1,2,3,4};
|
||||
|
||||
double actual = CollectionUtils.mean(values,0,0);
|
||||
assertEquals(Double.NaN, actual, EPSILON);
|
||||
}
|
||||
}
|
Reference in a new issue