Phase 02 Submission V1

This commit is contained in:
Michael Chen 2022-05-04 23:56:21 +02:00
parent 0cebf35e25
commit fa3c062d2d
No known key found for this signature in database
GPG Key ID: 1CBC7AA5671437BB
3 changed files with 170 additions and 12 deletions

View File

@ -0,0 +1,131 @@
package com.alibaba.fastjson.parser;
import com.alibaba.fastjson.JSONException;
import org.junit.Assert;
import org.junit.Test;
public class JSONScannerTest {
@Test
public void inputTokenTest_Comma() throws Throwable {
JSONScanner scanner = new JSONScanner(",");
scanner.nextToken();
Assert.assertEquals(JSONToken.COMMA, scanner.token());
}
@Test
public void inputTokenTest_String() throws Throwable {
JSONScanner scanner = new JSONScanner("\"text\"");
scanner.nextToken();
Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
Assert.assertEquals("text", scanner.stringVal());
}
@Test
public void inputTokenTest_Integer() throws Throwable {
JSONScanner scanner = new JSONScanner("-352");
scanner.nextToken();
Assert.assertEquals(JSONToken.LITERAL_INT, scanner.token());
Assert.assertEquals(-352, scanner.intValue());
}
@Test
public void inputTokenTest_True() throws Throwable {
JSONScanner scanner = new JSONScanner("true");
scanner.nextToken();
Assert.assertEquals(JSONToken.TRUE, scanner.token());
}
@Test
public void inputTokenTest_False() throws Throwable {
JSONScanner scanner = new JSONScanner("false");
scanner.nextToken();
Assert.assertEquals(JSONToken.FALSE, scanner.token());
}
@Test
public void inputTokenTest_Float() throws Throwable {
JSONScanner scanner = new JSONScanner("2.5e2");
scanner.nextToken();
Assert.assertEquals(JSONToken.LITERAL_FLOAT, scanner.token());
}
@Test
public void inputTokenTest_Null() throws Throwable {
JSONScanner scanner = new JSONScanner("null");
scanner.nextToken();
Assert.assertEquals(JSONToken.NULL, scanner.token());
}
@Test
public void scannerSequenceTest() throws Throwable {
JSONScanner scanner = new JSONScanner("5,:");
scanner.nextToken();
Assert.assertEquals(JSONToken.LITERAL_INT, scanner.token());
Assert.assertEquals(5, scanner.intValue());
scanner.nextToken();
Assert.assertEquals(JSONToken.COMMA, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.COLON, scanner.token());
}
@Test
public void scannerPositionTest() throws Throwable {
JSONScanner scanner = new JSONScanner("5,:");
scanner.nextToken();
Assert.assertEquals(0, scanner.pos());
scanner.nextToken();
Assert.assertEquals(1, scanner.pos());
scanner.nextToken();
Assert.assertEquals(2, scanner.pos());
}
@Test
public void scannerEofTest() throws Throwable {
JSONScanner scanner = new JSONScanner("5,:");
scanner.nextToken();
scanner.nextToken();
scanner.nextToken(); // colon
// scanner should now enter EOF
scanner.nextToken();
Assert.assertTrue(scanner.isEOF());
Assert.assertEquals(JSONToken.EOF, scanner.token());
}
@Test(expected=JSONException.class)
public void scannerInputFormatTest_Invalid() throws Throwable {
JSONScanner scanner = new JSONScanner("53fds"); // invalid literal value
scanner.nextToken(); // consumes numeric token
scanner.nextToken(); // should raise invalid literal
}
@Test()
public void complexExampleTest() throws Throwable {
JSONScanner scanner = new JSONScanner("{\"Name\":\"Michael\",\"Last\":\"Chen\"}");
scanner.nextToken();
Assert.assertEquals(JSONToken.LBRACE, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.COLON, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.COMMA, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.COLON, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.RBRACE, scanner.token());
scanner.nextToken();
Assert.assertEquals(JSONToken.EOF, scanner.token());
}
}

View File

@ -4,7 +4,7 @@ name = MichaelChen
solutionname = Solution_Phase$(phase)_$(name) solutionname = Solution_Phase$(phase)_$(name)
target = $(solutionname)_V$(version).zip target = $(solutionname)_V$(version).zip
package = $(solutionname).pdf Phase02_Task2_ACTS_System.txt Phase02_Task2_ACTS_System.result.txt package = $(solutionname).pdf Phase02_Task2_ACTS_System.txt Phase02_Task2_ACTS_System.result.txt JSONScannerTest.java
latexmkflags = latexmkflags =
actspath = "C:\\Program Files (x86)\\ACTS\\acts_3.2.jar" actspath = "C:\\Program Files (x86)\\ACTS\\acts_3.2.jar"

View File

