mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 10:33:59 -05:00
Assembly API documentation for Java Bytecode (#2817)
* Add assembly documentation endpoint for Java bytecode * Upstream asm docenizer for Java * Remove jvms.html from gitattributes as it is never checked into vcs * EOF line for docenizer-java.js * Use find-node to locate nodejs * Format code according to style guide
This commit is contained in:
@@ -8,3 +8,5 @@ views
|
||||
# Autogenerated files
|
||||
lib/handlers/asm-docs-amd64.js
|
||||
lib/handlers/asm-docs-arm32.js
|
||||
lib/handlers/asm-docs-java.js
|
||||
etc/scripts/vendor/jvms.html
|
||||
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -3,4 +3,5 @@ docs/* linguist-documentation
|
||||
*.asm linguist-generated
|
||||
lib/handlers/asm-docs-amd64.js linguist-generated
|
||||
lib/handlers/asm-docs-arm32.js linguist-generated
|
||||
lib/handlers/asm-docs-java.js linguist-generated
|
||||
test/*-cases/* linguist-generated
|
||||
|
||||
@@ -4,6 +4,7 @@ include:
|
||||
exclude:
|
||||
- lib/handlers/asm-docs-amd64.js
|
||||
- lib/handlers/asm-docs-arm32.js
|
||||
- lib/handlers/asm-docs-java.js
|
||||
- lib/compilers/fake-for-test.js
|
||||
report-dir: ./out/coverage
|
||||
reporter:
|
||||
|
||||
108
etc/scripts/docenizer-java.js
Normal file
108
etc/scripts/docenizer-java.js
Normal file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const cheerio = require('cheerio');
|
||||
const {promises: fs} = require('fs');
|
||||
|
||||
const JVMS_SPECIFICATION = './vendor/jvms.html';
|
||||
const VARIADIC_MAPPINGS = {
|
||||
'<n>': ['0', '1', '2', '3'],
|
||||
'<d>': ['0', '1'],
|
||||
'<f>': ['0, 1', '2'],
|
||||
'<i>': ['m1', '0', '1', '2', '3', '4', '5'],
|
||||
'<l>': ['0', '1'],
|
||||
'<op>': ['g', 'l'],
|
||||
'<cond>': ['eq', 'ne'],
|
||||
};
|
||||
|
||||
// interface InstructionInfo {
|
||||
// name: string
|
||||
// anchor: string
|
||||
// tooltip: string
|
||||
// format: string[]
|
||||
// stack: [string | null, string | null]
|
||||
// description: string
|
||||
// }
|
||||
|
||||
// extract: (node: cheerio.Cheerio<Element>, $: cheerio.CheerioAPI) => InstructionInfo[]
|
||||
const extract = (node, $) => {
|
||||
const anchorElement = node.find('div.titlepage > div > div > h3.title > a[name*="jvms-6.5"]').first();
|
||||
const nameElement = anchorElement.parent().find('span.emphasis > em');
|
||||
const anchor = anchorElement.attr('name');
|
||||
const name = nameElement.text();
|
||||
|
||||
const [
|
||||
operationSection,
|
||||
formatSection,
|
||||
_formsSection,
|
||||
operandStackSection,
|
||||
descriptionSection,
|
||||
] = node.find('div.section').toArray().map(it => $(it));
|
||||
|
||||
const operation = operationSection.find('p.norm').first().text();
|
||||
const format = formatSection.find('div.literallayout > p > span.emphasis > em').toArray().map(it => $(it).text());
|
||||
const description = descriptionSection.find('p.norm-dynamic').first();
|
||||
// rewrite links to oracle.com
|
||||
$(description).find('* > a[href*="jvms-"]').toArray().forEach((el) => {
|
||||
$(el).attr('href', `https://docs.oracle.com/javase/specs/jvms/se16/html/${$(el).attr('href')}`);
|
||||
});
|
||||
|
||||
const [stackBefore, stackAfter] = operandStackSection.find('p.norm')
|
||||
.toArray()
|
||||
.map(it => $(it));
|
||||
|
||||
// InstructionInfo[]
|
||||
const result = [];
|
||||
const hasVariadicMapping = Object.keys(VARIADIC_MAPPINGS).some((pat) => name.endsWith(pat));
|
||||
if (hasVariadicMapping) {
|
||||
for (const [pattern, mappings] of Object.entries(VARIADIC_MAPPINGS)) {
|
||||
if (name.endsWith(pattern)) {
|
||||
for (const mapping of mappings) {
|
||||
result.push({
|
||||
name: name.replace(pattern, mapping).replace('<', '[').replace('>', ']'),
|
||||
anchor: anchor,
|
||||
description: description.html(),
|
||||
tooltip: operation,
|
||||
stack: [stackBefore?.html(), stackAfter?.html()],
|
||||
format: format.map(x => x.replace('<', '[').replace('>', ']')),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.push({
|
||||
name,
|
||||
anchor: anchor,
|
||||
description: description.html(),
|
||||
tooltip: operation,
|
||||
stack: [stackBefore?.html(), stackAfter?.html()],
|
||||
format,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const file = await fs.readFile(JVMS_SPECIFICATION, 'utf-8');
|
||||
const $ = cheerio.load(file);
|
||||
const sections = $('div.section-execution');
|
||||
const instructions = sections.toArray()
|
||||
.slice(1) // Drop 1 because the first is the "mne monic"
|
||||
.map(it => extract($(it), $))
|
||||
.flat();
|
||||
console.log('export function getAsmOpcode(opcode) {');
|
||||
console.log(' if (!opcode) return;');
|
||||
console.log(' switch (opcode.toUpperCase()) {');
|
||||
for (const instruction of instructions) {
|
||||
console.log(` case '${instruction.name.toUpperCase()}':`);
|
||||
console.log(' return {');
|
||||
console.log(` url: \`https://docs.oracle.com/javase/specs/jvms/se16/html/jvms-6.html#${instruction.anchor}\`,`);
|
||||
const body = `<p>Instruction ${instruction.name}: ${instruction.tooltip}</p><p>Format: ${instruction.format.join(' ')}</p>${instruction.stack[0] && `<p>Operand Stack: ${instruction.stack[0]} ${instruction.stack[1]}</p>`}<p>${instruction.description}</p>`;
|
||||
console.log(` html: \`${body.replace(/\s\s+/g, ' ')}\`,`);
|
||||
console.log(` tooltip: \`${instruction.tooltip.replace(/\s\s+/g, ' ')}\`,`);
|
||||
console.log(' };');
|
||||
}
|
||||
console.log(' }');
|
||||
console.log('}');
|
||||
};
|
||||
|
||||
main();
|
||||
8
etc/scripts/docenizerJava.sh
Executable file
8
etc/scripts/docenizerJava.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#/usr/bin/bash
|
||||
|
||||
JVMS_PATH=$(pwd)/vendor/jvms.html
|
||||
|
||||
[ -f "$JVMS_PATH" ] || curl https://docs.oracle.com/javase/specs/jvms/se16/html/jvms-6.html -o "$JVMS_PATH"
|
||||
|
||||
$(pwd)/find-node ../../.node-bin
|
||||
$(cat ../../.node-bin) docenizer-java.js > ../../lib/handlers/asm-docs-java.js
|
||||
0
etc/scripts/vendor/.gitkeep
vendored
Normal file
0
etc/scripts/vendor/.gitkeep
vendored
Normal file
@@ -35,6 +35,7 @@ import * as utils from '../utils';
|
||||
import { AsmDocsHandler as AsmDocsHandlerAarch64 } from './asm-docs-api-aarch64';
|
||||
import { AsmDocsHandler as AsmDocsHandlerAmd64 } from './asm-docs-api-amd64';
|
||||
import { AsmDocsHandler as AsmDocsHandlerArm32 } from './asm-docs-api-arm32';
|
||||
import { AsmDocsHandler as AsmDocsHandlerJava } from './asm-docs-api-java';
|
||||
import { Formatter } from './formatting';
|
||||
|
||||
export class ApiHandler {
|
||||
@@ -67,6 +68,7 @@ export class ApiHandler {
|
||||
amd64: new AsmDocsHandlerAmd64(),
|
||||
arm32: new AsmDocsHandlerArm32(),
|
||||
aarch64: new AsmDocsHandlerAarch64(),
|
||||
java: new AsmDocsHandlerJava(),
|
||||
};
|
||||
this.handle.get('/asm/:arch/:opcode', (req, res) => {
|
||||
const handler = asmArch[req.params.arch];
|
||||
|
||||
50
lib/handlers/asm-docs-api-java.js
Normal file
50
lib/handlers/asm-docs-api-java.js
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2021, Compiler Explorer Authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import * as props from '../properties';
|
||||
|
||||
import { getAsmOpcode } from './asm-docs-java';
|
||||
|
||||
export class AsmDocsHandler {
|
||||
constructor() {
|
||||
const asmProps = props.propsFor('asm-docs');
|
||||
this.staticMaxAgeSecs = asmProps('staticMaxAgeSecs', 10);
|
||||
}
|
||||
|
||||
handle(req, res) {
|
||||
const info = getAsmOpcode(req.params.opcode);
|
||||
if (this.staticMaxAgeSecs) {
|
||||
res.setHeader('Cache-Control', `public, max-age=${this.staticMaxAgeSecs}`);
|
||||
}
|
||||
if (req.accepts(['text', 'json']) === 'json') {
|
||||
res.send({found: !!info, result: info});
|
||||
} else {
|
||||
if (info) {
|
||||
res.send(info.html);
|
||||
} else {
|
||||
res.send('Unknown opcode');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1163
lib/handlers/asm-docs-java.js
generated
Normal file
1163
lib/handlers/asm-docs-java.js
generated
Normal file
File diff suppressed because it is too large
Load Diff
185
package-lock.json
generated
185
package-lock.json
generated
@@ -3675,6 +3675,117 @@
|
||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
|
||||
"dev": true
|
||||
},
|
||||
"cheerio": {
|
||||
"version": "1.0.0-rc.10",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
|
||||
"integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cheerio-select": "^1.5.0",
|
||||
"dom-serializer": "^1.3.2",
|
||||
"domhandler": "^4.2.0",
|
||||
"htmlparser2": "^6.1.0",
|
||||
"parse5": "^6.0.1",
|
||||
"parse5-htmlparser2-tree-adapter": "^6.0.1",
|
||||
"tslib": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"dom-serializer": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
||||
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.2.0",
|
||||
"entities": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
|
||||
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
|
||||
"dev": true
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
||||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"cheerio-select": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
|
||||
"integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"css-select": "^4.1.3",
|
||||
"css-what": "^5.0.1",
|
||||
"domelementtype": "^2.2.0",
|
||||
"domhandler": "^4.2.0",
|
||||
"domutils": "^2.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"css-select": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
|
||||
"integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"boolbase": "^1.0.0",
|
||||
"css-what": "^5.0.0",
|
||||
"domhandler": "^4.2.0",
|
||||
"domutils": "^2.6.0",
|
||||
"nth-check": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz",
|
||||
"integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==",
|
||||
"dev": true
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
||||
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.2.0",
|
||||
"entities": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
|
||||
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
|
||||
"dev": true
|
||||
},
|
||||
"domutils": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz",
|
||||
"integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dom-serializer": "^1.0.1",
|
||||
"domelementtype": "^2.2.0",
|
||||
"domhandler": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"nth-check": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz",
|
||||
"integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"boolbase": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
|
||||
@@ -5143,6 +5254,23 @@
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
|
||||
"dev": true
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz",
|
||||
"integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
|
||||
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
||||
@@ -7915,6 +8043,48 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
|
||||
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.0.0",
|
||||
"domutils": "^2.5.2",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"dom-serializer": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
||||
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.2.0",
|
||||
"entities": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
|
||||
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
|
||||
"dev": true
|
||||
},
|
||||
"domutils": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz",
|
||||
"integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dom-serializer": "^1.0.1",
|
||||
"domelementtype": "^2.2.0",
|
||||
"domhandler": "^4.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-deceiver": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
|
||||
@@ -11047,6 +11217,21 @@
|
||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
||||
"dev": true
|
||||
},
|
||||
"parse5": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
|
||||
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
|
||||
"dev": true
|
||||
},
|
||||
"parse5-htmlparser2-tree-adapter": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
|
||||
"integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"parse5": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
"chai": "^4.3.4",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"chai-http": "^4.2.1",
|
||||
"cheerio": "^1.0.0-rc.10",
|
||||
"codecov": "^3.8.2",
|
||||
"copy-webpack-plugin": "^5.1.2",
|
||||
"css-loader": "^3.6.0",
|
||||
|
||||
86
test/handlers/asm-docs-tests-java.js
Normal file
86
test/handlers/asm-docs-tests-java.js
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2021, Compiler Explorer Authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import express from 'express';
|
||||
|
||||
import { AsmDocsHandler } from '../../lib/handlers/asm-docs-api-java';
|
||||
import { chai } from '../utils';
|
||||
|
||||
describe('Assembly documents', () => {
|
||||
let app;
|
||||
|
||||
before(() => {
|
||||
app = express();
|
||||
const handler = new AsmDocsHandler();
|
||||
app.use('/asm/:opcode', handler.handle.bind(handler));
|
||||
});
|
||||
|
||||
it('should respond with "unknown opcode" for unknown opcodes', () => {
|
||||
return chai.request(app).get('/asm/NOTANOPCODE')
|
||||
.then(res => {
|
||||
res.should.have.status(200);
|
||||
res.should.be.html;
|
||||
res.text.should.equal('Unknown opcode');
|
||||
})
|
||||
.catch(err => { throw err; });
|
||||
});
|
||||
|
||||
it('should respond to text requests', () => {
|
||||
return chai.request(app)
|
||||
.get('/asm/aaload')
|
||||
.then(res => {
|
||||
res.should.have.status(200);
|
||||
res.should.be.html;
|
||||
res.text.should.contain('Load reference from array');
|
||||
})
|
||||
.catch(err => { throw err; });
|
||||
});
|
||||
|
||||
it('should respond to json requests', () => {
|
||||
return chai.request(app)
|
||||
.get('/asm/aaload')
|
||||
.set('Accept', 'application/json')
|
||||
.then(res => {
|
||||
res.should.have.status(200);
|
||||
res.should.be.json;
|
||||
res.body.found.should.equal(true);
|
||||
res.body.result.html.should.contain('Load reference from array');
|
||||
res.body.result.tooltip.should.contain('Load reference from array');
|
||||
res.body.result.url.should.contain('https://docs.oracle.com/javase/specs/');
|
||||
})
|
||||
.catch(err => { throw err; });
|
||||
});
|
||||
|
||||
it('should respond to json for unknown opcodes', () => {
|
||||
return chai.request(app)
|
||||
.get('/asm/NOTANOPCODE')
|
||||
.set('Accept', 'application/json')
|
||||
.then(res => {
|
||||
res.should.have.status(200);
|
||||
res.should.be.json;
|
||||
res.body.found.should.equal(false);
|
||||
})
|
||||
.catch(err => { throw err; });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user