need not only to create class and register it in handler.properties, but (this is not described in instruction) add some code in SQLUnit.java near line 283 - for executing new tag.
if (!elTest.getName().equals("test")
&& !elTest.getName().equals("batchtest")
&& !elTest.getName().equals("diff")) {
continue;
}
May be to put list of executable tags in handler.properties in key like "root.executable.tags" ??? And check executable state of tag like:
if (!HandlerFactory.isTagRootExecutable (elTest.getName())) {
continue;
}
Now its not configurable and this operation is not described propetly ...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You are right that the top level tags are hardcoded. Your suggestion is interesting, that would help make it more configurable. There are other places (TestHandler.java, BatchTestHandler.java) in the code where there is some amount of hardcoding, generalizing your suggestion would help to do away with them too.
I will work on these and push these into CVS by the end of this week and let you know.
Thanks
Sujit
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
May be this functionality will useful not only for me, and i can give you my code to add this to your project. For my it will be more comfortable to communicate with you by usual email. My address is krocodl@yandex.ru
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok, I have moved the hardcoded logic out and made it configurable via handlers.properties. I have added the documentation in as well. Should be available in the next release (early 2005).
Oh, and please ignore my request for you to resend information about your new tags. I see it up here...
From what I understand, the dbLookup will allow you to run a query/stored procedure. Currently SQLUnit allows you to do that using the sql or call tags. The only thing it does not allow is to dump the result to stdout, perhaps all you need to add here is an EchoHandler?
As for the eaDefsCollection, it looks like a facility to group together actions and get the results from them, after a group of procedures have been fired, correct? This can also be done with SQLUnit right now, although there is no explicit facility for grouping calls.
Or perhaps I am missing something here. Perhaps if you describe the tags slightly more, it may be helpful for me and other readers in this forum.
Thanks
Sujit
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Victor has submitted quite a few handlers, of which I have added one in (EchoHandler) currently. I have cut and pasted the text of the email exchange with him so all of us can get an idea of what these new tags do.
On Fri, 2005-01-07 at 04:40, Victor Alekseev wrote:
Hi !
>
> 1. About DATE type for Oracle in situation, where there are no needs to use
> time-part of value
> Now i use improved version of standart TimestampType:
>
> protected static String SM_PATTERN = "yyyy-MM-dd";
> private SimpleDateFormat smFormatter = new SimpleDateFormat(SM_PATTERN);
>
> protected Object parse(final String str) throws SQLUnitException {
> try {
> Date d =
> str.indexOf(":")!=-1?formatter.parse(str):smFormatter.parse(str);
> ......
> }
>
> this equal next repair in types.properties
>
> #oracle.DATE.class = net.sourceforge.sqlunit.types.TimestampType
> #oracle.DATE.type = 91
> oracle.DATETIME.class = net.sourceforge.sqlunit.types.TimestampType
> oracle.DATETIME.type = 91
>
> What is better i dont konow ...
>
>
> 2. About datavase lookup
> Use "Set" tag to populate locale variables is a good method, but i has two
> lack:
> a). in every such place i need to duplicate defenition of SQL query
> b). it has more text
> In my project now i needs to define about 100 primities for convert from
> human readable names to id, and this is not a limit. For correct
> including this ability in code i needs only in IVariableResolver interface
>
> 4. About automatic building documentation ..
> I speak about documentation of ready test file with set of ready test.
> Because it needs for description of process of examination ready system ..
> Also, i want to build documentation of primitives like dbLookupDef and
> entityActionDef witch used for writing tests ...
>
> 5. about commit database operations
> I try to use transaction-support attribute of connection tag, but commits
> does anyway ..
>
> SqlHandler.java
> protected void release(final Statement ps, final Connection conn)
> throws Exception {
> ps.close();
> if (!conn.getAutoCommit()) { conn.commit(); }
> }
>
> Now i removed all hard coded commit in handlers,and add next code to
> ConnectionRegistry.releaseConnections :
>
> public static void releaseConnections() {
> LOG.debug(">> releaseConnections()");
> Iterator connIter = connections.values().iterator();
> while (connIter.hasNext()) {
> Connection conn = (Connection) connIter.next();
> try {
> if (conn != null) {
> String acStr =
> connProperties.get("commit")==null?"auto":(String)connProperties.get("commit
> ");
> if("off".equalsIgnoreCase(acStr));
> conn.rollback();
> if("on".equalsIgnoreCase(acStr));
> conn.commit();
> conn.close();
> conn = null;
> }
> } catch (SQLException e) {
> // :IGNORE: not necessary to trap this
> }
> }
> connections.clear();
> }
>
> Its no elegantly, but work ... it allow three methods of work:
> a) commit every operation - attribute auto-commit is on, commit not defined
> or auto ..
> b) commit all work - attribute commit is on
> c) no commit all work - attribute commit if off
>
> 6) about implementation of VariablesResolver
> SymbolTable.java:
>
> private static HashMap resolvers = new HashMap();
>
> public static synchronized void addResolver(IVariablesResolver resolver)
> {
> resolvers.put(resolver.getName(),resolver);
> }
>
> public static synchronized Object getObject(final String param) {
> LOG.debug(">> getObject(" + param + ")");
> if(!SymbolTable.isVariableName(param))
> return param;
> Object ret = symbols.get(param);
> if(ret!=null)
> return ret;
> Iterator iter = resolvers.values().iterator();
> while(iter.hasNext()) {
> IVariablesResolver resolver = (IVariablesResolver) iter.next();
> if(resolver.isVariableSupported(param))
> return resolver.getVariable(param);
> }
> return null;
> }
>
> public static synchronized void setObject(final String param,final
> Object obj) {
> LOG.debug(">> setObject(" + param + "," + obj.getClass().getName());
> Iterator iter = resolvers.values().iterator();
> while(iter.hasNext()) {
> IVariablesResolver resolver = (IVariablesResolver) iter.next();
> if(resolver.isVariableSupported(param)) {
> resolver.setVariable(param,obj);
> return;
> }
> }
> symbols.put(param, obj);
> }
>
> public static synchronized String replaceVariables(final String text) {
> LOG.debug(">> replaceVariables(" + text + ")");
> String tempText = text;
> int lookupPos = tempText.indexOf("${");
> while(lookupPos!=-1) {
> int lookupEnd = tempText.indexOf("}",lookupPos);
> if(lookupEnd==-1)
> break;
> String name = tempText.substring(lookupPos,lookupEnd+1);
> tempText = tempText.substring(0,lookupPos)+
> SymbolTable.getValue(name)+
> tempText.substring(lookupEnd+1);
> lookupPos = tempText.indexOf("${",lookupPos+1);
> }
> return tempText;
> }
>
> Sample or resovler - ru.custis.sqlunit.beans.dbLookup (included)
>
> 8) use JavaCC for parse templates with variables references is a very good
> idea. May be add next two patterns:
> ~{var}{ ... something... } = "something" if variable exist and not empty,
> and "" otherwise
> !{var}{ ... something... } = something if variable not exist or empty, and
> "something" otherwise
>
>
>
> My source code and main changed your sources i included in letter, with
> samples of ready tests. May be it will be useful for you ...
> Best wishes to you too and thank you.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok, the new tags that Victor contributed from his project are in. Many thanks to Victor for his excellent ideas. Here is a synopsis:
1) EchoHandler - echoes back to the log file (STDOUT for most of us) a value from the symbol table. Useful for doing debugging. I added an attribute value which is the expected value of the variable it should echo, mainly for testing the EchoHandler itself.
2) FuncHandler/FundDefHandler - originally called dbLookup/dbLookupDef/dbLookupDefCollection by Victor. Allows you to define SQL or stored procedure strings which returns a single value (like functions). It is specified in the setup within a funcdef tag, and can be called multiple times with 0-10 parameters using the func tag. I eliminated the dbLookupDefCollection tag which was a collection of DbLookupDefs, since that did not lend any value. Changed the DbLookup* to Func* since I thought that Func* was more intuitive.
3) SubHandler/SubDefHandler - originally called EntityAction/EntityActionDef/EntityActionDefCollection by Victor. Allows you to define a SQL or stored procedure with all the parameters, with placeholders for zero or all parameter values in the subdef tag inside the setup tag. Parameter values may be specified or overriden at runtime by calling the query from the sub tag. The sub tag lives inside the test tag and behaves like a predefined sql or call tag. Again renamed the tags to more intuitive names.
Documentation can be generated locally with ant htdoc and will be available in the next release, sometime end of this week or early next week.
-sujit
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
need not only to create class and register it in handler.properties, but (this is not described in instruction) add some code in SQLUnit.java near line 283 - for executing new tag.
if (!elTest.getName().equals("test")
&& !elTest.getName().equals("batchtest")
&& !elTest.getName().equals("diff")) {
continue;
}
May be to put list of executable tags in handler.properties in key like "root.executable.tags" ??? And check executable state of tag like:
if (!HandlerFactory.isTagRootExecutable (elTest.getName())) {
continue;
}
Now its not configurable and this operation is not described propetly ...
Hi Krocodl,
You are right that the top level tags are hardcoded. Your suggestion is interesting, that would help make it more configurable. There are other places (TestHandler.java, BatchTestHandler.java) in the code where there is some amount of hardcoding, generalizing your suggestion would help to do away with them too.
I will work on these and push these into CVS by the end of this week and let you know.
Thanks
Sujit
Now, i expand your product for use in my project and i am going to add some functionality. Now ready:
1)database lookup, lke:
<dbLookupDef name="streetId"
query="select id_street from t_street where full_name like '${0}'"/>
<dbLookup name="getStreetId" lookup="streetId" param="%Чернышевского%1%" var-name="var"/>
<echo name="echo" text="Variable after first lookup - ${var}"/>
<echo name="echo" text="Inline lookup - ${dbLookup.streetId.%Чернышевского%2%} "/>
2) entity operations:
<eaDefsCollection name="ERKC Entity Actions Collection" >
<entityActionDef name="street" action="add" code="begin :1 := pk_edit_street.upsert_street(:2,:3,:4,:5,:6,:7,:8,:9); end;">
<param id="1" type="INTEGER" name="return" inout="out" >${streetId}</param>
<param id="2" type="INTEGER" name="new_street" is-null="true" />
<param id="3" type="INTEGER" name="old_street">0</param>
<param id="4" type="CHAR" name="kind">ул.</param>
<param id="5" type="CHAR" name="simple_name">must_be_set</param>
<param id="6" type="CHAR" name="full_name">must_be_set</param>
<param id="7" type="INTEGER" name="cod_ps_sz" is-null="true" />
<param id="8" type="INTEGER" name="cod_street_sz" is-null="true" />
<param id="9" type="DATE" name="beg" is-null="true" />
</entityActionDef>
</eaDefsCollection>
<test name="Add street" failure-message="Add street failure" assert="exception-matches" >
<entityAction name="street" action="add">
<eaParam name="simple_name" value="Тестовая 24"/>
<eaParam name="full_name" value="Улица Тестовая 24"/>
</entityAction>
<result/>
</test>
May be this functionality will useful not only for me, and i can give you my code to add this to your project. For my it will be more comfortable to communicate with you by usual email. My address is krocodl@yandex.ru
Hi,
Ok, I have moved the hardcoded logic out and made it configurable via handlers.properties. I have added the documentation in as well. Should be available in the next release (early 2005).
Oh, and please ignore my request for you to resend information about your new tags. I see it up here...
From what I understand, the dbLookup will allow you to run a query/stored procedure. Currently SQLUnit allows you to do that using the sql or call tags. The only thing it does not allow is to dump the result to stdout, perhaps all you need to add here is an EchoHandler?
As for the eaDefsCollection, it looks like a facility to group together actions and get the results from them, after a group of procedures have been fired, correct? This can also be done with SQLUnit right now, although there is no explicit facility for grouping calls.
Or perhaps I am missing something here. Perhaps if you describe the tags slightly more, it may be helpful for me and other readers in this forum.
Thanks
Sujit
Victor has submitted quite a few handlers, of which I have added one in (EchoHandler) currently. I have cut and pasted the text of the email exchange with him so all of us can get an idea of what these new tags do.
On Fri, 2005-01-07 at 04:40, Victor Alekseev wrote:
Hi !
>
> 1. About DATE type for Oracle in situation, where there are no needs to use
> time-part of value
> Now i use improved version of standart TimestampType:
>
> protected static String SM_PATTERN = "yyyy-MM-dd";
> private SimpleDateFormat smFormatter = new SimpleDateFormat(SM_PATTERN);
>
> protected Object parse(final String str) throws SQLUnitException {
> try {
> Date d =
> str.indexOf(":")!=-1?formatter.parse(str):smFormatter.parse(str);
> ......
> }
>
> this equal next repair in types.properties
>
> #oracle.DATE.class = net.sourceforge.sqlunit.types.TimestampType
> #oracle.DATE.type = 91
> oracle.DATETIME.class = net.sourceforge.sqlunit.types.TimestampType
> oracle.DATETIME.type = 91
>
> What is better i dont konow ...
>
>
> 2. About datavase lookup
> Use "Set" tag to populate locale variables is a good method, but i has two
> lack:
> a). in every such place i need to duplicate defenition of SQL query
> b). it has more text
> In my project now i needs to define about 100 primities for convert from
> human readable names to id, and this is not a limit. For correct
> including this ability in code i needs only in IVariableResolver interface
>
> 4. About automatic building documentation ..
> I speak about documentation of ready test file with set of ready test.
> Because it needs for description of process of examination ready system ..
> Also, i want to build documentation of primitives like dbLookupDef and
> entityActionDef witch used for writing tests ...
>
> 5. about commit database operations
> I try to use transaction-support attribute of connection tag, but commits
> does anyway ..
>
> SqlHandler.java
> protected void release(final Statement ps, final Connection conn)
> throws Exception {
> ps.close();
> if (!conn.getAutoCommit()) { conn.commit(); }
> }
>
> Now i removed all hard coded commit in handlers,and add next code to
> ConnectionRegistry.releaseConnections :
>
> public static void releaseConnections() {
> LOG.debug(">> releaseConnections()");
> Iterator connIter = connections.values().iterator();
> while (connIter.hasNext()) {
> Connection conn = (Connection) connIter.next();
> try {
> if (conn != null) {
> String acStr =
> connProperties.get("commit")==null?"auto":(String)connProperties.get("commit
> ");
> if("off".equalsIgnoreCase(acStr));
> conn.rollback();
> if("on".equalsIgnoreCase(acStr));
> conn.commit();
> conn.close();
> conn = null;
> }
> } catch (SQLException e) {
> // :IGNORE: not necessary to trap this
> }
> }
> connections.clear();
> }
>
> Its no elegantly, but work ... it allow three methods of work:
> a) commit every operation - attribute auto-commit is on, commit not defined
> or auto ..
> b) commit all work - attribute commit is on
> c) no commit all work - attribute commit if off
>
> 6) about implementation of VariablesResolver
> SymbolTable.java:
>
> private static HashMap resolvers = new HashMap();
>
> public static synchronized void addResolver(IVariablesResolver resolver)
> {
> resolvers.put(resolver.getName(),resolver);
> }
>
> public static synchronized Object getObject(final String param) {
> LOG.debug(">> getObject(" + param + ")");
> if(!SymbolTable.isVariableName(param))
> return param;
> Object ret = symbols.get(param);
> if(ret!=null)
> return ret;
> Iterator iter = resolvers.values().iterator();
> while(iter.hasNext()) {
> IVariablesResolver resolver = (IVariablesResolver) iter.next();
> if(resolver.isVariableSupported(param))
> return resolver.getVariable(param);
> }
> return null;
> }
>
> public static synchronized void setObject(final String param,final
> Object obj) {
> LOG.debug(">> setObject(" + param + "," + obj.getClass().getName());
> Iterator iter = resolvers.values().iterator();
> while(iter.hasNext()) {
> IVariablesResolver resolver = (IVariablesResolver) iter.next();
> if(resolver.isVariableSupported(param)) {
> resolver.setVariable(param,obj);
> return;
> }
> }
> symbols.put(param, obj);
> }
>
> public static synchronized String replaceVariables(final String text) {
> LOG.debug(">> replaceVariables(" + text + ")");
> String tempText = text;
> int lookupPos = tempText.indexOf("${");
> while(lookupPos!=-1) {
> int lookupEnd = tempText.indexOf("}",lookupPos);
> if(lookupEnd==-1)
> break;
> String name = tempText.substring(lookupPos,lookupEnd+1);
> tempText = tempText.substring(0,lookupPos)+
> SymbolTable.getValue(name)+
> tempText.substring(lookupEnd+1);
> lookupPos = tempText.indexOf("${",lookupPos+1);
> }
> return tempText;
> }
>
> Sample or resovler - ru.custis.sqlunit.beans.dbLookup (included)
>
> 8) use JavaCC for parse templates with variables references is a very good
> idea. May be add next two patterns:
> ~{var}{ ... something... } = "something" if variable exist and not empty,
> and "" otherwise
> !{var}{ ... something... } = something if variable not exist or empty, and
> "something" otherwise
>
>
>
> My source code and main changed your sources i included in letter, with
> samples of ready tests. May be it will be useful for you ...
> Best wishes to you too and thank you.
Ok, the new tags that Victor contributed from his project are in. Many thanks to Victor for his excellent ideas. Here is a synopsis:
1) EchoHandler - echoes back to the log file (STDOUT for most of us) a value from the symbol table. Useful for doing debugging. I added an attribute value which is the expected value of the variable it should echo, mainly for testing the EchoHandler itself.
2) FuncHandler/FundDefHandler - originally called dbLookup/dbLookupDef/dbLookupDefCollection by Victor. Allows you to define SQL or stored procedure strings which returns a single value (like functions). It is specified in the setup within a funcdef tag, and can be called multiple times with 0-10 parameters using the func tag. I eliminated the dbLookupDefCollection tag which was a collection of DbLookupDefs, since that did not lend any value. Changed the DbLookup* to Func* since I thought that Func* was more intuitive.
3) SubHandler/SubDefHandler - originally called EntityAction/EntityActionDef/EntityActionDefCollection by Victor. Allows you to define a SQL or stored procedure with all the parameters, with placeholders for zero or all parameter values in the subdef tag inside the setup tag. Parameter values may be specified or overriden at runtime by calling the query from the sub tag. The sub tag lives inside the test tag and behaves like a predefined sql or call tag. Again renamed the tags to more intuitive names.
Documentation can be generated locally with ant htdoc and will be available in the next release, sometime end of this week or early next week.
-sujit