Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2006-05

Definition of the time-fration in a TDateTime before 30/12/1899

64 messages · 12 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Joost van der Sluis

Hi all,

I have some questions about the TDateTime format.

I always thought that you could do this:
TD : TDateTime

TD := EncodeDate()+encodeTime();

This would mean that you have the following: (24-hours notation)

0 = 12/30/1899 00:00 (as defined)
1 = 12/31/1899 00:00
1.25 = 12/31/1899 06:00
-1 = 12/29/1899 00:00
-2 = 12/28/1899 00:00
-1.25 = 12/28/1899 18:00 (-2+0.75)

But now the Delphi help says:

-1.25 = 12/29/1899 06:00

And this is how it's also implemented in FPC. But for instance PostgreSQL which also uses a format like TDateTime does it the other way. Which looks more logical to me, since if you want to know if DateTimeA is after DateTimeB you can do: DateTimeA>DateTimeB

With the Delphi-help variant this won't work. Since -1>-1.25 but 12/29/1899 00:00 > 12/29/1899 06:00 doesn't make sence to me.

This implementation will mean that if you compare TDateTime's you first have to check whether the date is before or after 12/30/1899 ?

There are some bugs in DecodeDate, DecodeTime and friends for dates before 12/30/1899 but to fix those, I need to know what to do with this problem.

Regards,
Joost.

Reply by email

Joost van der Sluis
to Michael Van Canneyt: It's also what Delphi does. Keep delphi compatibility. Also windows compatibility.…
Michael Van Canneyt wrote 47 lines
On Sun, 21 May 2006, Joost van der Sluis wrote: > I have some questions about the TDateTime format. > > I always thought that you could do this: > TD : TDateTime > > TD := EncodeDate()+encodeTime(); > > This would mean that you have the following: (24-hours notation) > > 0 = 12/30/1899 00:00 (as defined) > 1 = 12/31/1899 00:00 > 1.25 = 12/31/1899 06:00 > -1 = 12/29/1899 00:00 > -2 = 12/28/1899 00:00 > -1.25 = 12/28/1899 18:00 (-2+0.75) > > But now the Delphi help says: > > -1.25 = 12/29/1899 06:00 It's also what Delphi does. > > And this is how it's also implemented in FPC. But for instance > PostgreSQL which also uses a format like TDateTime does it the other > way. Which looks more logical to me, since if you want to know if > DateTimeA is after DateTimeB you can do: DateTimeA>DateTimeB > > With the Delphi-help variant this won't work. Since -1>-1.25 but > 12/29/1899 00:00 > 12/29/1899 06:00 doesn't make sence to me. > > This implementation will mean that if you compare TDateTime's you first > have to check whether the date is before or after 12/30/1899 ? > > There are some bugs in DecodeDate, DecodeTime and friends for dates > before 12/30/1899 but to fix those, I need to know what to do with this > problem. Keep delphi compatibility. Also windows compatibility. TDateTime is a windows construct. (see variants) They obviously judged that the idea of TD := EncodeDate()+encodeTime(); was more important than strict ordering.
That also doesn't work. If td < 0 you must do:
  TD := EncodeDate()+(1-EncodeTime());
Show quoted text 10 lines
The following remark in the Delphi help sheds more light on the issue: "When working with negative TDateTime values, computations must handle time portion separately. The fractional part reflects the fraction of a 24-hour day without regard to the sign of the TDateTime value. For example, 6:00 am on 12/29/1899 is -1.25, Not -1 + 0.25, which would be -0.75. There are no TDateTime values between -1 and 0."

That explains why -0.5 is the same as 0.5.
Where in the help can I find that?

So they are aware of the issue.

Ok, I'll fix the datetime utils with this in my mind.

Joost.

Reply by email

Michael Van Canneyt
to Joost van der Sluis: I have some questions about the TDateTime format. I always thought that you could do this:
Joost van der Sluis wrote 21 lines
Hi all, I have some questions about the TDateTime format. I always thought that you could do this: TD : TDateTime TD := EncodeDate()+encodeTime(); This would mean that you have the following: (24-hours notation) 0 = 12/30/1899 00:00 (as defined) 1 = 12/31/1899 00:00 1.25 = 12/31/1899 06:00 -1 = 12/29/1899 00:00 -2 = 12/28/1899 00:00 -1.25 = 12/28/1899 18:00 (-2+0.75) But now the Delphi help says: -1.25 = 12/29/1899 06:00

It's also what Delphi does.

Show quoted text 15 lines
And this is how it's also implemented in FPC. But for instance PostgreSQL which also uses a format like TDateTime does it the other way. Which looks more logical to me, since if you want to know if DateTimeA is after DateTimeB you can do: DateTimeA>DateTimeB With the Delphi-help variant this won't work. Since -1>-1.25 but 12/29/1899 00:00 > 12/29/1899 06:00 doesn't make sence to me. This implementation will mean that if you compare TDateTime's you first have to check whether the date is before or after 12/30/1899 ? There are some bugs in DecodeDate, DecodeTime and friends for dates before 12/30/1899 but to fix those, I need to know what to do with this problem.

Keep delphi compatibility.

Also windows compatibility. TDateTime is a windows construct. (see variants)

They obviously judged that the idea of
TD := EncodeDate()+encodeTime();
was more important than strict ordering.

The following remark in the Delphi help sheds more light on the issue:

"When working with negative TDateTime values, computations must handle time portion separately. The fractional part reflects the fraction of a 24-hour day without regard to the sign of the TDateTime value. For example,
6:00 am on 12/29/1899 is -1.25,
Not
-1 + 0.25,
which would be -0.75. There are no TDateTime values between -1 and 0."

So they are aware of the issue.

Michael.

Reply by email

Michael Van Canneyt
to Joost van der Sluis: That also doesn't work. If td < 0 you must do: TD := EncodeDate()+(1-EncodeTime()); That…
Joost van der Sluis wrote 51 lines
On Sun, 2006-05-21 at 16:40 +0200, Michael Van Canneyt wrote: > On Sun, 21 May 2006, Joost van der Sluis wrote: > > I have some questions about the TDateTime format. > > > > I always thought that you could do this: > > TD : TDateTime > > > > TD := EncodeDate()+encodeTime(); > > > > This would mean that you have the following: (24-hours notation) > > > > 0 = 12/30/1899 00:00 (as defined) > > 1 = 12/31/1899 00:00 > > 1.25 = 12/31/1899 06:00 > > -1 = 12/29/1899 00:00 > > -2 = 12/28/1899 00:00 > > -1.25 = 12/28/1899 18:00 (-2+0.75) > > > > But now the Delphi help says: > > > > -1.25 = 12/29/1899 06:00 > > It's also what Delphi does. > > > > > And this is how it's also implemented in FPC. But for instance > > PostgreSQL which also uses a format like TDateTime does it the other > > way. Which looks more logical to me, since if you want to know if > > DateTimeA is after DateTimeB you can do: DateTimeA>DateTimeB > > > > With the Delphi-help variant this won't work. Since -1>-1.25 but > > 12/29/1899 00:00 > 12/29/1899 06:00 doesn't make sence to me. > > > > This implementation will mean that if you compare TDateTime's you first > > have to check whether the date is before or after 12/30/1899 ? > > > > There are some bugs in DecodeDate, DecodeTime and friends for dates > > before 12/30/1899 but to fix those, I need to know what to do with this > > problem. > > Keep delphi compatibility. > > Also windows compatibility. TDateTime is a windows construct. > (see variants) > > They obviously judged that the idea of > TD := EncodeDate()+encodeTime(); > was more important than strict ordering. That also doesn't work. If td < 0 you must do: TD := EncodeDate()+(1-EncodeTime());

That is not correct, AFAIK ?

Show quoted text 14 lines
> The following remark in the Delphi help sheds more light on the issue: > > "When working with negative TDateTime values, computations must handle > time portion separately. The fractional part reflects the fraction of > a 24-hour day without regard to the sign of the TDateTime value. > For example, > 6:00 am on 12/29/1899 is -1.25, > Not > -1 + 0.25, > which would be -0.75. There are no TDateTime values between -1 and 0." That explains why -0.5 is the same as 0.5. Where in the help can I find that?

TDateTime type help.

Michael.

Reply by email

Joost van der Sluis
to Michael Van Canneyt
Michael Van Canneyt wrote 56 lines
On Sun, 21 May 2006, Joost van der Sluis wrote: > On Sun, 2006-05-21 at 16:40 +0200, Michael Van Canneyt wrote: > > On Sun, 21 May 2006, Joost van der Sluis wrote: > > > I have some questions about the TDateTime format. > > > > > > I always thought that you could do this: > > > TD : TDateTime > > > > > > TD := EncodeDate()+encodeTime(); > > > > > > This would mean that you have the following: (24-hours notation) > > > > > > 0 = 12/30/1899 00:00 (as defined) > > > 1 = 12/31/1899 00:00 > > > 1.25 = 12/31/1899 06:00 > > > -1 = 12/29/1899 00:00 > > > -2 = 12/28/1899 00:00 > > > -1.25 = 12/28/1899 18:00 (-2+0.75) > > > > > > But now the Delphi help says: > > > > > > -1.25 = 12/29/1899 06:00 > > > > It's also what Delphi does. > > > > > > > > And this is how it's also implemented in FPC. But for instance > > > PostgreSQL which also uses a format like TDateTime does it the other > > > way. Which looks more logical to me, since if you want to know if > > > DateTimeA is after DateTimeB you can do: DateTimeA>DateTimeB > > > > > > With the Delphi-help variant this won't work. Since -1>-1.25 but > > > 12/29/1899 00:00 > 12/29/1899 06:00 doesn't make sence to me. > > > > > > This implementation will mean that if you compare TDateTime's you first > > > have to check whether the date is before or after 12/30/1899 ? > > > > > > There are some bugs in DecodeDate, DecodeTime and friends for dates > > > before 12/30/1899 but to fix those, I need to know what to do with this > > > problem. > > > > Keep delphi compatibility. > > > > Also windows compatibility. TDateTime is a windows construct. > > (see variants) > > > > They obviously judged that the idea of > > TD := EncodeDate()+encodeTime(); > > was more important than strict ordering. > > That also doesn't work. If td < 0 you must do: > TD := EncodeDate()+(1-EncodeTime()); That is not correct, AFAIK ?

Right, I was wrong, but you still have to substract the time-part if the date-part < 0.

Look at the example above:

TD := EncodeDate(1899,12,28)+EncodeTime(18,0,0,0); => -2 + 0.75 = -1.25

Volgens de Delphi help is -1.25 12/29/1899 06:00

But if you do this

EncodeDate(1899,12,28)-EncodeTime(18,0,0,0)); => -2 - 0.75 = -2.75

the result is correct.

So EncodeDate+EncodeTime won't work. But it will if you use mine 'logical' definition of TDateTime.

I really don't get the logics behind the Delphi-TDateTime format, maybe only because Trunc(TDateTime) works so well to get the date-part. But what about floor() ?

Joost.

Reply by email

Bram Kuijvenhoven
to Michael Van Canneyt: It's also what Delphi does. Keep delphi compatibility. Also windows compatibility.…
Michael Van Canneyt wrote 10 lines
The following remark in the Delphi help sheds more light on the issue: "When working with negative TDateTime values, computations must handle time portion separately. The fractional part reflects the fraction of a 24-hour day without regard to the sign of the TDateTime value. For example, 6:00 am on 12/29/1899 is -1.25, Not -1 + 0.25, which would be -0.75. There are no TDateTime values between -1 and 0."

This is really bad -- I supposed the TDateTime was a nice 'linear' mapping of time (which is much nicer for all kinds of calculations). As Joost said, dateutil.inc will need quite some fixes.

I guess we will need plenty of unit tests to make sure all the functions work consistent, in particular also for dates close to and before 29-12-1899 :)

(Note: I sent some mail explaining the TryEncodeDateTime function some time ago (21-4-2006), on Graeme's request. I also mentioned an overflow problem in that code + how to fix. Perhaps this fix can be integrated into the code as well.)

Regards,

Bram

Reply by email

Michael Van Canneyt
to Bram Kuijvenhoven
Bram Kuijvenhoven wrote 14 lines
Michael Van Canneyt wrote: > The following remark in the Delphi help sheds more light on the issue: > > "When working with negative TDateTime values, computations must handle > time portion separately. The fractional part reflects the fraction of > a 24-hour day without regard to the sign of the TDateTime value. > For example, > 6:00 am on 12/29/1899 is -1.25, > Not > -1 + 0.25, > which would be -0.75. There are no TDateTime values between -1 and 0." This is really bad -- I supposed the TDateTime was a nice 'linear' mapping of time (which is much nicer for all kinds of calculations).

It is, but only for dates after 1899-12-30. God only knows why Microsoft picked this date.

Michael.

Reply by email

Marco van de Voort
to Michael Van Canneyt
Show quoted text 6 lines
On Mon, 22 May 2006, Bram Kuijvenhoven wrote: > This is really bad -- I supposed the TDateTime was a nice 'linear' mapping of > time (which is much nicer for all kinds of calculations). It is, but only for dates after 1899-12-30. God only knows why Microsoft picked this date.

Julian is 1900-1-1 noon iirc. The deviation comes from compability with older products that did leapyear calculation for the year 1900 wrong (and maybe more), needing to adjust the origin date.

The noon definition was also not very practical.

Reply by email

Graeme Geldenhuys
to Bram Kuijvenhoven: This is really bad -- I supposed the TDateTime was a nice 'linear' mapping of time (which…
Bram Kuijvenhoven wrote
I guess we will need plenty of unit tests to make sure all the functions work consistent, in particular also for dates close to and before 29-12-1899 :) (Note: I sent some mail explaining the TryEncodeDateTime function some time ago (21-4-2006), on Graeme's request. I also mentioned an overflow problem in that code + how to fix. Perhaps this fix can be integrated into the code as well.)

Hi Bram,

Yeah, I had my share of uphill battles with old dates (Delphi and FPC). I works fine with recent dates, but don't venture to far off!!

I already have a collection of unit tests for dates, which is incorporated into our products unit tests. We use fpcUnit extensively. I could always extend those tests a bit more, but as far as I understand, FPC developers dont' use fpcUnit, but rather some custom testing framework.

Regards,
Graeme.

There's no place like 127.0.0.1

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 21 lines
On 5/22/06, Bram Kuijvenhoven wrote: > I guess we will need plenty of unit tests to make sure all the functions work consistent, in particular also for dates close to and before 29-12-1899 :) > > (Note: I sent some mail explaining the TryEncodeDateTime function some time ago (21-4-2006), on Graeme's request. I also mentioned an overflow problem in that code + how to fix. Perhaps this fix can be integrated into the code as well.) > Hi Bram, Yeah, I had my share of uphill battles with old dates (Delphi and FPC). I works fine with recent dates, but don't venture to far off!! I already have a collection of unit tests for dates, which is incorporated into our products unit tests. We use fpcUnit extensively. I could always extend those tests a bit more, but as far as I understand, FPC developers dont' use fpcUnit, but rather some custom testing framework.

1. fpcunit didn't exist at the time the FPC tests were implemented.
2. Using FPCunit creates a dependency on it. The tests can run mostly with only the system unit...

Michael.

Reply by email

Florian Klaempfl
to Michael Van Canneyt
Michael Van Canneyt wrote 30 lines
On Mon, 22 May 2006, Graeme Geldenhuys wrote: > On 5/22/06, Bram Kuijvenhoven wrote: >> I guess we will need plenty of unit tests to make sure all the functions > work consistent, in particular also for dates close to and before > 29-12-1899 :) >> >> (Note: I sent some mail explaining the TryEncodeDateTime function >> some time > ago (21-4-2006), on Graeme's request. I also mentioned an overflow > problem in that code + how to fix. Perhaps this fix can be integrated > into the code as well.) >> > > Hi Bram, > > Yeah, I had my share of uphill battles with old dates (Delphi and > FPC). I works fine with recent dates, but don't venture to far off!! > > I already have a collection of unit tests for dates, which is > incorporated into our products unit tests. We use fpcUnit > extensively. I could always extend those tests a bit more, but as far > as I understand, FPC developers dont' use fpcUnit, but rather some > custom testing framework. 1. fpcunit didn't exist at the time the FPC tests were implemented. 2. Using FPCunit creates a dependency on it. The tests can run mostly with only the system unit...

Which dependencies? Maybe they can be reduced and a fpcunit can be added to tests?

Reply by email

Michael Van Canneyt
to Florian Klaempfl
Florian Klaempfl wrote 33 lines
Michael Van Canneyt wrote: > > > On Mon, 22 May 2006, Graeme Geldenhuys wrote: > >> On 5/22/06, Bram Kuijvenhoven wrote: >>> I guess we will need plenty of unit tests to make sure all the functions >> work consistent, in particular also for dates close to and before >> 29-12-1899 :) >>> >>> (Note: I sent some mail explaining the TryEncodeDateTime function >>> some time >> ago (21-4-2006), on Graeme's request. I also mentioned an overflow >> problem in that code + how to fix. Perhaps this fix can be integrated >> into the code as well.) >>> >> >> Hi Bram, >> >> Yeah, I had my share of uphill battles with old dates (Delphi and >> FPC). I works fine with recent dates, but don't venture to far off!! >> >> I already have a collection of unit tests for dates, which is >> incorporated into our products unit tests. We use fpcUnit >> extensively. I could always extend those tests a bit more, but as far >> as I understand, FPC developers dont' use fpcUnit, but rather some >> custom testing framework. > > 1. fpcunit didn't exist at the time the FPC tests were implemented. > 2. Using FPCunit creates a dependency on it. The tests can run mostly > with only the system unit... Which dependencies? Maybe they can be reduced and a fpcunit can be added to tests?

fpcunit depends on not so much, but I want to avoid using the FCL in the testsuite... Creating a copy seems rather silly too...

Michael.

Reply by email

Florian Klaempfl
to Michael Van Canneyt
Michael Van Canneyt wrote 42 lines
On Mon, 22 May 2006, Florian Klaempfl wrote: > Michael Van Canneyt wrote: >> >> >> On Mon, 22 May 2006, Graeme Geldenhuys wrote: >> >>> On 5/22/06, Bram Kuijvenhoven wrote: >>>> I guess we will need plenty of unit tests to make sure all the >>>> functions >>> work consistent, in particular also for dates close to and before >>> 29-12-1899 :) >>>> >>>> (Note: I sent some mail explaining the TryEncodeDateTime function >>>> some time >>> ago (21-4-2006), on Graeme's request. I also mentioned an overflow >>> problem in that code + how to fix. Perhaps this fix can be integrated >>> into the code as well.) >>>> >>> >>> Hi Bram, >>> >>> Yeah, I had my share of uphill battles with old dates (Delphi and >>> FPC). I works fine with recent dates, but don't venture to far off!! >>> >>> I already have a collection of unit tests for dates, which is >>> incorporated into our products unit tests. We use fpcUnit >>> extensively. I could always extend those tests a bit more, but as far >>> as I understand, FPC developers dont' use fpcUnit, but rather some >>> custom testing framework. >> >> 1. fpcunit didn't exist at the time the FPC tests were implemented. >> 2. Using FPCunit creates a dependency on it. The tests can run mostly >> with only the system unit... > > Which dependencies? Maybe they can be reduced and a fpcunit can be > added to tests? fpcunit depends on not so much, but I want to avoid using the FCL in the testsuite... Creating a copy seems rather silly too...

You can create an svn:external to important that one from the fcl without creating a real copy.

Reply by email

Florian Klaempfl
to Michael Van Canneyt: Good idea. Should we convert existing tests to fpcunit ? Michael.
Michael Van Canneyt wrote 16 lines
>>>> 1. fpcunit didn't exist at the time the FPC tests were implemented. >>>> 2. Using FPCunit creates a dependency on it. The tests can run mostly >>>> with only the system unit... >>> >>> Which dependencies? Maybe they can be reduced and a fpcunit can be >>> added to tests? >> >> fpcunit depends on not so much, but I want to avoid using the FCL in the >> testsuite... Creating a copy seems rather silly too... > > You can create an svn:external to important that one from the fcl without > creating a real copy. Good idea. Should we convert existing tests to fpcunit ?

No, too much work, no real gain :)

Reply by email

Michael Van Canneyt
to Florian Klaempfl: You can create an svn:external to important that one from the fcl without creating a real…
Florian Klaempfl wrote 46 lines
Michael Van Canneyt wrote: > > > On Mon, 22 May 2006, Florian Klaempfl wrote: > >> Michael Van Canneyt wrote: >>> >>> >>> On Mon, 22 May 2006, Graeme Geldenhuys wrote: >>> >>>> On 5/22/06, Bram Kuijvenhoven wrote: >>>>> I guess we will need plenty of unit tests to make sure all the >>>>> functions >>>> work consistent, in particular also for dates close to and before >>>> 29-12-1899 :) >>>>> >>>>> (Note: I sent some mail explaining the TryEncodeDateTime function >>>>> some time >>>> ago (21-4-2006), on Graeme's request. I also mentioned an overflow >>>> problem in that code + how to fix. Perhaps this fix can be integrated >>>> into the code as well.) >>>>> >>>> >>>> Hi Bram, >>>> >>>> Yeah, I had my share of uphill battles with old dates (Delphi and >>>> FPC). I works fine with recent dates, but don't venture to far off!! >>>> >>>> I already have a collection of unit tests for dates, which is >>>> incorporated into our products unit tests. We use fpcUnit >>>> extensively. I could always extend those tests a bit more, but as far >>>> as I understand, FPC developers dont' use fpcUnit, but rather some >>>> custom testing framework. >>> >>> 1. fpcunit didn't exist at the time the FPC tests were implemented. >>> 2. Using FPCunit creates a dependency on it. The tests can run mostly >>> with only the system unit... >> >> Which dependencies? Maybe they can be reduced and a fpcunit can be >> added to tests? > > fpcunit depends on not so much, but I want to avoid using the FCL in the > testsuite... Creating a copy seems rather silly too... You can create an svn:external to important that one from the fcl without creating a real copy.

Good idea.

Should we convert existing tests to fpcunit ?

Michael.

Reply by email

Graeme Geldenhuys
to Florian Klaempfl: No, too much work, no real gain :)
Florian Klaempfl wrote
> Should we convert existing tests to fpcunit ? No, too much work, no real gain :)

