JUnit testing method with assertions - testing

The isSorted() instance method in class A has a bug:
public class A {
private int[] a;
public A(int[] a) { this.a = a; }
/** Return true if this A object contains an array sorted
* in nondecreasing order; else false. */
public boolean isSorted() {
for(int i=1; i<a.length-1; i++) {
if(a[i] < a[i-1]) return false;
}
return true;
}
}
Write a JUnit test method testIsSorted() which will fail because of this bug, but will pass when the bug is fixed.
(Assume that there is no setUp() method defined.)
This is the answer:
public void testIsSorted() {
int[] array = {2, 1};
A haha = new A(array);
assertFalse(haha.isSorted);
}
first of all where is the bug, i cannot seem to located it.
Secondly shoudn't it be assertTrue(haha.isSorted)
because when its assertFalse it will pass because the array is in descending order, therefore the isSorted will return false and assertFalse(false) will return true where-as assertTrue(false) will return false.

The bug is on the line
for(int i=1; i<a.length-1; i++) {
Since array indexes start at 0, the definition of i should be int i=0, not 1. The index 1 points to the second element of the array.
The assertFalse statement checks that the isSorted() method returns false for the given array {2,1}. The isSorted() method checks that no entry is less than the previous one (conversely, each entry is greater than or equal to the previous one). In the example, it will return false, because 2 at index 0 is greater than 1 at index 1. Therefore, the assertFalse is the correct assertion for the case.
You could also test like this (note the reversed order of array).
public void testIsSorted() {
int[] array = {1, 2};
A haha = new A(array);
assertTrue(haha.isSorted());
}

Related

Error "Out of segment space" in VMEmulator cause by a getter mwthod in Jack

I am doing a project for nand2tetris. We write a program in Jack and test it on VMEmulator. The class looks like this:
class List {
field int data;
field List next;
/* Creates a new List object. */
constructor List new(int car, List cdr) {
let data = car;
let next = cdr;
return this;
}
/* Disposes this List by recursively disposing its tail. */
method void dispose() {
if (~(next = null)) {
do next.dispose();
}
// Use an OS routine to recycle the memory held by this object.
do Memory.deAlloc(this);
return;
}
/* Prints the list*/
method void print() {
do Output.printString(" -> ");
do Output.printInt(data);
if (~(next = null)) {
do next.print();
}
return;
}
/* Inserts the argument in the right position of the list (ascending order)*/
method void insertInOrder(int ins){
var List prev, curr, insert;
let prev = this;
let curr = prev.getnext();
while (ins > prev.getdata()){
if (ins < curr.getdata()){
let insert = List.new(ins, curr);
do prev.setnext(insert);
}
else{
let prev = prev.getnext();
let curr = prev.getnext();
}
}
return;
}
/* Searches the argument in the list, if found, it returns the corresponding List object*/
method List find(int toFind){
var List temp;
var List equal;
var boolean found;
let temp = this;
let found = false;
while (~(next = null)){
if(toFind = temp.getdata()){
let equal = temp;
let found = true;
}
let temp = temp.getnext();
}
if (found){
return equal;
}
else{
return null;
}
}
method List getnext(){
return next;
}
method void setnext(List object){
let next = object;
return;
}
method int getdata(){
return data;
}
}
It has one private variable data and a pointer next. So I wrote getter and setter method to return those values. Other methods are fine only the getdata()method is incorrect. When it runs through the VMEmulator, it shows the error Out of segment space in List.getdata.3. This shows in the VMEmulator.
0function List.getdata0
1push argument0
2pop pointer0
3push this 0
4return
the error is at the 4th line return. When I change the Jack code, the same error is still at the 4th line.
What exactly is the problem in my getter method?
When you run a VM program on the VMEmulator you must first manually set the pointers to the various segments, otherwise you may get an "Out of segment space" error.
To understand the necessary settings, look at what the corresponding .tst file does. An alternative method is to insert the proposed code inside a function, since the function call automatically makes this type of setting.
You can get this error when you try to access member data of an object which is not constructed. Could it be that the List cdr in the constructor was not properly constructed?

How do I properly write out a JUnit test for a method that counts how many e's are in a string?

Here is the method I have defined that is supposed to accept a String as input and should return the number of times the char 'e' occurs as an int:
public int count_e(String input){
int count = 0;
for (int i = 0;i<input.length();i++){
char e = 'e';
if (input.charAt(i)==e){
count=count+1;
i++;
return count;
}
else{
count=count+1;
i++;
}
}
return count;
}
}
I am trying to write a JUnit test to see if I can input a string into the method and return the correct number of e's. Below is my test, and at the moment I keep getting an error saying that my method count_e is undefined for type String.
Can someone tell me why it is coming up as undefined?
#Test
public void testCount_e() {
String input= "Isabelle";
int expected= 2;
int actual=input.count_e();
assertTrue("There are this many e's in the String.",expected==actual);
}
}
You failed to pass anything to your count_e method!
How about something like:
#Test
public void testCount_e() {
String input = "Isabelle";
int expected = 2;
int actual = count_e(input);
Assert.assertEqual("There are this many e's in the String.", expected, actual);
}
For a unit test, you could probably shorten it to:
#Test
public void testCount_e() {
Assert.assertEqual("There are this many e's in the String.", count_e("Isabelle"), 2);
}

