Refactor GcalScheduleSection and add tests

This is the remake of !504 (closed) per my dissertation in #1093. It is rebased on top of a more recent version, and redone like this:

  • GcalScheduleSection now uses unidirectional data flow for widget signals -> actions to perform -> create a new immutable data model -> compute new widget state
  • There are tests for (re)computing the data model, and computing the widget state.
  • There are some initial tests for timezone stuff: for now, just check that the start/end timezones are preserved when the end/start get changed to be out of order with respect to the other one.
  • The trick to "subtract one day from the date_end, add it back when applying" now has a roundtripping test, and I think the split between the data model and the widget state makes it clear what is going on there.

Pending:

  • Fix ::changed() and gcal_schedule_section_day_changed()
  • Move the recurrence stuff and the other data into the data model.
  • Think of what further tests to have.
  • Think what sorts of things are possible now that we have a testing infrastructure.
  • Run my !@#$ code by hand and actually see the widgets in action 😄
  • Use g_autoptr heap-allocated GcalScheduleSectionValues instead of stack-allocated, pass-by-value ones
  • Move the recurrence widgets to being handled by this scheme

Suggestions:

  • See if there is a bug for what happens when you toggle an all-day to be time-slot - what times should be set? (iOS uses the next-hour-from-right-now so if it is 12:34 and you turn an all-day to time-slot, it will set 13:00 to 14:00).
  • Write a test for #1120; it should be easy to fix now. See my comment in that bug; it's a two-fold problem (inconsistent states, plus bug in GCalDateTimeChooser)
  • Also #393. Gonna leave this as an exercise to the reader 😄
  • Also #43 (closed) which is where this whole thing started...
  • ... Basically, all the "times in the event editor are funky" conditions?
  • I think this provides a good starting point to decide what to do with inconsistent states, e.g. when you move date_start after date_end. Right now date_end gets pushed; iOS does something nice in which it just highlights the date/time in red, or with a strikethrough, and there is a final error dialog if you try to commit things in that state. If we choose to display things with a different style, that style would go in the WidgetState and there could be tests for it ("given these inconsistent date/time, assert that the resulting WidgetState specifies the style to indicate inconsistency").

Something I don't really like:

  • Right now there is no easy way to create a GcalEvent just for test purposes, something like gcal_event_from_string("BEGIN:VEVENT..."). Creating a GcalEvent requires a GcalCalendar, which requires an ESource and a gorilla with the entire jungle. So, for the current tests, I am simulating just the DTSTART/DTEND by creating GDateTime by hand, since after all, this is what gcal_schedule_section_set_event() does. This is sufficient for now, but if we are going to test the whole event editor, it may be nice to operate on complete events.
  • (I discovered e_cal_component_new_from_string(), so maybe it's not that hard with a little refactoring.)

Advice required:

  • To synthesize my dates, I'm using g_date_time_new_from_iso8601("20250303T10:00:00-06:00", NULL) because I couldn't figure out how to instantiate a GTimeZone. Is this sufficient for tests? I guess so, but if we are going to have tests for DST, I think we'll need to be able to create timezones by name, so we can use the ones where DST actually exists. How is g_time_zone_new() used?

CC @TitouanReal

Edited by Federico Mena Quintero

Merge request reports

Loading