Commit e18e4fe2 authored by Alexander Ryndin's avatar Alexander Ryndin
Browse files

impl. catch2-based tests generation

parent 6167615e
/**
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
* <p>
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* <p>
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.embeddedmontiarc.embeddedmontiarc;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ComponentSymbol;
import de.monticore.lang.monticar.stream._symboltable.StreamLanguage;
import de.monticore.lang.monticar.streamunits._symboltable.ComponentStreamUnitsSymbol;
import de.monticore.symboltable.Scope;
import de.se_rwth.commons.Names;
import de.se_rwth.commons.logging.Log;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public final class StreamScanner {
private final Path basePath;
private final Scope symTab;
public StreamScanner(Path basePath, Scope symTab) {
this.basePath = Log.errorIfNull(basePath);
this.symTab = Log.errorIfNull(symTab);
}
public Map<ComponentSymbol, Set<ComponentStreamUnitsSymbol>> scan() {
StreamLanguageFileVisitor v = new StreamLanguageFileVisitor(this);
try {
Files.walkFileTree(basePath, v);
} catch (IOException e) {
Log.error("error while processing stream files", e);
}
return new HashMap<>(v.getMapping());
}
private static class StreamLanguageFileVisitor extends SimpleFileVisitor<Path> {
private final StreamScanner scanner;
private final Map<ComponentSymbol, Set<ComponentStreamUnitsSymbol>> mapping = new HashMap<>();
StreamLanguageFileVisitor(StreamScanner scanner) {
this.scanner = scanner;
}
Map<ComponentSymbol, Set<ComponentStreamUnitsSymbol>> getMapping() {
return Collections.unmodifiableMap(mapping);
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (!attrs.isSymbolicLink() && attrs.isRegularFile()) {
File f = file.toFile();
if (f.exists() && f.isFile() && f.getName().toLowerCase().endsWith(StreamLanguage.FILE_ENDING)) {
Path relativePath = scanner.basePath.relativize(file);
String streamModelName = getStreamModelName(relativePath);
ComponentStreamUnitsSymbol s = scanner.symTab.<ComponentStreamUnitsSymbol>resolve(streamModelName, ComponentStreamUnitsSymbol.KIND).orElse(null);
if (s != null) {
ComponentSymbol relatedComponent = s.<ComponentSymbol>getComponentSymbol(ComponentSymbol.KIND).orElse(null);
if (relatedComponent != null) {
if (!mapping.containsKey(relatedComponent)) {
mapping.put(relatedComponent, new HashSet<>());
}
mapping.get(relatedComponent).add(s);
} else {
Log.warn("could not resolve component for which stream is defined in " + f.getAbsolutePath());
}
} else {
Log.warn("could not resolve stream model defined in file " + f.getAbsolutePath());
}
}
}
return FileVisitResult.CONTINUE;
}
private static String getStreamModelName(Path p) {
List<String> parts = new ArrayList<>();
for (Path dirName : p.getParent()) {
parts.add(dirName.toString());
}
String fileNameWithoutExtension = (p.getFileName().toString().split("\\."))[0];
parts.add(fileNameWithoutExtension);
return Names.getQualifiedName(parts);
}
}
}
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.embeddedmontiarc;
import de.monticore.ModelingLanguageFamily;
import de.monticore.io.paths.ModelPath;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc.StreamScanner;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ComponentSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.EmbeddedMontiArcLanguage;
import de.monticore.lang.monticar.streamunits._symboltable.ComponentStreamUnitsSymbol;
import de.monticore.lang.monticar.streamunits._symboltable.StreamUnitsLanguage;
import de.monticore.lang.monticar.struct._symboltable.StructLanguage;
import de.monticore.symboltable.GlobalScope;
import de.monticore.symboltable.Scope;
import org.junit.Assert;
import org.junit.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class StreamScannerTest {
private static final Path BASE_PATH = Paths.get("src/test/resources");
@Test
public void testMySuperSexyComponent() {
Scope symTab = createSymTab(BASE_PATH.toString());
StreamScanner scanner = new StreamScanner(BASE_PATH, symTab);
Map<ComponentSymbol, Set<ComponentStreamUnitsSymbol>> result = scanner.scan();
Assert.assertNotNull(result);
Assert.assertFalse(result.isEmpty());
ComponentSymbol mySuperSexyComponent = symTab.<ComponentSymbol>resolve("testing.MySuperSexyComponent", ComponentSymbol.KIND).orElse(null);
Assert.assertNotNull(mySuperSexyComponent);
Set<ComponentStreamUnitsSymbol> mySuperSexyStreams = result.get(mySuperSexyComponent);
Assert.assertNotNull(mySuperSexyStreams);
Assert.assertFalse(mySuperSexyStreams.isEmpty());
Assert.assertEquals(2, mySuperSexyStreams.size());
Iterator<ComponentStreamUnitsSymbol> it = mySuperSexyStreams.iterator();
ComponentStreamUnitsSymbol mySuperSexyStream1 = it.next();
ComponentStreamUnitsSymbol mySuperSexyStream2 = it.next();
if (!"MySuperSexyStream1".equals(mySuperSexyStream1.getName())) {
ComponentStreamUnitsSymbol swap = mySuperSexyStream1;
mySuperSexyStream1 = mySuperSexyStream2;
mySuperSexyStream2 = swap;
}
Assert.assertEquals("testing.MySuperSexyStream1", mySuperSexyStream1.getFullName());
Assert.assertEquals("testing.MySuperSexyStream2", mySuperSexyStream2.getFullName());
Assert.assertEquals(6, mySuperSexyStream1.getNamedStreams().size());
Assert.assertEquals(6, mySuperSexyStream2.getNamedStreams().size());
}
private static Scope createSymTab(String... modelPath) {
ModelingLanguageFamily fam = new ModelingLanguageFamily();
fam.addModelingLanguage(new EmbeddedMontiArcLanguage());
fam.addModelingLanguage(new StreamUnitsLanguage());
fam.addModelingLanguage(new StructLanguage());
final ModelPath mp = new ModelPath();
for (String m : modelPath) {
mp.addEntry(Paths.get(m));
}
GlobalScope scope = new GlobalScope(mp, fam);
de.monticore.lang.monticar.Utils.addBuiltInTypes(scope);
LogConfig.init();
return scope;
}
}
package testing;
component MySuperSexyComponent {
port
in B in1,
in Q (0.0 : 0.001 : 1.0) in2,
in Z (0 : oo) in3,
out B out1,
out Q (-1.0 : 0.001 : 0.0) out2,
out Z (-oo : 0) out3;
}
package testing;
stream MySuperSexyStream1 for MySuperSexyComponent {
in1: true tick false tick true;
in2: 0.500 tick 0.003 tick 0.750;
in3: 0 tick 1 tick 2;
out1: false tick true tick false;
out2: -0.500 tick -0.003 tick -0.750;
out3: 0 tick -1 tick -2;
}
package testing;
stream MySuperSexyStream2 for MySuperSexyComponent {
in1: false tick false tick false;
in2: 0.123 tick 0.345 tick 0.678;
in3: 1000 tick 10000 tick 100000;
out1: true tick true tick true;
out2: 0.123 +/- 0.1 tick 0.345 +/- 0.01 tick 0.678 +/- 0.001;
out3: 0 tick -1 +/- 1 tick -2 +/- 1;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment