Synchronize MathML WPT tests against upstream
[WebKit-https.git] / Websites / perf.webkit.org / public / v3 / models / commit-log.js
1 'use strict';
2
3 class CommitLog extends DataModelObject {
4     constructor(id, rawData)
5     {
6         console.assert(parseInt(id) == id);
7         super(id);
8         console.assert(id == rawData.id)
9         this._repository = rawData.repository;
10         console.assert(this._repository instanceof Repository);
11         this._rawData = rawData;
12         this._ownedCommits = null;
13         this._ownerCommit = null;
14         this._ownedCommitByOwnedRepository = new Map;
15     }
16
17     updateSingleton(rawData)
18     {
19         super.updateSingleton(rawData);
20
21         console.assert(+this._rawData['time'] == +rawData['time']);
22         console.assert(this._rawData['revision'] == rawData['revision']);
23
24         if (rawData.authorName)
25             this._rawData.authorName = rawData.authorName;
26         if (rawData.message)
27             this._rawData.message = rawData.message;
28         if (rawData.ownsCommits)
29             this._rawData.ownsCommits = rawData.ownsCommits;
30         if (rawData.order)
31             this._rawData.order = rawData.order;
32         if (rawData.testability)
33             this._rawData.testability = rawData.testability;
34     }
35
36     repository() { return this._repository; }
37     time() { return new Date(this._rawData['time']); }
38     hasCommitTime() { return this._rawData['time'] > 0 && this._rawData['time'] != null; }
39     testability() { return this._rawData['testability']; }
40     author() { return this._rawData['authorName']; }
41     revision() { return this._rawData['revision']; }
42     message() { return this._rawData['message']; }
43     url() { return this._repository.urlForRevision(this._rawData['revision']); }
44     ownsCommits() { return this._rawData['ownsCommits']; }
45     ownedCommits() { return this._ownedCommits; }
46     ownerCommit() { return this._ownerCommit; }
47     order() { return this._rawData['order']; }
48     hasCommitOrder() { return this._rawData['order'] != null; }
49     setOwnerCommits(ownerCommit) { this._ownerCommit = ownerCommit; }
50
51     label()
52     {
53         const revision = this.revision();
54         if (parseInt(revision) == revision) // e.g. r12345
55             return 'r' + revision;
56         if (revision.length == 40) // e.g. git hash
57             return revision.substring(0, 12);
58         return revision;
59     }
60     title() { return this._repository.name() + ' at ' + this.label(); }
61
62     diff(previousCommit)
63     {
64         if (this == previousCommit)
65             previousCommit = null;
66
67         const repository = this._repository;
68         if (!previousCommit)
69             return {repository: repository, label: this.label(), url: this.url()};
70
71         const to = this.revision();
72         const from = previousCommit.revision();
73         let label = null;
74         if (parseInt(from) == from)// e.g. r12345.
75             label = `r${from}-r${this.revision()}`;
76         else if (to.length == 40) // e.g. git hash
77             label = `${from.substring(0, 12)}..${to.substring(0, 12)}`;
78         else
79             label = `${from} - ${to}`;
80
81         return {repository: repository, label: label, url: repository.urlForRevisionRange(from, to)};
82     }
83
84     static fetchLatestCommitForPlatform(repository, platform)
85     {
86         console.assert(repository instanceof Repository);
87         console.assert(platform instanceof Platform);
88         return this.cachedFetch(`/api/commits/${repository.id()}/latest`, {platform: platform.id()}).then((data) => {
89             const commits = data['commits'];
90             if (!commits || !commits.length)
91                 return null;
92             const rawData = commits[0];
93             rawData.repository = repository;
94             return CommitLog.ensureSingleton(rawData.id, rawData);
95         });
96     }
97
98     static hasOrdering(firstCommit, secondCommit)
99     {
100         return (firstCommit.hasCommitTime() && secondCommit.hasCommitTime()) ||
101             (firstCommit.hasCommitOrder() && secondCommit.hasCommitOrder());
102     }
103
104     static orderTwoCommits(firstCommit, secondCommit)
105     {
106         console.assert(CommitLog.hasOrdering(firstCommit, secondCommit));
107         const firstCommitSmaller = firstCommit.hasCommitTime() && secondCommit.hasCommitTime() ?
108             firstCommit.time() < secondCommit.time() : firstCommit.order() < secondCommit.order();
109         return firstCommitSmaller ? [firstCommit, secondCommit] : [secondCommit, firstCommit];
110     }
111
112     ownedCommitForOwnedRepository(ownedRepository) { return this._ownedCommitByOwnedRepository.get(ownedRepository); }
113
114     fetchOwnedCommits()
115     {
116         if (!this.repository().ownedRepositories())
117             return Promise.reject();
118
119         if (!this.ownsCommits())
120             return Promise.reject();
121
122         if (this._ownedCommits)
123             return Promise.resolve(this._ownedCommits);
124
125         return CommitLog.cachedFetch(`../api/commits/${this.repository().id()}/owned-commits?owner-revision=${escape(this.revision())}`).then((data) => {
126             this._ownedCommits = CommitLog._constructFromRawData(data);
127             this._ownedCommits.forEach((ownedCommit) => {
128                 ownedCommit.setOwnerCommits(this);
129                 this._ownedCommitByOwnedRepository.set(ownedCommit.repository(), ownedCommit);
130             });
131             return this._ownedCommits;
132         });
133     }
134
135     _buildOwnedCommitMap()
136     {
137         const ownedCommitMap = new Map;
138         for (const commit of this._ownedCommits)
139             ownedCommitMap.set(commit.repository(), commit);
140         return ownedCommitMap;
141     }
142
143     static ownedCommitDifferenceForOwnerCommits(...commits)
144     {
145         console.assert(commits.length >= 2);
146
147         const ownedCommitRepositories = new Set;
148         const ownedCommitMapList = commits.map((commit) => {
149             console.assert(commit);
150             console.assert(commit._ownedCommits);
151             const ownedCommitMap = commit._buildOwnedCommitMap();
152             for (const repository of ownedCommitMap.keys())
153                 ownedCommitRepositories.add(repository);
154             return ownedCommitMap;
155         });
156
157         const difference = new Map;
158         ownedCommitRepositories.forEach((ownedCommitRepository) => {
159             const ownedCommits = ownedCommitMapList.map((ownedCommitMap) => ownedCommitMap.get(ownedCommitRepository));
160             const uniqueOwnedCommits = new Set(ownedCommits);
161             if (uniqueOwnedCommits.size > 1)
162                 difference.set(ownedCommitRepository, ownedCommits);
163         });
164         return difference;
165     }
166
167     static async fetchBetweenRevisions(repository, precedingRevision, lastRevision)
168     {
169         // FIXME: The cache should be smarter about fetching a range within an already fetched range, etc...
170         // FIXME: We should evict some entries from the cache in cachedFetch.
171         const data = await this.cachedFetch(`/api/commits/${repository.id()}/`, {precedingRevision, lastRevision});
172         return this._constructFromRawData(data);
173     }
174
175     static async fetchForSingleRevision(repository, revision, prefixMatch=false)
176     {
177         const commit = repository.commitForRevision(revision);
178         if (commit)
179             return [commit];
180
181         let params = {};
182         if (prefixMatch)
183             params['prefix-match'] = true;
184         const data = await this.cachedFetch(`/api/commits/${repository.id()}/${revision}`, params);
185         return this._constructFromRawData(data);
186     }
187
188     static _constructFromRawData(data)
189     {
190         return data['commits'].map((rawData) => {
191             const repositoryId = rawData.repository;
192             const repository = Repository.findById(repositoryId);
193             rawData.repository = repository;
194             const commit = CommitLog.ensureSingleton(rawData.id, rawData);
195             repository.setCommitForRevision(commit.revision(), commit);
196             return commit;
197         });
198     }
199 }
200
201 if (typeof module != 'undefined')
202     module.exports.CommitLog = CommitLog;