diff --git a/sdk/quantum/quantum-jobs/api-extractor.json b/sdk/quantum/quantum-jobs/api-extractor.json index 39fb341950f7..35163e09d62a 100644 --- a/sdk/quantum/quantum-jobs/api-extractor.json +++ b/sdk/quantum/quantum-jobs/api-extractor.json @@ -1,12 +1,12 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "./types/index.d.ts", + "mainEntryPointFilePath": "./types/src/index.d.ts", "docModel": { "enabled": true }, "apiReport": { "enabled": true, "reportFolder": "./review" }, "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./esm/index.d.ts" + "publicTrimmedFilePath": "./types/latest/quantum-jobs.d.ts" }, "messages": { "tsdocMessageReporting": { "default": { "logLevel": "none" } }, diff --git a/sdk/quantum/quantum-jobs/karma.conf.js b/sdk/quantum/quantum-jobs/karma.conf.js new file mode 100644 index 000000000000..ca3a84a4f2c8 --- /dev/null +++ b/sdk/quantum/quantum-jobs/karma.conf.js @@ -0,0 +1,128 @@ +// https://github.com/karma-runner/karma-chrome-launcher +process.env.CHROME_BIN = require("puppeteer").executablePath(); +require("dotenv").config(); + +module.exports = function(config) { + config.set({ + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: "./", + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ["mocha"], + + plugins: [ + "karma-mocha", + "karma-mocha-reporter", + "karma-chrome-launcher", + "karma-edge-launcher", + "karma-firefox-launcher", + "karma-ie-launcher", + "karma-env-preprocessor", + "karma-coverage", + "karma-sourcemap-loader", + "karma-junit-reporter" + ], + + // list of files / patterns to load in the browser + files: [ + // polyfill service supporting IE11 missing features + // Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes,Array.prototype.includes,Object.keys + "https://cdn.polyfill.io/v2/polyfill.js?features=Promise,String.prototype.startsWith,String.prototype.endsWith,String.prototype.repeat,String.prototype.includes,Array.prototype.includes,Object.keys|always", + "test-browser/index.js", + { pattern: "test-browser/index.js.map", type: "html", included: false, served: true } + ], + + // list of files / patterns to exclude + exclude: [], + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + "**/*.js": ["env"] + // IMPORTANT: COMMENT following line if you want to debug in your browsers!! + // Preprocess source file to calculate code coverage, however this will make source file unreadable + // "test-browser/index.js": ["coverage"] + }, + + // inject following environment values into browser testing with window.__env__ + // environment values MUST be exported or set with same console running "karma start" + // https://www.npmjs.com/package/karma-env-preprocessor + envPreprocessor: [ + "AZURE_CLIENT_ID", + "AZURE_CLIENT_SECRET", + "AZURE_TENANT_ID", + "TEST_MODE" + ], + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ["mocha", "coverage", "junit"], + + coverageReporter: { + // specify a common output directory + dir: "coverage-browser/", + reporters: [ + { type: "json", subdir: ".", file: "coverage.json" }, + { type: "lcovonly", subdir: ".", file: "lcov.info" }, + { type: "html", subdir: "html" }, + { type: "cobertura", subdir: ".", file: "cobertura-coverage.xml" } + ] + }, + + junitReporter: { + outputDir: "", // results will be saved as $outputDir/$browserName.xml + outputFile: "test-results.browser.xml", // if included, results will be saved as $outputDir/$browserName/$outputFile + suite: "", // suite will become the package name attribute in xml testsuite element + useBrowserName: false, // add browser name to report and classes names + nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element + classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element + properties: {} // key value pair of properties to add to the section of the report + }, + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + // 'ChromeHeadless', 'Chrome', 'Firefox', 'Edge', 'IE' + browsers: ["ChromeHeadlessNoSandbox"], + customLaunchers: { + ChromeHeadlessNoSandbox: { + base: "ChromeHeadless", + flags: ["--no-sandbox"] + } + }, + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: 1, + + browserNoActivityTimeout: 600000, + browserDisconnectTimeout: 10000, + browserDisconnectTolerance: 3, + + client: { + mocha: { + // change Karma's debug.html to the mocha web reporter + reporter: "html", + timeout: "600000" + } + } + }); +}; diff --git a/sdk/quantum/quantum-jobs/package.json b/sdk/quantum/quantum-jobs/package.json index e528621f23c8..db344b38cf38 100644 --- a/sdk/quantum/quantum-jobs/package.json +++ b/sdk/quantum/quantum-jobs/package.json @@ -6,79 +6,110 @@ "dependencies": { "@azure/core-paging": "^1.1.1", "@azure/core-http": "^1.2.0", - "tslib": "^2.0.0" + "tslib": "^2.0.0", + "@opentelemetry/api": "^0.10.2" }, "keywords": [ "node", "azure", "typescript", "browser", - "isomorphic" + "isomorphic", + "cloud" ], "license": "MIT", - "main": "./dist/quantum-jobs.js", - "module": "./esm/index.js", - "types": "./esm/index.d.ts", + "main": "dist/index.js", + "module": "./dist-esm/src/index.js", + "types": "./types/latest/quantum-jobs.d.ts", "devDependencies": { - "typescript": "4.1.2", - "rollup": "^1.16.3", "rollup-plugin-node-resolve": "^3.4.0", + "mkdirp": "^1.0.4", + "@azure/dev-tool": "^1.0.0", + "@azure/eslint-plugin-azure-sdk": "^3.0.0", + "@azure/identity": "^1.1.0", + "@azure/test-utils-recorder": "^1.0.0", + "@microsoft/api-extractor": "7.7.11", + "@rollup/plugin-commonjs": "11.0.2", + "@rollup/plugin-inject": "^4.0.0", + "@rollup/plugin-json": "^4.0.0", + "@rollup/plugin-multi-entry": "^3.0.0", + "@rollup/plugin-node-resolve": "^8.0.0", + "@rollup/plugin-replace": "^2.2.0", + "@types/chai": "^4.1.6", + "@types/mocha": "^7.0.2", + "@types/node": "^8.0.0", + "@types/sinon": "^9.0.4", + "assert": "^1.4.1", + "chai": "^4.2.0", + "dotenv": "^8.2.0", + "eslint": "^7.15.0", + "esm": "^3.2.18", + "karma": "^5.1.0", + "karma-chrome-launcher": "^3.0.0", + "karma-coverage": "^2.0.0", + "karma-edge-launcher": "^0.4.2", + "karma-env-preprocessor": "^0.1.1", + "karma-firefox-launcher": "^1.1.0", + "karma-ie-launcher": "^1.0.0", + "karma-junit-reporter": "^2.0.1", + "karma-mocha": "^2.0.1", + "karma-mocha-reporter": "^2.2.5", + "karma-sourcemap-loader": "^0.3.8", + "mocha": "^7.1.1", + "mocha-junit-reporter": "^1.18.0", + "nock": "^12.0.3", + "nyc": "^14.0.0", + "prettier": "^1.16.4", + "rimraf": "^3.0.0", + "rollup": "^1.16.3", + "rollup-plugin-shim": "^1.0.0", "rollup-plugin-sourcemaps": "^0.4.2", + "rollup-plugin-terser": "^5.1.1", + "sinon": "^9.0.2", + "ts-node": "^8.3.0", + "typescript": "4.1.2", "uglify-js": "^3.4.9", - "@microsoft/api-extractor": "7.7.11", - "mkdirp": "^1.0.4" + "cross-env": "^7.0.2", + "typedoc": "0.15.2" }, "homepage": "https://github.com/Azure/azure-sdk-for-js", - "repository": { - "type": "git", - "url": "https://github.com/Azure/azure-sdk-for-js.git" - }, + "repository": "github:Azure/azure-sdk-for-js", "bugs": { "url": "https://github.com/Azure/azure-sdk-for-js/issues" }, "files": [ - "dist/**/*.js", - "dist/**/*.js.map", - "dist/**/*.d.ts", - "dist/**/*.d.ts.map", - "esm/**/*.js", - "esm/**/*.js.map", - "esm/**/*.d.ts", - "esm/**/*.d.ts.map", - "./src//**/*.ts", + "dist/", + "dist-esm/src/", "README.md", - "rollup.config.js", - "tsconfig.json" + "LICENSE.txt" ], "scripts": { - "build": "tsc && rollup -c rollup.config.js && mkdirp ./review && npm run extract-api", + "build": "npm run build:node && npm run build:browser", + "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run extract-api", + "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", + "build:test": "npm run build:test:node && npm run build:test:browser", + "build:test:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c rollup.test.config.js 2>&1", + "build:test:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c rollup.test.config.js 2>&1", + "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "clean": "rimraf dist dist-esm dist-browser test-dist test-browser types *.tgz *.log", - "extract-api": "api-extractor run --local", + "extract-api": "tsc -p . && api-extractor run --local", + "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", + "lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix", + "lint": "eslint package.json api-extractor.json src test --ext .ts -f html -o quantum-jobs-lintReport.html || exit 0", + "prebuild": "npm run clean", + "pack": "npm pack 2>&1", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "integration-test:browser": "karma start --single-run", + "integration-test:node": "nyc mocha -r esm --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 180000 --full-trace dist-esm/test/*.spec.js dist-esm/test/**/*.spec.js", + "test:browser": "npm run clean && npm run build:test:browser && npm run unit-test:browser", + "test:node": "npm run clean && npm run build:test:node && npm run unit-test:node", + "test": "npm run clean && npm run test:node && npm run test:browser", + "unit-test:browser": "karma start --single-run", + "unit-test:node": "mocha --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 180000 --full-trace test-dist/index.node.js", + "unit-test": "npm run unit-test:node && npm run unit-test:browser", + "docs": "typedoc --excludePrivate --excludeNotExported --excludeExternals --stripInternal --mode file --out ./dist/docs ./src", "build:samples": "echo skip", - "build:node": "echo skip", - "build:browser": "echo skip", - "build:test": "echo skip", - "build:test:node": "echo skip", - "build:test:browser": "echo skip", - "check-format": "echo skip", - "coverage": "echo skip", - "execute:samples": "echo skip", - "format": "echo skip", - "lint:fix": "echo skip", - "lint": "echo skip", - "prebuild": "echo skip", - "pack": "echo skip", - "swagger": "echo skip", - "integration-test": "echo skip", - "integration-test:browser": "echo skip", - "integration-test:node": "echo skip", - "test": "echo skip", - "test:browser": "echo skip", - "test:node": "echo skip", - "unit-test": "echo skip", - "unit-test:browser": "echo skip", - "unit-test:node": "echo skip", - "docs": "echo skip" + "execute:samples": "echo skip" }, "sideEffects": false } diff --git a/sdk/quantum/quantum-jobs/rollup.base.config.js b/sdk/quantum/quantum-jobs/rollup.base.config.js new file mode 100644 index 000000000000..8863248170f6 --- /dev/null +++ b/sdk/quantum/quantum-jobs/rollup.base.config.js @@ -0,0 +1,166 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + */ +import nodeResolve from "@rollup/plugin-node-resolve"; +import multiEntry from "@rollup/plugin-multi-entry"; +import cjs from "@rollup/plugin-commonjs"; +import replace from "@rollup/plugin-replace"; +import { terser } from "rollup-plugin-terser"; +import sourcemaps from "rollup-plugin-sourcemaps"; +import shim from "rollup-plugin-shim"; +import json from "@rollup/plugin-json"; +import * as path from "path"; +import inject from "@rollup/plugin-inject"; + +const pkg = require("./package.json"); +const depNames = Object.keys(pkg.dependencies); +const input = "dist-esm/src/index.js"; +const production = process.env.NODE_ENV === "production"; + +const version = pkg.version; +const banner = [ + "/*!", + " * Copyright (c) Microsoft and contributors. All rights reserved.", + " * Licensed under the MIT License. See License.txt in the project root for", + " * license information.", + " * ", + ` * Azure Quantum Jobs SDK for JavaScript - ${version}`, + " */" +].join("\n"); + +const ignoreKnownWarnings = (warning) => { + if (warning.code === "THIS_IS_UNDEFINED") { + // This error happens frequently due to TypeScript emitting `this` at the + // top-level of a module. In this case its fine if it gets rewritten to + // undefined, so ignore this error. + return; + } + + if ( + warning.code === "CIRCULAR_DEPENDENCY" && + warning.importer.indexOf(path.normalize("node_modules/chai/lib") === 0) + ) { + // Chai contains circular references, but they are not fatal and can be ignored. + return; + } + + console.error(`(!) ${warning.message}`); +}; + +export function nodeConfig(test = false) { + const externalNodeBuiltins = ["events", "crypto", "path"]; + const baseConfig = { + input: input, + external: depNames.concat(externalNodeBuiltins), + output: { + file: "dist/index.js", + format: "cjs", + sourcemap: true, + banner: banner, + name: "azurequantumjobs" + }, + preserveSymlinks: false, + plugins: [ + sourcemaps(), + replace({ + delimiters: ["", ""] + }), + nodeResolve({ preferBuiltins: true }), + cjs() + ] + }; + + if (test) { + // Entry points - test files under the `test` folder(common for both browser and node), node specific test files + baseConfig.input = ["dist-esm/test/*.spec.js", "dist-esm/test/**/*.spec.js"]; + baseConfig.plugins.unshift( + multiEntry({ exports: false }), + json() // This allows us to import/require the package.json file, to get the version and test it against the user agent. + ); + + // different output file + baseConfig.output.file = "test-dist/index.node.js"; + + // mark assert packages we use as external + baseConfig.external.push("assert"); + + baseConfig.external.push(...Object.keys(pkg.dependencies), ...Object.keys(pkg.devDependencies)); + + // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, rollup started respecting + // the "sideEffects" field in package.json. Since our package.json sets "sideEffects=false", this also + // applies to test code, which causes all tests to be removed by tree-shaking. + baseConfig.treeshake = false; + } else if (production) { + baseConfig.plugins.push(terser()); + } + + return baseConfig; +} + +export function browserConfig(test = false) { + const baseConfig = { + input: input, + output: { + file: "dist-browser/quantumjobs.js", + format: "umd", + name: "Azure.QuantumJobs", + globals: { + "@azure/core-http": "Azure.Core.HTTP" + }, + sourcemap: true + }, + external: ["fs-extra"], + preserveSymlinks: false, + plugins: [ + sourcemaps(), + replace({ + delimiters: ["", ""] + }), + + nodeResolve({ + mainFields: ["module", "browser"], + preferBuiltins: false + }), + cjs({ + namedExports: { + chai: ["assert", "expect", "use"], + assert: ["ok", "equal", "strictEqual", "deepEqual", "fail", "throws", "notEqual"], + events: ["EventEmitter"], + "@opentelemetry/api": ["CanonicalCode", "SpanKind", "TraceFlags"] + } + }), + + inject({ + modules: { + process: "process" + }, + exclude: ["./**/package.json"] + }), + + json() + ] + }; + + baseConfig.onwarn = ignoreKnownWarnings; + + if (test) { + baseConfig.input = ["dist-esm/test/public/*.spec.js", "dist-esm/test/internal/*.spec.js"]; + + baseConfig.external.unshift(...["process"]); + + baseConfig.plugins.unshift(multiEntry({ exports: false })); + baseConfig.plugins.unshift( + ...[shim({ path: `export function join() {}`, dotenv: `export function config() { }` })] + ); + + baseConfig.output.file = "test-browser/index.js"; + + // Disable tree-shaking of test code. In rollup-plugin-node-resolve@5.0.0, rollup started respecting + // the "sideEffects" field in package.json. Since our package.json sets "sideEffects=false", this also + // applies to test code, which causes all tests to be removed by tree-shaking. + baseConfig.treeshake = false; + } + + return baseConfig; +} diff --git a/sdk/quantum/quantum-jobs/rollup.config.js b/sdk/quantum/quantum-jobs/rollup.config.js index 6a7c94feb4cf..809e2993c0eb 100644 --- a/sdk/quantum/quantum-jobs/rollup.config.js +++ b/sdk/quantum/quantum-jobs/rollup.config.js @@ -1,36 +1,17 @@ /* * Copyright (c) Microsoft Corporation. * Licensed under the MIT License. - * - * Code generated by Microsoft (R) AutoRest Code Generator. - * Changes may cause incorrect behavior and will be lost if the code is regenerated. */ +import * as base from "./rollup.base.config"; -import rollup from "rollup"; -import nodeResolve from "rollup-plugin-node-resolve"; -import sourcemaps from "rollup-plugin-sourcemaps"; +const inputs = []; -/** @type {rollup.RollupFileOptions} */ -const config = { - input: "./dist-esm/quantumJobClient.js", - external: ["@azure/core-http"], - output: { - file: "./dist/quantum-jobs.js", - format: "umd", - name: "Azure.QuantumJobs", - sourcemap: true, - globals: { - "@azure/core-http": "coreHttp" - }, - banner: `/* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - * - * Code generated by Microsoft (R) AutoRest Code Generator. - * Changes may cause incorrect behavior and will be lost if the code is regenerated. - */ ` - }, - plugins: [nodeResolve({ module: true }), sourcemaps()] -}; +if (!process.env.ONLY_BROWSER) { + inputs.push(base.nodeConfig()); +} -export default config; +if (!process.env.ONLY_NODE) { + inputs.push(base.browserConfig()); +} + +export default inputs; diff --git a/sdk/quantum/quantum-jobs/rollup.test.config.js b/sdk/quantum/quantum-jobs/rollup.test.config.js new file mode 100644 index 000000000000..4551b61a6025 --- /dev/null +++ b/sdk/quantum/quantum-jobs/rollup.test.config.js @@ -0,0 +1,18 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + */ + +import * as base from "./rollup.base.config"; + +const inputs = []; + +if (!process.env.ONLY_BROWSER) { + inputs.push(base.nodeConfig({ test: true })); +} + +if (!process.env.ONLY_NODE) { + inputs.push(base.browserConfig({ test: true })); +} + +export default inputs; diff --git a/sdk/quantum/quantum-jobs/test/public/quantumJobClient.spec.ts b/sdk/quantum/quantum-jobs/test/public/quantumJobClient.spec.ts new file mode 100644 index 000000000000..4be9e7e2378a --- /dev/null +++ b/sdk/quantum/quantum-jobs/test/public/quantumJobClient.spec.ts @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as assert from "assert"; +import { QuantumJobClient } from "../../src"; + +describe("Quantum Job Client tests", function() { + it("can create the client object successfully", () => { + const obj: QuantumJobClient = new QuantumJobClient( + "sample-subscription-id", + "sample-resource-group-name", + "sample-workspace-name" + ); + assert.notEqual(obj, null); + }); +});