Merge lp:~zsombi/ubuntu-ui-toolkit/alarm-fetch-fix into lp:ubuntu-ui-toolkit
- alarm-fetch-fix
- Merge into trunk
Status: | Superseded | ||||||||
---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/alarm-fetch-fix | ||||||||
Merge into: | lp:ubuntu-ui-toolkit | ||||||||
Diff against target: |
906 lines (+452/-91) 12 files modified
components.api (+2/-0) modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp (+56/-23) modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h (+2/-0) modules/Ubuntu/Components/plugin/alarmmanager_p.h (+2/-0) modules/Ubuntu/Components/plugin/ucalarm.cpp (+33/-27) modules/Ubuntu/Components/plugin/ucalarm_p.h (+1/-1) modules/Ubuntu/Test/UbuntuTestCase.qml (+69/-1) modules/Ubuntu/Test/deployment.pri (+6/-1) tests/resources/alarm/Alarms.qml (+6/-2) tests/unit/runtest.sh (+1/-1) tests/unit/tst_alarms/tst_alarms.cpp (+171/-20) tests/unit_x11/tst_test/tst_ubuntutestcase.qml (+103/-15) |
||||||||
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/alarm-fetch-fix | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Cris Dywan | Needs Fixing | ||
Review via email: mp+208749@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-04-10.
Commit message
Fix alarm fetching order and interval.
Description of the change
Zsombor Egri (zsombi) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:950
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:951
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
blank lines:
202 +
203 +
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
Missing debug:
114 + qDebug() << "UPDATE OCCURRENCE" << alarm.message << alarm.date << occurrence.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:953
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:957
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:958
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nekhelesh Ramananthan (nik90) wrote : | # |
Okay it was just confirmed to me by Pat McGowan that this MP seems to also fix https:/
Nekhelesh Ramananthan (nik90) wrote : | # |
So on testing this MP with the ubuntu-clock-app, here are the following observations,
1. Bug #1283859 doesn't appear to be fixed. The indicator-datetime does not show the updated recurring alarm values despite it being shown in the clock app.
2. Bug #1285958 seemed already fixed with Renato's patch to EDS which one can find at https:/
3. It also appears that this MP seemed to have fixed Bug #1283212. This bug was reported by Pat Mcgowan who was able to reproduce the bug in image #229. However after installing this MP, I was unable to reproduce the bug again.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:959
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:960
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cris Dywan (kalikiana) wrote : | # |
// do we get segfault because this is missing?
That's a strange comment. I'd assume you want to a) use deleteLater because you know that it can be used until the next main loop iteration, and have the comment say that, idealy by what b) or you scratch both the comment and the deleterLater if this isn't the case c) or FIXME: Work-around unexplained use of fetchRequest
// with EDS we need to query the occurrences separately as the fetch reports only the main events
Is there a bug on fixing the EDS backend?
// if we are on Monday, the first alarm occurrence is gonna be on Wednesday!
It's very bad to have different test results based on when it runs. I'd rather you mock the date or tweak the environment to test both.
QString envManager(
Would be good to have a test case to check that this works. And it might best to unconditionally set it so that you don't have to scratch your head on whether it was picked up or not but simply fails or works.
Zsombor Egri (zsombi) wrote : | # |
> // do we get segfault because this is missing?
>
> That's a strange comment. I'd assume you want to a) use deleteLater because
> you know that it can be used until the next main loop iteration, and have the
> comment say that, idealy by what b) or you scratch both the comment and the
> deleterLater if this isn't the case c) or FIXME: Work-around unexplained use
> of fetchRequest
Right, that comment was left there by mistake :)
>
> // with EDS we need to query the occurrences separately as the fetch reports
> only the main events
>
> Is there a bug on fixing the EDS backend?
There was a bug, the fix had landed way before... More than 1 month ago... The fix was made right after the Toolkit's alarm fetch got broken. However, the same logic works well with the memory manager, so basically there's no difference in logic. We skip the occurrences in the main fetch loop anyway, and only memory manager reports occurrences there (in completeFetchAl
>
> // if we are on Monday, the first alarm occurrence is gonna be on Wednesday!
>
> It's very bad to have different test results based on when it runs. I'd rather
> you mock the date or tweak the environment to test both.
I'll redo the test as it supposed to test whether the first occurrence is the right one. For instance if today is Monday and the occurrence is set to Sunday and Monday, the first occurrence of the alarm should be on Sunday the same week.
>
> QString envManager(
>
> Would be good to have a test case to check that this works. And it might best
> to unconditionally set it so that you don't have to scratch your head on
> whether it was picked up or not but simply fails or works.
This is tricky, as we only have two managers, eds and memory, and eds might not even be available, so I cannot be sure whether that will work. I can only test with arbitrary garbage unavailability....
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:961
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cris Dywan (kalikiana) wrote : | # |
Thanks for the update.
- 962. By Zsombor Egri
-
small fixes, stronger tests
- 963. By Zsombor Egri
-
trunk merge
Cris Dywan (kalikiana) wrote : | # |
// } else if (rawData.type != UCAlarm::OneTime) {
This confused me a bit why OneTime is relevant there.
How about changing checkDow() to avoid != to make it less confusing.
// alarm.setDate(
Somehow this looks arbitrary. Given the fact that it worked before and the week has neither 5 nor 1 days what exactly is the goal here?
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:963
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 964. By Zsombor Egri
-
kick
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:964
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Zsombor Egri (zsombi) wrote : | # |
> // } else if (rawData.type != UCAlarm::OneTime) {
>
> This confused me a bit why OneTime is relevant there.
>
> How about changing checkDow() to avoid != to make it less confusing.
Actually you are right, that is not in the right place there. I've moved the code under the recurring alarm check.
>
> // alarm.setDate(
>
> Somehow this looks arbitrary. Given the fact that it worked before and the
> week has neither 5 nor 1 days what exactly is the goal here?
It doesn't matter how many days are added. The test checks whether an already created alarm updates properly. I'll revert to the original one.
- 965. By Zsombor Egri
-
comments addressed, recurring alarm specific code moved to its proper place
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:965
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Zsombor Egri (zsombi) wrote : | # |
> > // } else if (rawData.type != UCAlarm::OneTime) {
> >
> > This confused me a bit why OneTime is relevant there.
> >
> > How about changing checkDow() to avoid != to make it less confusing.
>
> Actually you are right, that is not in the right place there. I've moved the
> code under the recurring alarm check.
And also refactored a bit. The date adjustment wasn't really belonging to that method, so I wiped the block out as the code under checkRecurringA
Zsombor Egri (zsombi) wrote : | # |
> > > // } else if (rawData.type != UCAlarm::OneTime) {
> > >
> > > This confused me a bit why OneTime is relevant there.
> > >
> > > How about changing checkDow() to avoid != to make it less confusing.
> >
> > Actually you are right, that is not in the right place there. I've moved the
> > code under the recurring alarm check.
>
> And also refactored a bit. The date adjustment wasn't really belonging to that
> method, so I wiped the block out as the code under checkRecurringA
> already does the adjustments.
Sorry, checkRepeatingW
- 966. By Zsombor Egri
-
date adjustments moved into checkRepeatingW
eekly() ; date normalization removed from test case, as that is not the ususl way to give datetime to API. - 967. By Zsombor Egri
-
staging merge
Unmerged revisions
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2014-04-01 12:57:27 +0000 |
3 | +++ components.api 2014-04-10 09:49:53 +0000 |
4 | @@ -593,6 +593,8 @@ |
5 | function findChild(obj,objectName) |
6 | function findInvisibleChild(obj,objectName) |
7 | function mouseMoveSlowly(item,x,y,dx,dy,steps,stepdelay) |
8 | + function flick(item, x, y, dx, dy, pressTimeout, steps, button, modifiers, delay) |
9 | + function mouseLongPress(item, x, y, button, modifiers, delay) |
10 | function tryCompareFunction(func, expectedResult, timeout) |
11 | plugins.qmltypes |
12 | name: "InverseMouseAreaType" |
13 | |
14 | === modified file 'modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp' |
15 | --- modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp 2014-02-21 20:02:29 +0000 |
16 | +++ modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp 2014-04-10 09:49:53 +0000 |
17 | @@ -21,6 +21,7 @@ |
18 | #include "alarmmanager_p.h" |
19 | #include "alarmrequest_p.h" |
20 | #include "alarmsadapter_p.h" |
21 | +#include <qorganizertodooccurrence.h> |
22 | |
23 | #include <QtCore/QFile> |
24 | #include <QtCore/QDir> |
25 | @@ -55,11 +56,15 @@ |
26 | , manager(0) |
27 | , fetchRequest(0) |
28 | { |
29 | - QOrganizerManager local; |
30 | - bool usingDefaultManager = local.availableManagers().contains(ALARM_MANAGER); |
31 | - manager = (usingDefaultManager) ? new QOrganizerManager(ALARM_MANAGER) : new QOrganizerManager(ALARM_MANAGER_FALLBACK); |
32 | + QString envManager(qgetenv("ALARM_BACKEND")); |
33 | + if (!envManager.isEmpty() && QOrganizerManager::availableManagers().contains(envManager)) { |
34 | + manager = new QOrganizerManager(envManager); |
35 | + } else { |
36 | + manager = QOrganizerManager::availableManagers().contains(ALARM_MANAGER) ? |
37 | + new QOrganizerManager(ALARM_MANAGER) : new QOrganizerManager(ALARM_MANAGER_FALLBACK); |
38 | + } |
39 | manager->setParent(q_ptr); |
40 | - if (!usingDefaultManager) { |
41 | + if (manager->managerName() != ALARM_MANAGER) { |
42 | qWarning() << "WARNING: default alarm manager not installed, using" << manager->managerName() << "manager."; |
43 | qWarning() << "This manager may not provide all the needed features."; |
44 | } |
45 | @@ -114,6 +119,7 @@ |
46 | |
47 | int type, days; |
48 | in >> alarm.message >> alarm.date >> alarm.sound >> type >> days >> alarm.enabled; |
49 | + alarm.originalDate = alarm.date; |
50 | alarm.type = static_cast<UCAlarm::AlarmType>(type); |
51 | alarm.days = static_cast<UCAlarm::DaysOfWeek>(days); |
52 | |
53 | @@ -142,7 +148,7 @@ |
54 | |
55 | Q_FOREACH(const AlarmData &alarm, alarmList) { |
56 | out << alarm.message |
57 | - << alarm.date |
58 | + << alarm.originalDate |
59 | << alarm.sound |
60 | << alarm.type |
61 | << alarm.days |
62 | @@ -157,7 +163,6 @@ |
63 | event.setCollectionId(collection.id()); |
64 | event.setAllDay(false); |
65 | event.setStartDateTime(alarm.date); |
66 | - event.setDueDateTime(alarm.date); |
67 | event.setDisplayLabel(alarm.message); |
68 | |
69 | if (alarm.enabled) { |
70 | @@ -224,8 +229,9 @@ |
71 | |
72 | alarm.cookie = QVariant::fromValue<QOrganizerItemId>(event.id()); |
73 | alarm.message = event.displayLabel(); |
74 | - alarm.date = AlarmData::normalizeDate(event.dueDateTime()); |
75 | + alarm.date = AlarmData::normalizeDate(event.startDateTime()); |
76 | alarm.sound = QUrl(event.description()); |
77 | + alarm.originalDate = alarm.date; |
78 | |
79 | // check if the alarm is enabled or not |
80 | QOrganizerItemVisualReminder visual = event.detail(QOrganizerItemDetail::TypeVisualReminder); |
81 | @@ -303,8 +309,8 @@ |
82 | Q_FOREACH(const QOrganizerItem &item, alarms) { |
83 | // repeating alarms may be fetched as occurences, therefore check their parent event |
84 | if (item.type() == QOrganizerItemType::TypeTodoOccurrence) { |
85 | - QOrganizerTodoOccurrence occurence = static_cast<QOrganizerTodoOccurrence>(item); |
86 | - QOrganizerItemId eventId = occurence.parentId(); |
87 | + QOrganizerTodoOccurrence occurrence = static_cast<QOrganizerTodoOccurrence>(item); |
88 | + QOrganizerItemId eventId = occurrence.parentId(); |
89 | if (parentId.contains(eventId)) { |
90 | continue; |
91 | } |
92 | @@ -317,6 +323,7 @@ |
93 | } |
94 | AlarmData alarm; |
95 | if (alarmDataFromOrganizerEvent(event, alarm) == UCAlarm::NoError) { |
96 | + adjustAlarmOccurrence(event, alarm); |
97 | alarmList << alarm; |
98 | } |
99 | } |
100 | @@ -324,9 +331,48 @@ |
101 | saveAlarms(); |
102 | Q_EMIT q_ptr->alarmsChanged(); |
103 | completed = true; |
104 | + fetchRequest->deleteLater(); |
105 | fetchRequest = 0; |
106 | } |
107 | |
108 | +void AlarmsAdapter::adjustAlarmOccurrence(const QOrganizerTodo &event, AlarmData &alarm) |
109 | +{ |
110 | + if (alarm.type == UCAlarm::OneTime) { |
111 | + return; |
112 | + } |
113 | + // with EDS we need to query the occurrences separately as the fetch reports only the main events |
114 | + // with fallback manager this does not reduce the performance and does work the same way. |
115 | + QDateTime currentDate = AlarmData::normalizeDate(QDateTime::currentDateTime()); |
116 | + if (alarm.date > currentDate) { |
117 | + // no need to adjust date, the event occurs in the future |
118 | + return; |
119 | + } |
120 | + QDateTime startDate; |
121 | + QDateTime endDate; |
122 | + if (alarm.type == UCAlarm::Repeating) { |
123 | + // 8 days is enough from the starting date (or current date depending on the start date) |
124 | + startDate = (alarm.date > currentDate) ? alarm.date : currentDate; |
125 | + endDate = startDate.addDays(8); |
126 | + } |
127 | + |
128 | + QList<QOrganizerItem> occurrences = manager->itemOccurrences(event, startDate, endDate, 10); |
129 | + // get the first occurrence and use the date from it |
130 | + if ((occurrences.length() > 0) && (occurrences[0].type() == QOrganizerItemType::TypeTodoOccurrence)) { |
131 | + // loop till we get a proper future due date |
132 | + for (int i = 0; i < occurrences.count(); i++) { |
133 | + QOrganizerTodoOccurrence occurrence = static_cast<QOrganizerTodoOccurrence>(occurrences[i]); |
134 | + // check if the date is after the current datetime |
135 | + // the first occurrence is the one closest to the currentDate, therefore we can safely |
136 | + // set that startDate to the alarm |
137 | + alarm.date = occurrence.startDateTime(); |
138 | + if (alarm.date > currentDate) { |
139 | + // we have the proper date set, leave |
140 | + break; |
141 | + } |
142 | + } |
143 | + } |
144 | +} |
145 | + |
146 | /*----------------------------------------------------------------------------- |
147 | * AlarmRequestAdapter implementation |
148 | */ |
149 | @@ -410,23 +456,10 @@ |
150 | QOrganizerItemFetchRequest *operation = new QOrganizerItemFetchRequest(q_ptr); |
151 | operation->setManager(owner->manager); |
152 | |
153 | - // FIXME: Since returning all events without a limit of date is not a good solution we need to find |
154 | - // a better solution for that. |
155 | - // The current solution filters only the next 7 days (one week). |
156 | - // This will be enough for now, since the current alarms occur weekly, but for the future |
157 | - // we want to allow create alarms with monthly or yearly recurrence |
158 | - QDate currentDate = QDate::currentDate(); |
159 | - QDateTime startDate(currentDate, |
160 | - QTime(0,0,0)); |
161 | - QDateTime endDate(currentDate.addDays(7), |
162 | - QTime(23,59,59)); |
163 | - operation->setStartDate(startDate); |
164 | - operation->setEndDate(endDate); |
165 | - |
166 | // set sort order |
167 | QOrganizerItemSortOrder sortOrder; |
168 | sortOrder.setDirection(Qt::AscendingOrder); |
169 | - sortOrder.setDetail(QOrganizerItemDetail::TypeTodoTime, QOrganizerTodoTime::FieldDueDateTime); |
170 | + sortOrder.setDetail(QOrganizerItemDetail::TypeTodoTime, QOrganizerTodoTime::FieldStartDateTime); |
171 | operation->setSorting(QList<QOrganizerItemSortOrder>() << sortOrder); |
172 | |
173 | // set filter |
174 | |
175 | === modified file 'modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h' |
176 | --- modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h 2013-09-18 10:13:04 +0000 |
177 | +++ modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h 2014-04-10 09:49:53 +0000 |
178 | @@ -24,6 +24,7 @@ |
179 | |
180 | #include <qorganizer.h> |
181 | #include <qorganizermanager.h> |
182 | +#include <qorganizertodo.h> |
183 | |
184 | QTORGANIZER_USE_NAMESPACE |
185 | |
186 | @@ -78,6 +79,7 @@ |
187 | QOrganizerCollection collection; |
188 | |
189 | void completeFetchAlarms(const QList<QOrganizerItem> &alarmList); |
190 | + void adjustAlarmOccurrence(const QOrganizerTodo &event, AlarmData &alarm); |
191 | |
192 | void loadAlarms(); |
193 | void saveAlarms(); |
194 | |
195 | === modified file 'modules/Ubuntu/Components/plugin/alarmmanager_p.h' |
196 | --- modules/Ubuntu/Components/plugin/alarmmanager_p.h 2013-09-12 05:27:40 +0000 |
197 | +++ modules/Ubuntu/Components/plugin/alarmmanager_p.h 2014-04-10 09:49:53 +0000 |
198 | @@ -48,6 +48,7 @@ |
199 | AlarmData(const AlarmData &other) |
200 | : changes(0) |
201 | , cookie(other.cookie) |
202 | + , originalDate(other.originalDate) |
203 | , date(other.date) |
204 | , message(other.message) |
205 | , type(other.type) |
206 | @@ -104,6 +105,7 @@ |
207 | QVariant cookie; |
208 | |
209 | // data members |
210 | + QDateTime originalDate; |
211 | QDateTime date; |
212 | QString message; |
213 | QUrl sound; |
214 | |
215 | === modified file 'modules/Ubuntu/Components/plugin/ucalarm.cpp' |
216 | --- modules/Ubuntu/Components/plugin/ucalarm.cpp 2013-09-18 10:25:18 +0000 |
217 | +++ modules/Ubuntu/Components/plugin/ucalarm.cpp 2014-04-10 09:49:53 +0000 |
218 | @@ -102,15 +102,21 @@ |
219 | |
220 | int UCAlarmPrivate::nextDayOfWeek(UCAlarm::DaysOfWeek days, int fromDay) |
221 | { |
222 | - if (fromDay <= 0) { |
223 | + if (fromDay <= 0 || fromDay >= Qt::Sunday) { |
224 | + // start from the beginning of the week |
225 | fromDay = Qt::Monday; |
226 | + } else { |
227 | + // start checking from the next day onwards |
228 | + fromDay++; |
229 | } |
230 | for (int d = fromDay; d <= Qt::Sunday; d++) { |
231 | if ((1 << (d - 1)) & days) { |
232 | return d; |
233 | } |
234 | } |
235 | - return 0; |
236 | + |
237 | + // none found for the rest of the week, return the fist day set |
238 | + return firstDayOfWeek(days); |
239 | } |
240 | |
241 | // checks whether the given num has more than one bit set |
242 | @@ -147,23 +153,14 @@ |
243 | return UCAlarm::NoError; |
244 | } |
245 | |
246 | -UCAlarm::Error UCAlarmPrivate::checkDow() |
247 | +// adjust dayOfWeek |
248 | +UCAlarm::Error UCAlarmPrivate::adjustDow() |
249 | { |
250 | if (!rawData.days) { |
251 | return UCAlarm::NoDaysOfWeek; |
252 | } else if (rawData.days == UCAlarm::AutoDetect) { |
253 | rawData.days = dayOfWeek(rawData.date); |
254 | rawData.changes |= AlarmData::Days; |
255 | - } else if (rawData.days != UCAlarm::Daily) { |
256 | - int alarmDay = firstDayOfWeek(rawData.days); |
257 | - int dayOfWeek = rawData.date.date().dayOfWeek(); |
258 | - if (alarmDay < dayOfWeek) { |
259 | - rawData.date = rawData.date.addDays(7 - dayOfWeek + alarmDay); |
260 | - rawData.changes |= AlarmData::Date; |
261 | - } else if (alarmDay > dayOfWeek) { |
262 | - rawData.date = rawData.date.addDays(alarmDay - dayOfWeek); |
263 | - rawData.changes |= AlarmData::Date; |
264 | - } |
265 | } |
266 | return UCAlarm::NoError; |
267 | } |
268 | @@ -175,8 +172,7 @@ |
269 | return UCAlarm::OneTimeOnMoreDays; |
270 | } |
271 | |
272 | - // adjust start date and/or dayOfWeek according to their values |
273 | - UCAlarm::Error result = checkDow(); |
274 | + UCAlarm::Error result = adjustDow(); |
275 | if (result != UCAlarm::NoError) { |
276 | return result; |
277 | } |
278 | @@ -193,23 +189,25 @@ |
279 | // start date is adjusted depending on the days value; |
280 | // start date can be set to be the current time, as scheduling will move |
281 | // it to the first occurence. |
282 | - UCAlarm::Error result = checkDow(); |
283 | + UCAlarm::Error result = adjustDow(); |
284 | if (result != UCAlarm::NoError) { |
285 | return result; |
286 | } |
287 | |
288 | - // move start time to the first occurence if needed |
289 | + // move start time of the first occurence if needed |
290 | int dayOfWeek = rawData.date.date().dayOfWeek(); |
291 | if (!isDaySet(dayOfWeek, rawData.days) || (rawData.date <= QDateTime::currentDateTime())) { |
292 | // check the next occurence of the alarm |
293 | - int nextOccurence = nextDayOfWeek(rawData.days, dayOfWeek); |
294 | - if (nextOccurence <= 0) { |
295 | - // the starting date should be moved to the next week |
296 | - nextOccurence = firstDayOfWeek(rawData.days); |
297 | - rawData.date.addDays(7 - dayOfWeek + nextOccurence); |
298 | + int nextOccurrence = nextDayOfWeek(rawData.days, dayOfWeek); |
299 | + if (nextOccurrence == dayOfWeek) { |
300 | + // move the date to the same day next week |
301 | + rawData.date = rawData.date.addDays(7); |
302 | + } else if (nextOccurrence < dayOfWeek) { |
303 | + // the starting date should be moved to the next week's occurrence |
304 | + rawData.date = rawData.date.addDays(7 - dayOfWeek + nextOccurrence); |
305 | } else { |
306 | // the starting date is still this week |
307 | - rawData.date.addDays(nextOccurence - dayOfWeek); |
308 | + rawData.date = rawData.date.addDays(nextOccurrence - dayOfWeek); |
309 | } |
310 | rawData.changes |= AlarmData::Date; |
311 | } |
312 | @@ -304,7 +302,7 @@ |
313 | : QObject(parent) |
314 | , d_ptr(new UCAlarmPrivate(this)) |
315 | { |
316 | - d_ptr->rawData.date = dt; |
317 | + d_ptr->rawData.date = AlarmData::normalizeDate(dt); |
318 | if (!message.isEmpty()) { |
319 | d_ptr->rawData.message = message; |
320 | } |
321 | @@ -315,7 +313,7 @@ |
322 | : QObject(parent) |
323 | , d_ptr(new UCAlarmPrivate(this)) |
324 | { |
325 | - d_ptr->rawData.date = dt; |
326 | + d_ptr->rawData.date = AlarmData::normalizeDate(dt); |
327 | d_ptr->rawData.type = Repeating; |
328 | d_ptr->rawData.days = days; |
329 | if (!message.isEmpty()) { |
330 | @@ -366,12 +364,16 @@ |
331 | void UCAlarm::setDate(const QDateTime &date) |
332 | { |
333 | Q_D(UCAlarm); |
334 | - if (d->rawData.date == date) { |
335 | + if (d->rawData.date == AlarmData::normalizeDate(date)) { |
336 | return; |
337 | } |
338 | - d->rawData.date = date; |
339 | + d->rawData.date = AlarmData::normalizeDate(date); |
340 | d->rawData.changes |= AlarmData::Date; |
341 | Q_EMIT dateChanged(); |
342 | + if (d->rawData.type == UCAlarm::OneTime) { |
343 | + // adjust dayOfWeek as well |
344 | + setDaysOfWeek(UCAlarm::AutoDetect); |
345 | + } |
346 | } |
347 | |
348 | /*! |
349 | @@ -520,6 +522,8 @@ |
350 | Q_EMIT soundChanged(); |
351 | } |
352 | |
353 | + |
354 | + |
355 | /*! |
356 | * \qmlproperty Error Alarm::error |
357 | * The property holds the error code occurred during the last performed operation. |
358 | @@ -670,6 +674,8 @@ |
359 | if (result != UCAlarm::NoError) { |
360 | d->_q_syncStatus(Saving, Fail, result); |
361 | } else { |
362 | + // the alarm has been modified, therefore update the original date as well |
363 | + d->rawData.originalDate = d->rawData.date; |
364 | if (d->createRequest()) { |
365 | d->request->save(d->rawData); |
366 | } |
367 | |
368 | === modified file 'modules/Ubuntu/Components/plugin/ucalarm_p.h' |
369 | --- modules/Ubuntu/Components/plugin/ucalarm_p.h 2013-09-18 10:25:18 +0000 |
370 | +++ modules/Ubuntu/Components/plugin/ucalarm_p.h 2014-04-10 09:49:53 +0000 |
371 | @@ -50,7 +50,7 @@ |
372 | static int nextDayOfWeek(UCAlarm::DaysOfWeek days, int fromDay); |
373 | static bool multipleDaysSet(UCAlarm::DaysOfWeek days); |
374 | UCAlarm::Error checkAlarm(); |
375 | - UCAlarm::Error checkDow(); |
376 | + UCAlarm::Error adjustDow(); |
377 | UCAlarm::Error checkOneTime(); |
378 | UCAlarm::Error checkRepeatingWeekly(); |
379 | |
380 | |
381 | === modified file 'modules/Ubuntu/Test/UbuntuTestCase.qml' |
382 | --- modules/Ubuntu/Test/UbuntuTestCase.qml 2014-02-25 12:36:27 +0000 |
383 | +++ modules/Ubuntu/Test/UbuntuTestCase.qml 2014-04-10 09:49:53 +0000 |
384 | @@ -87,7 +87,75 @@ |
385 | } |
386 | } |
387 | |
388 | - /*! |
389 | + /*! |
390 | + \qmlmethod UbuntuTestCase::flick(item, x, y, dx, dy, pressTimeout = -1, steps = -1, button = Qt.LeftButton, modifiers = Qt.NoModifiers, delay = -1) |
391 | + |
392 | + The function produces a flick event when executed on Flickables. When used |
393 | + on other components it provides the same functionality as \l mouseDrag() |
394 | + function. The optional \a pressTimeout parameter can be used to introduce |
395 | + a small delay between the mouse press and the first mouse move. Setting a |
396 | + negative or zero value will disable the timeout. |
397 | + |
398 | + The default flick velocity is built up using 5 move points. This can be altered |
399 | + by setting a positive value to \a steps parameter. The bigger the number the |
400 | + longer the flick will be. When a negative or zero value is given, the default |
401 | + of 5 move points will be used. |
402 | + |
403 | + \note The function can be used to select a text in a TextField or TextArea by |
404 | + specifying at least 400 millisecods to \a pressTimeout. |
405 | + */ |
406 | + function flick(item, x, y, dx, dy, pressTimeout, steps, button, modifiers, delay) { |
407 | + if (item === undefined || item.x === undefined || item.y === undefined) |
408 | + return |
409 | + if (button === undefined) |
410 | + button = Qt.LeftButton |
411 | + if (modifiers === undefined) |
412 | + modifiers = Qt.NoModifier |
413 | + if (steps === undefined || steps <= 0) |
414 | + steps = 4; |
415 | + // make sure we have at least two move steps so the flick will be sensed |
416 | + steps += 1; |
417 | + if (delay === undefined) |
418 | + delay = -1; |
419 | + |
420 | + var ddx = dx / steps; |
421 | + var ddy = dy / steps; |
422 | + |
423 | + mousePress(item, x, y, button, modifiers, delay); |
424 | + if (pressTimeout !== undefined && pressTimeout > 0) { |
425 | + wait(pressTimeout); |
426 | + } |
427 | + for (var i = 1; i <= steps; i++) { |
428 | + // mouse moves are all processed immediately, without delay in between events |
429 | + mouseMove(item, x + i * ddx, y + i * ddy, -1, button); |
430 | + } |
431 | + mouseRelease(item, x + dx, y + dy, button, modifiers, delay); |
432 | + // empty event buffer |
433 | + wait(200); |
434 | + } |
435 | + |
436 | + /*! |
437 | + \qmlmethod UbuntuTestCase::mouseLongPress(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifiers, delay = -1) |
438 | + |
439 | + Simulates a long press on a mouse \a button with an optional \a modifier |
440 | + on an \a item. The position is defined by \a x and \a y. If \a delay is |
441 | + specified, the test will wait the specified amount of milliseconds before |
442 | + the press. |
443 | + |
444 | + The position given by \a x and \a y is transformed from the co-ordinate |
445 | + system of \a item into window co-ordinates and then delivered. |
446 | + If \a item is obscured by another item, or a child of \a item occupies |
447 | + that position, then the event will be delivered to the other item instead. |
448 | + |
449 | + \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel() |
450 | + */ |
451 | + function mouseLongPress(item, x, y, button, modifiers, delay) { |
452 | + mousePress(item, x, y, button, modifiers, delay); |
453 | + // the delay is taken from QQuickMouseArea |
454 | + wait(800); |
455 | + } |
456 | + |
457 | + /*! |
458 | Keeps executing a given parameter-less function until it returns the given |
459 | expected result or the timemout is reached (in which case a test failure |
460 | is generated) |
461 | |
462 | === modified file 'modules/Ubuntu/Test/deployment.pri' |
463 | --- modules/Ubuntu/Test/deployment.pri 2014-01-17 12:30:05 +0000 |
464 | +++ modules/Ubuntu/Test/deployment.pri 2014-04-10 09:49:53 +0000 |
465 | @@ -7,9 +7,14 @@ |
466 | # make found deployables visible in Qt Creator |
467 | OTHER_FILES += $$QMLDIR_FILE |
468 | |
469 | +QML_FILES = $$system(ls *.qml) |
470 | +JS_FILES = $$system(ls *.js) |
471 | + |
472 | # define deployment for found deployables |
473 | qmldir_file.path = $$installPath |
474 | qmldir_file.files = $$QMLDIR_FILE |
475 | +qml_files.path = $$installPath |
476 | +qml_files.files = $$QML_FILES |
477 | js_files.path = $$installPath |
478 | js_files.files = $$JS_FILES |
479 | |
480 | @@ -20,4 +25,4 @@ |
481 | # https://bugreports.qt-project.org/browse/QTBUG-36243 |
482 | plugins_qmltypes.extra = $$[QT_INSTALL_BINS]/qmlplugindump -notrelocatable Ubuntu.Test 0.1 ../../ 2>/dev/null > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes |
483 | |
484 | -INSTALLS += qmldir_file plugins_qmltypes |
485 | +INSTALLS += qmldir_file plugins_qmltypes qml_files js_files |
486 | |
487 | === modified file 'tests/resources/alarm/Alarms.qml' |
488 | --- tests/resources/alarm/Alarms.qml 2013-09-18 10:13:04 +0000 |
489 | +++ tests/resources/alarm/Alarms.qml 2014-04-10 09:49:53 +0000 |
490 | @@ -21,7 +21,7 @@ |
491 | |
492 | MainView { |
493 | id: mainView |
494 | - width: units.gu(40) |
495 | + width: units.gu(80) |
496 | height: units.gu(71) |
497 | objectName: "mainView" |
498 | |
499 | @@ -162,7 +162,11 @@ |
500 | clip: true |
501 | model: alarmModel |
502 | delegate: Standard { |
503 | - text: message |
504 | + text: message + recurring(model) + "\n" + model.date |
505 | + function recurring(alarmData) { |
506 | + return (alarmData.type === Alarm.Repeating) ? "[Repeating]" : "[Onetime]"; |
507 | + } |
508 | + |
509 | removable: true |
510 | control: Switch { |
511 | checked: model.enabled |
512 | |
513 | === modified file 'tests/unit/runtest.sh' |
514 | --- tests/unit/runtest.sh 2014-03-31 18:26:46 +0000 |
515 | +++ tests/unit/runtest.sh 2014-04-10 09:49:53 +0000 |
516 | @@ -33,7 +33,7 @@ |
517 | if [ $_TARGET != $_TESTFILE ]; then |
518 | _CMD="$_CMD -input $_TESTFILE" |
519 | fi |
520 | - _CMD="$_CMD -maxwarnings 4" |
521 | + _CMD="$_CMD -maxwarnings 40" |
522 | } |
523 | |
524 | function execute_test_cmd { |
525 | |
526 | === modified file 'tests/unit/tst_alarms/tst_alarms.cpp' |
527 | --- tests/unit/tst_alarms/tst_alarms.cpp 2014-02-21 18:23:41 +0000 |
528 | +++ tests/unit/tst_alarms/tst_alarms.cpp 2014-04-10 09:49:53 +0000 |
529 | @@ -25,6 +25,7 @@ |
530 | #include "adapters/alarmsadapter_p.h" |
531 | #undef protected |
532 | |
533 | +#include "uctestcase.h" |
534 | #include <QtCore/QString> |
535 | #include <QtCore/QTextCodec> |
536 | #include <QtCore/QDebug> |
537 | @@ -64,11 +65,18 @@ |
538 | syncFetch(); |
539 | } |
540 | |
541 | - bool containsAlarm(UCAlarm *alarm) |
542 | + bool containsAlarm(UCAlarm *alarm, bool trace = false) |
543 | { |
544 | UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(alarm); |
545 | QList<AlarmData> alarms = AlarmManager::instance().alarms(); |
546 | Q_FOREACH(AlarmData i, alarms) { |
547 | + if (trace && (alarm->message() == i.message)) { |
548 | + qDebug() << "----------------------"; |
549 | + qDebug() << "Alarm data:" << alarm->message(); |
550 | + qDebug() << alarm->date() << i.date; |
551 | + qDebug() << alarm->type() << i.type; |
552 | + qDebug() << alarm->daysOfWeek() << i.days; |
553 | + } |
554 | if (i == pAlarm->rawData) { |
555 | return true; |
556 | } |
557 | @@ -127,7 +135,7 @@ |
558 | |
559 | void test_repeating_autoDetect() |
560 | { |
561 | - UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::AutoDetect, "test_repeating_autoDetect"); |
562 | + UCAlarm alarm(QDateTime::currentDateTime().addSecs(20), UCAlarm::AutoDetect, "test_repeating_autoDetect"); |
563 | |
564 | alarm.save(); |
565 | waitForRequest(&alarm); |
566 | @@ -137,28 +145,92 @@ |
567 | |
568 | void test_repeating_daily() |
569 | { |
570 | - UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::Daily, "test_repeating_daily"); |
571 | - |
572 | - alarm.save(); |
573 | - waitForRequest(&alarm); |
574 | - QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
575 | - QVERIFY(containsAlarm(&alarm)); |
576 | - } |
577 | - |
578 | - void test_repeating_givenDay() |
579 | - { |
580 | - UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::Wednesday, "test_repeating_givenDay"); |
581 | - |
582 | - alarm.save(); |
583 | - waitForRequest(&alarm); |
584 | - QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
585 | - QVERIFY(containsAlarm(&alarm)); |
586 | + UCAlarm alarm(QDateTime::currentDateTime().addSecs(10), UCAlarm::Daily, "test_repeating_daily"); |
587 | + |
588 | + alarm.save(); |
589 | + waitForRequest(&alarm); |
590 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
591 | + QVERIFY(containsAlarm(&alarm)); |
592 | + } |
593 | + |
594 | + void test_repeating_givenDay_exact_data() |
595 | + { |
596 | + QTest::addColumn<QString>("message"); |
597 | + QTest::addColumn<int>("day"); |
598 | + |
599 | + QTest::newRow("Monday") << "Monday" << (int)UCAlarm::Monday; |
600 | + QTest::newRow("Tuesday") << "Tuesday" << (int)UCAlarm::Tuesday; |
601 | + QTest::newRow("Wednesday") << "Wednesday" << (int)UCAlarm::Wednesday; |
602 | + QTest::newRow("Thursday") << "Thursday" << (int)UCAlarm::Thursday; |
603 | + QTest::newRow("Friday") << "Friday" << (int)UCAlarm::Friday; |
604 | + QTest::newRow("Saturday") << "Saturday" << (int)UCAlarm::Saturday; |
605 | + QTest::newRow("Sunday") << "Sunday" << (int)UCAlarm::Sunday; |
606 | + } |
607 | + |
608 | + void test_repeating_givenDay_exact() |
609 | + { |
610 | + QFETCH(QString, message); |
611 | + QFETCH(int, day); |
612 | + UCAlarm alarm(QDateTime::currentDateTime(), (UCAlarm::DaysOfWeek)day, "test_repeating_givenDay_exact_" + message); |
613 | + |
614 | + alarm.save(); |
615 | + waitForRequest(&alarm); |
616 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
617 | + QVERIFY(containsAlarm(&alarm)); |
618 | + } |
619 | + |
620 | + void test_repeating_moreDays_data() |
621 | + { |
622 | + QTest::addColumn<QString>("message"); |
623 | + QTest::addColumn<int>("days"); |
624 | + |
625 | + QTest::newRow("First on Monday") << "Monday" << (int)(UCAlarm::Monday | UCAlarm::Sunday); |
626 | + QTest::newRow("First on Tuesday") << "Tuesday" << (int)(UCAlarm::Tuesday | UCAlarm::Monday); |
627 | + QTest::newRow("First on Wednesday") << "Wednesday" << (int)(UCAlarm::Wednesday | UCAlarm::Tuesday); |
628 | + QTest::newRow("First on Thursday") << "Thursday" << (int)(UCAlarm::Thursday | UCAlarm::Wednesday); |
629 | + QTest::newRow("First on Friday") << "Friday" << (int)(UCAlarm::Friday | UCAlarm::Thursday); |
630 | + QTest::newRow("First on Saturday") << "Saturday" << (int)(UCAlarm::Saturday | UCAlarm::Friday); |
631 | + QTest::newRow("First on Sunday") << "Sunday" << (int)(UCAlarm::Sunday | UCAlarm::Saturday); |
632 | } |
633 | |
634 | void test_repeating_moreDays() |
635 | { |
636 | - UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::Monday | UCAlarm::Wednesday, "test_repeating_moreDays"); |
637 | - |
638 | + QFETCH(QString, message); |
639 | + QFETCH(int, days); |
640 | + |
641 | + QDateTime currentDate(QDateTime::currentDateTime()); |
642 | + |
643 | + UCAlarm alarm(currentDate, (UCAlarm::DaysOfWeek)days, "test_repeating_moreDays" + message); |
644 | + // the distance is always 6 days between the occurrences |
645 | + UCAlarm firstOccurrence(currentDate, alarm.daysOfWeek(), alarm.message()); |
646 | + // make sure we have the same setup as the original one; checkAlarm() adjusts all alarm data |
647 | + UCAlarmPrivate::get(&firstOccurrence)->checkAlarm(); |
648 | + |
649 | + alarm.save(); |
650 | + waitForRequest(&alarm); |
651 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
652 | + QVERIFY(containsAlarm(&alarm)); |
653 | + QVERIFY(containsAlarm(&firstOccurrence)); |
654 | + } |
655 | + |
656 | + void test_repeating_weekly_data() { |
657 | + QTest::addColumn<QString>("message"); |
658 | + QTest::addColumn<int>("dow"); |
659 | + |
660 | + QTest::newRow("Monday") << "Monday" << (int)UCAlarm::Monday; |
661 | + QTest::newRow("Tuesday") << "Tuesday" << (int)UCAlarm::Tuesday; |
662 | + QTest::newRow("Wednesday") << "Wednesday" << (int)UCAlarm::Wednesday; |
663 | + QTest::newRow("Thursday") << "Thursday" << (int)UCAlarm::Thursday; |
664 | + QTest::newRow("Friday") << "Friday" << (int)UCAlarm::Friday; |
665 | + QTest::newRow("Saturday") << "Saturday" << (int)UCAlarm::Saturday; |
666 | + QTest::newRow("Sunday") << "Sunday" << (int)UCAlarm::Sunday; |
667 | + } |
668 | + void test_repeating_weekly() |
669 | + { |
670 | + QFETCH(QString, message); |
671 | + QFETCH(int, dow); |
672 | + |
673 | + UCAlarm alarm(QDateTime::currentDateTime().addSecs(3600), (UCAlarm::DaysOfWeek)dow, "test_repeating_weekly_" + message); |
674 | alarm.save(); |
675 | waitForRequest(&alarm); |
676 | QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
677 | @@ -273,6 +345,85 @@ |
678 | QVERIFY(!containsAlarm(©)); |
679 | } |
680 | |
681 | + void test_updateAlarm_Repeating() |
682 | + { |
683 | + UCAlarm alarm(QDateTime::currentDateTime().addMSecs(5000), UCAlarm::AutoDetect, "test_updateAlarm_Repeating"); |
684 | + |
685 | + alarm.save(); |
686 | + waitForRequest(&alarm); |
687 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
688 | + QVERIFY(containsAlarm(&alarm)); |
689 | + |
690 | + alarm.setDate(alarm.date().addDays(1)); |
691 | + alarm.save(); |
692 | + waitForRequest(&alarm); |
693 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
694 | + QVERIFY(containsAlarm(&alarm)); |
695 | + |
696 | + alarm.setDaysOfWeek(UCAlarm::Daily); |
697 | + alarm.save(); |
698 | + waitForRequest(&alarm); |
699 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
700 | + QVERIFY(containsAlarm(&alarm)); |
701 | + } |
702 | + |
703 | + void test_fetchAlarmPlus7Days() |
704 | + { |
705 | + QDateTime dt = QDateTime::currentDateTime().addDays(10); |
706 | + UCAlarm alarm(dt, "test_fetchAlarmPlus7Days"); |
707 | + |
708 | + alarm.save(); |
709 | + waitForRequest(&alarm); |
710 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
711 | + QVERIFY(containsAlarm(&alarm)); |
712 | + |
713 | + UCAlarm nextMonth(dt.addMonths(1), "test_fetchAlarmPlus1Month"); |
714 | + nextMonth.save(); |
715 | + waitForRequest(&nextMonth); |
716 | + QCOMPARE(nextMonth.error(), (int)UCAlarm::NoError); |
717 | + QVERIFY(containsAlarm(&nextMonth)); |
718 | + |
719 | + UCAlarm nextYear(dt.addYears(1), "test_fetchAlarmPlus1Year"); |
720 | + nextYear.save(); |
721 | + waitForRequest(&nextYear); |
722 | + QCOMPARE(nextYear.error(), (int)UCAlarm::NoError); |
723 | + QVERIFY(containsAlarm(&nextYear)); |
724 | + } |
725 | + |
726 | + void test_correctAlarmOrderDaily() |
727 | + { |
728 | + QDate cd = QDate::currentDate(); |
729 | + QTime ct = QTime::currentTime(); |
730 | + QDateTime dt(cd, QTime(ct.hour(), ct.minute(), ct.second() + 2)); |
731 | + QDateTime nextDt(cd.addDays(1), QTime(ct.hour(), ct.minute(), ct.second() + 2)); |
732 | + UCAlarm alarm(dt, UCAlarm::Daily, "test_correctAlarmOrderDaily"); |
733 | + UCAlarm nextAlarm(nextDt, UCAlarm::Daily, "test_correctAlarmOrderDaily"); |
734 | + |
735 | + alarm.save(); |
736 | + waitForRequest(&alarm); |
737 | + QTest::qWait(2000); |
738 | + syncFetch(); |
739 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
740 | + QVERIFY(containsAlarm(&nextAlarm)); |
741 | + } |
742 | + |
743 | + void test_correctAlarmOrderWeekly() |
744 | + { |
745 | + QDate cd = QDate::currentDate(); |
746 | + QTime ct = QTime::currentTime(); |
747 | + QDateTime dt(cd, QTime(ct.hour(), ct.minute(), ct.second() + 1)); |
748 | + QDateTime nextDt(cd.addDays(7), QTime(ct.hour(), ct.minute(), ct.second() + 1)); |
749 | + UCAlarm alarm(dt, UCAlarm::AutoDetect, "test_correctAlarmOrderWeekly"); |
750 | + UCAlarm nextAlarm(nextDt, UCAlarm::AutoDetect, "test_correctAlarmOrderWeekly"); |
751 | + |
752 | + alarm.save(); |
753 | + waitForRequest(&alarm); |
754 | + QTest::qWait(2000); |
755 | + syncFetch(); |
756 | + QCOMPARE(alarm.error(), (int)UCAlarm::NoError); |
757 | + QVERIFY(containsAlarm(&nextAlarm)); |
758 | + } |
759 | + |
760 | }; |
761 | |
762 | QTEST_MAIN(tst_UCAlarms) |
763 | |
764 | === modified file 'tests/unit_x11/tst_test/tst_ubuntutestcase.qml' |
765 | --- tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-02-13 10:27:14 +0000 |
766 | +++ tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-04-10 09:49:53 +0000 |
767 | @@ -23,30 +23,57 @@ |
768 | width: 800 |
769 | height: 600 |
770 | |
771 | - MouseArea { |
772 | - id: mouseArea |
773 | - objectName: "myMouseArea" |
774 | - anchors.fill: parent |
775 | - hoverEnabled: true |
776 | - property int testX : 0 |
777 | - property int testY : 0 |
778 | - property int steps : 0 |
779 | + Column { |
780 | + anchors.fill: parent |
781 | + MouseArea { |
782 | + id: mouseArea |
783 | + objectName: "myMouseArea" |
784 | + width: parent.width |
785 | + height: 300 |
786 | + hoverEnabled: true |
787 | + acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton |
788 | + property int testX : 0 |
789 | + property int testY : 0 |
790 | + property int steps : 0 |
791 | |
792 | - onPositionChanged: { |
793 | - testX = mouseX; |
794 | - testY = mouseY; |
795 | - steps++; |
796 | - } |
797 | + onPositionChanged: { |
798 | + testX = mouseX; |
799 | + testY = mouseY; |
800 | + steps++; |
801 | + } |
802 | + } |
803 | + Flickable { |
804 | + id: flicker |
805 | + width: parent.width |
806 | + height: 400 |
807 | + contentWidth: rect.width |
808 | + contentHeight: rect.height |
809 | + clip: true |
810 | + Rectangle { |
811 | + id: rect |
812 | + color: "blue" |
813 | + width: 1000 |
814 | + height: 1000 |
815 | + } |
816 | + } |
817 | } |
818 | |
819 | UbuntuTestCase { |
820 | name: "TestTheUbuntuTestCase" |
821 | when: windowShown |
822 | |
823 | + function init() { |
824 | + mouseArea.steps = 0; |
825 | + } |
826 | + function cleanup() { |
827 | + movementSpy.clear(); |
828 | + longPressSpy.clear(); |
829 | + } |
830 | + |
831 | function test_mouseMoveSlowly() { |
832 | - mouseMoveSlowly(root,0,0,800,600,10,100); |
833 | + mouseMoveSlowly(root,0,0,800,300,10,100); |
834 | compare(mouseArea.testX,800); |
835 | - compare(mouseArea.testY,600); |
836 | + compare(mouseArea.testY,300); |
837 | compare(mouseArea.steps,10); |
838 | } |
839 | |
840 | @@ -58,5 +85,66 @@ |
841 | child = findChild(root,"NoSuchChildHere"); |
842 | compare(child===null,true,"When there is no child, function should return null"); |
843 | } |
844 | + |
845 | + SignalSpy { |
846 | + id: longPressSpy |
847 | + target: mouseArea |
848 | + signalName: "onPressAndHold" |
849 | + } |
850 | + |
851 | + function test_longPress_left() { |
852 | + longPressSpy.clear(); |
853 | + mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2); |
854 | + longPressSpy.wait(); |
855 | + // cleanup |
856 | + mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2); |
857 | + } |
858 | + |
859 | + function test_longPress_right() { |
860 | + longPressSpy.clear(); |
861 | + mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.RightButton); |
862 | + longPressSpy.wait(); |
863 | + // cleanup |
864 | + mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.RightButton); |
865 | + } |
866 | + |
867 | + function test_longPress_middle() { |
868 | + longPressSpy.clear(); |
869 | + mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.MiddleButton); |
870 | + longPressSpy.wait(); |
871 | + // cleanup |
872 | + mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.MiddleButton); |
873 | + } |
874 | + |
875 | + SignalSpy { |
876 | + id: movementSpy |
877 | + target: flicker |
878 | + signalName: "onMovementEnded" |
879 | + } |
880 | + |
881 | + function test_flick_default() { |
882 | + flick(flicker, 0, 0, flicker.width, flicker.height); |
883 | + movementSpy.wait(); |
884 | + } |
885 | + function test_flick_long() { |
886 | + flick(flicker, 0, 0, flicker.width, flicker.height, -1, 10); |
887 | + movementSpy.wait(); |
888 | + } |
889 | + function test_flick_short() { |
890 | + flick(flicker, 0, 0, flicker.width, flicker.height, -1, 1); |
891 | + movementSpy.wait(); |
892 | + } |
893 | + function test_flick_pressTimeout() { |
894 | + flick(flicker, 0, 0, flicker.width, flicker.height, 400); |
895 | + movementSpy.wait(); |
896 | + } |
897 | + function test_flick_pressTimeout_short() { |
898 | + flick(flicker, flicker.width, flicker.height, -flicker.width, -flicker.height, 400, 1); |
899 | + movementSpy.wait(); |
900 | + } |
901 | + function test_flick_pressTimeout_long() { |
902 | + flick(flicker, flicker.width, flicker.height, -flicker.width, -flicker.height, 400, 100); |
903 | + movementSpy.wait(); |
904 | + } |
905 | } |
906 | } |
*DO NOT REVIEW IT YET*