@ -7,6 +7,7 @@
\usepackage{subcaption} \usepackage{subcaption}
\usepackage{amsmath} \usepackage{amsmath}
\usepackage{float} \usepackage{float}
\usepackage{fancyvrb} % for "\Verb" macro
\usepackage{hyperref} \usepackage{hyperref}
\usepackage{pgf} \usepackage{pgf}
@ -206,12 +207,12 @@
\begin{enumerate}[topsep=0pt, leftmargin=*] \begin{enumerate}[topsep=0pt, leftmargin=*]
\item Explain why the selected method is suitable for the input domain model approach (1-2 sentences) \item Explain why the selected method is suitable for the input domain model approach (1-2 sentences)
\begin{answer} \begin{answer}
[TODO: Add answer here] I chose the \texttt{JSONScanner.token()} function as a test subject. This method is particularly interesting because it is does not have any direct function parameters but rather solely depends on the state of an object as an input parameter. This does not make the method particularly suitable for the IDM approach, but it is still important to test this method extensively because the entire project is based on this.
\end{answer} \end{answer}
\item Identify the input domain of your method (2-3 sentences) \item Identify the input domain of your method (2-3 sentences)
\begin{answer} \begin{answer}
[TODO: Add answer here] The \texttt{JSONScanner} is quite a complex object and not all of the fields are of interest for this specific method so I will only name input parameters that are relevant for this test subject. Most significantly the text field of the scanner is of importance because it provides the scanner with the raw character data it has to tokenize (called $t$). Next the current token position and the token end position are important to keep track of the current state of the lexer. Finally the input text length is of importance as a boundary to the position parameters. This also influences the EOF state of the object, which signals if the input buffer is exhausted.
\end{answer} \end{answer}
\item Similar to task 2, gather the results of the following sub-tasks as shown in Table~\ref{table:example}: \item Similar to task 2, gather the results of the following sub-tasks as shown in Table~\ref{table:example}:
@ -220,31 +221,57 @@
\item Derive sets of equivalence classes from these characteristics (Note: At least one of your partitions must consist of a number of blocks $\geq 3$. Also make sure that you have enough characteristics and corresponding blocks to derive $12$ distinct tests from them later on.) \item Derive sets of equivalence classes from these characteristics (Note: At least one of your partitions must consist of a number of blocks $\geq 3$. Also make sure that you have enough characteristics and corresponding blocks to derive $12$ distinct tests from them later on.)
\end{enumerate} \end{enumerate}
\begin{answer} \begin{answer}
[TODO: Add answer here] See table~\ref{tab:scannercharacteristics}. Note: the predicates valid and invalid on $t$ correspond to the input containing a well-formed sequence of tokens or not, respectively.
\begin{table}
\centering
\begin{tabular}{llll}
\hline
Characteristic & Eq-Class 1 & Eq-Class 2 & Eq-Class 3 \\
\hline
$q_1 = \text{"input token"}$ & others & \multicolumn{2}{c}{$\forall T : \{ t = "T" \}$} \\
$q_2 = \text{"position"}$ & $\{0<\text{pos}<\text{len}-1\}$ & $\{\text{pos}=0\}$ & $\{\text{pos}=\text{len}-1\}$ \\
$q_3 = \text{"EOF state"}$ & $\{\text{eof} = \texttt{true}\}$ & $\{\text{eof} = \texttt{false}\}$ \\
$q_4 = \text{"input format"}$ & $\{t\text{ is valid}\}$ & $\{t\text{ is invalid}\}$ \\
\hline
\end{tabular}
\caption{Characteristics for the \texttt{JSONScanner.token()} function}
\label{tab:scannercharacteristics}
\end{table}
\end{answer} \end{answer}
\item Can you identify any non-valid combinations of blocks from your characteristics? (1-2 sentences) \item Can you identify any non-valid combinations of blocks from your characteristics? (1-2 sentences)
\begin{answer} \begin{answer}
[TODO: Add answer here] Because the EOF flag and the position are tightly coupled. If a token at the current position consumes the rest of the input buffer the object will signal an EOF soon. Another invalid combination is between characteristics $q_1$ and $q_4$, because trivially every input token as a string is also a well-formed trivial sequence of tokens, this the second class of $q_4$ is not achievable with any of the token strings.
\end{answer} \end{answer}
\item Derive (at least) one representative value for each equivalence class. Which strategy did you use for the value selection? \item Derive (at least) one representative value for each equivalence class. Which strategy did you use for the value selection?
\begin{answer} \begin{answer}
[TODO: Add answer here] See table~\ref{tab:scannervalues}.
\begin{table}
\centering
\begin{tabular}{llll}
\hline
Characteristic & Val-Class 1 & Val-Class 2 & Val-Class 3 \\
\hline
$q_1 = \text{"input token"}$ & \texttt{"5,:"} & \multicolumn{2}{c}{\texttt{""text""}, \texttt{"5"}, \texttt{":"}, $\dots$} \\
$q_2 = \text{"position"}$ & $1$ & $0$ & $\text{len}-1$ \\
$q_3 = \text{"EOF state"}$ & \texttt{true} & \texttt{false} \\
$q_4 = \text{"input format"}$ & \multicolumn{2}{c}{\Verb+"\{"Name":"Michael","Last":"Chen"\}"+} & \texttt{"53fds"} \\
\hline
\end{tabular}
\caption{Characteristics for the \texttt{JSONScanner.token()} function}
\label{tab:scannervalues}
\end{table}
\end{answer} \end{answer}
\item Combine the selected values from the partitions of each input argument to complete test vectors. You can decide whether you want to approach this sub-task manually or using \textit{ACTS} (therefore, only the resulting vectors should be documented). \item Combine the selected values from the partitions of each input argument to complete test vectors. You can decide whether you want to approach this sub-task manually or using \textit{ACTS} (therefore, only the resulting vectors should be documented).
\begin{answer} \begin{answer}
[TODO: Add answer here] See test suite in file \texttt{JSONScannerTest.java}.
\end{answer} \end{answer}
\item Create JUnit tests for your method, which trigger test runs with the selected test vectors, and assert each individual output. For the submission, merge all these tests into one \texttt{*.java} file. \item Create JUnit tests for your method, which trigger test runs with the selected test vectors, and assert each individual output. For the submission, merge all these tests into one \texttt{*.java} file.
\begin{answer} \begin{answer}
[TODO: Add answer here] See test suite in file \texttt{JSONScannerTest.java}.
\begin{lstlisting}[language=Java,belowskip=-0.8\baselineskip]
/* Add code here */
\end{lstlisting}
\end{answer} \end{answer}
\end{enumerate} \end{enumerate}