@axiapps/gw2-data 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/overrides.json +24 -0
- package/package.json +4 -1
- package/src/engine/attributes.js +102 -23
- package/src/engine/boons.js +19 -1
- package/src/engine/constants.js +27 -2
- package/src/engine/index.js +4 -4
- package/src/engine/modifiers.js +57 -21
- package/src/index.js +5 -0
- package/src/wiki/parser.js +17 -9
- package/scripts/generate-fixtures.js +0 -242
- package/tests/api-client.test.js +0 -138
- package/tests/cache.test.js +0 -108
- package/tests/engine/attributes.test.js +0 -252
- package/tests/engine/boons.test.js +0 -129
- package/tests/engine/combos.test.js +0 -76
- package/tests/engine/constants.test.js +0 -576
- package/tests/engine/fixtures/berserker-thief.json +0 -61
- package/tests/engine/fixtures/berserker-warrior.json +0 -113
- package/tests/engine/fixtures/celestial-firebrand-wvw.json +0 -94
- package/tests/engine/fixtures/harrier-druid.json +0 -119
- package/tests/engine/fixtures/viper-mirage.json +0 -104
- package/tests/engine/graph.test.js +0 -30
- package/tests/engine/integration.test.js +0 -111
- package/tests/engine/modifiers.test.js +0 -473
- package/tests/engine/overrides.test.js +0 -70
- package/tests/engine/snapshot.test.js +0 -53
- package/tests/engine/test-utils.js +0 -20
- package/tests/engine/tooltips.test.js +0 -62
- package/tests/fixtures/capture.js +0 -160
- package/tests/fixtures/fixtures.json +0 -839
- package/tests/integration.test.js +0 -100
- package/tests/match.test.js +0 -176
- package/tests/merge.test.js +0 -128
- package/tests/normalize.test.js +0 -78
- package/tests/parser.test.js +0 -506
- package/tests/real-data.test.js +0 -296
- package/tests/relations.test.js +0 -80
- package/tests/resolver.test.js +0 -721
- package/tests/validate-live.js +0 -191
- package/tests/wiki-client.test.js +0 -468
- package/tests/wiki-integration.test.js +0 -177
- package/tests/wiki-live-validation.test.js +0 -61
- package/tests/wiki-snapshots.test.js +0 -166
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Capture real GW2 API + Wiki data for fixture-based regression tests.
|
|
6
|
-
*
|
|
7
|
-
* Usage: node packages/gw2-data/tests/fixtures/capture.js
|
|
8
|
-
*
|
|
9
|
-
* Fetches skill/trait data from the live GW2 API and corresponding wikitext
|
|
10
|
-
* from wiki.guildwars2.com, then writes a single fixtures.json file.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const fs = require("fs");
|
|
14
|
-
const path = require("path");
|
|
15
|
-
|
|
16
|
-
const GW2_API = "https://api.guildwars2.com/v2";
|
|
17
|
-
const WIKI_API = "https://wiki.guildwars2.com/api.php";
|
|
18
|
-
const RATE_LIMIT_MS = 250;
|
|
19
|
-
const USER_AGENT = "@axiapps/gw2-data fixture-capture";
|
|
20
|
-
|
|
21
|
-
// Representative skills/traits covering different edge cases:
|
|
22
|
-
//
|
|
23
|
-
// Skills with balance splits (WvW differs from PvE):
|
|
24
|
-
// 5489 - Fireball (Elementalist) — basic damage skill, split
|
|
25
|
-
// 5536 - Arcane Blast (Elementalist) — split with different coefficients
|
|
26
|
-
// 30185 - Berserk (Warrior) — known regression target, complex facts
|
|
27
|
-
//
|
|
28
|
-
// Skills with various fact types:
|
|
29
|
-
// 5507 - Meteor Shower (Elementalist) — damage + burning + hits + radius
|
|
30
|
-
// 5492 - Fire Attunement (Elementalist) — attunement with flipSkill (Overload)
|
|
31
|
-
// 5503 - Glyph of Storms (Elementalist) — multi-attunement skill
|
|
32
|
-
//
|
|
33
|
-
// Traits with splits:
|
|
34
|
-
// 1510 - Flow like Water (Weaver) — trait with split
|
|
35
|
-
// 1502 - Swift Revenge (Weaver) — trait
|
|
36
|
-
//
|
|
37
|
-
// Skills with healing/barrier:
|
|
38
|
-
// 5569 - Water Blast (Elementalist) — healing skill
|
|
39
|
-
//
|
|
40
|
-
// Skills with combo fields/finishers:
|
|
41
|
-
// 5548 - Eruption (Elementalist) — blast finisher + fire field
|
|
42
|
-
|
|
43
|
-
const SKILLS_TO_CAPTURE = [
|
|
44
|
-
{ id: 5489, wiki: "Fireball", note: "basic damage, has split" },
|
|
45
|
-
{ id: 5536, wiki: "Arcane Blast", note: "split with different coefficients" },
|
|
46
|
-
{ id: 30185, wiki: "Berserk", note: "warrior elite, regression target" },
|
|
47
|
-
{ id: 5507, wiki: "Meteor Shower", note: "damage+burning+hits+radius" },
|
|
48
|
-
{ id: 5492, wiki: "Fire Attunement", note: "attunement with flipSkill" },
|
|
49
|
-
{ id: 5548, wiki: "Eruption", note: "blast finisher + fire field" },
|
|
50
|
-
{ id: 5569, wiki: "Water Blast", note: "healing skill" },
|
|
51
|
-
{ id: 5503, wiki: "Glyph of Storms", note: "multi-attunement" },
|
|
52
|
-
];
|
|
53
|
-
|
|
54
|
-
const TRAITS_TO_CAPTURE = [
|
|
55
|
-
{ id: 1510, wiki: "Flow like Water", note: "Weaver trait with split" },
|
|
56
|
-
{ id: 1502, wiki: "Swift Revenge", note: "Weaver trait" },
|
|
57
|
-
{ id: 264, wiki: "Burning Precision", note: "trait with condition" },
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
let lastRequestTime = 0;
|
|
61
|
-
|
|
62
|
-
async function rateLimitedFetch(url) {
|
|
63
|
-
const now = Date.now();
|
|
64
|
-
const elapsed = now - lastRequestTime;
|
|
65
|
-
if (elapsed < RATE_LIMIT_MS) {
|
|
66
|
-
await new Promise((r) => setTimeout(r, RATE_LIMIT_MS - elapsed));
|
|
67
|
-
}
|
|
68
|
-
lastRequestTime = Date.now();
|
|
69
|
-
const res = await fetch(url, { headers: { "User-Agent": USER_AGENT } });
|
|
70
|
-
return res;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async function fetchApiSkill(id) {
|
|
74
|
-
const url = `${GW2_API}/skills/${id}?lang=en`;
|
|
75
|
-
const res = await rateLimitedFetch(url);
|
|
76
|
-
if (!res.ok) {
|
|
77
|
-
console.warn(` API skill ${id}: HTTP ${res.status}`);
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return res.json();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async function fetchApiTrait(id) {
|
|
84
|
-
const url = `${GW2_API}/traits/${id}?lang=en`;
|
|
85
|
-
const res = await rateLimitedFetch(url);
|
|
86
|
-
if (!res.ok) {
|
|
87
|
-
console.warn(` API trait ${id}: HTTP ${res.status}`);
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
return res.json();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async function fetchWikitext(title) {
|
|
94
|
-
const url =
|
|
95
|
-
`${WIKI_API}?action=query&prop=revisions&rvprop=content` +
|
|
96
|
-
`&titles=${encodeURIComponent(title)}&format=json&formatversion=2`;
|
|
97
|
-
const res = await rateLimitedFetch(url);
|
|
98
|
-
if (!res.ok) {
|
|
99
|
-
console.warn(` Wiki "${title}": HTTP ${res.status}`);
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
const data = await res.json();
|
|
103
|
-
const page = data.query?.pages?.[0];
|
|
104
|
-
if (!page || page.missing) {
|
|
105
|
-
console.warn(` Wiki "${title}": page not found`);
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
return page.revisions?.[0]?.content || null;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async function main() {
|
|
112
|
-
const fixtures = { skills: [], traits: [], capturedAt: new Date().toISOString() };
|
|
113
|
-
|
|
114
|
-
console.log("Capturing skill fixtures...");
|
|
115
|
-
for (const entry of SKILLS_TO_CAPTURE) {
|
|
116
|
-
process.stdout.write(` ${entry.id} (${entry.wiki})...`);
|
|
117
|
-
const api = await fetchApiSkill(entry.id);
|
|
118
|
-
const wikitext = await fetchWikitext(entry.wiki);
|
|
119
|
-
if (api && wikitext) {
|
|
120
|
-
fixtures.skills.push({
|
|
121
|
-
id: entry.id,
|
|
122
|
-
wikiTitle: entry.wiki,
|
|
123
|
-
note: entry.note,
|
|
124
|
-
api,
|
|
125
|
-
wikitext,
|
|
126
|
-
});
|
|
127
|
-
console.log(" OK");
|
|
128
|
-
} else {
|
|
129
|
-
console.log(" SKIPPED");
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
console.log("\nCapturing trait fixtures...");
|
|
134
|
-
for (const entry of TRAITS_TO_CAPTURE) {
|
|
135
|
-
process.stdout.write(` ${entry.id} (${entry.wiki})...`);
|
|
136
|
-
const api = await fetchApiTrait(entry.id);
|
|
137
|
-
const wikitext = await fetchWikitext(entry.wiki);
|
|
138
|
-
if (api && wikitext) {
|
|
139
|
-
fixtures.traits.push({
|
|
140
|
-
id: entry.id,
|
|
141
|
-
wikiTitle: entry.wiki,
|
|
142
|
-
note: entry.note,
|
|
143
|
-
api,
|
|
144
|
-
wikitext,
|
|
145
|
-
});
|
|
146
|
-
console.log(" OK");
|
|
147
|
-
} else {
|
|
148
|
-
console.log(" SKIPPED");
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const outPath = path.join(__dirname, "fixtures.json");
|
|
153
|
-
fs.writeFileSync(outPath, JSON.stringify(fixtures, null, 2));
|
|
154
|
-
console.log(`\nWrote ${fixtures.skills.length} skills + ${fixtures.traits.length} traits to ${outPath}`);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
main().catch((err) => {
|
|
158
|
-
console.error(err);
|
|
159
|
-
process.exit(1);
|
|
160
|
-
});
|