1   package com.trikelane.turtlescript;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.IOException;
6   import java.io.StringReader;
7   import java.util.Arrays;
8   import java.util.Collection;
9   import java.util.LinkedList;
10  import java.util.List;
11   
12  import org.apache.log4j.Logger;
13  import org.junit.Assert;
14  import org.junit.BeforeClass;
15  import org.junit.Test;
16  import org.junit.runner.RunWith;
17  import org.junit.runners.Parameterized;
18  import org.junit.runners.Parameterized.Parameters;
19  import org.mozilla.javascript.Context;
20  import org.mozilla.javascript.ContextFactory;
21  import org.mozilla.javascript.Scriptable;
22  import org.mozilla.javascript.ScriptableObject;
23  import org.mozilla.javascript.WrapFactory;
24  
25  import com.hp.hpl.jena.rdf.model.Model;
26  import com.hp.hpl.jena.rdf.model.ModelFactory;
27  import com.hp.hpl.jena.util.FileUtils;
28   
29  /**
30   * W3C Acceptance Tests
31   */
32  @RunWith(value = Parameterized.class)
33  public class W3CTest {
34  	 private static Logger logger = Logger.getLogger(W3CTest.class);
35  	
36  	 private File ttlFile;
37  	 private File outFile;
38   
39  	 public W3CTest(File ttlFile) {
40  		 this.ttlFile = ttlFile;
41  		 this.outFile = new File(ttlFile.getAbsolutePath().replaceAll("\\.ttl$", ".out"));
42  	 }
43  	 
44  	 @Parameters
45  	 public static Collection<File[]> data() {
46  	   List<File[]> files = new LinkedList<File[]>();
47  
48  	   for( File file : new File("target/w3cTests").listFiles()) {
49  		   String fileName = file.getName();
50  		   if (fileName.matches("^test-[0-9]+\\.ttl$") &&
51  				 !(fileName.equals("test-01.ttl") ||
52  				   fileName.equals("test-14.ttl") ||
53  				   fileName.equals("test-15.ttl") ||
54  				   fileName.equals("test-16.ttl") ||
55  				   fileName.equals("test-14.ttl") ||
56  				   fileName.equals("test-18.ttl") ||
57  				   fileName.equals("test-23.ttl") ||
58  				   fileName.equals("test-28.ttl") ||
59  				   fileName.equals("test-29.ttl"))) {
60  			   files.add( new File[] { file } );
61  		   }
62  	   }
63  	   return files;
64  	 }
65  	  
66  	 @Test(timeout=15000)
67  	 public void pushTest() throws IOException {
68  		 logger.debug(ttlFile.getAbsolutePath());
69  		 logger.debug(outFile.getAbsolutePath());
70  		 
71  		 String ttlString = FileUtils.readWholeFileAsUTF8(new FileInputStream(ttlFile)).replaceAll("\\\\(u)", "\\\\\\\\u");
72  		 
73  		 logger.debug("fileAsUTF8: " + ttlString);
74  		 
75  		 String base = "http://www.w3.org/2001/sw/DataAccess/df1/tests/" + ttlFile.getName();
76  		 
77  		 if (ttlFile.getName().equals("test-30.ttl")) {
78  			 base = "http://www.w3.org/2001/sw/DataAccess/df1/tests/";  // per comment in the test file.
79  		 }
80  		 
81  		 String result = helper(ttlString, "printNTriples();\n", base);
82  		 logger.debug(result);
83  		 
84  		 Model ttlModel = ModelFactory.createDefaultModel();
85  		 ttlModel.read(new StringReader(result), "", "N-TRIPLES");
86  		 
87  		 Model outModel = ModelFactory.createDefaultModel();
88  		 outModel.read(new FileInputStream(outFile), "http://www.w3.org/2001/sw/DataAccess/df1/tests/", "N-TRIPLES");
89  		 
90  		 boolean pass = ttlModel.isIsomorphicWith(outModel);
91  		 logger.debug("Pass: " + pass);
92  		 
93  		 Assert.assertTrue(pass);
94  	 }
95   
96  		public static Class getSandboxClassLoader() {
97  			return SandboxClassLoader.class;
98  		}
99  			
100 		/**
101 		 * rhino.js by default (and I haven't figured out a way to override it) loads all of your Java classes
102 		 * into the JavaScript context.  This is causing the org.antlr Java objects to conflict with the org.antlr
103 		 * JavaScript objects.  That said, the custom class loader isn't working yet.
104 		 * 
105 		 * TODO: make the custom class loader work (at not loading all the Java classes).
106 		 */
107 		@BeforeClass
108 		public static void messWithClassLoader() {
109 			ContextFactory.initGlobal(new ContextFactory() {
110 				@Override
111 				protected Context makeContext() {
112 					Context cx = super.makeContext();
113 					cx.setWrapFactory(new WrapFactory() {
114 						@Override
115 						public Object wrap(Context cx, Scriptable scope, Object obj, Class staticType) {
116 							return super.wrap(cx, scope, obj, staticType);
117 						}
118 						@Override
119 						public Scriptable wrapNewObject(Context cx, Scriptable scope, Object obj) {
120 							return super.wrapNewObject(cx, scope, obj);
121 						}
122 						@Override
123 						public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class staticType) {
124 							return new SandboxNativeJavaObject(scope, javaObject, staticType);
125 						}						
126 					});
127 					return cx;
128 				}				
129 			});
130 			ContextFactory factory = ContextFactory.getGlobal();
131 			factory.initApplicationClassLoader(new SandboxClassLoader(TurtleSpecSection2_1Test.class.getClassLoader()));		
132 		} 
133 		
134 		private String helper(String ttlString, String testString, String base) {
135 			StringBuilder script = new StringBuilder();
136 			List<String> javascriptResources = Arrays.asList(
137 				"/html/lib/antlr3-all-min.js",
138 				"/html/lib/antlr3-cli-min.js",
139 				"/TTLLexer.js",
140 				"/TTLParser.js",
141 				"/html/lib/treeTTL.js",
142 				"/html/lib/emitter.js");
143 							
144 			try {
145 				Context cx = ContextFactory.getGlobal().enterContext();
146 				Scriptable scope = cx.initStandardObjects();
147 				Object wrappedOut = Context.javaToJS(System.out, scope);
148 				ScriptableObject.putProperty(scope, "out", wrappedOut);
149 
150 				Object result = null;
151 				
152 				for (String resource : javascriptResources) {
153 					try {
154 						result = cx.evaluateString(scope,
155 						FileUtils.readWholeFileAsUTF8(this.getClass().getResourceAsStream(resource)).replaceAll("org", "xorg"),
156 						resource,
157 						1,
158 						(Object)null);
159 					} catch (NullPointerException e) {
160 						System.out.println("Failed to load " + resource);
161 					}
162 				}
163 				
164 				String escapedString = 
165 					"parseTtlToWalker('" + 
166 					ttlString.replaceAll("org", "xorg").replaceAll("\\n","\\\\n").replaceAll("\\'","\\\\'").replaceAll("\\\\u", "\\\\\\\\u").replaceAll("\\\\U", "\\\\\\\\U") +
167 					 "', '" + base + "'); debugOutput;";
168 				logger.debug(escapedString);
169 				
170 				result = 
171 					cx.evaluateString(
172 						scope, 
173 						escapedString, 
174 						"file:///ttlString", 
175 						1, 
176 						(Object)null);
177 
178 				logger.debug("debugOutput:\n" + result);
179 				
180 				result = 
181 					cx.evaluateString(
182 						scope, 
183 						testString.replaceAll("org", "xorg"), 
184 						"file:///testString", 
185 						1, 
186 						(Object)null);
187 
188 				return Context.toString(result).trim().replaceAll("xorg", "org");
189 			} catch (IOException e) {
190 				e.printStackTrace();
191 			}
192 			
193 			return null;
194 		} 
195 }