Just curious...

I have never looked at the tests created in FPC, but how much work (lines of code) would it take to test something like the following snippet of our tests we have. (very simple example) If it isn't to much work, the benefits will be huge as fpcUnit has a lot of advantages. TestDecorator, Exception testing, XML output, etc... As I said, we use fpcUnit extensively. Currently running at around 1500+ unit tests, testing database connections, string utils, threading, etc...

In the example below tiUtils.tiDateTimeAsIntlDateDisp outputs dates in the ISO international datetime format. Most of our test are as easy as this, 1 or 2 liners. Not to mention fpcUnit give you results in XML output which we convert to a html page via xslt to be viewer over the web to see what the nightly build did.

procedure TTestTIUtils.tiDateTimeAsIntlDateDisp;
var
  dt: TDateTime;
begin
  dt := EncodeDate(2006, 1, 18) + EncodeTime(15, 19, 22, 0);
  CheckEquals('2006-01-18 15:19:22',
tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 1');
  dt := EncodeDate(2002, 1, 02) + EncodeTime(12, 34, 56, 12);
  CheckEquals('2002-01-02 12:34:56',
tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 2');
  dt := EncodeDate(2006, 1, 18);
  CheckEquals('2006-01-18 00:00:00',
tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 3');
  dt := EncodeTime(9, 10, 41, 22);
  CheckEquals('0000-00-00 09:10:41',
tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 4');
  dt := EncodeDateTime(1652, 6, 15, 12, 34, 56, 12);
  CheckEquals('1652-06-15 12:34:56',
tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 5');
[....]
end;

Regards,
- Graeme -

There's no place like 127.0.0.1

Reply by email

Vincent Snijders
to Graeme Geldenhuys
Graeme Geldenhuys wrote 49 lines
On 5/22/06, Florian Klaempfl wrote: > > Should we convert existing tests to fpcunit ? > > No, too much work, no real gain :) Just curious... I have never looked at the tests created in FPC, but how much work (lines of code) would it take to test something like the following snippet of our tests we have. (very simple example) If it isn't to much work, the benefits will be huge as fpcUnit has a lot of advantages. TestDecorator, Exception testing, XML output, etc... As I said, we use fpcUnit extensively. Currently running at around 1500+ unit tests, testing database connections, string utils, threading, etc... In the example below tiUtils.tiDateTimeAsIntlDateDisp outputs dates in the ISO international datetime format. Most of our test are as easy as this, 1 or 2 liners. Not to mention fpcUnit give you results in XML output which we convert to a html page via xslt to be viewer over the web to see what the nightly build did. procedure TTestTIUtils.tiDateTimeAsIntlDateDisp; var dt: TDateTime; begin dt := EncodeDate(2006, 1, 18) + EncodeTime(15, 19, 22, 0); CheckEquals('2006-01-18 15:19:22', tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 1'); dt := EncodeDate(2002, 1, 02) + EncodeTime(12, 34, 56, 12); CheckEquals('2002-01-02 12:34:56', tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 2'); dt := EncodeDate(2006, 1, 18); CheckEquals('2006-01-18 00:00:00', tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 3'); dt := EncodeTime(9, 10, 41, 22); CheckEquals('0000-00-00 09:10:41', tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 4'); dt := EncodeDateTime(1652, 6, 15, 12, 34, 56, 12); CheckEquals('1652-06-15 12:34:56', tiUtils.tiDateTimeAsIntlDateDisp(dt), 'Failed on 5'); [....] end;

In the current framework it would look like this:

program tiDateTimeAsIntlDateDisp;
uses
   tiUtils; // I am guessing it is a unit, but it could be an object too.
var
  dt: TDateTime;
begin
  dt := EncodeDate(2006, 1, 18) + EncodeTime(15, 19, 22, 0);
  if '2006-01-18 15:19:22'
    tiUtils.tiDateTimeAsIntlDateDisp(dt) then halt(1);
  dt := EncodeDate(2002, 1, 02) + EncodeTime(12, 34, 56, 12);
  if '2002-01-02 12:34:56'  tiUtils.tiDateTimeAsIntlDateDisp(dt)
     then halt(2);
  dt := EncodeDate(2006, 1, 18);
  if '2006-01-18 00:00:00'tiUtils.tiDateTimeAsIntlDateDisp(dt)
    then halt(3);
  dt := EncodeTime(9, 10, 41, 22);
  if '0000-00-00 09:10:41'tiUtils.tiDateTimeAsIntlDateDisp(dt)
    then halt(4);
  dt := EncodeDateTime(1652, 6, 15, 12, 34, 56, 12);
  if '1652-06-15 12:34:56'  tiUtils.tiDateTimeAsIntlDateDisp(dt)
    then halt(5);
[....]
end.

The results are gathered and published on:
http://www.freepascal.org/cgi-bin/testsuite.cgi

Vincent.

Reply by email

Florian Klaempfl
to Vincent Snijders
Vincent Snijders wrote 6 lines
dt := EncodeDateTime(1652, 6, 15, 12, 34, 56, 12); if '1652-06-15 12:34:56' tiUtils.tiDateTimeAsIntlDateDisp(dt) then halt(5); [....] end.

We use the simple approach with halt because using the fpcunit for basic tests would require that OOP works always but it could be easily broken and thus all tests would fail. So we designed the test suite in a way which keeps prerequisits as low as possible.

Reply by email

Michael Van Canneyt
to Florian Klaempfl
Florian Klaempfl wrote 12 lines
Vincent Snijders wrote: > dt := EncodeDateTime(1652, 6, 15, 12, 34, 56, 12); > if '1652-06-15 12:34:56' tiUtils.tiDateTimeAsIntlDateDisp(dt) > then halt(5); > > [....] > end. We use the simple approach with halt because using the fpcunit for basic tests would require that OOP works always but it could be easily broken and thus all tests would fail. So we designed the test suite in a way which keeps prerequisits as low as possible.

That is what I would like to keep :)

Michael.

Reply by email

Jonas Maebe
to Florian Klaempfl: We use the simple approach with halt because using the fpcunit for basic tests would…
Florian Klaempfl wrote 6 lines
We use the simple approach with halt because using the fpcunit for basic tests would require that OOP works always but it could be easily broken and thus all tests would fail. So we designed the test suite in a way which keeps prerequisits as low as possible.

Given that the code generator is almost entirely OOP nowadays, I doubt we would even get to the testsuite if it were to be broken :)

Jonas

Reply by email

Graeme Geldenhuys
to Vincent Snijders: In the current framework it would look like this: program tiDateTimeAsIntlDateDisp; uses…

Ok, so every set of tests is a actual program.

[I am not forcing fpcUnit, just curious as what FPC's tests can do. Also not sure what your knowlegde is on the workings of a xUnit testing framework. ]

So if you have to test something a little more complex, and every unittest needs some predefined state (example a set of objects need to be created or a database connection needs to be created) and then once the test has completed, those objects need to be freed or db connection closed. That will add a lof of extra code to the FPC test framework as far as I can see. Here is another big benefit of using a unittest framework like fpcUnit. In fpcUnit I could add two methods to my TestCase class (Setup and TearDown) which will be called before and after each test without me have to wrap anything in a try..finally block etc.

Another example will be to test a method that needs to raise an exception and you are testing for a specific type of exception.

Also as part of the XML results generated by fpcUnit, is the line number a Error occured (unexpected result) including the exception that was raised, or the message string a test failure occured at (eg: 'Failed on 1' including the Actual and Expected results).

Tests could also be grouped in test suites.

---------- sample xml test output ------------------ <Failure>
<Message>TTestTIUtils.tiFloatToCurrency: Failed on 4 expected: <$ 0.01> but was: <$ 0.00></Message>
<ExceptionClass>EAssertionFailedError</ExceptionClass> <ExceptionMessage>Failed on 4 expected: <$ 0.01> but was: <$ 0.00></ExceptionMessage>
</Failure>

<Error>
<Message>TTestTIUtils.tiVariantArrayToString: Variant array locked</Message> <ExceptionClass>EVariantArrayLockedError</ExceptionClass> <ExceptionMessage>Variant array locked</ExceptionMessage> <SourceUnitName></SourceUnitName>
<LineNumber>1702</LineNumber>
<FailedMethodName></FailedMethodName>
</Error>
-------------------------------------------------------

Where in SubVersion are the fpc tests located?

Regards,
- Graeme -

Vincent Snijders wrote 12 lines
Graeme Geldenhuys schreef: > On 5/22/06, Florian Klaempfl wrote: The results are gathered and published on: http://www.freepascal.org/cgi-bin/testsuite.cgi Vincent. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel
There's no place like 127.0.0.1

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys: Ok, so every set of tests is a actual program. [I am not forcing fpcUnit, just curious as…
Graeme Geldenhuys wrote 27 lines
Ok, so every set of tests is a actual program. [I am not forcing fpcUnit, just curious as what FPC's tests can do. Also not sure what your knowlegde is on the workings of a xUnit testing framework. ] So if you have to test something a little more complex, and every unittest needs some predefined state (example a set of objects need to be created or a database connection needs to be created) and then once the test has completed, those objects need to be freed or db connection closed. That will add a lof of extra code to the FPC test framework as far as I can see. Here is another big benefit of using a unittest framework like fpcUnit. In fpcUnit I could add two methods to my TestCase class (Setup and TearDown) which will be called before and after each test without me have to wrap anything in a try..finally block etc. Another example will be to test a method that needs to raise an exception and you are testing for a specific type of exception. Also as part of the XML results generated by fpcUnit, is the line number a Error occured (unexpected result) including the exception that was raised, or the message string a test failure occured at (eg: 'Failed on 1' including the Actual and Expected results). Tests could also be grouped in test suites.

This is all correct. No-one questions the usefullness of fpcunit (on the contrary), but the point is to test the compiler and RTL. There are many tests which simply should fail when compiling, or where the compiler should give a specific error.

-> You can't test that with fpcunit :-)

If we need to design tests for the "Inherited;" construct, then you can't use fpcunit for that, since fpcunit relies on "Inherited;" working correctly in the first place.

A kind of chicken-and-egg problem :-)

But more high-level routines could definitely be implemented using fpcunit...

Michael.

Reply by email

Graeme Geldenhuys
to Florian Klaempfl: We use the simple approach with halt because using the fpcunit for basic tests would…
Florian Klaempfl wrote
We use the simple approach with halt because using the fpcunit for basic tests would require that OOP works always but it could be easily broken and thus all tests would fail. So we designed the test suite in a way which keeps prerequisits as low as possible.

That's fair enough. I guess compiler development is a sensitive case and a low prerequisit is very important.
Using you example though that would mean you will get a very visible indication that a major screw-up did occur on the last svn commit, and fpcUnit would still have done it's job.

What we do [ and no we don't develop compilers :) ] in our organization is that before anybody is allowed to commit changes, they need to run the set of unit tests (and yes our unit test must run quickly - a few minutes < 10 max). Currently it takes just over 2minutes to complete our 1500+ test suite. A unit test is everything inside the procedure TTestTIUtils.tiDateTimeAsIntlDateDisp method mentioned earlier, so it is a lot of tests.

Regards,
Graeme .

_______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel
There's no place like 127.0.0.1

Reply by email

Florian Klaempfl
to Jonas Maebe: Given that the code generator is almost entirely OOP nowadays, I doubt we would even get…
Jonas Maebe wrote 12 lines
On 22 mei 2006, at 16:38, Florian Klaempfl wrote: > We use the simple approach with halt because using the fpcunit for > basic tests > would require that OOP works always but it could be easily broken and > thus all > tests would fail. So we designed the test suite in a way which keeps > prerequisits as low as possible. Given that the code generator is almost entirely OOP nowadays, I doubt we would even get to the testsuite if it were to be broken :)

Well, for regression testing this is true but not for bootstrap testing :)

Reply by email

Joost van der Sluis
to Joost van der Sluis: Right, I was wrong, but you still have to substract the time-part if the date-part < 0.…

The attached patch fixs some problems with negative TDateTimes.

It could be that the changes in DecodeDate are for the same problem as Bram already send a patch for:

+ removed obsolete DayTable
+ fixed DateTimeToTimestamp, EncodeDate, DecodeDate, DecodeTime for TDatetimes < 0
+ MSecsToTimeStamp must change day at 24:00, not at 12:00
+ removed double code in Now and DecodeDateFully

Regards,

Joost.

Reply by email

Vincent Snijders
to Michael Van Canneyt: This is all correct. No-one questions the usefullness of fpcunit (on the contrary), but…
Michael Van Canneyt wrote 48 lines
On Mon, 22 May 2006, Graeme Geldenhuys wrote: > Ok, so every set of tests is a actual program. > > [I am not forcing fpcUnit, just curious as what FPC's tests can do. > Also not sure what your knowlegde is on the workings of a xUnit > testing framework. ] > > > So if you have to test something a little more complex, and every > unittest needs some predefined state (example a set of objects need to > be created or a database connection needs to be created) and then once > the test has completed, those objects need to be freed or db > connection closed. That will add a lof of extra code to the FPC test > framework as far as I can see. Here is another big benefit of using a > unittest framework like fpcUnit. In fpcUnit I could add two methods > to my TestCase class (Setup and TearDown) which will be called before > and after each test without me have to wrap anything in a try..finally > block etc. > > Another example will be to test a method that needs to raise an > exception and you are testing for a specific type of exception. > > Also as part of the XML results generated by fpcUnit, is the line > number a Error occured (unexpected result) including the exception > that was raised, or the message string a test failure occured at (eg: > 'Failed on 1' including the Actual and Expected results). > > Tests could also be grouped in test suites. This is all correct. No-one questions the usefullness of fpcunit (on the contrary), but the point is to test the compiler and RTL. There are many tests which simply should fail when compiling, or where the compiler should give a specific error. -> You can't test that with fpcunit :-) If we need to design tests for the "Inherited;" construct, then you can't use fpcunit for that, since fpcunit relies on "Inherited;" working correctly in the first place. A kind of chicken-and-egg problem :-) But more high-level routines could definitely be implemented using fpcunit...

I would propose to create a tests\fpunit and/or a tests\webfpu directory where fpunit testcase could be added.

This is not a replacement for the current method, since reports for IE or syntax errors cannot be adequately tested with it and in some / most cases a simple program showing the bug is easier to write and compiles faster (good for the fixer).

From Greame I would like to know how he proposes to update the TestSuite, if a new tests it added.

For the current test method, this is not an issue, since all programs in a directory are compiled.

Vincent.

Reply by email

Vincent Snijders
to Micha Nelissen
Micha Nelissen wrote 10 lines
On Mon, 22 May 2006 18:07:52 +0200 Joost van der Sluis wrote: >The attached patch fixs some problems with negative TDateTimes. Can you introduce constants instead of all these hardcoded numbers so the code is more readable ?

Maybe Brams mail should be incorporated, given the fact that the constants don't have a clear meaning.

Vincent.

Reply by email

Graeme Geldenhuys
to Vincent Snijders
Vincent Snijders wrote 8 lines
> Can you introduce constants instead of all these hardcoded numbers so the > code is more readable ? > Maybe Brams mail should be incorporated, given the fact that the constants don't have a clear meaning. Vincent.

This is exactly why I asked my original question regarding the date routines. After reading is email, I could see why constants where not used. I meant to document somewhere in fpcdoc or even better, in the code what all those numbers meant. Could we add his email as a comment above the code? Or a comment linking it to some help file explaining what he said.

Regards,
- Graeme -

There's no place like 127.0.0.1

Reply by email

Graeme Geldenhuys
to Vincent Snijders: I would propose to create a tests\fpunit and/or a tests\webfpu directory where fpunit…
Vincent Snijders wrote
From Greame I would like to know how he proposes to update the TestSuite, if a new tests it added.

I am busy looking at the /tests directory now, to understand how tests get grouped. This should give me a clearer idea of what is possible. It took us a while to get a decent test structure for our code as well.

I agree that certain tests will have to stay in the format they are in now. Things that shouldn't compile, etc... All other tests could be group in test suites. RTL suite, FCL suite, etc..
Maybe Dean Zobec has some ideas on this too. Dean?

I like the idea you guys have of using the Bug Report Number as the test name. This could be done with fpcUnit as well and should make tracking of what tests have been converted to fpcUnit quite easy. eg: Lets say we have a bug #1234 in the RTL. Edit the RTL suite, by adding a new method to the test class and the same naming convention could be used. No extra objects / classes need to be created, just a new method needs to be added. Even the person reporting the bug could write a simple fpcUnit test and submit that to Mantis, which can then be copied into the correct suite. I submitted a couple of simple fpcUnit test cases to show a bug, until I found out the FPCCore team doesn't use the fpcUnit testing framework. At that stage, I thought using fpcUnit was the logical choice as it shipped with FPC.

---------  simple example  -----------------
  TRTLTestSuite= class(TTestCase)
  published
    [...]
    procedure Bug1234;
  end;
implementation
procedure TRTLTestSuite.Bug1234;
begin
  Fail('Write your own test');
end;
------------------------------------------------------

Having had a look at a few random tests, they are really short and to the point, so shouldn't take much time to convert to fpcUnit.

Graeme.

There's no place like 127.0.0.1

Reply by email

Joost van der Sluis
to Graeme Geldenhuys
Graeme Geldenhuys wrote 26 lines
On 5/22/06, Vincent Snijders wrote: > From Greame I would like to know how he proposes to update the > TestSuite, if a new tests it added. I am busy looking at the /tests directory now, to understand how tests get grouped. This should give me a clearer idea of what is possible. It took us a while to get a decent test structure for our code as well. I agree that certain tests will have to stay in the format they are in now. Things that shouldn't compile, etc... All other tests could be group in test suites. RTL suite, FCL suite, etc.. Maybe Dean Zobec has some ideas on this too. Dean? I like the idea you guys have of using the Bug Report Number as the test name. This could be done with fpcUnit as well and should make tracking of what tests have been converted to fpcUnit quite easy. eg: Lets say we have a bug #1234 in the RTL. Edit the RTL suite, by adding a new method to the test class and the same naming convention could be used. No extra objects / classes need to be created, just a new method needs to be added. Even the person reporting the bug could write a simple fpcUnit test and submit that to Mantis, which can then be copied into the correct suite. I submitted a couple of simple fpcUnit test cases to show a bug, until I found out the FPCCore team doesn't use the fpcUnit testing framework. At that stage, I thought using fpcUnit was the logical choice as it shipped with FPC.

Attached you can find an example for how this could be implemented.

The fpcunittests program runs all tests. It get those tests from the testunits.inc file. Use the gentestunits.sh script to generate that include file and fill it with all files names test*.pp. (bash/unix only. Maybe put this in a sort of makefile-system, if that's possible?)

So to add a new unit with tests, name it test*.pp and place it in the same dir as the rest and run the script.

The output is XML, but we could easily add a resultswriter which generates plain text like a logfile.

A unit with 'bug2345' test could be added easily.

I've made a dateutils-test for my last changes. One test still fails, I have a patch ready for that, will send that tomorrow.

What do you guys think?

Regards,

Joost.

ps: No, Bram's patch for EncodeDate didn't get applied

Reply by email

Peter Vreman
to Florian Klaempfl: No, too much work, no real gain :)
Show quoted text 22 lines
Michael Van Canneyt wrote: >>>>> 1. fpcunit didn't exist at the time the FPC tests were implemented. >>>>> 2. Using FPCunit creates a dependency on it. The tests can run >>>>> mostly >>>>> with only the system unit... >>>> >>>> Which dependencies? Maybe they can be reduced and a fpcunit can be >>>> added to tests? >>> >>> fpcunit depends on not so much, but I want to avoid using the FCL in >>> the >>> testsuite... Creating a copy seems rather silly too... >> >> You can create an svn:external to important that one from the fcl >> without >> creating a real copy. > > Good idea. > > Should we convert existing tests to fpcunit ? No, too much work, no real gain :)

I agree here. New tests can be added with fpcunit. But the basic principe of using the halt and the dotest program needs to stay in place.

Reply by email

John E Briggs

I do not know how relevant this site is but it maybe worthwhile to browse

http://www.chronos-st.org

You maybe able to develope a few libraries/units for date/timekeeping purposes from the ideas presented on this site.

John

Graeme Geldenhuys wrote 24 lines
On 5/22/06, Bram Kuijvenhoven wrote: >I guess we will need plenty of unit tests to make sure all the functions >work consistent, in particular also for dates close to and before >29-12-1899 :) > >(Note: I sent some mail explaining the TryEncodeDateTime function some >time ago (21-4-2006), on Graeme's request. I also mentioned an overflow >problem in that code + how to fix. Perhaps this fix can be integrated into >the code as well.) > Hi Bram, Yeah, I had my share of uphill battles with old dates (Delphi and FPC). I works fine with recent dates, but don't venture to far off!! I already have a collection of unit tests for dates, which is incorporated into our products unit tests. We use fpcUnit extensively. I could always extend those tests a bit more, but as far as I understand, FPC developers dont' use fpcUnit, but rather some custom testing framework. Regards, Graeme.

Reply by email

Michael Van Canneyt
to Joost van der Sluis: The attached patch fixs some problems with negative TDateTimes. It could be that the…
Joost van der Sluis wrote 10 lines
The attached patch fixs some problems with negative TDateTimes. It could be that the changes in DecodeDate are for the same problem as Bram already send a patch for: + removed obsolete DayTable + fixed DateTimeToTimestamp, EncodeDate, DecodeDate, DecodeTime for TDatetimes < 0 + MSecsToTimeStamp must change day at 24:00, not at 12:00 + removed double code in Now and DecodeDateFully

I reviewed and applied the patch, thanks !

Michael.

Reply by email

Michael Van Canneyt
to Peter Vreman: I agree here. New tests can be added with fpcunit. But the basic principe of using the…
Peter Vreman wrote 25 lines
> Michael Van Canneyt wrote: >>>>>> 1. fpcunit didn't exist at the time the FPC tests were implemented. >>>>>> 2. Using FPCunit creates a dependency on it. The tests can run >>>>>> mostly >>>>>> with only the system unit... >>>>> >>>>> Which dependencies? Maybe they can be reduced and a fpcunit can be >>>>> added to tests? >>>> >>>> fpcunit depends on not so much, but I want to avoid using the FCL in >>>> the >>>> testsuite... Creating a copy seems rather silly too... >>> >>> You can create an svn:external to important that one from the fcl >>> without >>> creating a real copy. >> >> Good idea. >> >> Should we convert existing tests to fpcunit ? > > No, too much work, no real gain :) I agree here. New tests can be added with fpcunit. But the basic principe of using the halt and the dotest program needs to stay in place.

That is one of the "problems" of fpcunit: it runs a lot of tests in 1 program. The test suite stores 1 result per program; it would need a lot of modifications, I think.

Michael.

Reply by email

Jonas Maebe
to Michael Van Canneyt
Michael Van Canneyt wrote 7 lines
> I agree here. New tests can be added with fpcunit. But the basic > principe > of using the halt and the dotest program needs to stay in place. That is one of the "problems" of fpcunit: it runs a lot of tests in 1 program. The test suite stores 1 result per program; it would need a lot of modifications, I think.

On the other hand, it would speed up things quite a bit.

Jonas

Reply by email

Bram Kuijvenhoven
to Graeme Geldenhuys: This is exactly why I asked my original question regarding the date routines. After…
Graeme Geldenhuys wrote 17 lines
On 5/22/06, Vincent Snijders wrote: > > Can you introduce constants instead of all these hardcoded numbers > so the > > code is more readable ? > > > > Maybe Brams mail should be incorporated, given the fact that the > constants don't have a clear meaning. > > Vincent. This is exactly why I asked my original question regarding the date routines. After reading is email, I could see why constants where not used. I meant to document somewhere in fpcdoc or even better, in the code what all those numbers meant. Could we add his email as a comment above the code? Or a comment linking it to some help file explaining what he said.

You [i.e. FPC] are free to add the text of the email to the documentation.

Whether the text should be included in one big comment or in the fpdoc documentation, with a link in a comment, is probably depending on some policy -- is there a policy for this? Should implementation details be put in the docs?

Regards,

Bram

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt: That is one of the "problems" of fpcunit: it runs a lot of tests in 1 program. The test…
Michael Van Canneyt wrote 6 lines
> I agree here. New tests can be added with fpcunit. But the basic principe > of using the halt and the dotest program needs to stay in place. That is one of the "problems" of fpcunit: it runs a lot of tests in 1 program. The test suite stores 1 result per program; it would need a lot of modifications, I think.

Yes it runs a lot of tests, but it shows individual results in the xml file generated. Is shows a summary (total tests, total failed results, total error results) and a detailed section of each test including details of the failure or error.

It should be easy to created a new listener and output in whatever format is required. XML results is what ships with fpcUnit, but any output format could be supported.

Graeme.

There's no place like 127.0.0.1

Reply by email

Vincent Snijders
to Joost van der Sluis: Attached you can find an example for how this could be implemented. The fpcunittests…
Joost van der Sluis wrote 33 lines
On Mon, 2006-05-22 at 23:06 +0200, Graeme Geldenhuys wrote: > On 5/22/06, Vincent Snijders wrote: >> From Greame I would like to know how he proposes to update the >> TestSuite, if a new tests it added. > I am busy looking at the /tests directory now, to understand how tests > get grouped. This should give me a clearer idea of what is possible. > It took us a while to get a decent test structure for our code as > well. > > I agree that certain tests will have to stay in the format they are in > now. Things that shouldn't compile, etc... All other tests could be > group in test suites. RTL suite, FCL suite, etc.. > Maybe Dean Zobec has some ideas on this too. Dean? > > I like the idea you guys have of using the Bug Report Number as the > test name. This could be done with fpcUnit as well and should make > tracking of what tests have been converted to fpcUnit quite easy. > eg: Lets say we have a bug #1234 in the RTL. Edit the RTL suite, by > adding a new method to the test class and the same naming convention > could be used. No extra objects / classes need to be created, just a > new method needs to be added. Even the person reporting the bug could > write a simple fpcUnit test and submit that to Mantis, which can then > be copied into the correct suite. I submitted a couple of simple > fpcUnit test cases to show a bug, until I found out the FPCCore team > doesn't use the fpcUnit testing framework. At that stage, I thought > using fpcUnit was the logical choice as it shipped with FPC. Attached you can find an example for how this could be implemented. The fpcunittests program runs all tests. It get those tests from the testunits.inc file. Use the gentestunits.sh script to generate that include file and fill it with all files names test*.pp. (bash/unix only. Maybe put this in a sort of makefile-system, if that's possible?)

Why not a pascal program, to remove the dependency on sh?

So to add a new unit with tests, name it test*.pp and place it in the same dir as the rest and run the script.

Vincent.

Reply by email

Tomas Hajny
to Jonas Maebe: On the other hand, it would speed up things quite a bit. Jonas
Jonas Maebe wrote 12 lines
On 23 mei 2006, at 09:41, Michael Van Canneyt wrote: >> I agree here. New tests can be added with fpcunit. But the basic >> principe >> of using the halt and the dotest program needs to stay in place. > > That is one of the "problems" of fpcunit: it runs a lot of tests in 1 > program. The test suite stores 1 result per program; it would need > a lot of modifications, I think. On the other hand, it would speed up things quite a bit.

Couldn't it happen that one of the tests just crashes the whole program, so further tests are not run at all then?

Tomas

Reply by email

Michael Van Canneyt
to Jonas Maebe: On the other hand, it would speed up things quite a bit. Jonas
Jonas Maebe wrote 11 lines
On 23 mei 2006, at 09:41, Michael Van Canneyt wrote: >> I agree here. New tests can be added with fpcunit. But the basic principe >> of using the halt and the dotest program needs to stay in place. > > That is one of the "problems" of fpcunit: it runs a lot of tests in 1 > program. The test suite stores 1 result per program; it would need > a lot of modifications, I think. On the other hand, it would speed up things quite a bit.

Correct.
I'm not against changing to fpcunit, but it will require again a lot of work...

Michael.

Reply by email

Graeme Geldenhuys
to Tomas Hajny: Couldn't it happen that one of the tests just crashes the whole program, so further tests…
Tomas Hajny wrote
Couldn't it happen that one of the tests just crashes the whole program, so further tests are not run at all then?

Nope. That is the beauty of xUnit testing frameworks. A Failures (something you are testing for) and Errors (unexpected like exceptions though you can test for exceptions as well) are caught by the testing framework, so results can be written to show what happened on each test case. Tests are guaranteed to run (or tried to run).

Regards,
- Graeme -

There's no place like 127.0.0.1

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt: Correct. I'm not against changing to fpcunit, but it will require again a lot of work...…
Michael Van Canneyt wrote 5 lines
> On the other hand, it would speed up things quite a bit. Correct. I'm not against changing to fpcunit, but it will require again a lot of work...

Yes much faster! I just finished a case in point on our code. One of our developers (new to unit testing) used the Setup and TearDown methods in a TestSuite to setup a db connection, do a test and close the connection. Over and over and over. The 27 tests took over 30seconds to execute.

I relocated the db connection code to a test decorator (part of fpcUnit and took 15 lines of code to implement) and now it creates a single connection for the lifetime of all tests in that TestSuite. Time to run those 27 test are now 1.9 seconds!

I can't see how something like this is possible with the way the fpc team does testing.

Regards,
Graeme.

There's no place like 127.0.0.1

Reply by email

Vincent Snijders
to Graeme Geldenhuys
Graeme Geldenhuys wrote 21 lines
On 5/23/06, Michael Van Canneyt wrote: > > On the other hand, it would speed up things quite a bit. > > Correct. > I'm not against changing to fpcunit, but it will require again a lot of > work... Yes much faster! I just finished a case in point on our code. One of our developers (new to unit testing) used the Setup and TearDown methods in a TestSuite to setup a db connection, do a test and close the connection. Over and over and over. The 27 tests took over 30seconds to execute. I relocated the db connection code to a test decorator (part of fpcUnit and took 15 lines of code to implement) and now it creates a single connection for the lifetime of all tests in that TestSuite. Time to run those 27 test are now 1.9 seconds! I can't see how something like this is possible with the way the fpc team does testing.

It doesn't create database connection at all :-)

Vincent.

Reply by email

Joost van der Sluis
to Graeme Geldenhuys: Yes much faster! I just finished a case in point on our code. One of our developers…
Graeme Geldenhuys wrote 20 lines
On 5/23/06, Michael Van Canneyt wrote: > > On the other hand, it would speed up things quite a bit. > > Correct. > I'm not against changing to fpcunit, but it will require again a lot of > work... Yes much faster! I just finished a case in point on our code. One of our developers (new to unit testing) used the Setup and TearDown methods in a TestSuite to setup a db connection, do a test and close the connection. Over and over and over. The 27 tests took over 30seconds to execute. I relocated the db connection code to a test decorator (part of fpcUnit and took 15 lines of code to implement) and now it creates a single connection for the lifetime of all tests in that TestSuite. Time to run those 27 test are now 1.9 seconds! I can't see how something like this is possible with the way the fpc team does testing.

Well.... fcl/dbtests ...

They are still slow, though. Since the data must get be clear between every test. But there's still a lot to improve..

Joost.

Reply by email

Jonas Maebe
to Graeme Geldenhuys: Yes much faster! I just finished a case in point on our code. One of our developers…
Graeme Geldenhuys wrote 13 lines
Yes much faster! I just finished a case in point on our code. One of our developers (new to unit testing) used the Setup and TearDown methods in a TestSuite to setup a db connection, do a test and close the connection. Over and over and over. The 27 tests took over 30seconds to execute. I relocated the db connection code to a test decorator (part of fpcUnit and took 15 lines of code to implement) and now it creates a single connection for the lifetime of all tests in that TestSuite. Time to run those 27 test are now 1.9 seconds! I can't see how something like this is possible with the way the fpc team does testing.

Our output is simply redirected to a file. This file is later parsed and committed to the database in one go using another program (well, actually it's uploaded to www.freepascal.org, where a program does this parsing and committing).

The main cause of slowness when running the fpc test suite is the thousands of compiler, assembler, linker and test program invocations (assembler and linker only on platforms without an internal assembler and/or linker, obviously).

Jonas

Reply by email

Marco van de Voort
to Graeme Geldenhuys: Yes much faster! I just finished a case in point on our code. One of our developers…
Show quoted text 7 lines
I relocated the db connection code to a test decorator (part of fpcUnit and took 15 lines of code to implement) and now it creates a single connection for the lifetime of all tests in that TestSuite. Time to run those 27 test are now 1.9 seconds! I can't see how something like this is possible with the way the fpc team does testing.

This already happens. The output of all tests is collected by a collector (dotest) program, and is then optionally submitted to a db.

This because one can't require a db connection because the testsuite must also run on embedded targets.

Note that this infrastructure has to persist anyway for all tests that somehow have a global effect on the program (so that you can't combine multiple ones in a program), or even fail to compile/start.

Reply by email

Florian Klaempfl
to Peter Vreman: I agree here. New tests can be added with fpcunit. But the basic principe of using the…
Peter Vreman wrote 20 lines
> Michael Van Canneyt wrote: >>>>>> 1. fpcunit didn't exist at the time the FPC tests were implemented. >>>>>> 2. Using FPCunit creates a dependency on it. The tests can run >>>>>> mostly >>>>>> with only the system unit... >>>>> Which dependencies? Maybe they can be reduced and a fpcunit can be >>>>> added to tests? >>>> fpcunit depends on not so much, but I want to avoid using the FCL in >>>> the >>>> testsuite... Creating a copy seems rather silly too... >>> You can create an svn:external to important that one from the fcl >>> without >>> creating a real copy. >> Good idea. >> >> Should we convert existing tests to fpcunit ? > No, too much work, no real gain :) I agree here. New tests can be added with fpcunit. But the basic principe of using the halt and the dotest program needs to stay in place.

I see no problem to execute "high" level tests using fpcunit. Maybe we need to redesign our tests structure a little bit because with the current test system we can't test fcl, packages and friends.

Reply by email

Michael Van Canneyt
to Florian Klaempfl
Florian Klaempfl wrote 25 lines
Peter Vreman wrote: >> Michael Van Canneyt wrote: >>>>>>> 1. fpcunit didn't exist at the time the FPC tests were implemented. >>>>>>> 2. Using FPCunit creates a dependency on it. The tests can run >>>>>>> mostly >>>>>>> with only the system unit... >>>>>> Which dependencies? Maybe they can be reduced and a fpcunit can be >>>>>> added to tests? >>>>> fpcunit depends on not so much, but I want to avoid using the FCL in >>>>> the >>>>> testsuite... Creating a copy seems rather silly too... >>>> You can create an svn:external to important that one from the fcl >>>> without >>>> creating a real copy. >>> Good idea. >>> >>> Should we convert existing tests to fpcunit ? >> No, too much work, no real gain :) > > I agree here. New tests can be added with fpcunit. But the basic principe > of using the halt and the dotest program needs to stay in place. I see no problem to execute "high" level tests using fpcunit. Maybe we need to redesign our tests structure a little bit because with the current test system we can't test fcl, packages and friends.

If we want to do this, there are 2 options:

1. Include the test programs with the packages/fcl/rtl whatever.
2. Use a completely separate test directory, as it is now.

Personally, I am slightly in favour of 2, because 1 will require us to put the fpcunit in the RTL. 1. will require a more thorough rewrite of the test suite...

Michael.

Reply by email

Florian Klaempfl
to Michael Van Canneyt
Michael Van Canneyt wrote 42 lines
On Tue, 23 May 2006, Florian Klaempfl wrote: > Peter Vreman wrote: >>> Michael Van Canneyt wrote: >>>>>>>> 1. fpcunit didn't exist at the time the FPC tests were >>>>>>>> implemented. >>>>>>>> 2. Using FPCunit creates a dependency on it. The tests can run >>>>>>>> mostly >>>>>>>> with only the system unit... >>>>>>> Which dependencies? Maybe they can be reduced and a fpcunit can be >>>>>>> added to tests? >>>>>> fpcunit depends on not so much, but I want to avoid using the FCL in >>>>>> the >>>>>> testsuite... Creating a copy seems rather silly too... >>>>> You can create an svn:external to important that one from the fcl >>>>> without >>>>> creating a real copy. >>>> Good idea. >>>> >>>> Should we convert existing tests to fpcunit ? >>> No, too much work, no real gain :) >> >> I agree here. New tests can be added with fpcunit. But the basic >> principe >> of using the halt and the dotest program needs to stay in place. > > I see no problem to execute "high" level tests using fpcunit. Maybe we > need to > redesign our tests structure a little bit because with the current > test system > we can't test fcl, packages and friends. If we want to do this, there are 2 options: 1. Include the test programs with the packages/fcl/rtl whatever. 2. Use a completely separate test directory, as it is now. Personally, I am slightly in favour of 2, because 1 will require us to put the fpcunit in the RTL. 1. will require a more thorough rewrite of the test suite...

Either:
tests can be modelled after fpc/ i.e. containing also rtl/fcl/packages etc. tests go in each dir

With some more makefile magic testing can be limited either to rtl/compiler or extended to everything.

I'am quite sure that fpcunit based tests can be easily extended to return an error level 0 in case of an error so they fit into the current testsuite. In the worst case we add some postprocessor program checking all xml output and writing the errors and exiting with 1. Maybe dotest could be even extended with little effort to parse the xml output of a test which is marked with e.g. %XML and write appropriate info to the logs.

We don't perfect metrics for the fcl/packages how good/bad our implementation is but simply information what's broken and what not.

Reply by email

Tomas Hajny
to Graeme Geldenhuys: Nope. That is the beauty of xUnit testing frameworks. A Failures (something you are…
Graeme Geldenhuys wrote 9 lines
On 5/23/06, Tomas Hajny wrote: > Couldn't it happen that one of the tests just crashes the whole program, > so further tests are not run at all then? Nope. That is the beauty of xUnit testing frameworks. A Failures (something you are testing for) and Errors (unexpected like exceptions though you can test for exceptions as well) are caught by the testing framework, so results can be written to show what happened on each test case. Tests are guaranteed to run (or tried to run).

Well, I'm fairly sure that it wouldn't work like that for the OS/2 target at least (no FPC exception handler), but that's another story. However, I believe this may happen for other targets too - if you have a misbehaving RTL routine that overwrites half of your heap, you'll probably end up in the whole program crashing (i.e. if all the tests are run in one process, some of the tests will never be started).

Tomas

Reply by email

Joost van der Sluis
to Florian Klaempfl: Either: tests can be modelled after fpc/ i.e. containing also rtl/fcl/packages etc. tests…
Florian Klaempfl wrote 47 lines
Michael Van Canneyt wrote: > On Tue, 23 May 2006, Florian Klaempfl wrote: >> Peter Vreman wrote: >>>> Michael Van Canneyt wrote: >>>>>>>>> 1. fpcunit didn't exist at the time the FPC tests were >>>>>>>>> implemented. >>>>>>>>> 2. Using FPCunit creates a dependency on it. The tests can run >>>>>>>>> mostly >>>>>>>>> with only the system unit... >>>>>>>> Which dependencies? Maybe they can be reduced and a fpcunit can be >>>>>>>> added to tests? >>>>>>> fpcunit depends on not so much, but I want to avoid using the FCL in >>>>>>> the >>>>>>> testsuite... Creating a copy seems rather silly too... >>>>>> You can create an svn:external to important that one from the fcl >>>>>> without >>>>>> creating a real copy. >>>>> Good idea. >>>>> >>>>> Should we convert existing tests to fpcunit ? >>>> No, too much work, no real gain :) >>> >>> I agree here. New tests can be added with fpcunit. But the basic >>> principe >>> of using the halt and the dotest program needs to stay in place. >> >> I see no problem to execute "high" level tests using fpcunit. Maybe we >> need to >> redesign our tests structure a little bit because with the current >> test system >> we can't test fcl, packages and friends. > > If we want to do this, there are 2 options: > > 1. Include the test programs with the packages/fcl/rtl whatever. > 2. Use a completely separate test directory, as it is now. > > Personally, I am slightly in favour of 2, because 1 will require > us to put the fpcunit in the RTL. 1. will require a more thorough > rewrite of the test suite... Either: tests can be modelled after fpc/ i.e. containing also rtl/fcl/packages etc. tests go in each dir With some more makefile magic testing can be limited either to rtl/compiler or extended to everything.

I should use option 2 - add a directory to tests for the fpcunit-tests. Then, depending on some switch you can turn of the compilation of groups of tests. Like only compile the RTL-tests, or compile RTL, FCL and DB- tests.

That's easily done with the example i've send to the list.

Also, if people want to do that, they can use the Lazarus-fpcunit- runner. They only need to include the right include-files.

But you can only do this for the high-level tests, offcourse. I woudn't change the current tests...

Show quoted text 6 lines
I'am quite sure that fpcunit based tests can be easily extended to return an error level 0 in case of an error so they fit into the current testsuite. In the worst case we add some postprocessor program checking all xml output and writing the errors and exiting with 1. Maybe dotest could be even extended with little effort to parse the xml output of a test which is marked with e.g. %XML and write appropriate info to the logs.

The fpc-test runner is only 8 lines of code. 'If errorcount>0 then exit (errorcount);' or something like that is very easily added. It's also possible to change the output to a better readable log.

The advantage is that the user himself can choose if he wants XML, Logfile or graphical output.

And adding the results to the testsuite-db can be done the same way as it's done now.

Joost.

Reply by email

Graeme Geldenhuys
to Tomas Hajny: Well, I'm fairly sure that it wouldn't work like that for the OS/2 target at least (no…
Tomas Hajny wrote
believe this may happen for other targets too - if you have a misbehaving RTL routine that overwrites half of your heap, you'll probably end up in the whole program crashing (i.e. if all the tests are run in one process, some of the tests will never be started).

In such a case, slap the developer that commited broken code! :) UnitTests should be able to run quickly and should be done by the developer before commiting any changes. This process works for our company and we love to slap developers that break the nightly build!! ;-)

Regards,
Graeme.

There's no place like 127.0.0.1

Reply by email

Florian Klaempfl
to Graeme Geldenhuys
Graeme Geldenhuys wrote 9 lines
On 5/23/06, Tomas Hajny wrote: > believe this may happen for other targets too - if you have a misbehaving > RTL routine that overwrites half of your heap, you'll probably end up in > the whole program crashing (i.e. if all the tests are run in one process, > some of the tests will never be started). In such a case, slap the developer that commited broken code! :) UnitTests should be able to run quickly and should be done by the developer before commiting any changes.

That's not possible with FPC. You can usually run the test suite only for your development platform.

Reply by email

Vincent Snijders
to Graeme Geldenhuys: In such a case, slap the developer that commited broken code! :) UnitTests should be…
Graeme Geldenhuys wrote 11 lines
On 5/23/06, Tomas Hajny wrote: > believe this may happen for other targets too - if you have a misbehaving > RTL routine that overwrites half of your heap, you'll probably end up in > the whole program crashing (i.e. if all the tests are run in one process, > some of the tests will never be started). In such a case, slap the developer that commited broken code! :) UnitTests should be able to run quickly and should be done by the developer before commiting any changes. This process works for our company and we love to slap developers that break the nightly build!! ;-)

The problem is, that you can not expect a developer to test it on all 10+ supported platforms before committing.

Vincent.

Reply by email

Graeme Geldenhuys
to Joost van der Sluis: I should use option 2 - add a directory to tests for the fpcunit-tests. Then, depending…
Joost van der Sluis wrote 9 lines
> With some more makefile magic testing can be limited either to rtl/compiler or > extended to everything. I should use option 2 - add a directory to tests for the fpcunit-tests. Then, depending on some switch you can turn of the compilation of groups of tests. Like only compile the RTL-tests, or compile RTL, FCL and DB- tests. That's easily done with the example i've send to the list.

That's already possible with fpcUnit's text runner. If you group the tests in suites like I suggested before (FCL suite, RTL suite, etc) you can pass the command line param to the text test runner and it will only execute that suites tests.

use --suite=MyTestSuiteName to run only the tests in a single test suite class use --all to run all test suites registered.

Regards,
Graeme.

There's no place like 127.0.0.1

Reply by email

Graeme Geldenhuys
to Vincent Snijders: The problem is, that you can not expect a developer to test it on all 10+ supported…
Vincent Snijders wrote
The problem is, that you can not expect a developer to test it on all 10+ supported platforms before committing.

Umm, I keep forgetting FPC is a *beast* !!
Our apps only get deployed under Windows and Linux. We are able to use VMWare for all platform testing before a daily commit. 10+ platforms are a different story!

Graeme.

There's no place like 127.0.0.1

Reply by email

Joost van der Sluis
to Graeme Geldenhuys: That's already possible with fpcUnit's text runner. If you group the tests in suites…
Graeme Geldenhuys wrote 18 lines
On 5/23/06, Joost van der Sluis wrote: > > With some more makefile magic testing can be limited either to rtl/compiler or > > extended to everything. > > I should use option 2 - add a directory to tests for the fpcunit-tests. > Then, depending on some switch you can turn of the compilation of groups > of tests. Like only compile the RTL-tests, or compile RTL, FCL and DB- > tests. > > That's easily done with the example i've send to the list. That's already possible with fpcUnit's text runner. If you group the tests in suites like I suggested before (FCL suite, RTL suite, etc) you can pass the command line param to the text test runner and it will only execute that suites tests. use --suite=MyTestSuiteName to run only the tests in a single test suite class use --all to run all test suites registered.

I've used the fpcUnit's text runner. (a stripper version, but ok) The problem is that you don't want to compile all those tests. Thus the FCL-testsuite shoudn't be compiled, since it won't work or you don't want to pull the FCL in.

You can't do that with a command line param

Joost.

Reply by email

Florian Klaempfl
to Graeme Geldenhuys: Umm, I keep forgetting FPC is a *beast* !! Our apps only get deployed under Windows and…
Graeme Geldenhuys wrote 9 lines
On 5/23/06, Vincent Snijders wrote: > The problem is, that you can not expect a developer to test it on all > 10+ supported > platforms before committing. Umm, I keep forgetting FPC is a *beast* !! Our apps only get deployed under Windows and Linux. We are able to use VMWare for all platform testing before a daily commit. 10+ platforms are a different story!

Well, OSes aren't the real problem, the problem are the six supported CPU platforms :) Maybe with QEmu it could be done, that's how I run the ARM test suite for Linux usually.

Reply by email

Marco van de Voort
to Graeme Geldenhuys: In such a case, slap the developer that commited broken code! :) UnitTests should be…
Show quoted text 7 lines
On 5/23/06, Tomas Hajny wrote: > believe this may happen for other targets too - if you have a misbehaving > RTL routine that overwrites half of your heap, you'll probably end up in > the whole program crashing (i.e. if all the tests are run in one process, > some of the tests will never be started). In such a case, slap the developer that commited broken code! :)

1) he might not be on the same continent/timezone
2) he might be busy with Real Life(tm)
3) he might not being able to duplicate it using your particular platform
4) a discussion might spin-off on some maillist how this should be fixed.

All of this time, the crash is blocking getting useful results from the testsuite.

This process works for our company and we love to slap developers that break the nightly build!!;-)

I hope that above points make clear that an OSS project is not a company.

Reply by email

Graeme Geldenhuys
to Marco van de Voort
Marco van de Voort wrote
> This process works for our company and we love to slap developers that > break the nightly build!!;-) I hope that above points make clear that an OSS project is not a company.

Point taken, and the slap was meant with a smiley face at the end...

Graeme.

There's no place like 127.0.0.1

Reply by email