Have you considered the Null-Object Pattern? http://en.wikipedia.org/wiki/Null_Object_pattern
Also, I would have thought a DateConverter (ie returning Date objects) would be simpler and more appropriate for the usecase at hand, whereas Calendar objects are used for Date manipulations. On 02/02/2010 18:26, Christopher Gardner wrote: > Not sure how to avoid introducing a null Calendar object. We have > requirements that an insurance plan either has a date or not. This > gets setup accordingly in the database. > > On Tue, Feb 2, 2010 at 11:39 AM, Mauro Talevi > <[email protected]> wrote: >> Christopher, >> >> I've added scenario to verify behaviour with null calendar objects: >> >> https://svn.codehaus.org/jbehave/trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/scenarios/claims_with_null_calendar.scenario >> >> It shows HTML/XML reports can now be generated. Obviously, though, >> because you introduced a null object (quite a bad anti-pattern, IMO) you >> need to be careful not to invoke any method on it without having first >> verified it's not null. >> >> I'll let you verify that it works for you before cutting a 2.4.1 release. >> >> Cheers >> >> On 30/01/2010 10:33, Mauro Talevi wrote: >>> There may some other source of nulls. I've committed a fix that checks >>> for null objects when escaping values. I've deployed 2.5-SNAPSHOT, >>> could you please try it out (or try out building snapshot from latest >>> trunk?) I've not had time to build full scenario to verify behaviour >>> from your example, but will do so. >>> >>> Cheers >>> >>> On 29/01/2010 17:19, Christopher Gardner wrote: >>>> I tried the empty string, but received >>>> >>>> java.lang.NullPointerException >>>> at >>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter$1.transform(PrintStreamScenarioReporter.java:245) >>>> at >>>> org.apache.commons.collections.CollectionUtils.transform(CollectionUtils.java:433) >>>> at >>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter.escape(PrintStreamScenarioReporter.java:252) >>>> at >>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter.escapeAll(PrintStreamScenarioReporter.java:230) >>>> at >>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter.format(PrintStreamScenarioReporter.java:222) >>>> at >>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter.beforeExamples(PrintStreamScenarioReporter.java:188) >>>> at >>>> org.jbehave.scenario.reporters.DelegatingScenarioReporter.beforeExamples(DelegatingScenarioReporter.java:80) >>>> at >>>> org.jbehave.scenario.ScenarioRunner.runExamplesTableScenario(ScenarioRunner.java:94) >>>> at org.jbehave.scenario.ScenarioRunner.run(ScenarioRunner.java:63) >>>> at org.jbehave.scenario.ScenarioRunner.run(ScenarioRunner.java:48) >>>> at org.jbehave.scenario.ScenarioRunner.run(ScenarioRunner.java:38) >>>> at >>>> org.jbehave.scenario.AbstractScenario.runScenario(AbstractScenario.java:75) >>>> at >>>> org.jbehave.scenario.JUnitScenario.runScenario(JUnitScenario.java:54) >>>> at >>>> org.jbehave.scenario.JUnitScenario.testScenario(JUnitScenario.java:84) >>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>> at >>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>>> at >>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>>> at java.lang.reflect.Method.invoke(Method.java:592) >>>> at junit.framework.TestCase.runTest(TestCase.java:168) >>>> at junit.framework.TestCase.runBare(TestCase.java:134) >>>> at junit.framework.TestResult$1.protect(TestResult.java:110) >>>> at junit.framework.TestResult.runProtected(TestResult.java:128) >>>> at junit.framework.TestResult.run(TestResult.java:113) >>>> at junit.framework.TestCase.run(TestCase.java:124) >>>> at junit.framework.TestSuite.runTest(TestSuite.java:232) >>>> at junit.framework.TestSuite.run(TestSuite.java:227) >>>> at >>>> org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79) >>>> at >>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) >>>> at >>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) >>>> >>>> >>>> >>>> On Fri, Jan 29, 2010 at 9:09 AM, Christopher Gardner >>>> <[email protected]> wrote: >>>>> Thanks, Mauro. >>>>> >>>>> On Fri, Jan 29, 2010 at 2:22 AM, Mauro Talevi >>>>> <[email protected]> wrote: >>>>>> The problem is that in your CalendarConverter you return a null object >>>>>> for the "none" date entry. Simply return an empty string and it will >>>>>> work for now. >>>>>> >>>>>> Cheers >>>>>> >>>>>> On 28/01/2010 15:52, Christopher Gardner wrote: >>>>>>> Mauro, >>>>>>> >>>>>>> I can't give the real version of the Steps class, as it has >>>>>>> significant proprietary information, but attached are 2 files: A >>>>>>> .scenario file and a CalendarConverter.java file that converts string >>>>>>> dates in the form of mm/dd/yyyy or "none" into an appropriate Calendar >>>>>>> representation. Note in the .scenario file the parameter "<outcome>" >>>>>>> is quoted. In the Steps class those quotes are escaped. >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Thu, Jan 28, 2010 at 9:16 AM, Mauro Talevi >>>>>>> <[email protected]> wrote: >>>>>>>> Hi Christopher, >>>>>>>> >>>>>>>> the problem occurs because it tries to escape HTML chars from the >>>>>>>> values >>>>>>>> of the examples table that it does not find (defaulting to null). The >>>>>>>> reason it does not fail for CONSOLE and TXT is that only HTML and XML >>>>>>>> reporters escape chars. >>>>>>>> >>>>>>>> Opened issue to improve resilience: >>>>>>>> >>>>>>>> http://jira.codehaus.org/browse/JBEHAVE-237 >>>>>>>> >>>>>>>> But if could you please forward the scenario you're using we can help >>>>>>>> you sort out the data issues to get it working properly in the first >>>>>>>> place. >>>>>>>> >>>>>>>> Cheers >>>>>>>> >>>>>>>> On 27/01/2010 22:10, Christopher Gardner wrote: >>>>>>>>> I created my own AbstractScenario class to handle the configuration of >>>>>>>>> the scenario filenames, pending steps, and reports. If I specify only >>>>>>>>> CONSOLE and TXT, reports work as expected: The jbehave-reports >>>>>>>>> directory is generated with the .txt and .stats files. If, however, I >>>>>>>>> add HTML the builder, I receive an exception: >>>>>>>>> >>>>>>>>> java.lang.NullPointerException >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter$1.transform(PrintStreamScenarioReporter.java:245) >>>>>>>>> at >>>>>>>>> org.apache.commons.collections.CollectionUtils.transform(CollectionUtils.java:433) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter.escape(PrintStreamScenarioReporter.java:252) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter.escapeAll(PrintStreamScenarioReporter.java:230) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter.format(PrintStreamScenarioReporter.java:222) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.reporters.PrintStreamScenarioReporter.beforeExamples(PrintStreamScenarioReporter.java:188) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.reporters.DelegatingScenarioReporter.beforeExamples(DelegatingScenarioReporter.java:80) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.ScenarioRunner.runExamplesTableScenario(ScenarioRunner.java:94) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.ScenarioRunner.run(ScenarioRunner.java:63) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.ScenarioRunner.run(ScenarioRunner.java:48) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.ScenarioRunner.run(ScenarioRunner.java:38) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.AbstractScenario.runScenario(AbstractScenario.java:75) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.JUnitScenario.runScenario(JUnitScenario.java:54) >>>>>>>>> at >>>>>>>>> org.jbehave.scenario.JUnitScenario.testScenario(JUnitScenario.java:84) >>>>>>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>>>>>>> at >>>>>>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>>>>>>>> at >>>>>>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>>>>>>>> at java.lang.reflect.Method.invoke(Method.java:592) >>>>>>>>> at junit.framework.TestCase.runTest(TestCase.java:168) >>>>>>>>> at junit.framework.TestCase.runBare(TestCase.java:134) >>>>>>>>> at junit.framework.TestResult$1.protect(TestResult.java:110) >>>>>>>>> at junit.framework.TestResult.runProtected(TestResult.java:128) >>>>>>>>> at junit.framework.TestResult.run(TestResult.java:113) >>>>>>>>> at junit.framework.TestCase.run(TestCase.java:124) >>>>>>>>> at junit.framework.TestSuite.runTest(TestSuite.java:232) >>>>>>>>> at junit.framework.TestSuite.run(TestSuite.java:227) >>>>>>>>> at >>>>>>>>> org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79) >>>>>>>>> at >>>>>>>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) >>>>>>>>> at >>>>>>>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) >>>>>>>>> at >>>>>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) >>>>>>>>> at >>>>>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) >>>>>>>>> at >>>>>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) >>>>>>>>> at >>>>>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) >>>>>>>>> >>>>>>>>> >>>>>>>>> Here is my AbstractScenario. Subclasses are responsible for providing >>>>>>>>> their class objects and instantiating CandidateSteps. >>>>>>>>> >>>>>>>>> package base; >>>>>>>>> >>>>>>>>> import static >>>>>>>>> org.jbehave.scenario.reporters.ScenarioReporterBuilder.Format.*; >>>>>>>>> import org.jbehave.scenario.*; >>>>>>>>> import org.jbehave.scenario.errors.*; >>>>>>>>> import org.jbehave.scenario.parser.*; >>>>>>>>> import org.jbehave.scenario.reporters.FilePrintStreamFactory; >>>>>>>>> import org.jbehave.scenario.reporters.ScenarioReporter; >>>>>>>>> import org.jbehave.scenario.reporters.ScenarioReporterBuilder; >>>>>>>>> import org.jbehave.scenario.steps.*; >>>>>>>>> >>>>>>>>> public abstract class AbstractScenario extends JUnitScenario { >>>>>>>>> >>>>>>>>> protected static ScenarioNameResolver converter = new >>>>>>>>> UnderscoredCamelCaseResolver(".scenario"); >>>>>>>>> >>>>>>>>> public AbstractScenario(final Class<? extends RunnableScenario> >>>>>>>>> scenarioClass, CandidateSteps... candidateSteps) { >>>>>>>>> super(new PropertyBasedConfiguration() { >>>>>>>>> @Override >>>>>>>>> public ScenarioDefiner forDefiningScenarios() { >>>>>>>>> return new ClasspathScenarioDefiner(converter, new >>>>>>>>> PatternScenarioParser(keywords())); >>>>>>>>> } >>>>>>>>> >>>>>>>>> @Override >>>>>>>>> public PendingErrorStrategy forPendingSteps() { >>>>>>>>> return PendingErrorStrategy.FAILING; >>>>>>>>> } >>>>>>>>> >>>>>>>>> @Override >>>>>>>>> public ScenarioReporter forReportingScenarios() { >>>>>>>>> return new ScenarioReporterBuilder(new >>>>>>>>> FilePrintStreamFactory(scenarioClass, converter)) >>>>>>>>> .with(CONSOLE) >>>>>>>>> .with(HTML) >>>>>>>>> .with(TXT) >>>>>>>>> .build(); >>>>>>>>> } >>>>>>>>> }, candidateSteps); >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> Any suggestions as to what I'm doing wrong? >>>>>>>>> >>>>>>>>> Thanks. >>>>>>>>> >>>>>>>>> --------------------------------------------------------------------- >>>>>>>>> To unsubscribe from this list, please visit: >>>>>>>>> >>>>>>>>> http://xircles.codehaus.org/manage_email >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> --------------------------------------------------------------------- >>>>>>>> To unsubscribe from this list, please visit: >>>>>>>> >>>>>>>> http://xircles.codehaus.org/manage_email >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> --------------------------------------------------------------------- >>>>>>>> To unsubscribe from this list, please visit: >>>>>>>> >>>>>>>> http://xircles.codehaus.org/manage_email >>>>>> >>>>>> >>>>>> >>>>>> --------------------------------------------------------------------- >>>>>> To unsubscribe from this list, please visit: >>>>>> >>>>>> http://xircles.codehaus.org/manage_email >>>>>> >>>>>> >>>>>> >>>>> >>>> >>>> --------------------------------------------------------------------- >>>> To unsubscribe from this list, please visit: >>>> >>>> http://xircles.codehaus.org/manage_email >>>> >>>> >>>> >>> >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe from this list, please visit: >>> >>> http://xircles.codehaus.org/manage_email >>> >>> >>> >> >> >> >> --------------------------------------------------------------------- >> To unsubscribe from this list, please visit: >> >> http://xircles.codehaus.org/manage_email >> >> >> > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email
