-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #197 from JetBrains/fix-browser-platforms
Add JS and Wasm for 2.0.x version
- Loading branch information
Showing
13 changed files
with
197 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import { expect, Page, test } from '@playwright/test'; | ||
|
||
import { readFileSync } from 'fs'; | ||
import { join } from 'path'; | ||
|
||
import { gotoHtmlWidget } from './utlis/server/playground'; | ||
|
||
import { RESULT_SELECTOR, WIDGET_SELECTOR } from './utlis/selectors'; | ||
|
||
import { prepareNetwork, printlnCode } from './utlis'; | ||
import { mockRunRequest, waitRunRequest } from './utlis/mocks/compiler'; | ||
import { runButton } from './utlis/interactions'; | ||
import { makeJSPrintCode } from './utlis/mocks/result'; | ||
|
||
const OUTPUTS = Object.freeze({ | ||
'js-ir': { | ||
jsCode: makeJSPrintCode('Hello, world!'), | ||
errors: { 'File.kt': [] }, | ||
exception: null, | ||
text: '<outStream>Hello, world!\n</outStream>', | ||
}, | ||
wasm: JSON.parse( | ||
readFileSync(join(__dirname, 'utlis/mocks/wasm.json'), 'utf-8'), | ||
), | ||
}); | ||
|
||
const VERSIONS = [ | ||
{ version: '1.3.10' }, | ||
{ version: '1.9.20', latestStable: true }, | ||
{ version: '2.0.1' }, | ||
] as const; | ||
|
||
test.describe('platform restrictions', () => { | ||
test.beforeEach(async ({ page, baseURL }) => { | ||
await prepareNetwork(page, baseURL, { | ||
versions: (route) => | ||
route.fulfill({ | ||
body: JSON.stringify(VERSIONS), | ||
}), | ||
}); // offline mode | ||
}); | ||
|
||
test('JS_IR for unsupported version', async ({ page }) => { | ||
await shouldFailedRun( | ||
page, | ||
'js-ir', | ||
'1.3.10', | ||
'JS IR compiler backend accessible only since 1.5.0 version', | ||
); | ||
}); | ||
|
||
test('JS_IR for supported by minor version', async ({ page }) => { | ||
await shouldSuccessRun(page, 'js-ir', '1.9.0'); | ||
}); | ||
|
||
test('JS_IR for supported by major version', async ({ page }) => { | ||
await shouldSuccessRun(page, 'js-ir', '2.0.1'); | ||
}); | ||
|
||
test('WASM for unsupported version', async ({ page }) => { | ||
await shouldFailedRun( | ||
page, | ||
'wasm', | ||
'1.3.10', | ||
'Wasm compiler backend accessible only since 1.9.0 version', | ||
); | ||
}); | ||
|
||
test('WASM for supported by minor version', async ({ page, browserName }) => { | ||
test.skip( | ||
browserName !== 'chromium', | ||
"WASM doesn't supported in this browser", | ||
); | ||
await shouldSuccessRun(page, 'wasm', '1.9.0'); | ||
}); | ||
|
||
test('WASM for supported by major version', async ({ page, browserName }) => { | ||
test.skip( | ||
browserName !== 'chromium', | ||
"WASM doesn't supported in this browser", | ||
); | ||
await shouldSuccessRun(page, 'wasm', '2.0.1'); | ||
}); | ||
}); | ||
|
||
async function shouldSuccessRun( | ||
page: Page, | ||
platform: keyof typeof OUTPUTS, | ||
version: string, | ||
) { | ||
await gotoHtmlWidget( | ||
page, | ||
{ selector: 'code', version: version }, | ||
/* language=html */ ` | ||
<code data-target-platform='${platform}'>${printlnCode( | ||
'Hello, world!', | ||
)}</code> | ||
`, | ||
); | ||
|
||
const resolveRun = await mockRunRequest(page); | ||
|
||
const editor = page.locator(WIDGET_SELECTOR); | ||
|
||
await Promise.all([waitRunRequest(page), runButton(editor)]); | ||
|
||
resolveRun({ | ||
json: Object.freeze(OUTPUTS[platform]), | ||
}); | ||
|
||
// playground loaded | ||
await expect(editor.locator(RESULT_SELECTOR)).toBeVisible(); | ||
await expect(editor.locator(RESULT_SELECTOR)).toContainText('Hello, world!'); | ||
} | ||
|
||
async function shouldFailedRun( | ||
page: Page, | ||
platform: string, | ||
version: string, | ||
text: string, | ||
) { | ||
await gotoHtmlWidget( | ||
page, | ||
{ selector: 'code', version: version }, | ||
/* language=html */ ` | ||
<code data-target-platform='${platform}'>${printlnCode( | ||
'Hello, world!', | ||
)}</code> | ||
`, | ||
); | ||
|
||
const editor = page.locator(WIDGET_SELECTOR); | ||
await runButton(editor); | ||
|
||
await expect(editor.locator(RESULT_SELECTOR)).toBeVisible(); | ||
await expect( | ||
editor.locator(RESULT_SELECTOR).locator('.test-fail'), | ||
).toContainText(text); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export function makeJSPrintCode(text: string) { | ||
return `var moduleId = function (_) {\n 'use strict';\n //region block: pre-declaration\n setMetadataFor(Unit, 'Unit', objectMeta);\n setMetadataFor(BaseOutput, 'BaseOutput', classMeta);\n setMetadataFor(NodeJsOutput, 'NodeJsOutput', classMeta, BaseOutput);\n setMetadataFor(BufferedOutput, 'BufferedOutput', classMeta, BaseOutput, VOID, BufferedOutput);\n setMetadataFor(BufferedOutputToConsoleLog, 'BufferedOutputToConsoleLog', classMeta, BufferedOutput, VOID, BufferedOutputToConsoleLog);\n //endregion\n function Unit() {\n }\n protoOf(Unit).toString = function () {\n return 'kotlin.Unit';\n };\n var Unit_instance;\n function Unit_getInstance() {\n return Unit_instance;\n }\n function get_output() {\n _init_properties_console_kt__rfg7jv();\n return output;\n }\n var output;\n function BaseOutput() {\n }\n function NodeJsOutput(outputStream) {\n BaseOutput.call(this);\n this.outputStream_1 = outputStream;\n }\n protoOf(NodeJsOutput).print_o1pwgy_k$ = function (message) {\n // Inline function 'kotlin.io.String' call\n var messageString = String(message);\n this.outputStream_1.write(messageString);\n };\n function BufferedOutputToConsoleLog() {\n BufferedOutput.call(this);\n }\n protoOf(BufferedOutputToConsoleLog).print_o1pwgy_k$ = function (message) {\n // Inline function 'kotlin.io.String' call\n var s = String(message);\n // Inline function 'kotlin.text.nativeLastIndexOf' call\n // Inline function 'kotlin.js.asDynamic' call\n var i = s.lastIndexOf('\\n', 0);\n if (i >= 0) {\n var tmp = this;\n var tmp_0 = this.buffer_1;\n // Inline function 'kotlin.text.substring' call\n // Inline function 'kotlin.js.asDynamic' call\n tmp.buffer_1 = tmp_0 + s.substring(0, i);\n this.flush_shahbo_k$();\n // Inline function 'kotlin.text.substring' call\n var this_0 = s;\n var startIndex = i + 1 | 0;\n // Inline function 'kotlin.js.asDynamic' call\n s = this_0.substring(startIndex);\n }\n this.buffer_1 = this.buffer_1 + s;\n };\n protoOf(BufferedOutputToConsoleLog).flush_shahbo_k$ = function () {\n console.log(this.buffer_1);\n this.buffer_1 = '';\n };\n function BufferedOutput() {\n BaseOutput.call(this);\n this.buffer_1 = '';\n }\n protoOf(BufferedOutput).print_o1pwgy_k$ = function (message) {\n var tmp = this;\n var tmp_0 = this.buffer_1;\n // Inline function 'kotlin.io.String' call\n tmp.buffer_1 = tmp_0 + String(message);\n };\n function print(message) {\n _init_properties_console_kt__rfg7jv();\n get_output().print_o1pwgy_k$(message);\n }\n var properties_initialized_console_kt_gll9dl;\n function _init_properties_console_kt__rfg7jv() {\n if (!properties_initialized_console_kt_gll9dl) {\n properties_initialized_console_kt_gll9dl = true;\n // Inline function 'kotlin.run' call\n // Inline function 'kotlin.contracts.contract' call\n // Inline function 'kotlin.io.output.<anonymous>' call\n var isNode = typeof process !== 'undefined' && process.versions && !!process.versions.node;\n output = isNode ? new NodeJsOutput(process.stdout) : new BufferedOutputToConsoleLog();\n }\n }\n function implement(interfaces) {\n var maxSize = 1;\n var masks = [];\n var inductionVariable = 0;\n var last = interfaces.length;\n while (inductionVariable < last) {\n var i = interfaces[inductionVariable];\n inductionVariable = inductionVariable + 1 | 0;\n var currentSize = maxSize;\n var tmp1_elvis_lhs = i.prototype.$imask$;\n var imask = tmp1_elvis_lhs == null ? i.$imask$ : tmp1_elvis_lhs;\n if (!(imask == null)) {\n masks.push(imask);\n currentSize = imask.length;\n }\n var iid = i.$metadata$.iid;\n var tmp;\n if (iid == null) {\n tmp = null;\n } else {\n // Inline function 'kotlin.let' call\n // Inline function 'kotlin.contracts.contract' call\n // Inline function 'kotlin.js.implement.<anonymous>' call\n tmp = bitMaskWith(iid);\n }\n var iidImask = tmp;\n if (!(iidImask == null)) {\n masks.push(iidImask);\n currentSize = Math.max(currentSize, iidImask.length);\n }\n if (currentSize > maxSize) {\n maxSize = currentSize;\n }\n }\n return compositeBitMask(maxSize, masks);\n }\n function bitMaskWith(activeBit) {\n var numberIndex = activeBit >> 5;\n var intArray = new Int32Array(numberIndex + 1 | 0);\n var positionInNumber = activeBit & 31;\n var numberWithSettledBit = 1 << positionInNumber;\n intArray[numberIndex] = intArray[numberIndex] | numberWithSettledBit;\n return intArray;\n }\n function compositeBitMask(capacity, masks) {\n var tmp = 0;\n var tmp_0 = new Int32Array(capacity);\n while (tmp < capacity) {\n var tmp_1 = tmp;\n var result = 0;\n var inductionVariable = 0;\n var last = masks.length;\n while (inductionVariable < last) {\n var mask = masks[inductionVariable];\n inductionVariable = inductionVariable + 1 | 0;\n if (tmp_1 < mask.length) {\n result = result | mask[tmp_1];\n }\n }\n tmp_0[tmp_1] = result;\n tmp = tmp + 1 | 0;\n }\n return tmp_0;\n }\n function protoOf(constructor) {\n return constructor.prototype;\n }\n function defineProp(obj, name, getter, setter) {\n return Object.defineProperty(obj, name, {configurable: true, get: getter, set: setter});\n }\n function objectCreate(proto) {\n return Object.create(proto);\n }\n function classMeta(name, defaultConstructor, associatedObjectKey, associatedObjects, suspendArity) {\n return createMetadata('class', name, defaultConstructor, associatedObjectKey, associatedObjects, suspendArity, null);\n }\n function createMetadata(kind, name, defaultConstructor, associatedObjectKey, associatedObjects, suspendArity, iid) {\n var undef = VOID;\n return {kind: kind, simpleName: name, associatedObjectKey: associatedObjectKey, associatedObjects: associatedObjects, suspendArity: suspendArity, $kClass$: undef, defaultConstructor: defaultConstructor, iid: iid};\n }\n function setMetadataFor(ctor, name, metadataConstructor, parent, interfaces, defaultConstructor, associatedObjectKey, associatedObjects, suspendArity) {\n if (!(parent == null)) {\n ctor.prototype = Object.create(parent.prototype);\n ctor.prototype.constructor = ctor;\n }\n var metadata = metadataConstructor(name, defaultConstructor, associatedObjectKey, associatedObjects, suspendArity == null ? [] : suspendArity);\n ctor.$metadata$ = metadata;\n if (!(interfaces == null)) {\n var receiver = !(metadata.iid == null) ? ctor : ctor.prototype;\n receiver.$imask$ = implement(interfaces);\n }\n }\n function objectMeta(name, defaultConstructor, associatedObjectKey, associatedObjects, suspendArity) {\n return createMetadata('object', name, defaultConstructor, associatedObjectKey, associatedObjects, suspendArity, null);\n }\n function get_VOID() {\n _init_properties_void_kt__3zg9as();\n return VOID;\n }\n var VOID;\n var properties_initialized_void_kt_e4ret2;\n function _init_properties_void_kt__3zg9as() {\n if (!properties_initialized_void_kt_e4ret2) {\n properties_initialized_void_kt_e4ret2 = true;\n VOID = void 0;\n }\n }\n function main() {\n print('${text}');\n }\n //region block: init\n Unit_instance = new Unit();\n //endregion\nif (typeof get_output !== "undefined") {\n get_output();\n output = new BufferedOutput();\n _.output = get_output();\n}\n main();\n return _;\n}(typeof moduleId === 'undefined' ? {} : moduleId);\nmoduleId.output?.buffer_1;\n\n` as const; | ||
} |
Oops, something went wrong.