Skip to content

Commit

Permalink
cross function test suite. #1204
Browse files Browse the repository at this point in the history
  • Loading branch information
jackyq2015 committed Jun 28, 2017
1 parent f8bf4f9 commit 1ee339c
Show file tree
Hide file tree
Showing 2 changed files with 209 additions and 1 deletion.
2 changes: 1 addition & 1 deletion main/src/com/google/refine/expr/functions/Cross.java
Expand Up @@ -79,7 +79,7 @@ public void write(JSONWriter writer, Properties options)
throws JSONException {

writer.object();
writer.key("description"); writer.value("join with anothe project by column");
writer.key("description"); writer.value("join with another project by column");
writer.key("params"); writer.value("cell c, string projectName, string columnName");
writer.key("returns"); writer.value("array");
writer.endObject();
Expand Down
@@ -0,0 +1,208 @@

package com.google.refine.tests.expr.functions;

import static org.mockito.Mockito.mock;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;

import org.json.JSONObject;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.google.refine.ProjectManager;
import com.google.refine.ProjectMetadata;
import com.google.refine.RefineServlet;
import com.google.refine.expr.EvalError;
import com.google.refine.expr.HasFieldsListImpl;
import com.google.refine.expr.WrappedRow;
import com.google.refine.grel.ControlFunctionRegistry;
import com.google.refine.grel.Function;
import com.google.refine.importers.SeparatorBasedImporter;
import com.google.refine.importing.ImportingJob;
import com.google.refine.importing.ImportingManager;
import com.google.refine.model.Project;
import com.google.refine.model.Row;
import com.google.refine.tests.ProjectManagerStub;
import com.google.refine.tests.RefineServletStub;
import com.google.refine.tests.RefineTest;

/**
* Test cases for cross function.
*/
public class CrossFunctionTests extends RefineTest {
static Properties bindings;

@Override
@BeforeTest
public void init() {
logger = LoggerFactory.getLogger(this.getClass());
}

// dependencies
RefineServlet servlet;
Project projectGift;
Project projectAddress;
ProjectMetadata metadata;
ImportingJob job;
JSONObject options;
SeparatorBasedImporter importer;

@BeforeMethod
public void SetUp() {
bindings = new Properties();

servlet = new RefineServletStub();
ProjectManager.singleton = new ProjectManagerStub();
ImportingManager.initialize(servlet);
projectAddress = new Project();

job = ImportingManager.createJob();
options = mock(JSONObject.class);
importer = new SeparatorBasedImporter();

createMyAddressBook();
projectGift = createChristmasGifts();
bindings.put("project", projectGift);

// add a column address based on column recipient
bindings.put("columnName", "recipient");
}

// data from: https://github.com/OpenRefine/OpenRefine/wiki/GREL-Other-Functions
private Project createMyAddressBook() {
String projectName = "My Address Book";
String input = "friend;address\n"
+ "john;120 Main St.\n"
+ "mary;50 Broadway Ave.\n"
+ "john;999 XXXXXX St.\n" // john's 2nd address
+ "anne;17 Morning Crescent\n";
return createProject(projectName, input);
}

private Project createChristmasGifts() {
String projectName = "Christmas Gifts";
String input = "gift;recipient\n"
+ "lamp;mary\n"
+ "clock;john\n";
return createProject(projectName, input);
}

private Project createProject(String projectName, String input) {
Project project = new Project();
ProjectMetadata metadata = new ProjectMetadata();

metadata.setName(projectName);
prepareOptions(";", -1, 0, 0, 1, false, false);

This comment has been minimized.

Copy link
@thadguidry

thadguidry Jun 28, 2017

Member

Why is the third to last not a boolean ? Isn't that guessCellValueTypes in prepareOptions() ? wait a sec...I see 8 options in prepareOptions() but only 7 here. We should probably set all 8 for the test case, and not rely on defaults (which might change in future)

This comment has been minimized.

Copy link
@jackyq2015

jackyq2015 Jun 29, 2017

Author Contributor

Yes, there are 7 arguments and we set 8. storeBlankCellsAsNulls is hard coded to true by mocking the method. ie, there's no default value used by test case. They are all set in the test case by different ways. That's the way other similar importing UT use. I think the reasoning is that option storeBlankCellsAsNulls is not required tweaked.

This comment has been minimized.

Copy link
@thadguidry

thadguidry Jun 29, 2017

Member

Ah, your probably right. OK. thanks @jackyq2015 !

List<Exception> exceptions = new ArrayList<Exception>();
importer.parseOneFile(project, metadata, job, "filesource", new StringReader(input), -1, options, exceptions);
project.update();
ProjectManager.singleton.registerProject(project, metadata);

return project;
}

@AfterMethod
public void TearDown() {
ImportingManager.disposeJob(job.id);
ProjectManager.singleton.deleteProject(projectGift.id);
ProjectManager.singleton.deleteProject(projectAddress.id);
job = null;
metadata = null;
projectGift = null;
projectAddress = null;
options = null;
importer = null;
}


@Test
public void crossFunctionOneToOneTest() throws Exception {
Row row = ((Row)((WrappedRow) ((HasFieldsListImpl) invoke("cross", "mary", "My Address Book", "friend")).get(0)).row);
String address = row.getCell(1).value.toString();
Assert.assertEquals(address, "50 Broadway Ave.");
}

/**
* To demonstrate that the cross function can join multiple rows.
*/
@Test
public void crossFunctionOneToManyTest() throws Exception {
Row row = ((Row)((WrappedRow) ((HasFieldsListImpl) invoke("cross", "john", "My Address Book", "friend")).get(1)).row);
String address = row.getCell(1).value.toString();
Assert.assertEquals(address, "999 XXXXXX St.");
}


@Test
public void crossFunctionCaseSensitiveTest() throws Exception {
Assert.assertNull(invoke("cross", "Anne", "My Address Book", "friend"));
}

/**
* If no match, return null.
*
* But if user still apply grel:value.cross("My Address Book", "friend")[0].cells["address"].value,
* from the "Preview", the target cell shows "Error: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0".
* It will still end up with blank if the onError set so.
*/
@Test
public void crossFunctionMatchNotFoundTest() throws Exception {
Assert.assertNull(invoke("cross", "NON-EXIST", "My Address Book", "friend"));
}

/**
*
* rest of cells shows "Error: cross expects a string, a project name to join with, and a column name in that project"
*/
@Test
public void crossFunctionNonLiteralValue() throws Exception {
Assert.assertEquals(((EvalError) invoke("cross", 1, "My Address Book", "friend")).message,
"cross expects a string, a project name to join with, and a column name in that project");

Assert.assertEquals(((EvalError) invoke("cross", null, "My Address Book", "friend")).message,
"cross expects a string, a project name to join with, and a column name in that project");

Assert.assertEquals(((EvalError) invoke("cross", Calendar.getInstance(), "My Address Book", "friend")).message,
"cross expects a string, a project name to join with, and a column name in that project");
}

/**
* Lookup a control function by name and invoke it with a variable number of args
*/
private static Object invoke(String name,Object... args) {
// registry uses static initializer, so no need to set it up
Function function = ControlFunctionRegistry.getFunction(name);
if (function == null) {
throw new IllegalArgumentException("Unknown function "+name);
}
if (args == null) {
return function.call(bindings,new Object[0]);
} else {
return function.call(bindings,args);
}
}


private void prepareOptions(
String sep, int limit, int skip, int ignoreLines,
int headerLines, boolean guessValueType, boolean ignoreQuotes) {

whenGetStringOption("separator", options, sep);
whenGetIntegerOption("limit", options, limit);
whenGetIntegerOption("skipDataLines", options, skip);
whenGetIntegerOption("ignoreLines", options, ignoreLines);
whenGetIntegerOption("headerLines", options, headerLines);
whenGetBooleanOption("guessCellValueTypes", options, guessValueType);
whenGetBooleanOption("processQuotes", options, !ignoreQuotes);
whenGetBooleanOption("storeBlankCellsAsNulls", options, true);
}

}

0 comments on commit 1ee339c

Please sign in to comment.