/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package org.absmodels.abs.plugin.internal;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.StringReader;
import org.absmodels.abs.plugin.internal.IncrementalModelBuilder;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.junit.Before;
import org.junit.Test;
import abs.frontend.analyser.SemanticConditionList;
import abs.frontend.ast.CompilationUnit;
import abs.frontend.parser.Main;
import abs.frontend.typechecker.locationtypes.infer.LocationTypeInferrerExtension.LocationTypingPrecision;
public class ModelBuilderTest {
private IncrementalModelBuilder modelbuilder;
@Before
public void setupModelBuilder(){
this.modelbuilder = new IncrementalModelBuilder();
}
@Test
public void testTypecheck() throws Exception{
String moduleText =
"//$id: Peertopeer.abs 5108 2010-07-17 20:14:12Z jschaefer $ \n"+
"\n"+
"module PeerToPeer;\n"+
"import * from ImportTest;\n"+
"\n"+
"//type synonyms \n"+
"\n"+
"type Filename = String ;\n"+
"type Filenames = Set<String> ;\n"+
"type Packet = String ;\n"+
"type File = List<Packet> ;\n"+
"type Catalog = List<Pair<Peer, Filenames> > ;\n"+
"\n"+
" \n"+
" \n"+
"// Application functions\n"+
"def Peer findServer(Filename file, Catalog catalog) =\n"+
" case catalog {\n"+
" Nil => null;\n"+
" Cons(Pair(server, files), rest) =>\n"+
" case contains(files, file) { True => server;\n"+
" False => findServer(file, rest); };\n"+
" };\n"+
"\n"+
"interface Server {\n"+
" Filenames enquire();\n"+
" Int getLength(Filename fId);\n"+
" Packet getPack(Filename fId, Int pNbr);\n"+
"}\n"+
"\n"+
"\n"+
"interface Peer extends Client, Server { \n"+
" Unit setAdmin(Network admin);\n"+
" Unit run();\n"+
"}\n"+
"\n"+
"interface Network {\n"+
" List<Peer> getNeighbors(Peer caller);\n"+
"}\n"+
"\n"+
"interface DataBase {\n"+
" File getFile(Filename fId);\n"+
" Int getLength(Filename fId);\n"+
" Unit storeFile(Filename fId, File file);\n"+
" Filenames listFiles();\n"+
"}\n"+
"\n"+
"interface Client {\n"+
" Unit reqFile(Server sId, Filename fId);\n"+
"}\n"+
"\n"+
"class DataBaseImpl(Map<Filename, File> db) implements DataBase {\n"+
" File getFile(Filename fId) {\n"+
" return lookupUnsafe(db, fId);\n"+
" }\n"+
"\n"+
" Int getLength(Filename fId) {\n"+
" return length(lookupUnsafe(db,fId));\n"+
" }\n"+
"\n"+
" Unit storeFile(Filename fId, File file) {\n"+
" db = InsertAssoc(Pair(fId,file), db);\n"+
" } \n"+
"\n"+
" Filenames listFiles() {\n"+
" return keys(db);\n"+
" }\n"+
"}\n"+
"\n"+
"class Node(DataBase db, Filename file) implements Peer {\n"+
" Catalog catalog = Nil;\n"+
" List<Peer> myNeighbors = Nil;\n"+
" Network admin = null;\n"+
"\n"+
" Unit run() {\n"+
" Fut<Catalog> c ; \n"+
" Fut<List<Peer>> f;\n"+
" Server server ; \n"+
"\n"+
" await admin != null;\n"+
" f = admin!getNeighbors(this); // Asynchronous call to admin\n"+
" await f?;\n"+
" myNeighbors = f.get;\n"+
" c = this!availFiles(myNeighbors); // Asynchronous call\n"+
" await c?; // Allow other peers to call in the meantime\n"+
" catalog = c.get; // Build the catalog\n"+
" server = findServer(file, catalog); // Find the server for the requested file\n"+
" if (server != null) {\n"+
" this.reqFile(server,file) ; // Download file\n"+
" }\n"+
" }\n"+
"\n"+
" Unit setAdmin(Network admin) {\n"+
" this.admin = admin;\n"+
" }\n"+
"\n"+
" Filenames enquire() { \n"+
" Fut<Filenames> f ; \n"+
" f = db!listFiles();\n"+
" await f?;\n"+
" return f.get;\n"+
" }\n"+
"\n"+
" Int getLength(Filename fId) {\n"+
" Fut<Int> length ; \n"+
" length = db!getLength(fId);\n"+
" await length?;\n"+
" return length.get;\n"+
" }\n"+
"\n"+
" Packet getPack(Filename fId, Int pNbr) {\n"+
" File f = Nil;\n"+
" Fut<File> ff;\n"+
" ff = db!getFile(fId);\n"+
" await ff?;\n"+
" f = ff.get;\n"+
" return nth(f, pNbr);\n"+
" }\n"+
"\n"+
" Catalog availFiles (List<Peer> sList) {\n"+
" Catalog cat = Nil;\n"+
" Filenames fNames = EmptySet; \n"+
" Fut<Filenames> fN;\n"+
" Catalog catList = Nil; \n"+
" Fut<Catalog> cL;\n"+
"\n"+
" if (sList != Nil) {\n"+
" fN = head(sList)!enquire();\n"+
" cL = this!availFiles(tail(sList));\n"+
" await fN? & cL?;\n"+
" catList = cL.get;\n"+
" fNames = fN.get;\n"+
" cat = appendright(catList, Pair(head(sList), fNames)); \n"+
" }\n"+
" return cat; \n"+
" }\n"+
"\n"+
" Unit reqFile(Server sId, Filename fId) {\n"+
" File file = Nil;\n"+
" Packet pack = \"\";\n"+
" Int lth = 0;\n"+
" Fut<Int> l1;\n"+
" Fut<Packet> l2;\n"+
"\n"+
" l1 = sId!getLength(fId);\n"+
" await l1?;\n"+
" lth = l1.get; \n"+
" while (lth > 0) {\n"+
" lth = lth - 1; // indexing is zero-based\n"+
" l2 = sId!getPack(fId, lth);\n"+
" await l2?;\n"+
" pack = l2.get ;\n"+
" file = Cons(pack, file); \n"+
" } \n"+
" db!storeFile(fId, file);\n"+
" }\n"+
"}\n"+
"\n"+
"class OurTopology(Peer node0, Peer node1, Peer node2, Peer node3)\n"+
"implements Network\n"+
"{\n"+
" List<Peer> getNeighbors(Peer caller) {\n"+
" List<Peer> res = Nil;\n"+
" if (caller == node0) { res = list[node1, node2]; }\n"+
" if (caller == node1) { res = list[node3]; }\n"+
" if (caller == node2) { res = list[node0, node1, node3]; }\n"+
" if (caller == node3) { res = list[node0, node2]; }\n"+
" return res;\n"+
" }\n"+
"}\n"+
"\n"+
"{ \n"+
" Peer node0;\n"+
" Peer node1;\n"+
" Peer node2;\n"+
" Peer node3;\n"+
" DataBase db0;\n"+
" DataBase db1;\n"+
" DataBase db2;\n"+
" Network admin;\n"+
" // Map<Filename, File>\n"+
" db0 = new DataBaseImpl(map[Pair(\"file0\", list[\"file\", \"from\", \"db0\"])]);\n"+
" db1 = new DataBaseImpl(map[Pair(\"file1\", list[\"file\", \"from\", \"db1\"])]);\n"+
" db2 = new DataBaseImpl(map[Pair(\"file2\", list[\"file\", \"from\", \"db2\"])]);\n"+
" node0 = new Node(db0, \"file2\");\n"+
" node1 = new Node(db1, \"file2\");\n"+
" node2 = new Node(db2, \"file1\");\n"+
" node3 = new Node(db2, \"file0\");\n"+
" admin = new OurTopology(node0, node1, node2, node3);\n"+
" node0!setAdmin(admin);\n"+
" node1!setAdmin(admin);\n"+
" node2!setAdmin(admin);\n"+
" node3!setAdmin(admin);\n"+
" \n"+
" node0!run();\n"+
" node1!run();\n"+
" node2!run();\n"+
" node3!run();\n"+
"}\n";
Main absParser = new Main();
CompilationUnit testcu = absParser.parseUnit(new File("PeerToPeer.abs"), moduleText, new StringReader(moduleText));
assertEquals(testcu.getParserErrors().toString(), 0, testcu.getParserErrors().size());
modelbuilder.addCompilationUnit(testcu);
SemanticConditionList testel = modelbuilder.typeCheckModel(new NullProgressMonitor(), true, "Somewhere", LocationTypingPrecision.BASIC.toString(),false);
assertEquals(testel.toString(),1, testel.getErrorCount());
System.err.println("Test 1 finished");
String importTestText = "module ImportTest;";
CompilationUnit importTestCU = absParser.parseUnit(new File("importtest.abs"), importTestText, new StringReader(importTestText));
modelbuilder.addCompilationUnit(importTestCU);
SemanticConditionList testel1 = modelbuilder.typeCheckModel(new NullProgressMonitor(), true, "Somewhere", LocationTypingPrecision.BASIC.toString(),false);
assertEquals(testel1.toString(), 0, testel1.getErrorCount());
System.err.println("Test 2 finished");
modelbuilder.removeCompilationUnit(importTestCU);
SemanticConditionList testel2 = modelbuilder.typeCheckModel(new NullProgressMonitor(), true, "Somewhere", LocationTypingPrecision.BASIC.toString(),false);
assertEquals(1, testel2.getErrorCount());
}
}