Why is this method throwing a null pointer exception?

I'm attempting to write a class to create a prefix tree (or trie) with an addWord method that takes in a string as a parameter and stores each character in it's appropriate place in the tree.
However, I keep getting a NullPointerException in the line of my first if statement (indicated below). Can anyone help me understand what's causing this? Thank you in advance!
public class PrefixTree {
private Node root;
public PrefixTree () {
root = new Node();
}
public void addWord(String word) {
int length = word.length();
char currentCharacter = word.charAt(0);
Node currentNode = root;
//Essentially this is saying "for each character in the string..."
for(int i=0; i<length; i++){
currentCharacter= word.charAt(i);
//if the children array of parent node does not contain the current character
//create a new node and add it to the parent array.
//HERE IS WHERE THE EXCEPTION IS BEING THROWN
if(currentNode.children[currentCharacter - 'a'] == null) {
Node newNode = new Node();
//set the node character value equal to the current character
newNode.c=currentCharacter;
//add the new node to the child array of its parent node
currentNode.children[currentCharacter - 'a']= newNode;
//if this is the last character in the word, change the endWord value to true
if( i == length-1) {
newNode.endWord = true;
//stores the complete string in its ending node
newNode.fullWord = word;
}
//set current node equal to the new node created and repeat the process
currentNode = newNode;
}
}
}
private class Node {
public boolean endWord;
public char c;
public Node[] children;
public String fullWord;
public Node(){
c = '0';
endWord = false;
Node[] children = new Node[26];
//Stores the complete string of a word ending w/ this node to make life easier later
String fullWord = null;
}
}
public static void main(String [] args){
PrefixTree test = new PrefixTree();
test.addWord("test");
}
}
Because you're assigning to local variables in Node's constructor. Change to this:
public Node(){
c = '0';
endWord = false;
this.children = new Node[26];
//Stores the complete string of a word ending w/ this node to make life easier later
this.fullWord = null;
}

Comparator in binary search

I am not sure how to write comparator for Collectionos.binarySearch(). Can anyone help ? sample code:
List<Object> list1 = new ArrayList<>();
List<List<Object>> list2 = new ArrayList<>();
//loop starts
// adds elements into list1
list1.add(values);//values is an object containing elements like [3, John, Smith]
if (list2.size() == 0) {
list2.add(list1);//first element
} else {
if (index >= 0) {
int index = Collections.binarySearch(list2, list1, comparator);
list2.add(index, list1);//I want to add these elements in ascending order ?
}
}
//loop ends
How do I write comparator, so that elements in list 2 are added in ascending or descending order.
You can use an anonymous class which implements a Comparator<List<Object>>:
int index = Collections.binarySearch(list2, list1, new Comparator<List<Object>>() {
#Override
public int compare(List<Object> o1, List<Object> o2) {
// Your implementation here
return 0;
}
});
You could implement an IComparer<List<Object>> class, or use a lambda expression.
You just need to create a class that implements the Comparator interface.
For example, you can do this inline with an anonymous class:
Comparator<List<Object>> comparator = new Comparator<List<Object>>() {
#Override
public int compare(List<Object> x, List<Object> y) {
// custom logic to compare x and y here. Return a negative number
// if x < y, a positive number if x > y, and 0 otherwise
}
};
Collections.binarySearch(list, comparator);

How to multiply several fields in a tuple by a given field of the tuple

For each row of data, I would like to multiply fields 1 through N by field 0. The data could have hundreds of fields per row (or a variable number of fields for that matter), so writing out each pair is not feasible. Is there a way to specify a range of fields, sort of like the the following (incorrect) snippet?
A = LOAD 'foo.csv' USING PigStorage(',');
B = FOREACH A GENERATE $0*($1,..);
A UDF could come in handy here.
Implement exec(Tuple input) and iterate over all fields of the tuple as follows (not tested):
public class MultiplyField extends EvalFunc<Long> {
public Long exec(Tuple input) throws IOException {
if (input == null || input.size() == 0) {
return null;
}
try {
Long retVal = 1;
for (int i = 0; i < input.size(); i++) {
Long j = (Long)input.get(i);
retVal *= j;
}
return retVal;
} catch(Exception e) {
throw WrappedIOException.wrap("Caught exception processing input row ", e);
}
}
}
Then register your UDF and call it from your FOREACH.