code: package com.taxonic.carml.logical_source_resolver;
  
  import static org.hamcrest.MatcherAssert.assertThat;
  import static org.hamcrest.core.Is.is;
  
  import com.google.common.collect.Iterables;
  import com.google.common.collect.Lists;
  import com.taxonic.carml.engine.EvaluateExpression;
  import com.taxonic.carml.logical_source_resolver.LogicalSourceResolver.ExpressionEvaluatorFactory;
  import com.taxonic.carml.model.LogicalSource;
  import com.taxonic.carml.model.impl.CarmlLogicalSource;
  import com.taxonic.carml.vocab.Rdf.Ql;
  import com.univocity.parsers.common.record.Record;
  import java.io.IOException;
  import java.nio.charset.StandardCharsets;
  import java.util.List;
  import java.util.function.Function;
  import org.apache.commons.io.IOUtils;
  import org.junit.Before;
  import org.junit.Test;
  
  public class CsvResolverTest {
  	
  	private static final String SOURCE = 
  			"Year,Make,Model,Description,Price\r\n" + 
  			"1997,Ford,E350,\"ac, abs, moon\",3000.00\r\n" + 
  			"1999,Chevy,\"Venture \"\"Extended Edition\"\"\",\"\",4900.00" ;
  	
  	private static final LogicalSource LSOURCE = 
  			new CarmlLogicalSource(SOURCE, null, Ql.Csv);
  	
  	private static final String SOURCE_DELIM = 
  			"Year^Make^Model^Description^Price\r\n" + 
  			"1997^Ford^E350^\"ac, abs, moon\"^3000.00\r\n" + 
  			"1999^Chevy^\"Venture \"\"Extended Edition\"\"\"^\"\"^4900.00" ;
  	
  	private static final LogicalSource LSOURCE_DELIM = 
  			new CarmlLogicalSource(SOURCE_DELIM, null, Ql.Csv);
  	
  	private Function<Object, String> sourceResolver = s -> s.toString();
  	
  	private CsvResolver csvResolver;
  	
  	@Before
  	public void init() {
  		csvResolver = new CsvResolver();
  	}
  	
  	@Test
  	public void sourceIterator_givenCsv_shoulReturnAllRecords() {	
  		Iterable<Record> recordIterator = csvResolver.bindSource(LSOURCE, sourceResolver).get();
  		assertThat(Iterables.size(recordIterator), is(2));
  	}
  	
  	@Test
  	public void sourceIterator_givenRandomDelimitedCsv_shoulReturnAllCorrectRecords() {
  		Iterable<Record> recordIterator = csvResolver.bindSource(LSOURCE_DELIM, sourceResolver).get();
  		List<Record> records = Lists.newArrayList(recordIterator);
  		assertThat(records.size(), is(2));
  		assertThat(records.get(0).getValues().length, is(5));
  	}
  	
  	@Test
  	public void expressionEvaluator_givenExpression_shoulReturnCorrectValue() {
  		String expression = "Year";
  		Iterable<Record> recordIterator = csvResolver.bindSource(LSOURCE, sourceResolver).get();
  		ExpressionEvaluatorFactory<Record> evaluatorFactory = 
  				csvResolver.getExpressionEvaluatorFactory();
  		
  		List<Record> records = Lists.newArrayList(recordIterator);
  		EvaluateExpression evaluateExpression = evaluatorFactory.apply(records.get(0));
  		assertThat(evaluateExpression.apply(expression).get(), is("1997"));
  	}
  
  	@Test
  	public void expressionEvaluator_shouldMapLargeColumns() throws IOException {
  		String csv = IOUtils.toString(CsvResolverTest.class.getResourceAsStream("large_column.csv"), StandardCharsets.UTF_8);
  		LogicalSource logicalSource = new CarmlLogicalSource(csv, null, Ql.Csv);
  		Iterable<Record> recordIterator = csvResolver.bindSource(logicalSource, sourceResolver).get();
  		assertThat(Iterables.size(recordIterator), is(1));
  	}
  }
  