I tried to run the example from the fitnesse web
package info.fitnesse.fixturegallery;
import java.util.Arrays;
import fitlibrary.SequenceFixture;
public class SequenceFixtureTest extends SequenceFixture{
public String letters;
public void fill(int count,char c){
char[] arr=new char[count];
Arrays.fill(arr,c);
letters=new String(arr);
}
public void setList(char[] array){
letters=new String(array);
}
public char charAt(int position){
return letters.charAt(position);
}
}
But when i try to run the example table
!|SequenceFixtureTest|
|fill|10|x|
|check|char at|4|x|
|set list|A,B,C,D|
|check|char at|2|C|
I get the error
SequenceFixtureTest: Bad table! Table has 3 header columns, but row 2 only has 2 columns.
I imported the lib of SequenceFixture. It seems that it tries to recognize the table like a ColumnFixture and that is what i get the error of Bad Table, but i don't want a ColumnFixture.
What i'm doing wrong?
SequenceFixture is not supported by Slim. You need to use !define TEST_SYSTEM {fit}
Related
When having two Xtext models in the same project but in different folders using the same names (ID) for different objects, the scoping does not work how I want it to. How can I restrict the scoping to inside one folder and not the whole project?
Example:
grammar:
Model:
persons+=Person*
greetings+=Greeting*;
Greeting:
'Hello' name=[Person] '!';
Person:
'person' name=ID;
folder structure:
project
|-folder1
|-person1.mydsl
|-folder2
|-greeting.mydsl
|-person2.mydsl
person1.mydsl contains a Person ("Jane"), person2.mydsl also contains a Person ("Jane") and greeting.mydsl contains a Greeting ("Hello Jane!") referencing the person in person1.mydsl instead of the person in person2.mydsl.
The documentation tells me to use the StateBasedContainerManager but I don't understand where and how.
Thanks to #Christian and this I found a solution. So first adding a filter to the DefaultGlobalScopeProvider
public class MyGlobalScopeProvider extends DefaultGlobalScopeProvider {
#Override
public IScope getScope(Resource resource, EReference reference, Predicate<IEObjectDescription> filter) {
filter = new Predicate<IEObjectDescription>() {
#Override
public boolean apply(IEObjectDescription input) {
// implement here
}
};
return super.getScope(resource, reference, filter);
}
}
and then telling my runtime module to use my provider instead
public class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
#Override
public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() {
return MyGlobalScopeProvider.class;
}
}
I am using Spring Data Neo4j RX. And I have a query like this:
#Query("MATCH (a:Repo)-[:REPO_DEPEND_ON]->(b:Repo) WHERE a.name= $name RETURN a.name, b.name")
String[] getSingleRepoDependencyTo(String name);
I know the return type is wrong here, as it cannot be a String array. But how can I get the result properly, which contains two fields?
I have searched online for a long time but cannot find an answer. The "#QueryResult" annotation is not supported in this RX version yet.
Thanks for your help.
Assuming that you have a mapped #Node Repo with its relationships like
#Node
public class Repo {
// other things
String name;
#Relationship("REPO_DEPEND_ON") Repo repo;
}
and defining this method in a ...extends Neo4jRepository<Repo,...>,
you could use Projections.
public interface RepoProjection {
String getName();
DependingRepo getRepo();
/**
* nested projection
*/
interface DependingRepo {
String getName();
}
}
Important to keep in mind that the returned values should be the nodes and relationship to make it work this way.
You could also remove the custom query and do something like:
RepoProjection findByName(String name)
if you do not have the need for a findByName in this repository for the entity itself.
Take a look here: https://neo4j.github.io/sdn-rx/current/#projections.interfaces
It seems to list exactly what you want. From those docs:
interface NamesOnly {
String getFirstName();
String getLastName();
}
interface PersonRepository extends Neo4jRepository<Person, Long> {
List<NamesOnly> findByFirstName(String firstName);
}
There are some other variations too.
You can use annotation #QueryResult on your expected model. For instance you can do that in this way.
DTO:
import org.springframework.data.neo4j.annotation.QueryResult;
#QueryResult
public class SomeDto {
private int someInt;
private SomeObject sobj;
private double sdouble;
private AnotherObject anObj;
//getters setters
}
Neo4jRepository:
public interface DomainObjectRepository extends Neo4jRepository<DomainObject, Long> {
#Query("MATCH(n:SomeTable) RETURN someInt, sobj, sdouble, anObj") //Return a few columns
Optional<SomeDto> getSomeDto();
}
I've created a small interface:
import ...
abstract class IController {
void navigateTo(BuildContext context, String routeName);
Future<LocationData> get location;
// registration process
void registerGender(Gender gender);
void registerBirthday(DateTime birthday);
Future<bool> register(String email, String password);
}
And then I tried to implement this:
import ...
class Controller implements IController {
static final Controller _instance = Controller._internal();
final ServiceAuthenticate _serviceAuth = ServiceAuthenticate();
final ServiceDatabase _serviceDb = ServiceDatabase();
final ServiceGPS _serviceGPS = ServiceGPS();
User _user;
String _routeName;
UserData _userData;
Controller._internal() {
this._routeName = ROUTE_WELCOME;
}
factory Controller() => _instance;
void navigateTo(BuildContext context, String routeName) {
this._routeName = routeName;
Navigator.pushReplacementNamed(context, routeName);
}
Future<LocationData> get location async{
this._userData.location = await this._serviceGPS.location;
print(this._userData.location);
return this._userData.location;
}
void registerGender(Gender gender){
this._userData = UserData();
this._userData.gender = gender;
}
void registerBirthday(DateTime birthday) {
this._userData.birthday = birthday;
}
Future<bool> register(String email, String password) async {
User user = await this._serviceAuth.registerWithEmailAndPassword(email, password);
if(user == null){
return false;
}
this._user = user;
return true;
}
}
But that code produces the following error:
error: 'Controller.navigateTo' ('void Function(BuildContext, String)') isn't a valid override of 'IController.navigateTo' ('void Function(dynamic, String)'). (invalid_override at [prototype] lib\controller\controller.dart:30)
It looks like Dart thinks, that the BuildContext in the IController is dynamic, but this is obviously not the case.
How can I fix this? I'm new to Dart and don't know what to do.
Thanks for help :)
I'm stupid.
My import statement was wrong.
The line
import 'package:prototype/Controller/IController.dart';
produced this error, because the folder controller starts with a lowercase Letter.
The correct import statement is
import 'package:prototype/controller/IController.dart';
But regardless of my stupid mistake is the error message quite interesting.
A had a similar error and in my case the problem was that the return type of the buggy function was such that there were two different classes in the codebase with the same name. And the interface was using one and the implementation the other.
The one line answer is :
Your import statement is wrong.
But now , you need to take care in which file the import statement is going wrong.
There can be many scenarios, but I would like to give an example where I was stuck.
I had two different files in different package, but both files were importing some method where the method names were same.
So while importing the file which contain this method, I had imported the same name method from one file, and at other place, the same name method from second file.
So that's where everything went wrong!
So if import file is correct in the file which is giving some error, check the other dependent file, where same method import statement is written, that may be wrong.
In Xtext, how do I follow a reference from grammar B to grammar A, within a validator of grammar B (which is in the ui-plugin)? Consider the following example.
Grammar A is org.xtext.people.People
grammar org.xtext.people.People with org.eclipse.xtext.common.Terminals
generate people "http://www.xtext.org/people/People"
People:
people+=Person*;
Person:
'person' name=ID ';';
and an instance
person Alice {citizenship "MN"; id "12345"; }
person Bob {citizenship "CH"; id "54321";}
person Malice {citizenship "XXX"; id "66666"; }
At an airport, entries of people are recorded.
enter Alice;
enter Bob;
enter Malice;
Entries are modelled with a second grammar B org.xtext.entries.Entries
grammar org.xtext.entries.Entries with org.eclipse.xtext.common.Terminals
generate entries "http://www.xtext.org/entries/Entries"
import "http://www.xtext.org/people/People"
Entries:
entries+=Entry*;
Entry:
'enter' person=[Person] ';';
After ensuring that the Eclipse project org.xtext.entries has the project org.xtext.people on it's classpath, and ensuring that the org.xtext.entries plugin has the org.xtext.people as a dependency, all works as expected.
There is a travel ban on people from country XXX, although certain deserving people are excluded. Only the CIA knows who is excluded from the ban. Entries must not be allowed for people from XXX unless excluded.
The updated grammar is
grammar org.xtext.entries.Entries with org.eclipse.xtext.common.Terminals
generate entries "http://www.xtext.org/entries/Entries"
import "http://www.xtext.org/people/People"
Entries:
entries+=Entry*;
Entry:
travelBanOverride=TravelBanOverride?
'enter' person=[Person] ';';
TravelBanOverride: '#TravelBanOverride' '(' code=STRING ')';
with validator
package org.xtext.entries.validation
import org.eclipse.xtext.validation.Check
import org.xtext.entries.entries.EntriesPackage
import org.xtext.entries.entries.Entry
import org.xtext.entries.CIA
class EntriesValidator extends AbstractEntriesValidator {
public static val BAN = 'BAN'
public static val ILLEGAL_OVERRIDE = 'ILLEGAL_OVERRIDE'
#Check
def checkBan(Entry entry) {
if (entry.person.citizenship == "XXX") {
if (entry.travelBanOverride === null) {
error('Violation of Travel Ban', EntriesPackage.Literals.ENTRY__PERSON, BAN)
}
else {
val overridecode = entry.travelBanOverride.code;
val valid = CIA.valid(entry.person.name, entry.person.id, overridecode)
if (!valid) {
error('Illegal override code', EntriesPackage.Literals.ENTRY__TRAVEL_BAN_OVERRIDE, ILLEGAL_OVERRIDE)
}
}
}
}
}
where the driver for the external CIA web-app is modelled for example by
package org.xtext.entries;
public class CIA {
public static boolean valid(String name, String id, String overrideCode) {
System.out.println("UNValid["+name+","+overrideCode+"]");
return name.equals("Malice") && id.equals("66666") && overrideCode.equals("123");
}
}
The validations work as expected.
I now wish to provided a quick-fix for BAN, that checks for an override code from the CIA.
package org.xtext.entries.ui.quickfix
import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider
import org.eclipse.xtext.ui.editor.quickfix.Fix
import org.xtext.entries.validation.EntriesValidator
import org.eclipse.xtext.validation.Issue
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor
import org.xtext.entries.entries.Entry
import org.xtext.entries.Helper
class EntriesQuickfixProvider extends DefaultQuickfixProvider {
#Fix(EntriesValidator.BAN)
def tryOverride(Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, 'Try override', 'Override if CIA says so.', 'override.png')
[element ,context |
val entry = element as Entry
// val person = entry.person // no such attribute
//val person = Helper.get(entry); // The method get(Entry) from the type Helper refers to the missing type Object
]
}
}
The first commented line does not compile: there is no attribute person. The second commented line is an attempt to solve the problem by getting a helper class in org.xtext.entries to get the person, but this does not compile either, giving a "The method get(Entry) from the type Helper refers to the missing type Object" error message.
For completeness, here is that helper.
package org.xtext.entries
import org.xtext.people.people.Person
import org.xtext.entries.entries.Entry
class Helper {
static def Person get(Entry entry) {
return entry.person;
}
}
Further, entry.travelBanOverride compiles fine, but entry.person does not. Clicking on Entry in Eclipse takes one to the expected code, which has both travelBanOverride and person.
The issue does not occur with a Java class in the same project and package.
package org.xtext.entries.ui.quickfix;
import org.xtext.entries.entries.Entry;
import org.xtext.people.people.Person;
public class Test {
public static void main(String[] args) {
Entry entry = null;
Person p = entry.getPerson();
}
}
Rewriting the quickfix in Java solves the problem.
package org.xtext.entries.ui.quickfix;
import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider;
import org.eclipse.xtext.ui.editor.quickfix.Fix;
import org.xtext.entries.validation.EntriesValidator;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor;
import org.xtext.entries.entries.Entry;
import org.xtext.entries.Helper;
import org.eclipse.xtext.ui.editor.model.edit.IModificationContext;
import org.eclipse.xtext.ui.editor.model.edit.ISemanticModification;
import org.eclipse.emf.ecore.EObject;
import org.xtext.entries.entries.Entry;
import org.xtext.people.people.Person;
public class EntriesQuickfixProvider extends DefaultQuickfixProvider {
#Fix(EntriesValidator.BAN)
public void tryOverride(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue,
"Try to override",
"Override",
"override.gif",
new ISemanticModification() {
public void apply(EObject element, IModificationContext context) {
Entry entry = (Entry) element;
System.out.println(entry.getPerson());
}
}
);
}
}
How do I follow a reference from grammar B (Entries) to grammar A (People), within a validator of grammar B?
My mistake is the following.
After ensuring that the Eclipse project org.xtext.entries has the
project org.xtext.people on it's classpath, and ensuring that the
org.xtext.entries plugin has the org.xtext.people as a dependency, all
works as expected.
The org.xtext.entries.ui ui-plugin must also have the org.xtext.people on its Java (Eclipse project) build path. Exporting and making a plugin-dependency it not enough.
Note that this setting should be made early, before crafting the quick-fix, because the Xtend editor has refreshing issues.
I have the following problem : I need to produce migration file for a database in production. Currently I'm using ant and following ant task :
<liquibase:updateDatabase changeLogFile=db.changelog-master.xml" databaseRef="oracle-database" outputFile="out_ora.sql" />
But my file includes insert statements for DATABASECHANGELOG table. How can I produce output file without this statements ? (I wouldn't like to delete this statements manually or by some script later).
You can use this extension: https://github.com/liquibase/liquibase-nochangelogupdate
Just add the jar to your classpath and liquibase will not output any databasechangelog SQL
If you want to filter the insert/update from ChangeSets irrespective of Liquibase Insert/update statements retaining only the Create, Alter scripts.
Define a property with list of classes to be excluded
sqlgenerator.exclude=liquibase.statement.core.InsertOrUpdateStatement,liquibase.statement.core.InsertStatement,liquibase.statement.core.UpdateStatement,liquibase.statement.core.GetNextChangeSetSequenceValueStatement,liquibase.statement.core.MarkChangeSetRanStatement,liquibase.statement.core.RemoveChangeSetRanStatusStatement,liquibase.statement.core.UpdateChangeSetChecksumStatement
Implement a SQL Generator class that filters all the SQL statements falls into the class category listed above.
Spring injects the property into the class. Be sure to create the class under the package "liquibase.sqlgenerator.ext".
#Component
public class FilteredSQLGenerator extends AbstractSqlGenerator<AbstractSqlStatement> {
private static final Logger LOGGER = Logger.getLogger(FilteredSQLGenerator.class);
private static String[] excludeArr = new String[0];
#Value("${sqlgenerator.exclude}")
private String exclude;
#PostConstruct
public void init() {
LOGGER.debug(" Exclude List set to : " + exclude);
if (StringUtils.isNotBlank(exclude)) {
excludeArr = StringUtils.split(exclude, ',');
}
}
#Override
public ValidationErrors validate(AbstractSqlStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
return sqlGeneratorChain.validate(statement, database);
}
#Override
public int getPriority() {
return 1000;
}
#Override
public Sql[] generateSql(AbstractSqlStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
String clazzName = statement.getClass().getName();
for (String exclude : excludeArr) {
if (exclude.equals(clazzName)) {
return new Sql[0];
}
}
return sqlGeneratorChain.generateSql(statement, database);
}
}