diff options
author | Jose <jose@zeroc.com> | 2018-10-16 00:53:00 +0200 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2018-10-16 00:53:00 +0200 |
commit | cf8292f9cdadcb6619287ada4f5273c25c5a3cfb (patch) | |
tree | 4a227f287d2a5e22e36b1f488f00a3c96add7a44 | |
parent | Updated VS2017 requirement (diff) | |
download | ice-cf8292f9cdadcb6619287ada4f5273c25c5a3cfb.tar.bz2 ice-cf8292f9cdadcb6619287ada4f5273c25c5a3cfb.tar.xz ice-cf8292f9cdadcb6619287ada4f5273c25c5a3cfb.zip |
Typescript support
201 files changed, 23201 insertions, 439 deletions
diff --git a/CHANGELOG-3.7.md b/CHANGELOG-3.7.md index c4b23bb39f1..cd39ec55e79 100644 --- a/CHANGELOG-3.7.md +++ b/CHANGELOG-3.7.md @@ -57,6 +57,13 @@ These are the changes since Ice 3.7.1 included in this pre-release. - Fixed Android IceSSL issue which would cause SSL connections to hang with Android >= 8.0. +## JavaScript Changes + +- Added TypeScript declaration files for Ice for JavaScript. + +- Slice to JavaScript compiler can now generate TypeScript declaration files + for JavaScript generated code using `--typescript` command line option. + # Changes in Ice 3.7.1 These are the changes since Ice 3.7.0. diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 19ed36efd5f..e1be83afdc4 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -362,10 +362,11 @@ Slice::SyntaxTreeBase::visit(ParserVisitor*, bool) { } -Slice::SyntaxTreeBase::SyntaxTreeBase(const UnitPtr& unit) : - _unit(unit) +Slice::SyntaxTreeBase::SyntaxTreeBase(const UnitPtr& unit, const DefinitionContextPtr& definitionContext) : + _unit(unit), + _definitionContext(definitionContext) { - if(_unit) + if(!_definitionContext && _unit) { _definitionContext = unit->currentDefinitionContext(); } @@ -4359,8 +4360,8 @@ Slice::Proxy::_class() const } Slice::Proxy::Proxy(const ClassDeclPtr& cl) : - SyntaxTreeBase(cl->unit()), - Type(cl->unit()), + SyntaxTreeBase(cl->unit(), cl->definitionContext()), + Type(cl->unit()), _classDecl(cl) { } diff --git a/cpp/src/Slice/Parser.h b/cpp/src/Slice/Parser.h index 736c6c3c59c..219c14ae151 100644 --- a/cpp/src/Slice/Parser.h +++ b/cpp/src/Slice/Parser.h @@ -319,7 +319,7 @@ public: protected: - SyntaxTreeBase(const UnitPtr&); + SyntaxTreeBase(const UnitPtr&, const DefinitionContextPtr& = 0); UnitPtr _unit; DefinitionContextPtr _definitionContext; diff --git a/cpp/src/Slice/SliceUtil.cpp b/cpp/src/Slice/SliceUtil.cpp index ae45fe5967d..85dee38106c 100644 --- a/cpp/src/Slice/SliceUtil.cpp +++ b/cpp/src/Slice/SliceUtil.cpp @@ -44,6 +44,10 @@ normalizePath(const string& path) { startReplace = 2; } + else + { + result[0] = toUpper(result.substr(0, 1))[0]; + } #endif string::size_type pos; while((pos = result.find("//", startReplace)) != string::npos) diff --git a/cpp/src/slice2js/Gen.cpp b/cpp/src/slice2js/Gen.cpp index 7a4e61f3115..be159aa206b 100644 --- a/cpp/src/slice2js/Gen.cpp +++ b/cpp/src/slice2js/Gen.cpp @@ -11,19 +11,11 @@ #include <IceUtil/StringUtil.h> #include <IceUtil/InputUtil.h> #include <Gen.h> -#include <limits> -#include <sys/stat.h> -#ifndef _WIN32 -#include <unistd.h> -#else -#include <direct.h> -#endif #include <IceUtil/Iterator.h> #include <IceUtil/UUID.h> #include <Slice/Checksum.h> #include <Slice/FileTracker.h> #include <Slice/Util.h> -#include <string.h> using namespace std; using namespace Slice; @@ -86,9 +78,289 @@ getDeprecateReason(const ContainedPtr& p1, const ContainedPtr& p2, const string& return deprecateReason; } +void +printHeader(IceUtilInternal::Output& out) +{ + static const char* header = + "// **********************************************************************\n" + "//\n" + "// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved.\n" + "//\n" + "// This copy of Ice is licensed to you under the terms described in the\n" + "// ICE_LICENSE file included in this distribution.\n" + "//\n" + "// **********************************************************************\n" + ; + + out << header; + out << "//\n"; + out << "// Ice version " << ICE_STRING_VERSION << "\n"; + out << "//\n"; +} + +string +escapeParam(const ParamDeclList& params, const string& name) +{ + string r = name; + for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) + { + if(Slice::JsGenerator::fixId((*p)->name()) == name) + { + r = name + "_"; + break; + } + } + return r; +} + +void +writeDocLines(Output& out, const StringList& lines, bool commentFirst, const string& space = " ") +{ + StringList l = lines; + if(!commentFirst) + { + out << l.front(); + l.pop_front(); + } + for(StringList::const_iterator i = l.begin(); i != l.end(); ++i) + { + out << nl << " *"; + if(!i->empty()) + { + out << space << *i; + } + } +} + +void +writeSeeAlso(Output& out, const StringList& lines, const string& space = " ") +{ + for(StringList::const_iterator i = lines.begin(); i != lines.end(); ++i) + { + out << nl << " *"; + if(!i->empty()) + { + out << space << "@see " << *i; + } + } +} + +string +getDocSentence(const StringList& lines) +{ + // + // Extract the first sentence. + // + ostringstream ostr; + for(StringList::const_iterator i = lines.begin(); i != lines.end(); ++i) + { + const string ws = " \t"; + + if(i->empty()) + { + break; + } + if(i != lines.begin() && i->find_first_not_of(ws) == 0) + { + ostr << " "; + } + string::size_type pos = i->find('.'); + if(pos == string::npos) + { + ostr << *i; + } + else if(pos == i->size() - 1) + { + ostr << *i; + break; + } + else + { + // + // Assume a period followed by whitespace indicates the end of the sentence. + // + while(pos != string::npos) + { + if(ws.find((*i)[pos + 1]) != string::npos) + { + break; + } + pos = i->find('.', pos + 1); + } + if(pos != string::npos) + { + ostr << i->substr(0, pos + 1); + break; + } + else + { + ostr << *i; + } + } + } + + return ostr.str(); +} + +void +writeDocSummary(Output& out, const ContainedPtr& p) +{ + if(p->comment().empty()) + { + return; + } + + CommentPtr doc = p->parseComment(false); + + out << nl << "/**"; + + if(!doc->overview().empty()) + { + writeDocLines(out, doc->overview(), true); + } + + if(!doc->misc().empty()) + { + writeDocLines(out, doc->misc(), true); + } + + if(!doc->seeAlso().empty()) + { + writeSeeAlso(out, doc->seeAlso()); + } + + if(!doc->deprecated().empty()) + { + out << nl << " *"; + out << nl << " * @deprecated "; + writeDocLines(out, doc->deprecated(), false); + } + else if(doc->isDeprecated()) + { + out << nl << " *"; + out << nl << " * @deprecated"; + } + + out << nl << " */"; +} + +enum OpDocParamType { OpDocInParams, OpDocOutParams, OpDocAllParams }; + +void +writeOpDocParams(Output& out, const OperationPtr& op, const CommentPtr& doc, OpDocParamType type, + const StringList& preParams = StringList(), const StringList& postParams = StringList()) +{ + ParamDeclList params; + switch (type) + { + case OpDocInParams: + params = op->inParameters(); + break; + case OpDocOutParams: + params = op->outParameters(); + break; + case OpDocAllParams: + params = op->parameters(); + break; + } + + if (!preParams.empty()) + { + writeDocLines(out, preParams, true); + } + + map<string, StringList> paramDoc = doc->parameters(); + for (ParamDeclList::iterator p = params.begin(); p != params.end(); ++p) + { + map<string, StringList>::iterator q = paramDoc.find((*p)->name()); + if(q != paramDoc.end()) + { + out << nl << " * @param " << Slice::JsGenerator::fixId(q->first) << " "; + writeDocLines(out, q->second, false); + } + } + + if(!postParams.empty()) + { + writeDocLines(out, postParams, true); + } +} + +void +writeOpDocExceptions(Output& out, const OperationPtr& op, const CommentPtr& doc) +{ + map<string, StringList> exDoc = doc->exceptions(); + for (map<string, StringList>::iterator p = exDoc.begin(); p != exDoc.end(); ++p) + { + // + // Try to locate the exception's definition using the name given in the comment. + // + string name = p->first; + ExceptionPtr ex = op->container()->lookupException(name, false); + if (ex) + { + name = ex->scoped().substr(2); + } + out << nl << " * @throws " << name << " "; + writeDocLines(out, p->second, false); + } } -Slice::JsVisitor::JsVisitor(Output& out) : _out(out) +void +writeOpDocSummary(Output& out, const OperationPtr& op, const CommentPtr& doc, OpDocParamType type, bool showExceptions, + const StringList& preParams = StringList(), const StringList& postParams = StringList(), + const StringList& returns = StringList()) +{ + out << nl << "/**"; + + if (!doc->overview().empty()) + { + writeDocLines(out, doc->overview(), true); + } + + writeOpDocParams(out, op, doc, type, preParams, postParams); + + if(!returns.empty()) + { + out << nl << " * @return "; + writeDocLines(out, returns, false); + } + + if(showExceptions) + { + writeOpDocExceptions(out, op, doc); + } + + if(!doc->misc().empty()) + { + writeDocLines(out, doc->misc(), true); + } + + if(!doc->seeAlso().empty()) + { + writeSeeAlso(out, doc->seeAlso()); + } + + if(!doc->deprecated().empty()) + { + out << nl << " *"; + out << nl << " * @deprecated "; + writeDocLines(out, doc->deprecated(), false); + } + else if(doc->isDeprecated()) + { + out << nl << " *"; + out << nl << " * @deprecated"; + } + + out << nl << " */"; +} + +} + +Slice::JsVisitor::JsVisitor(Output& out, const vector<pair<string, string>>& imports) : + _out(out), + _imports(imports) { } @@ -96,6 +368,12 @@ Slice::JsVisitor::~JsVisitor() { } +vector<pair<string, string>> +Slice::JsVisitor::imports() const +{ + return _imports; +} + void Slice::JsVisitor::writeMarshalDataMembers(const DataMemberList& dataMembers, const DataMemberList& optionalMembers) { @@ -131,7 +409,7 @@ Slice::JsVisitor::writeUnmarshalDataMembers(const DataMemberList& dataMembers, c } void -Slice::JsVisitor::writeInitDataMembers(const DataMemberList& dataMembers, const string& scope) +Slice::JsVisitor::writeInitDataMembers(const DataMemberList& dataMembers) { for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) { @@ -188,7 +466,7 @@ Slice::JsVisitor::getValue(const string& scope, const TypePtr& type) EnumPtr en = EnumPtr::dynamicCast(type); if(en) { - return getReference(scope, en->scoped()) + '.' + fixId((*en->enumerators().begin())->name()); + return fixId(en->scoped()) + '.' + fixId((*en->enumerators().begin())->name()); } StructPtr st = StructPtr::dynamicCast(type); @@ -208,7 +486,7 @@ Slice::JsVisitor::writeConstantValue(const string& scope, const TypePtr& type, c ConstPtr constant = ConstPtr::dynamicCast(valueType); if(constant) { - os << getReference(scope, constant->scoped()); + os << fixId(constant->scoped()); } else { @@ -243,7 +521,7 @@ Slice::JsVisitor::writeConstantValue(const string& scope, const TypePtr& type, c { EnumeratorPtr lte = EnumeratorPtr::dynamicCast(valueType); assert(lte); - os << getReference(scope, ep->scoped()) << '.' << fixId(lte->name()); + os << fixId(ep->scoped()) << '.' << fixId(lte->name()); } else { @@ -331,18 +609,20 @@ Slice::JsVisitor::writeDocComment(const ContainedPtr& p, const string& deprecate _out << nl << " **/"; } -Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const string& dir) : +Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const string& dir, bool typeScript) : _includePaths(includePaths), - _useStdout(false) + _useStdout(false), + _typeScript(typeScript) { _fileBase = base; + string::size_type pos = base.find_last_of("/\\"); if(pos != string::npos) { _fileBase = base.substr(pos + 1); } - string file = _fileBase + ".js"; + string file = _fileBase + (typeScript ? ".d.ts" : ".js"); if(!dir.empty()) { @@ -358,14 +638,16 @@ Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const st } FileTracker::instance()->addFile(file); - printHeader(); + printHeader(_out); printGeneratedHeader(_out, _fileBase + ".ice"); } -Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const string& dir, ostream& out) : +Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const string& dir, bool typeScript, + ostream& out) : _out(out), _includePaths(includePaths), - _useStdout(true) + _useStdout(true), + _typeScript(typeScript) { _fileBase = base; string::size_type pos = base.find_last_of("/\\"); @@ -374,7 +656,7 @@ Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const st _fileBase = base.substr(pos + 1); } - printHeader(); + printHeader(_out); printGeneratedHeader(_out, _fileBase + ".ice"); } @@ -390,70 +672,106 @@ void Slice::Gen::generate(const UnitPtr& p) { // - // Check for global "js:ice-build" and "js:es6-module" - // metadata. If this is set then we are building Ice. + // Check for "js:module:ice" metadata. If this + // is set then we are building Ice. + // + ModuleList modules = p->modules(); + bool icejs = false; + for(ModuleList::const_iterator i = modules.begin(); i != modules.end(); i++) + { + if(p->topLevelFile() == (*i)->definitionContext()->filename() && + getModuleMetadata(ContainedPtr::dynamicCast(*i)) == "ice") + { + icejs = true; + break; + } + } + + // + // Check for global "js:es6-module" metadata. // DefinitionContextPtr dc = p->findDefinitionContext(p->topLevelFile()); assert(dc); StringList globalMetaData = dc->getMetaData(); - bool icejs = find(globalMetaData.begin(), globalMetaData.end(), "js:ice-build") != globalMetaData.end(); bool es6module = find(globalMetaData.begin(), globalMetaData.end(), "js:es6-module") != globalMetaData.end(); - _out << nl << "/* eslint-disable */"; - _out << nl << "/* jshint ignore: start */"; - _out << nl; + if(_typeScript) + { + TypeScriptRequireVisitor requireVisitor(_out); + p->visit(&requireVisitor, false); + requireVisitor.writeRequires(p); + + // + // If at some point TypeScript adds an operator to refer to a type in the global scope + // we can get rid of the TypeScriptAliasVisitor and use this. For now we need to generate + // a type alias when there is an abiguity. + // see: https://github.com/Microsoft/TypeScript/issues/983 + // + TypeScriptAliasVisitor aliasVisitor(_out); + p->visit(&aliasVisitor, false); + aliasVisitor.writeAlias(p); - if(!es6module) + TypeScriptVisitor typeScriptVisitor(_out, requireVisitor.imports()); + p->visit(&typeScriptVisitor, false); + } + else { - if(icejs) - { - _out.zeroIndent(); - _out << nl << "/* slice2js browser-bundle-skip */"; - _out.restoreIndent(); - } - _out << nl << "(function(module, require, exports)"; - _out << sb; - if(icejs) + _out << nl << "/* eslint-disable */"; + _out << nl << "/* jshint ignore: start */"; + _out << nl; + + if(!es6module) { - _out.zeroIndent(); - _out << nl << "/* slice2js browser-bundle-skip-end */"; - _out.restoreIndent(); + if(icejs) + { + _out.zeroIndent(); + _out << nl << "/* slice2js browser-bundle-skip */"; + _out.restoreIndent(); + } + _out << nl << "(function(module, require, exports)"; + _out << sb; + if(icejs) + { + _out.zeroIndent(); + _out << nl << "/* slice2js browser-bundle-skip-end */"; + _out.restoreIndent(); + } } - } - RequireVisitor requireVisitor(_out, _includePaths, icejs, es6module); - p->visit(&requireVisitor, false); - vector<string> seenModules = requireVisitor.writeRequires(p); + RequireVisitor requireVisitor(_out, _includePaths, icejs, es6module); + p->visit(&requireVisitor, false); + vector<string> seenModules = requireVisitor.writeRequires(p); - TypesVisitor typesVisitor(_out, seenModules, icejs); - p->visit(&typesVisitor, false); + TypesVisitor typesVisitor(_out, seenModules, icejs); + p->visit(&typesVisitor, false); - // - // Export the top-level modules. - // - ExportVisitor exportVisitor(_out, icejs, es6module); - p->visit(&exportVisitor, false); + // + // Export the top-level modules. + // + ExportVisitor exportVisitor(_out, icejs, es6module); + p->visit(&exportVisitor, false); - if(!es6module) - { - if(icejs) + if(!es6module) { - _out.zeroIndent(); - _out << nl << "/* slice2js browser-bundle-skip */"; - _out.restoreIndent(); - } + if(icejs) + { + _out.zeroIndent(); + _out << nl << "/* slice2js browser-bundle-skip */"; + _out.restoreIndent(); + } - _out << eb; - _out << nl << "(typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? module : undefined," - << nl << " typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? require :" - << nl << " (typeof WorkerGlobalScope !== \"undefined\" && self instanceof WorkerGlobalScope) ? self.Ice._require : window.Ice._require," - << nl << " typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? exports :" - << nl << " (typeof WorkerGlobalScope !== \"undefined\" && self instanceof WorkerGlobalScope) ? self : window));"; + _out << eb; + _out << nl << "(typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? module : undefined," + << nl << " typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? require :" + << nl << " (typeof WorkerGlobalScope !== \"undefined\" && self instanceof WorkerGlobalScope) ? self.Ice._require : window.Ice._require," + << nl << " typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? exports :" + << nl << " (typeof WorkerGlobalScope !== \"undefined\" && self instanceof WorkerGlobalScope) ? self : window));"; - if(icejs) - { - _out.zeroIndent(); - _out << nl << "/* slice2js browser-bundle-skip-end */"; - _out.restoreIndent(); + if(icejs) + { + _out.zeroIndent(); + _out << nl << "/* slice2js browser-bundle-skip-end */"; + _out.restoreIndent(); + } } } } @@ -464,26 +782,6 @@ Slice::Gen::closeOutput() _out.close(); } -void -Slice::Gen::printHeader() -{ - static const char* header = -"// **********************************************************************\n" -"//\n" -"// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved.\n" -"//\n" -"// This copy of Ice is licensed to you under the terms described in the\n" -"// ICE_LICENSE file included in this distribution.\n" -"//\n" -"// **********************************************************************\n" - ; - - _out << header; - _out << "//\n"; - _out << "// Ice version " << ICE_STRING_VERSION << "\n"; - _out << "//\n"; -} - Slice::Gen::RequireVisitor::RequireVisitor(IceUtilInternal::Output& out, vector<string> includePaths, bool icejs, bool es6modules) : JsVisitor(out), @@ -549,9 +847,17 @@ void Slice::Gen::RequireVisitor::visitSequence(const SequencePtr& seq) { BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); - if(builtin && builtin->kind() == Builtin::KindObject) + if(builtin) { - _seenObjectSeq = true; + switch(builtin->kind()) + { + case Builtin::KindObject: + _seenObjectSeq = true; + case Builtin::KindObjectProxy: + _seenObjectProxySeq = true; + default: + break; + } } } @@ -559,9 +865,17 @@ void Slice::Gen::RequireVisitor::visitDictionary(const DictionaryPtr& dict) { BuiltinPtr builtin = BuiltinPtr::dynamicCast(dict->valueType()); - if(builtin && builtin->kind() == Builtin::KindObject) + if(builtin) { - _seenObjectDict = true; + switch(builtin->kind()) + { + case Builtin::KindObject: + _seenObjectDict = true; + case Builtin::KindObjectProxy: + _seenObjectProxyDict = true; + default: + break; + } } } @@ -579,66 +893,12 @@ bool iceBuiltinModule(const string& name) return name == "Glacier2" || name == "Ice" || name == "IceGrid" || name == "IceMX" || name == "IceStorm"; } -string -relativePath(string p1, string p2) -{ - vector<string> tokens1; - vector<string> tokens2; - - splitString(p1, "/\\", tokens1); - splitString(p2, "/\\", tokens2); - - string f1 = tokens1.back(); - string f2 = tokens2.back(); - - tokens1.pop_back(); - tokens2.pop_back(); - - vector<string>::const_iterator i1 = tokens1.begin(); - vector<string>::const_iterator i2 = tokens2.begin(); - - while(i1 != tokens1.end() && i2 != tokens2.end() && *i1 == *i2) - { - i1++; - i2++; - } - - // - // Different volumes, relative path not possible. - // - if(i1 == tokens1.begin() && i2 == tokens2.begin()) - { - return p1; - } - - string newPath; - if(i2 == tokens2.end()) - { - newPath += "./"; - for(; i1 != tokens1.end(); ++i1) - { - newPath += *i1 + "/"; - } - } - else - { - for(;i2 != tokens2.end();++i2) - { - newPath += "../"; - } - } - newPath += f1; - - return newPath; -} - } vector<string> Slice::Gen::RequireVisitor::writeRequires(const UnitPtr& p) { vector<string> seenModules; - map<string, list<string> > requires; if(_icejs) { @@ -925,7 +1185,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) { base = bases.front(); bases.erase(bases.begin()); - baseRef = getReference(scope, base->scoped()); + baseRef = fixId(base->scoped()); } else { @@ -1040,7 +1300,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) { _out << nl << "super" << spar << baseParamNames << epar << ';'; } - writeInitDataMembers(dataMembers, scope); + writeInitDataMembers(dataMembers); _out << eb; if(!p->isLocal()) @@ -1091,12 +1351,12 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) // // Define servant an proxy types for non local classes // - if(!p->isLocal()) + if(!p->isLocal() && (p->isInterface() || !p->allOperations().empty())) { _out << sp; writeDocComment(p, getDeprecateReason(p, 0, "type")); _out << nl << localScope << "." << (p->isInterface() ? p->name() : p->name() + "Disp") << " = class extends "; - if(hasBaseClass) + if(hasBaseClass && !base->allOperations().empty()) { _out << getLocalScope(base->scope()) << "." << base->name() << "Disp"; } @@ -1140,7 +1400,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) // Generate a proxy class for interfaces or classes with operations. // string proxyType = "undefined"; - if(p->isInterface() || p->allOperations().size() > 0) + if(p->isInterface() || !p->allOperations().empty()) { proxyType = localScope + '.' + prxName; string baseProxy = "Ice.ObjectPrx"; @@ -1442,7 +1702,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) string baseRef; if(base) { - baseRef = getReference(scope, base->scoped()); + baseRef = fixId(base->scoped()); } else { @@ -1514,7 +1774,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) _out << "_cause = \"\"" << epar; _out << sb; _out << nl << "super" << spar << baseParamNames << "_cause" << epar << ';'; - writeInitDataMembers(dataMembers, scope); + writeInitDataMembers(dataMembers); _out << eb; _out << sp; @@ -1529,8 +1789,6 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) _out << nl << "return \"" << p->scoped() << "\";"; _out << eb; - // TODO: equals? - if(!p->isLocal()) { _out << sp; @@ -1630,7 +1888,7 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p) _out << epar; _out << sb; - writeInitDataMembers(dataMembers, scope); + writeInitDataMembers(dataMembers); _out << eb; if(!p->isLocal()) @@ -1900,3 +2158,1038 @@ Slice::Gen::ExportVisitor::visitModuleStart(const ModulePtr& p) } return false; } + +Slice::Gen::TypeScriptRequireVisitor::TypeScriptRequireVisitor(IceUtilInternal::Output& out) : + JsVisitor(out), + _nextImport(0) +{ +} + +string +Slice::Gen::TypeScriptRequireVisitor::nextImportPrefix() +{ + ostringstream ns; + ns << "iceNS" << _nextImport++; + return ns.str(); +} + +void +Slice::Gen::TypeScriptRequireVisitor::addImport(const TypePtr& definition, const ContainedPtr& toplevel) +{ + if(!BuiltinPtr::dynamicCast(definition)) + { + const string m1 = getModuleMetadata(definition); + const string m2 = getModuleMetadata(toplevel); + + const string p1 = definition->definitionContext()->filename(); + const string p2 = toplevel->definitionContext()->filename(); + + addImport(m1, m2, p1, p2); + } +} + +void +Slice::Gen::TypeScriptRequireVisitor::addImport(const ContainedPtr& definition, const ContainedPtr& toplevel) +{ + const string m1 = getModuleMetadata(definition); + const string m2 = getModuleMetadata(toplevel); + + const string p1 = definition->definitionContext()->filename(); + const string p2 = toplevel->definitionContext()->filename(); + + addImport(m1, m2, p1, p2); +} + +void +Slice::Gen::TypeScriptRequireVisitor::addImport(const string& m1, const string& m2, + const string& p1, const string& p2) +{ + // + // Generate an import for a definition that is outside a JS module and comes from + // a different definition context or for a definition defined in a module different + // than the current module. + // + if(m1.empty()) + { + if(p1 != p2) + { + string relpath = relativePath(p1, p2); + + string::size_type pos = relpath.rfind('.'); + if(pos != string::npos) + { + relpath.erase(pos); + } + + for(vector<pair<string, string>>::const_iterator i = _imports.begin(); i != _imports.end(); ++i) + { + if(i->first == relpath) + { + return; + } + } + _imports.push_back(make_pair(relpath, nextImportPrefix())); + } + } + else if(m1 != m2) + { + for(vector<pair<string, string>>::const_iterator i = _imports.begin(); i != _imports.end(); ++i) + { + if(i->first == m1) + { + return; + } + } + _imports.push_back(make_pair(m1, nextImportPrefix())); + } +} + +bool +Slice::Gen::TypeScriptRequireVisitor::visitModuleStart(const ModulePtr& p) +{ + // + // Import ice module if not building Ice + // + if(UnitPtr::dynamicCast(p->container())) + { + const string prefix = "js:module:"; + string m; + findMetaData(prefix, p->getMetaData(), m); + if(_imports.empty() && m != "ice") + { + _imports.push_back(make_pair("ice", nextImportPrefix())); + } + } + return true; +} + +bool +Slice::Gen::TypeScriptRequireVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + // + // Add imports required for base classes + // + ClassList bases = p->bases(); + for(ClassList::const_iterator i = bases.begin(); i != bases.end(); ++i) + { + addImport(ContainedPtr::dynamicCast(*i), p); + } + + // + // Add imports required for data members + // + const DataMemberList allDataMembers = p->allDataMembers(); + for(DataMemberList::const_iterator i = allDataMembers.begin(); i != allDataMembers.end(); ++i) + { + addImport((*i)->type(), p); + } + + // + // Add imports required for operation parameters and return type + // + const OperationList operationList = p->allOperations(); + for(OperationList::const_iterator i = operationList.begin(); i != operationList.end(); ++i) + { + const TypePtr ret = (*i)->returnType(); + if(ret && ret->definitionContext()) + { + addImport(ret, p); + } + + const ParamDeclList paramList = (*i)->parameters(); + for(ParamDeclList::const_iterator j = paramList.begin(); j != paramList.end(); ++j) + { + addImport((*j)->type(), p); + } + } + return false; +} + +bool +Slice::Gen::TypeScriptRequireVisitor::visitStructStart(const StructPtr& p) +{ + // + // Add imports required for data members + // + const DataMemberList dataMembers = p->dataMembers(); + for(DataMemberList::const_iterator i = dataMembers.begin(); i != dataMembers.end(); ++i) + { + addImport((*i)->type(), p); + } + return false; +} + +bool +Slice::Gen::TypeScriptRequireVisitor::visitExceptionStart(const ExceptionPtr& p) +{ + // + // Add imports required for base exceptions + // + ExceptionPtr base = p->base(); + if(base) + { + addImport(ContainedPtr::dynamicCast(base), p); + } + + // + // Add imports required for data members + // + const DataMemberList allDataMembers = p->allDataMembers(); + for(DataMemberList::const_iterator i = allDataMembers.begin(); i != allDataMembers.end(); ++i) + { + addImport((*i)->type(), p); + } + return false; +} + +void +Slice::Gen::TypeScriptRequireVisitor::visitSequence(const SequencePtr& seq) +{ + // + // Add import required for the sequence element type + // + addImport(seq->type(), seq); +} + +void +Slice::Gen::TypeScriptRequireVisitor::visitDictionary(const DictionaryPtr& dict) +{ + // + // Add imports required for the dictionary key and value types + // + addImport(dict->keyType(), dict); + addImport(dict->valueType(), dict); +} + +void +Slice::Gen::TypeScriptRequireVisitor::writeRequires(const UnitPtr& p) +{ + for(vector<pair<string, string>>::const_iterator i = _imports.begin(); i != _imports.end(); ++i) + { + _out << nl << "import * as " << i->second << " from \"" << i->first << "\""; + } +} + +Slice::Gen::TypeScriptAliasVisitor::TypeScriptAliasVisitor(IceUtilInternal::Output& out) : + JsVisitor(out) +{ +} + +void +Slice::Gen::TypeScriptAliasVisitor::addAlias(const ExceptionPtr& type, const ContainedPtr& toplevel) +{ + string m1 = getModuleMetadata(ContainedPtr::dynamicCast(type)); + string m2 = getModuleMetadata(toplevel); + + // + // Do not add alias for a type defined in the current module + // + if(!m1.empty() && m1 == m2) + { + return; + } + + const string prefix = importPrefix(ContainedPtr::dynamicCast(type), toplevel, imports()); + const string typeS = prefix + getUnqualified(fixId(type->scoped()), toplevel->scope(), prefix); + + addAlias(typeS, prefix, toplevel); +} + +void +Slice::Gen::TypeScriptAliasVisitor::addAlias(const TypePtr& type, const ContainedPtr& toplevel) +{ + string m1 = getModuleMetadata(type); + string m2 = getModuleMetadata(toplevel); + + // + // Do not add alias for a type defined in the current module + // + if(!m1.empty() && m1 == m2) + { + return; + } + + addAlias(typeToString(type, toplevel, imports(), true), + importPrefix(type, toplevel, imports()), + toplevel); +} + +void +Slice::Gen::TypeScriptAliasVisitor::addAlias(const string& type, const string& prefix, + const ContainedPtr& toplevel) +{ + const string scope = fixId(toplevel->scoped()) + "."; + // + // When using an import prefix we don't need an alias, prefixes use iceNSXX that is reserved + // name prefix + // + string::size_type i = type.find("."); + if(prefix.empty() && i != string::npos) + { + if(scope.find("." + type.substr(0, i + 1)) != string::npos) + { + for(vector<pair<string, string>>::const_iterator j = _aliases.begin(); j != _aliases.end(); ++j) + { + if(j->first == type) + { + return; + } + } + string alias = type; + replace(alias.begin(), alias.end(), '.', '_'); + // + // We prefix alias with iceA this avoid conflict with iceNSX used for + // import prefixes + // + _aliases.push_back(make_pair(type, "iceA_" + alias)); + } + } +} + +bool +Slice::Gen::TypeScriptAliasVisitor::visitModuleStart(const ModulePtr& p) +{ + return true; +} + +bool +Slice::Gen::TypeScriptAliasVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + ModulePtr module = ModulePtr::dynamicCast(p->container()); + // + // Add alias required for base classes + // + ClassList bases = p->bases(); + for(ClassList::const_iterator i = bases.begin(); i != bases.end(); ++i) + { + addAlias(TypePtr::dynamicCast((*i)->declaration()), module); + } + + // + // Add alias required for data members + // + const DataMemberList allDataMembers = p->allDataMembers(); + for(DataMemberList::const_iterator i = allDataMembers.begin(); i != allDataMembers.end(); ++i) + { + addAlias((*i)->type(), module); + } + + // + // Add alias required for operation parameters + // + const OperationList operationList = p->allOperations(); + for(OperationList::const_iterator i = operationList.begin(); i != operationList.end(); ++i) + { + const TypePtr ret = (*i)->returnType(); + if(ret && ret->definitionContext()) + { + addAlias(ret, module); + } + + const ParamDeclList paramList = (*i)->parameters(); + for(ParamDeclList::const_iterator j = paramList.begin(); j != paramList.end(); ++j) + { + addAlias((*j)->type(), module); + } + } + return false; +} + +bool +Slice::Gen::TypeScriptAliasVisitor::visitStructStart(const StructPtr& p) +{ + ModulePtr module = ModulePtr::dynamicCast(p->container()); + // + // Add alias required for data members + // + const DataMemberList dataMembers = p->dataMembers(); + for(DataMemberList::const_iterator i = dataMembers.begin(); i != dataMembers.end(); ++i) + { + addAlias((*i)->type(), module); + } + return false; +} + +bool +Slice::Gen::TypeScriptAliasVisitor::visitExceptionStart(const ExceptionPtr& p) +{ + ModulePtr module = ModulePtr::dynamicCast(p->container()); + // + // Add alias required for base exception + // + ExceptionPtr base = p->base(); + if(base) + { + addAlias(base, module); + } + + // + // Add alias required for data members + // + const DataMemberList allDataMembers = p->allDataMembers(); + for(DataMemberList::const_iterator i = allDataMembers.begin(); i != allDataMembers.end(); ++i) + { + addAlias((*i)->type(), module); + } + return false; +} + +void +Slice::Gen::TypeScriptAliasVisitor::visitSequence(const SequencePtr& seq) +{ + addAlias(seq->type(), ModulePtr::dynamicCast(seq->container())); +} + +void +Slice::Gen::TypeScriptAliasVisitor::visitDictionary(const DictionaryPtr& dict) +{ + ModulePtr module = ModulePtr::dynamicCast(dict->container()); + addAlias(dict->keyType(), module); + addAlias(dict->valueType(), module); +} + +void +Slice::Gen::TypeScriptAliasVisitor::writeAlias(const UnitPtr& p) +{ + if(!_aliases.empty()) + { + _out << sp; + for(vector<pair<string, string>>::const_iterator i = _aliases.begin(); i != _aliases.end(); ++i) + { + _out << nl << "type " << i->second << " = " << i->first << ";"; + } + } +} + +Slice::Gen::TypeScriptVisitor::TypeScriptVisitor(::IceUtilInternal::Output& out, + const vector<pair<string, string>>& imports) : + JsVisitor(out, imports) +{ +} + +bool +Slice::Gen::TypeScriptVisitor::visitModuleStart(const ModulePtr& p) +{ + UnitPtr unit = UnitPtr::dynamicCast(p->container()); + if(unit) + { + string module = getModuleMetadata(ContainedPtr::dynamicCast(p)); + + _out << sp; + if(module.empty()) + { + _out << nl << "export namespace " << fixId(p->name()) << sb; + } + else + { + _out << nl << "declare module \"" << fixId(module) << "\"" << sb; + _out << nl << "namespace " << fixId(p->name()) << sb; + } + } + else + { + _out << nl << "namespace " << fixId(p->name()) << sb; + } + return true; +} + +void +Slice::Gen::TypeScriptVisitor::visitModuleEnd(const ModulePtr& p) +{ + _out << eb; // namespace end + + if(UnitPtr::dynamicCast(p->container())) + { + string module = getModuleMetadata(ContainedPtr::dynamicCast(p)); + if(!module.empty()) + { + _out << eb; // module end + } + } +} + +bool +Slice::Gen::TypeScriptVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + const string toplevelModule = getModuleMetadata(ContainedPtr::dynamicCast(p)); + const string icePrefix = importPrefix("Ice.", p); + if(p->isDelegate()) + { + // A delegate only has one operation + OperationPtr op = p->allOperations().front(); + CommentPtr comment = op->parseComment(false); + if(comment) + { + writeOpDocSummary(_out, op, comment, OpDocAllParams, true, StringList(), StringList(), comment->returns()); + } + _out << nl << "type " << fixId(p->name()) << " = " << spar; + ParamDeclList paramList = op->parameters(); + for(ParamDeclList::iterator q = paramList.begin(); q != paramList.end(); ++q) + { + ostringstream os; + os << fixId((*q)->name()) << ":"; + if((*q)->isOutParam()) + { + os << icePrefix << getUnqualified("Ice.Holder", p->scope(), icePrefix) << "<"; + } + os << typeToString((*q)->type(), p, imports(), true, false, true); + if((*q)->isOutParam()) + { + os << ">"; + } + _out << os.str(); + } + _out << epar << " => "; + TypePtr ret = op->returnType(); + if(ret) + { + _out << typeToString(ret, p, imports(), true, false, true) << ";"; + } + else + { + _out << "void;"; + } + } + else if(p->isLocal()) + { + const ClassList bases = p->bases(); + const DataMemberList dataMembers = p->dataMembers(); + const DataMemberList allDataMembers = p->allDataMembers(); + + _out << sp; + writeDocSummary(_out, p); + _out << nl; + _out << (p->isInterface() ? "interface" : "class") << " " << fixId(p->name()); + if(!bases.empty() && !bases.front()->isInterface()) + { + const string prefix = importPrefix(ContainedPtr::dynamicCast(bases.front()), p, imports()); + _out << " extends " << prefix << getUnqualified(fixId(bases.front()->scoped()), p->scope(), prefix); + } + _out << sb; + if(!p->isInterface()) + { + _out << nl << "/**"; + _out << nl << " * One-shot constructor to initialize all data members."; + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + CommentPtr comment = (*q)->parseComment(false); + if(comment) + { + _out << nl << " * @param " << fixId((*q)->name()) << " " << getDocSentence(comment->overview()); + } + } + _out << nl << " */"; + _out << nl << "constructor" << spar; + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + _out << (fixId((*q)->name()) + "?:" + typeToString((*q)->type(), p, imports(), true, false, true)); + } + _out << epar << ";"; + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + writeDocSummary(_out, *q); + _out << nl << fixId((*q)->name()) << ":" << typeToString((*q)->type(), p, imports(), true, false, true) + << ";"; + } + } + + OperationList allOperations = p->allOperations(); + for(OperationList::const_iterator q = allOperations.begin(); q != allOperations.end(); ++q) + { + OperationPtr op = *q; + ParamDeclList params = op->parameters(); + ParamDeclList inParams, outParams; + for(ParamDeclList::const_iterator r = params.begin(); r != params.end(); ++r) + { + if((*r)->isOutParam()) + { + outParams.push_back(*r); + } + else + { + inParams.push_back(*r); + } + } + + TypePtr ret = op->returnType(); + bool async = op->hasMetaData("js:async") || op->hasMetaData("async-oneway"); + CommentPtr comment = op->parseComment(false); + if(comment) + { + StringList returns; + if(async) + { + returns.push_back("@returns The asynchronous result object for the invocation."); + } + else if(ret) + { + returns = comment->returns(); + } + writeOpDocSummary(_out, op, comment, OpDocAllParams, true, StringList(), StringList(), returns); + } + + _out << nl << fixId((*q)->name()) << spar; + for(ParamDeclList::const_iterator r = inParams.begin(); r != inParams.end(); r++) + { + _out << (fixId((*r)->name()) + ":" + typeToString((*r)->type(), p, imports(), true, false, true)); + } + + for(ParamDeclList::const_iterator r = outParams.begin(); r != outParams.end(); r++) + { + const string prefix = importPrefix("Ice.Holder", p); + _out << (fixId((*r)->name()) + ":" + prefix + + getUnqualified("Ice.Holder", p->scope(), prefix) + "<" + + typeToString((*r)->type(), p, imports(), true, false, true) + ">"); + } + + _out << epar; + + _out << ":"; + if(async) + { + _out << icePrefix << getUnqualified("Ice.AsyncResultBase", p->scope(), icePrefix) << "<"; + } + + if(ret) + { + _out << typeToString(ret, p, imports(), true, false, true); + } + else + { + _out << "void"; + } + + if (async) + { + _out << ">"; + } + _out << ";"; + } + + if(p->hasMetaData("js:comparable")) + { + _out << nl << "equals(rhs:any):boolean"; + } + _out << eb; + } + else + { + // + // Define servant an proxy types for non local classes + // + _out << sp; + _out << nl << "abstract class " << fixId(p->name() + "Prx") + << " extends " << icePrefix << getUnqualified("Ice.ObjectPrx", p->scope(), icePrefix); + _out << sb; + const OperationList ops = p->allOperations(); + for(OperationList::const_iterator q = ops.begin(); q != ops.end(); ++q) + { + const OperationPtr op = *q; + const ParamDeclList paramList = op->parameters(); + const TypePtr ret = op->returnType(); + ParamDeclList inParams, outParams; + for(ParamDeclList::const_iterator r = paramList.begin(); r != paramList.end(); ++r) + { + if((*r)->isOutParam()) + { + outParams.push_back(*r); + } + else + { + inParams.push_back(*r); + } + } + + const string contextParam = escapeParam(paramList, "context"); + CommentPtr comment = op->parseComment(false); + const string contextDoc = "@param " + contextParam + " The Context map to send with the invocation."; + const string asyncDoc = "The asynchronous result object for the invocation."; + if(comment) + { + StringList postParams, returns; + postParams.push_back(contextDoc); + returns.push_back(asyncDoc); + writeOpDocSummary(_out, op, comment, OpDocInParams, false, StringList(), postParams, returns); + } + _out << nl << fixId((*q)->name()) << spar; + for(ParamDeclList::const_iterator r = inParams.begin(); r != inParams.end(); ++r) + { + _out << (fixId((*r)->name()) + + ((*r)->optional() ? "?" : "") + + ":" + + typeToString((*r)->type(), p, imports(), true, false, true)); + } + _out << "context?:Map<string, string>"; + _out << epar; + + _out << ":" << icePrefix << getUnqualified("Ice.AsyncResult", p->scope(), icePrefix); + if(!ret && outParams.empty()) + { + _out << "<void>"; + } + else if((ret && outParams.empty()) || (!ret && outParams.size() == 1)) + { + TypePtr t = ret ? ret : outParams.front()->type(); + _out << "<" << typeToString(t, p, imports(), true, false, true) << ">"; + } + else + { + _out << "<["; + if(ret) + { + _out << typeToString(ret, p, imports(), true, false, true) << ", "; + } + + for(ParamDeclList::const_iterator i = outParams.begin(); i != outParams.end();) + { + _out << typeToString((*i)->type(), p, imports(), true, false, true); + if(++i != outParams.end()) + { + _out << ", "; + } + } + + _out << "]>"; + } + + _out << ";"; + } + + const string icePrefix = importPrefix("Ice.ObjectPrx", p); + _out << sp; + _out << nl << "/**"; + _out << nl << " * Downcasts a proxy without confirming the target object's type via a remote invocation."; + _out << nl << " * @param prx The target proxy."; + _out << nl << " * @return A proxy with the requested type."; + _out << nl << " */"; + _out << nl << "static uncheckedCast(prx:" << icePrefix + << getUnqualified("Ice.ObjectPrx", p->scope(), icePrefix) << ", " + << "facet?:string):" + << fixId(p->name() + "Prx") << ";"; + _out << nl << "/**"; + _out << nl << " * Downcasts a proxy after confirming the target object's type via a remote invocation."; + _out << nl << " * @param prx The target proxy."; + _out << nl << " * @param facet A facet name."; + _out << nl << " * @param context The context map for the invocation."; + _out << nl << " * @return A proxy with the requested type and facet, or nil if the target proxy is nil or the target"; + _out << nl << " * object does not support the requested type."; + _out << nl << " */"; + _out << nl << "static checkedCast(prx:" << icePrefix + << getUnqualified("Ice.ObjectPrx", p->scope(), icePrefix) << ", " + << "facet?:string, contex?:Map<string, string>):" << icePrefix + << getUnqualified("Ice.AsyncResult", p->scope(), icePrefix) << "<" << fixId(p->name() + "Prx") << ">;"; + _out << eb; + + if(p->isInterface() || !ops.empty()) + { + _out << sp; + _out << nl << "abstract class " << fixId(p->name() + (p->isInterface() ? "" : "Disp")) + << " extends " << icePrefix << getUnqualified("Ice.Object", p->scope(), icePrefix); + _out << sb; + for(OperationList::const_iterator q = ops.begin(); q != ops.end(); ++q) + { + const OperationPtr op = *q; + const ParamDeclList paramList = op->parameters(); + const TypePtr ret = op->returnType(); + ParamDeclList inParams, outParams; + for(ParamDeclList::const_iterator r = paramList.begin(); r != paramList.end(); ++r) + { + if((*r)->isOutParam()) + { + outParams.push_back(*r); + } + else + { + inParams.push_back(*r); + } + } + + const string currentParam = escapeParam(inParams, "current"); + CommentPtr comment = p->parseComment(false); + const string currentDoc = "@param " + currentParam + " The Current object for the invocation."; + const string resultDoc = "The result or a promise like object that will " + "be resolved with the result of the invocation."; + if(comment) + { + StringList postParams, returns; + postParams.push_back(currentDoc); + returns.push_back(resultDoc); + writeOpDocSummary(_out, op, comment, OpDocInParams, false, StringList(), postParams, returns); + } + _out << nl << "abstract " << fixId((*q)->name()) << spar; + for(ParamDeclList::const_iterator r = inParams.begin(); r != inParams.end(); ++r) + { + _out << (fixId((*r)->name()) + ":" + typeToString((*r)->type(), p, imports(), true, false, true)); + } + _out << ("current:" + icePrefix + getUnqualified("Ice.Current", p->scope(), icePrefix)); + _out << epar << ":"; + + if(!ret && outParams.empty()) + { + _out << "PromiseLike<void>|void"; + } + else if((ret && outParams.empty()) || (!ret && outParams.size() == 1)) + { + TypePtr t = ret ? ret : outParams.front()->type(); + string returnType = typeToString(t, p, imports(), true, false, true); + _out << "PromiseLike<" << returnType << ">|" << returnType; + } + else + { + ostringstream os; + if(ret) + { + os << typeToString(ret, p, imports(), true, false, true) << ", "; + } + + for(ParamDeclList::const_iterator i = outParams.begin(); i != outParams.end();) + { + os << typeToString((*i)->type(), p, imports(), true, false, true); + if(++i != outParams.end()) + { + os << ", "; + } + } + _out << "PromiseLike<[" << os.str() << "]>|[" << os.str() << "]"; + } + _out << ";"; + } + _out << nl << "/**"; + _out << nl << " * Obtains the Slice type ID of this type."; + _out << nl << " * @return The return value is always \"" + p->scoped() + "\"."; + _out << nl << " */"; + _out << nl << "static ice_staticId():string;"; + _out << eb; + } + + if(!p->isInterface()) + { + const DataMemberList dataMembers = p->dataMembers(); + const DataMemberList allDataMembers = p->allDataMembers(); + _out << sp; + writeDocSummary(_out, p); + _out << nl << "class " << fixId(p->name()) << " extends "; + const string scope = p->scope(); + const string scoped = p->scoped(); + ClassList bases = p->bases(); + if(!bases.empty() && !bases.front()->isInterface()) + { + ClassDefPtr base = bases.front(); + const string prefix = importPrefix(ContainedPtr::dynamicCast(base), p, imports()); + _out << prefix << getUnqualified(fixId(base->scoped()), p->scope(), prefix); + } + else + { + _out << icePrefix << getUnqualified("Ice.Value", p->scope(), icePrefix); + } + _out << sb; + _out << nl << "/**"; + _out << nl << " * One-shot constructor to initialize all data members."; + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + CommentPtr comment = (*q)->parseComment(false); + if(comment) + { + _out << nl << " * @param " << fixId((*q)->name()) << " " << getDocSentence(comment->overview()); + } + } + _out << nl << " */"; + _out << nl << "constructor" << spar; + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + _out << (fixId((*q)->name()) + "?:" + typeToString((*q)->type(), p, imports(), true, false, true)); + } + _out << epar << ";"; + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + writeDocSummary(_out, *q); + _out << nl << fixId((*q)->name()) << ":" << typeToString((*q)->type(), p, imports(), true, false, true) + << ";"; + } + _out << eb; + } + } + return false; +} + +bool +Slice::Gen::TypeScriptVisitor::visitExceptionStart(const ExceptionPtr& p) +{ + const string name = fixId(p->name()); + const DataMemberList dataMembers = p->dataMembers(); + const DataMemberList allDataMembers = p->allDataMembers(); + const string toplevelModule = getModuleMetadata(ContainedPtr::dynamicCast(p)); + const string icePrefix = importPrefix("Ice.", p); + + ExceptionPtr base = p->base(); + string baseRef; + if(base) + { + const string prefix = importPrefix(ContainedPtr::dynamicCast(base), p, imports()); + baseRef = prefix + getUnqualified(fixId(base->scoped()), p->scope(), prefix); + } + else + { + baseRef = p->isLocal() ? + icePrefix + getUnqualified("Ice.LocalException", p->scope(), icePrefix) : + icePrefix + getUnqualified("Ice.UserException", p->scope(), icePrefix); + } + + _out << sp; + writeDocSummary(_out, p); + _out << nl << "class " << name << " extends " << baseRef << sb; + if(!allDataMembers.empty()) + { + _out << nl << "/**"; + _out << nl << " * One-shot constructor to initialize all data members."; + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + CommentPtr comment = (*q)->parseComment(false); + if(comment) + { + _out << nl << " * @param " << fixId((*q)->name()) << " " << getDocSentence(comment->overview()); + } + } + _out << nl << " */"; + _out << nl << "constructor" << spar; + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + _out << (fixId((*q)->name()) + "?:" + typeToString((*q)->type(), p, imports(), true, false, true)); + } + _out << epar << ";"; + } + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + _out << nl << fixId((*q)->name()) << ":" << typeToString((*q)->type(), p, imports(), true, false, true) << ";"; + } + _out << eb; + return false; +} + +bool +Slice::Gen::TypeScriptVisitor::visitStructStart(const StructPtr& p) +{ + const string icePrefix = importPrefix("Ice.", p); + const string name = fixId(p->name()); + const DataMemberList dataMembers = p->dataMembers(); + const string toplevelModule = getModuleMetadata(ContainedPtr::dynamicCast(p)); + _out << sp; + writeDocSummary(_out, p); + _out << nl << "class " << name << sb; + _out << nl << "constructor" << spar; + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + _out << (fixId((*q)->name()) + "?:" + typeToString((*q)->type(), p, imports(), true, false, true)); + } + _out << epar << ";"; + + _out << nl << "clone():" << name << ";"; + _out << nl << "equals(rhs:any):boolean;"; + + // + // Only generate hashCode if this structure type is a legal dictionary key type. + // + bool containsSequence = false; + bool legalKeyType = Dictionary::legalKeyType(p, containsSequence); + if(legalKeyType) + { + _out << nl << "hashCode():number;"; + } + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + _out << nl << fixId((*q)->name()) << ":" << typeToString((*q)->type(), p, imports(), true, false, true) << ";"; + } + + // + // Streaming API + // + _out << nl << "static write(outs:" << icePrefix << getUnqualified("Ice.OutputStream", p->scope(), icePrefix) + << ", value:" << name << "):void;"; + _out << nl << "static read(ins:" << icePrefix << getUnqualified("Ice.InputStream", p->scope(), icePrefix) << "):" + << name << ";"; + _out << eb; + return false; +} + +void +Slice::Gen::TypeScriptVisitor::visitSequence(const SequencePtr& p) +{ + const string icePrefix = importPrefix("Ice.", p); + const string toplevelModule = getModuleMetadata(ContainedPtr::dynamicCast(p)); + const string name = fixId(p->name()); + _out << sp; + writeDocSummary(_out, p); + _out << nl << "type " << name << " = " << typeToString(p, p, imports(), true, true) << ";"; + + _out << sp; + _out << nl << "class " << fixId(p->name() + "Helper"); + _out << sb; + // + // Streaming API + // + _out << nl << "static write(outs:" << icePrefix << getUnqualified("Ice.OutputStream", p->scope(), icePrefix) + << ", value:" << name << "):void;"; + _out << nl << "static read(ins:" << icePrefix << getUnqualified("Ice.InputStream", p->scope(), icePrefix) << "):" + << name << ";"; + _out << eb; +} + +void +Slice::Gen::TypeScriptVisitor::visitDictionary(const DictionaryPtr& p) +{ + const string icePrefix = importPrefix("Ice.", p); + const string toplevelModule = getModuleMetadata(ContainedPtr::dynamicCast(p)); + const string name = fixId(p->name()); + _out << sp; + writeDocSummary(_out, p); + _out << nl << "class " << name << " extends " << typeToString(p, p, imports(), true, true); + _out << sb; + _out << eb; + + _out << sp; + _out << nl << "class " << fixId(p->name() + "Helper"); + _out << sb; + // + // Streaming API + // + _out << nl << "static write(outs:" << icePrefix << getUnqualified("Ice.OutputStream", p->scope(), icePrefix) + << ", value:" << name << "):void;"; + _out << nl << "static read(ins:" << icePrefix << getUnqualified("Ice.InputStream", p->scope(), icePrefix) << "):" + << name << ";"; + _out << eb; +} + +void +Slice::Gen::TypeScriptVisitor::visitEnum(const EnumPtr& p) +{ + _out << sp; + writeDocSummary(_out, p); + _out << nl << "class " << fixId(p->name()); + _out << sb; + const EnumeratorList enumerators = p->enumerators(); + for(EnumeratorList::const_iterator en = enumerators.begin(); en != enumerators.end(); ++en) + { + writeDocSummary(_out, *en); + _out << nl << "static readonly " << fixId((*en)->name()) << ":" << fixId(p->name()) << ";"; + } + _out << nl; + _out << nl << "static valueOf(value:number):" << fixId(p->name()) << ";"; + _out << nl << "equals(other:any):boolean;"; + _out << nl << "hashCode():number;"; + _out << nl << "toString():string;"; + _out << nl; + _out << nl << "readonly name:string;"; + _out << nl << "readonly value:number;"; + _out << eb; +} + +void +Slice::Gen::TypeScriptVisitor::visitConst(const ConstPtr& p) +{ + const string toplevelModule = getModuleMetadata(p->type()); + _out << sp; + writeDocSummary(_out, p); + _out << nl << "const " << fixId(p->name()) << ":" << typeToString(p->type(), p, imports(), true) << ";"; +} diff --git a/cpp/src/slice2js/Gen.h b/cpp/src/slice2js/Gen.h index a778ba65fd4..f5bc6216a52 100644 --- a/cpp/src/slice2js/Gen.h +++ b/cpp/src/slice2js/Gen.h @@ -19,14 +19,18 @@ class JsVisitor : public JsGenerator, public ParserVisitor { public: - JsVisitor(::IceUtilInternal::Output&); + JsVisitor(::IceUtilInternal::Output&, + const std::vector<std::pair<std::string, std::string>>& imports = + std::vector<std::pair<std::string, std::string>>()); virtual ~JsVisitor(); + std::vector<std::pair<std::string, std::string>> imports() const; + protected: void writeMarshalDataMembers(const DataMemberList&, const DataMemberList&); void writeUnmarshalDataMembers(const DataMemberList&, const DataMemberList&); - void writeInitDataMembers(const DataMemberList&, const std::string&); + void writeInitDataMembers(const DataMemberList&); std::string getValue(const std::string&, const TypePtr&); @@ -36,6 +40,8 @@ protected: void writeDocComment(const ContainedPtr&, const std::string&, const std::string& = ""); ::IceUtilInternal::Output& _out; + + std::vector<std::pair<std::string, std::string>> _imports; }; class Gen : public JsGenerator @@ -44,11 +50,13 @@ public: Gen(const std::string&, const std::vector<std::string>&, - const std::string&); + const std::string&, + bool); Gen(const std::string&, const std::vector<std::string>&, const std::string&, + bool, std::ostream&); ~Gen(); @@ -58,14 +66,14 @@ public: private: - std::ofstream _stdout; IceUtilInternal::Output _out; std::vector<std::string> _includePaths; std::string _fileBase; bool _useStdout; - - void printHeader(); + bool _typeScript; + bool _buildModule; + bool _noModule; class RequireVisitor : public JsVisitor { @@ -95,7 +103,9 @@ private: bool _seenLocalException; bool _seenEnum; bool _seenObjectSeq; + bool _seenObjectProxySeq; bool _seenObjectDict; + bool _seenObjectProxyDict; std::vector<std::string> _includePaths; }; @@ -103,7 +113,7 @@ private: { public: - TypesVisitor(::IceUtilInternal::Output&, std::vector< std::string>, bool); + TypesVisitor(::IceUtilInternal::Output&, std::vector<std::string>, bool); virtual bool visitModuleStart(const ModulePtr&); virtual void visitModuleEnd(const ModulePtr&); @@ -130,12 +140,81 @@ private: ExportVisitor(::IceUtilInternal::Output&, bool, bool); virtual bool visitModuleStart(const ModulePtr&); + private: bool _icejs; bool _es6modules; std::vector<std::string> _exported; }; + + class TypeScriptRequireVisitor : public JsVisitor + { + public: + + TypeScriptRequireVisitor(::IceUtilInternal::Output&); + + virtual bool visitModuleStart(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual bool visitStructStart(const StructPtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual void visitSequence(const SequencePtr&); + virtual void visitDictionary(const DictionaryPtr&); + + void writeRequires(const UnitPtr&); + + private: + + void addImport(const TypePtr&, const ContainedPtr&); + void addImport(const ContainedPtr&, const ContainedPtr&); + void addImport(const std::string&, const std::string&, const std::string&, const std::string&); + + std::string nextImportPrefix(); + + int _nextImport; + std::map<std::string, std::string> _modulePrefix; + }; + + class TypeScriptAliasVisitor : public JsVisitor + { + public: + + TypeScriptAliasVisitor(::IceUtilInternal::Output&); + + virtual bool visitModuleStart(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual bool visitStructStart(const StructPtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual void visitSequence(const SequencePtr&); + virtual void visitDictionary(const DictionaryPtr&); + + void writeAlias(const UnitPtr&); + + private: + + void addAlias(const ExceptionPtr&, const ContainedPtr&); + void addAlias(const TypePtr&, const ContainedPtr&); + void addAlias(const std::string&, const std::string&, const ContainedPtr&); + std::vector<std::pair<std::string, std::string>> _aliases; + }; + + class TypeScriptVisitor : public JsVisitor + { + public: + + TypeScriptVisitor(::IceUtilInternal::Output&, + const std::vector<std::pair<std::string, std::string>>&); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual bool visitStructStart(const StructPtr&); + virtual void visitSequence(const SequencePtr&); + virtual void visitDictionary(const DictionaryPtr&); + virtual void visitEnum(const EnumPtr&); + virtual void visitConst(const ConstPtr&); + }; }; } diff --git a/cpp/src/slice2js/JsUtil.cpp b/cpp/src/slice2js/JsUtil.cpp index b33dfacb9d6..ec262b7c648 100644 --- a/cpp/src/slice2js/JsUtil.cpp +++ b/cpp/src/slice2js/JsUtil.cpp @@ -10,6 +10,7 @@ #include <JsUtil.h> #include <Slice/Util.h> #include <IceUtil/Functional.h> +#include <IceUtil/StringUtil.h> #include <sys/types.h> #include <sys/stat.h> @@ -27,6 +28,64 @@ using namespace Slice; using namespace IceUtil; using namespace IceUtilInternal; +string +Slice::relativePath(const string& p1, const string& p2) +{ + vector<string> tokens1; + vector<string> tokens2; + + splitString(p1, "/\\", tokens1); + splitString(p2, "/\\", tokens2); + + string f1 = tokens1.back(); + string f2 = tokens2.back(); + + tokens1.pop_back(); + tokens2.pop_back(); + + vector<string>::const_iterator i1 = tokens1.begin(); + vector<string>::const_iterator i2 = tokens2.begin(); + + while(i1 != tokens1.end() && i2 != tokens2.end() && *i1 == *i2) + { + i1++; + i2++; + } + + // + // Different volumes, relative path not possible. + // + if(i1 == tokens1.begin() && i2 == tokens2.begin()) + { + return p1; + } + + string newPath; + if(i2 == tokens2.end()) + { + newPath += "./"; + for (; i1 != tokens1.end(); ++i1) + { + newPath += *i1 + "/"; + } + } + else + { + for(size_t i = tokens2.end() - i2; i > 0; i--) + { + newPath += "../"; + } + + for(; i1 != tokens1.end(); ++i1) + { + newPath += *i1 + "/"; + } + } + newPath += f1; + + return newPath; +} + static string lookupKwd(const string& name) { @@ -99,11 +158,71 @@ fixIds(const StringList& ids) return newIds; } +string +Slice::JsGenerator::getModuleMetadata(const TypePtr& type) +{ + static const char* builtinModuleTable[] = + { + "", // byte + "", // bool + "", // short + "", // int + "ice", // long + "", // float + "", // double + "", // string + "ice", // Ice.Value + "ice", // Ice.ObjectPrx + "", // LocalObject + "ice" // Ice.Object + }; + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + return builtinModuleTable[builtin->kind()]; + } + + ProxyPtr proxy = ProxyPtr::dynamicCast(type); + return getModuleMetadata(proxy ? ContainedPtr::dynamicCast(proxy->_class()->definition()) : + ContainedPtr::dynamicCast(type)); +} + +string +Slice::JsGenerator::getModuleMetadata(const ContainedPtr& cont) +{ + // + // Traverse to the top-level module. + // + ModulePtr m; + ContainedPtr p = cont; + while (true) + { + if(ModulePtr::dynamicCast(p)) + { + m = ModulePtr::dynamicCast(p); + } + + ContainerPtr c = p->container(); + p = ContainedPtr::dynamicCast(c); // This cast fails for Unit. + if(!p) + { + break; + } + } + + const string prefix = "js:module:"; + string value; + findMetaData(prefix, m->getMetaData(), value); + return value; +} + bool Slice::JsGenerator::isClassType(const TypePtr& type) { BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); - return (builtin && (builtin->kind() == Builtin::KindObject || builtin->kind() == Builtin::KindValue)) || ClassDeclPtr::dynamicCast(type); + return (builtin && (builtin->kind() == Builtin::KindObject || builtin->kind() == Builtin::KindValue)) || + ClassDeclPtr::dynamicCast(type); } // @@ -146,20 +265,182 @@ Slice::JsGenerator::fixId(const ContainedPtr& cont) } string -Slice::JsGenerator::typeToString(const TypePtr& type) +Slice::JsGenerator::importPrefix(const TypePtr& type, + const ContainedPtr& toplevel, + const vector<pair<string, string>>& imports) +{ + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + return typeToString(type, toplevel, imports, true); + } + else if(ProxyPtr::dynamicCast(type)) + { + ProxyPtr proxy = ProxyPtr::dynamicCast(type); + return importPrefix(ContainedPtr::dynamicCast(proxy->_class()->definition()), toplevel, imports); + } + else if(ContainedPtr::dynamicCast(type)) + { + bool local = false; + if(toplevel) + { + if(ConstructedPtr::dynamicCast(toplevel)) + { + local = ConstructedPtr::dynamicCast(toplevel)->isLocal(); + } + else if(ClassDefPtr::dynamicCast(toplevel)) + { + local = ClassDefPtr::dynamicCast(toplevel)->isLocal(); + } + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + if(cl && cl->isInterface() && !local) + { + return "iceNS0."; + } + else + { + return importPrefix(ContainedPtr::dynamicCast(type), toplevel, imports); + } + } + return ""; +} + +string +Slice::JsGenerator::importPrefix(const ContainedPtr& contained, + const ContainedPtr& toplevel, + const vector<pair<string, string>>& imports) +{ + string m1 = getModuleMetadata(contained); + string m2 = getModuleMetadata(toplevel); + + string p; + + if(m1.empty()) + { + string p1 = contained->definitionContext()->filename(); + string p2 = toplevel->definitionContext()->filename(); + + p = relativePath(p1, p2); + + string::size_type pos = p.rfind('.'); + if (pos != string::npos) + { + p.erase(pos); + } + } + else if(m1 == "ice" && m1 != m2) + { + return "iceNS0."; + } + else if(m1 != m2) + { + p = m1; + } + + if(!p.empty()) + { + for (vector<pair<string, string>>::const_iterator i = imports.begin(); i != imports.end(); ++i) + { + if (i->first == p) + { + return i->second + "."; + } + } + } + + return ""; +} + +bool +Slice::JsGenerator::findMetaData(const string& prefix, const StringList& metaData, string& value) +{ + for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); i++) + { + string s = *i; + if(s.find(prefix) == 0) + { + value = s.substr(prefix.size()); + return true; + } + } + return false; +} + +string +Slice::JsGenerator::importPrefix(const string& type, const ContainedPtr& toplevel) +{ + const string module = getModuleMetadata(toplevel); + return (type.find("Ice.") == 0 && module != "ice") ? "iceNS0." : ""; +} + +string +Slice::JsGenerator::getUnqualified(const string& type, const string& scope, const string& importPrefix) +{ + if(importPrefix.empty()) + { + const string localScope = getLocalScope(scope) + "."; + if(type.find(localScope) == 0) + { + string t = type.substr(localScope.size()); + if(t.find(".") == string::npos) + { + return t; + } + } + } + return type; +} + +string +Slice::JsGenerator::typeToString(const TypePtr& type, + const ContainedPtr& toplevel, + const vector<pair<string, string>>& imports, + bool typescript, + bool definition) { if(!type) { return "void"; } - static const char* builtinTable[] = + bool local = false; + if(toplevel) + { + if(ConstructedPtr::dynamicCast(toplevel)) + { + local = ConstructedPtr::dynamicCast(toplevel)->isLocal(); + } + else if(ClassDefPtr::dynamicCast(toplevel)) + { + local = ClassDefPtr::dynamicCast(toplevel)->isLocal(); + } + } + + static const char* typeScriptBuiltinTable[] = + { + "number", // byte + "boolean", // bool + "number", // short + "number", // int + "Ice.Long", // long + "number", // float + "number", // double + "string", + "Ice.Object", + "Ice.ObjectPrx", + "Object", + "Ice.Value" + }; + + static const char* javaScriptBuiltinTable[] = { "Number", // byte "Boolean", // bool "Number", // short "Number", // int - "Number", // long + "Ice.Long", // long "Number", // float "Number", // double "String", @@ -172,39 +453,186 @@ Slice::JsGenerator::typeToString(const TypePtr& type) BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); if(builtin) { - return builtinTable[builtin->kind()]; + if(typescript) + { + int kind = (!local && builtin->kind() == Builtin::KindObject) ? Builtin::KindValue : builtin->kind(); + ostringstream os; + if(getModuleMetadata(type) == "ice" && getModuleMetadata(toplevel) != "ice") + { + os << "iceNS0."; + } + os << getUnqualified(typeScriptBuiltinTable[kind], toplevel->scope(), "iceNS0."); + return os.str(); + } + else + { + return javaScriptBuiltinTable[builtin->kind()]; + } + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + if(cl) + { + string prefix; + ostringstream os; + if(typescript) + { + if(cl->isInterface() && !local) + { + prefix = importPrefix("Ice.Value", toplevel); + } + else + { + prefix = importPrefix(ContainedPtr::dynamicCast(cl), toplevel, imports); + } + } + os << prefix; + if(!prefix.empty() && typescript) + { + if(cl->isInterface() && !local) + { + os << getUnqualified("Ice.Value", toplevel->scope(), prefix); + } + else + { + os << getUnqualified(fixId(cl->scoped()), toplevel->scope(), prefix); + } + } + else + { + os << fixId(cl->scoped()); + } + return os.str(); } ProxyPtr proxy = ProxyPtr::dynamicCast(type); if(proxy) { - return fixId(proxy->_class()->scoped() + "Prx"); - } + ostringstream os; + string prefix; + if(typescript) + { + prefix = importPrefix(ContainedPtr::dynamicCast(proxy->_class()->definition()), toplevel, imports); + os << prefix; + } - SequencePtr seq = SequencePtr::dynamicCast(type); - if(seq) - { - return typeToString(seq->type()) + "[]"; + if(prefix.empty() && typescript) + { + os << getUnqualified(fixId(proxy->_class()->scoped() + "Prx"), toplevel->scope(), prefix); + } + else + { + os << fixId(proxy->_class()->scoped() + "Prx"); + } + return os.str(); } - DictionaryPtr d = DictionaryPtr::dynamicCast(type); - if(d) + if(!typescript || definition) { - const TypePtr keyType = d->keyType(); - BuiltinPtr b = BuiltinPtr::dynamicCast(keyType); - return ((b && b->kind() == Builtin::KindLong) || StructPtr::dynamicCast(keyType)) ? "Ice.HashMap" : "Map"; + SequencePtr seq = SequencePtr::dynamicCast(type); + if (seq) + { + BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type()); + if (b && b->kind() == Builtin::KindByte) + { + return "Uint8Array"; + } + else + { + return typeToString(seq->type(), toplevel, imports, typescript) + "[]"; + } + } + + DictionaryPtr d = DictionaryPtr::dynamicCast(type); + if(d) + { + const TypePtr keyType = d->keyType(); + BuiltinPtr builtin = BuiltinPtr::dynamicCast(keyType); + ostringstream os; + if ((builtin && builtin->kind() == Builtin::KindLong) || StructPtr::dynamicCast(keyType)) + { + const string prefix = importPrefix("Ice.HashMap", toplevel); + os << prefix << getUnqualified("Ice.HashMap", toplevel->scope(), prefix); + } + else + { + os << "Map"; + } + + if (typescript) + { + os << "<" + << typeToString(keyType, toplevel, imports, true) << ", " + << typeToString(d->valueType(), toplevel, imports, true) << ">"; + } + return os.str(); + } } ContainedPtr contained = ContainedPtr::dynamicCast(type); if(contained) { - return fixId(contained->scoped()); + ostringstream os; + string prefix; + if(typescript) + { + prefix = importPrefix(contained, toplevel, imports); + os << prefix; + } + + if(prefix.empty() && typescript) + { + os << getUnqualified(fixId(contained->scoped()), toplevel->scope(), prefix); + } + else + { + os << fixId(contained->scoped()); + } + return os.str(); } return "???"; } string +Slice::JsGenerator::typeToString(const TypePtr& type, + const ContainedPtr& toplevel, + const std::vector<std::pair<std::string, std::string>>& imports, + bool typeScript, + bool definition, + bool usealias) +{ + string t = typeToString(type, toplevel, imports, typeScript, definition); + if(usealias) + { + string m1 = getModuleMetadata(type); + string m2 = getModuleMetadata(toplevel); + if (!m1.empty() && m1 == m2) + { + // we are using the same module + return t; + } + string p = importPrefix(type, toplevel, imports); + + // + // When using an import prefix we don't need an alias, prefixes use iceNSXX that is reserved + // name prefix + // + string::size_type i = t.find("."); + if(p.empty() && i != string::npos) + { + const string scoped = fixId(toplevel->scoped()) + "."; + if(scoped.find("." + t.substr(0, i + 1)) != string::npos) + { + replace(t.begin(), t.end(), '.', '_'); + t = "iceA_" + t; + } + } + } + return t; +} + +string Slice::JsGenerator::getLocalScope(const string& scope, const string& separator) { assert(!scope.empty()); @@ -222,6 +650,7 @@ Slice::JsGenerator::getLocalScope(const string& scope, const string& separator) { fixedScope = scope; } + if(fixedScope.empty()) { return ""; @@ -243,39 +672,6 @@ Slice::JsGenerator::getLocalScope(const string& scope, const string& separator) return result.str(); } -string -Slice::JsGenerator::getReference(const string& scope, const string& target) -{ - // - // scope and target should be fully-qualified symbols. - // - assert(!scope.empty() && scope[0] == ':' && !target.empty() && target[0] == ':'); - - // - // Check whether the target is in the given scope. - // - if(target.find(scope) == 0) - { - // - // Remove scope from target, but keep the leading "::". - // - const string rem = target.substr(scope.size() - 2); - assert(!rem.empty()); - const StringList ids = fixIds(splitScopedName(rem)); - stringstream result; - result << getLocalScope(scope); - for(StringList::const_iterator i = ids.begin(); i != ids.end(); ++i) - { - result << '.' << *i; - } - return result.str(); - } - else - { - return fixId(target); - } -} - void Slice::JsGenerator::writeMarshalUnmarshalCode(Output &out, const TypePtr& type, diff --git a/cpp/src/slice2js/JsUtil.h b/cpp/src/slice2js/JsUtil.h index 69d9ad6e9c6..e56162a698d 100644 --- a/cpp/src/slice2js/JsUtil.h +++ b/cpp/src/slice2js/JsUtil.h @@ -16,20 +16,46 @@ namespace Slice { +std::string relativePath(const std::string&, const std::string&); + class JsGenerator : private ::IceUtil::noncopyable { public: virtual ~JsGenerator() {}; -protected: - static bool isClassType(const TypePtr&); + static std::string getModuleMetadata(const TypePtr&); + static std::string getModuleMetadata(const ContainedPtr&); static std::string fixId(const std::string&); static std::string fixId(const ContainedPtr&); - static std::string typeToString(const TypePtr&); + static bool findMetaData(const std::string&, const StringList&, std::string&); + static std::string importPrefix(const TypePtr&, + const ContainedPtr&, + const std::vector<std::pair<std::string, std::string>>&); + + static std::string importPrefix(const ContainedPtr&, + const ContainedPtr&, + const std::vector<std::pair<std::string, std::string>>&); + static std::string importPrefix(const std::string&, const ContainedPtr&); + + static std::string getUnqualified(const std::string&, const std::string&, const std::string&); + + static std::string typeToString(const TypePtr&, + const ContainedPtr& = 0, + const std::vector<std::pair<std::string, std::string>>& = + std::vector<std::pair<std::string, std::string>>(), + bool typeScript = false, + bool definition = false); + + static std::string typeToString(const TypePtr&, + const ContainedPtr&, + const std::vector<std::pair<std::string, std::string>>&, + bool typeScript, + bool definition, + bool usealias); + static std::string getLocalScope(const std::string&, const std::string& separator = "."); - static std::string getReference(const std::string&, const std::string&); static std::string getHelper(const TypePtr&); // diff --git a/cpp/src/slice2js/Main.cpp b/cpp/src/slice2js/Main.cpp index 46cf1671d48..062abe2083f 100644 --- a/cpp/src/slice2js/Main.cpp +++ b/cpp/src/slice2js/Main.cpp @@ -75,6 +75,7 @@ usage(const string& n) "--depend-file FILE Write dependencies to FILE instead of standard output.\n" "--validate Validate command line options.\n" "--stdout Print generated code to stdout.\n" + "--typescript Generate TypeScript declaration file\n" "--depend-json Generate dependency information in JSON format.\n" "--ice Allow reserved Ice prefix in Slice identifiers\n" " deprecated: use instead [[\"ice-prefix\"]] metadata.\n" @@ -95,6 +96,7 @@ compile(const vector<string>& argv) opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); opts.addOpt("E"); opts.addOpt("", "stdout"); + opts.addOpt("", "typescript"); opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg); opts.addOpt("", "depend"); opts.addOpt("", "depend-json"); @@ -172,6 +174,8 @@ compile(const vector<string>& argv) bool underscore = opts.isSet("underscore"); + bool typeScript = opts.isSet("typescript"); + if(args.empty()) { consoleErr << argv[0] << ": error: no input file" << endl; @@ -247,16 +251,16 @@ compile(const vector<string>& argv) for(vector<string>::const_iterator i = sources.begin(); i != sources.end();) { - if(depend || dependJSON || dependxml) - { - PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); - FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2JS__"); + PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); + FILE* cppHandle = icecpp->preprocess(true, "-D__SLICE2JS__"); - if(cppHandle == 0) - { - return EXIT_FAILURE; - } + if(cppHandle == 0) + { + return EXIT_FAILURE; + } + if(depend || dependJSON || dependxml) + { UnitPtr u = Unit::createUnit(false, false, ice, underscore); int parseStatus = u->parse(*i, cppHandle, debug); u->destroy(); @@ -292,13 +296,6 @@ compile(const vector<string>& argv) } else { - PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); - FILE* cppHandle = icecpp->preprocess(true, "-D__SLICE2JS__"); - - if(cppHandle == 0) - { - return EXIT_FAILURE; - } if(preprocess) { char buf[4096]; @@ -335,12 +332,12 @@ compile(const vector<string>& argv) { if(useStdout) { - Gen gen(icecpp->getBaseName(), includePaths, output, cout); + Gen gen(icecpp->getBaseName(), includePaths, output, typeScript, cout); gen.generate(p); } else { - Gen gen(icecpp->getBaseName(), includePaths, output); + Gen gen(icecpp->getBaseName(), includePaths, output, typeScript); gen.generate(p); } } diff --git a/js/.gitignore b/js/.gitignore index c3861572228..6b094f9429f 100644 --- a/js/.gitignore +++ b/js/.gitignore @@ -16,3 +16,9 @@ src/es5/IceMX src/es5/IceSSL src/es5/IceStorm test/es5 + +# +# Typescript test generated files +# +test/ts/**/*.js +test/ts/**/*.d.ts diff --git a/js/gulp/bundle.js b/js/gulp/bundle.js index c2210e9a224..31459415cc3 100644 --- a/js/gulp/bundle.js +++ b/js/gulp/bundle.js @@ -326,12 +326,14 @@ function bundle(args) sb.write(preamble); sb.write(" var root = typeof(window) !== \"undefined\" ? window : typeof(global) !== \"undefined\" ? global : typeof(self) !== \"undefined\" ? self : {};\n"); - lineOffset += 3; + sb.write(" var ice = root.ice || {};\n"); + lineOffset += 4; args.modules.forEach( function(m){ sb.write(" root." + m + " = root." + m + " || {};\n"); lineOffset++; - + sb.write(" ice." + m + " = root." + m + ";\n"); + lineOffset++; if(m == "Ice") { sb.write(" Ice.Slice = Ice.Slice || {};\n"); diff --git a/js/gulp/ts-bundle.js b/js/gulp/ts-bundle.js new file mode 100644 index 00000000000..922fd792c62 --- /dev/null +++ b/js/gulp/ts-bundle.js @@ -0,0 +1,189 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +const fs = require("fs"); +const ts = require("typescript"); +const path = require("path"); +const os = require("os"); +const gutil = require("gulp-util"); +const PluginError = gutil.PluginError; +const PLUGIN_NAME = "gulp-ts-bundle"; +const through = require("through2"); + + +const namespaces = [""]; +const definitions = new Map(); +definitions.set("", ""); +let namespace = ""; + +const copyrightHeader = `// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// **********************************************************************`; + +function visitFile(file, data) +{ + visitNode(ts.createSourceFile(file, data, ts.ScriptTarget.ES7, true)); +} + +function exportDefinition(node) +{ + let out = definitions.get(namespace); + const data = node.getText().trim(); + if(data != "") + { + out += os.EOL; + if(node.jsDoc) + { + out += "/**" + os.EOL; + for(const l of node.jsDoc[0].comment.split(os.EOL)) + { + out += " * " + l + os.EOL; + } + out += " */" + os.EOL; + } + if(data.indexOf("export ") == -1) + { + out += "export "; + } + out += data; + out += os.EOL; + definitions.set(namespace, out); + } +} + +function visitNode(node, parent) +{ + switch(node.kind) + { + case ts.SyntaxKind.SourceFile: + { + + for(const s of node.referencedFiles) + { + const f = path.normalize(path.join(path.dirname(node.fileName), s.fileName)); + visitFile(f, fs.readFileSync(f).toString()); + } + if(node.referencedFiles == 0) + { + ts.forEachChild(node, child => + { + visitNode(child, node); + }); + } + break; + } + case ts.SyntaxKind.ModuleDeclaration: + { + if(node.modifiers && node.modifiers.some(n => n.kind == ts.SyntaxKind.DeclareKeyword)) + { + if(node.name.text == "ice") + { + ts.forEachChild(node.body, child => + { + visitNode(child, node); + }); + } + } + else if((parent.modifiers && parent.modifiers.some(n => n.kind == ts.SyntaxKind.DeclareKeyword))) + { + namespace = node.name.text; + if(namespaces.indexOf(namespace) == -1) + { + namespaces.push(namespace); + definitions.set(namespace, ""); + } + ts.forEachChild(node.body, child => + { + visitNode(child, node); + }); + namespace = ""; + } + else + { + exportDefinition(node); + } + break; + } + case ts.SyntaxKind.ClassDeclaration: + { + exportDefinition(node); + break; + } + default: + { + exportDefinition(node); + break; + } + } +} + +class StringBuffer +{ + constructor() + { + // Use new Buffer.alloc(string, encoding) if available, Buffer constructor are deprecated. + this.buffer = typeof Buffer.alloc === 'function' ? Buffer.alloc(0) : new Buffer(0); + } + + writeLine(data) + { + data += os.EOL; + // Use new Buffer.from(string, encoding) if Buffer.alloc is avilable, Buffer constructors are deprecated. + // NOTE: we don't check for Buffer.from which already exists but only accepts array. + this.buffer = Buffer.concat([this.buffer, + typeof Buffer.alloc === 'function' ? Buffer.from(data, "utf8") : + new Buffer(data, "utf8")]); + } +} + +function bundle(args) +{ + return through.obj( + function(file, enc, cb) + { + if(file.isNull()) + { + return; + } + + if(file.isStream()) + { + return this.emit('error', new PluginError(PLUGIN_NAME, 'Streaming not supported')); + } + + visitFile(file.path, file.contents.toString()); + const b = new StringBuffer(); + b.writeLine(copyrightHeader); + b.writeLine(""); + b.writeLine(`export as namespace ice;`); + for(const name of namespaces) + { + if(name == "") + { + b.writeLine(definitions.get(name)); + } + else + { + b.writeLine(`export namespace ${name}`); + b.writeLine("{"); + b.writeLine(definitions.get(name)); + b.writeLine("}"); + } + } + file.contents = b.buffer; + cb(null, file); + }); +} + +module.exports = bundle; diff --git a/js/gulpfile.js b/js/gulpfile.js index 42418a6cb48..cbaf1f55196 100644 --- a/js/gulpfile.js +++ b/js/gulpfile.js @@ -9,6 +9,7 @@ var babel = require("gulp-babel"), bundle = require("./gulp/bundle"), + tsbundle = require("./gulp/ts-bundle"), concat = require('gulp-concat'), del = require("del"), extreplace = require("gulp-ext-replace"), @@ -16,16 +17,14 @@ var babel = require("gulp-babel"), gulp = require("gulp"), gzip = require('gulp-gzip'), iceBuilder = require('gulp-ice-builder'), - jshint = require('gulp-jshint'), - cleancss = require('gulp-clean-css'), newer = require('gulp-newer'), - open = require("gulp-open"), path = require('path'), paths = require('vinyl-paths'), pump = require('pump'), rollup = require("rollup").rollup, sourcemaps = require('gulp-sourcemaps'), - spawn = require("child_process").spawn, + tsc = require('gulp-typescript'), + tsformat = require('gulp-typescript-formatter'), uglify = require('gulp-uglifyes'); var sliceDir = path.resolve(__dirname, '..', 'slice'); @@ -160,7 +159,7 @@ gulp.task("common:clean", [], "test/es5/Common/TestHelper.js"]); }); -gulp.task("import:slice2js", [], +gulp.task("import:slice2js", ["dist"], function(cb){ pump([ gulp.src(["test/Ice/import/Demo/Point.ice", @@ -238,12 +237,111 @@ gulp.task("test", tests.map(testBabelTask).concat( gulp.task("test:clean", tests.map(testBabelCleanTask).concat(["common:clean", "import:clean"])); +// TypeScript tests +var tstests = [ + "test/ts/Ice/acm", + "test/ts/Ice/adapterDeactivation", + "test/ts/Ice/ami", + "test/ts/Ice/binding", + "test/ts/Ice/defaultValue", + "test/ts/Ice/enums", + "test/ts/Ice/exceptions", + "test/ts/Ice/facets", + "test/ts/Ice/hold", + "test/ts/Ice/info", + "test/ts/Ice/inheritance", + "test/ts/Ice/location", + "test/ts/Ice/number", + "test/ts/Ice/objects", + "test/ts/Ice/operations", + "test/ts/Ice/optional", + "test/ts/Ice/properties", + "test/ts/Ice/proxy", + "test/ts/Ice/retry", + "test/ts/Ice/scope", + "test/ts/Ice/servantLocator", + "test/ts/Ice/slicing/exceptions", + "test/ts/Ice/slicing/objects", + "test/ts/Ice/stream", + "test/ts/Ice/timeout", + "test/ts/Glacier2/router", + "test/ts/Slice/macros" +]; + +function testTypeScriptSliceCompileJsTask(name) { return testTask(name) + ":ts:slice-compile-js"; } +function testTypeScriptSliceCompileTsTask(name) { return testTask(name) + ":ts:slice-compile-ts"; } +function testTypeScriptCompileTask(name) { return testTask(name) + ":ts:compile"; } + +function testTypeScriptSliceJsCleanTask(name) { return testTask(name) + ":ts:slice:js-clean"; } +function testTypeScriptSliceTsCleanTask(name) { return testTask(name) + ":ts:slice:ts-clean"; } +function testTypeScriptCleanTask(name) { return testTask(name) + ":ts:clean"; } + +tstests.forEach((name) => + { + gulp.task(testTypeScriptSliceCompileJsTask(name), [], + function(cb){ + pump([ + gulp.src(path.join(name, "*.ice")), + slice2js({include:[name], dest: name}), + gulp.dest(name) + ], cb); + }); + + gulp.task(testTypeScriptSliceCompileTsTask(name), [], + function(cb){ + pump([ + gulp.src(path.join(name, "*.ice")), + slice2js({include:[name], dest:name, args: ["--typescript"]}), + gulp.dest(name) + ], cb); + }); + + gulp.task(testTypeScriptCompileTask(name), + [ + testTypeScriptSliceCompileJsTask(name), + testTypeScriptSliceCompileTsTask(name), + ].concat(useBinDist ? [] : ["ice-module"]), + function(cb){ + pump([ + gulp.src(path.join(name, "*.ts")), + tsc( + { + lib: ["dom", "es2017"], + target: "es2017", + module: "commonjs", + noImplicitAny:true + }), + gulp.dest(name) + ], cb); + }); + + gulp.task(testTypeScriptSliceJsCleanTask(name), [], + function(cb){ + pump([gulp.src(path.join(name, "*.ice")), extreplace(".js"), paths(del)], cb); + }); + + gulp.task(testTypeScriptSliceTsCleanTask(name), [], + function(cb){ + pump([gulp.src(path.join(name, "*.ice")), extreplace(".d.ts"), paths(del)], cb); + }); + + gulp.task(testTypeScriptCleanTask(name), + [testTypeScriptSliceJsCleanTask(name), testTypeScriptSliceTsCleanTask(name)], + function(cb){ + pump([gulp.src(path.join(name, "*.ts")), extreplace(".js"), paths(del)], cb); + }); + }); + +gulp.task("test:ts", tstests.map(testTypeScriptCompileTask)); +gulp.task("test:ts:clean", tstests.map(testTypeScriptCleanTask)); + // // Tasks to build IceJS Distribution // var root = path.resolve(path.join('__dirname', '..')); var libs = ["Ice", "Glacier2", "IceStorm", "IceGrid"]; +function generateTypeScriptTask(name) { return name.toLowerCase() + ":generate-typescript"; } function generateTask(name){ return name.toLowerCase() + ":generate"; } function libTask(name){ return name.toLowerCase() + ":lib"; } function minLibTask(name){ return name.toLowerCase() + ":lib-min"; } @@ -321,13 +419,22 @@ libs.forEach( function(lib){ var sources = JSON.parse(fs.readFileSync(path.join(srcDir(lib), "sources.json"), {encoding: "utf8"})); - gulp.task(generateTask(lib), - function(cb){ - pump([ - gulp.src(sources.slice.map(sliceFile)), - slice2js({dest: srcDir(lib)}), - gulp.dest(srcDir(lib))], cb); - }); + gulp.task(generateTypeScriptTask(lib), + function(cb){ + var sliceSources = sources.typescriptSlice || sources.slice; + pump([ + gulp.src(sliceSources.map(sliceFile)), + slice2js({dest: srcDir(lib), args: ["--typescript"]}), + gulp.dest(srcDir(lib))], cb); + }); + + gulp.task(generateTask(lib), [generateTypeScriptTask(lib)], + function(cb){ + pump([ + gulp.src(sources.slice.map(sliceFile)), + slice2js({dest: srcDir(lib)}), + gulp.dest(srcDir(lib))], cb); + }); gulp.task(libTask(lib), [generateTask(lib)], function(cb){ @@ -398,15 +505,30 @@ libs.forEach( gulp.task(libCleanTask(lib), [], function(){ del(libGeneratedFiles(lib, sources)); }); }); +gulp.task("ts:bundle", libs.map(generateTypeScriptTask), + function(cb){ + pump([ + gulp.src("./src/index.d.ts"), + tsbundle(), + tsformat({}), + gulp.dest("lib")], cb); + }); + +gulp.task("ts:bundle:clean", [], + function(){ + del("./lib/index.d.ts"); + }); + gulp.task("dist", useBinDist ? [] : libs.map(libTask).concat(libs.map(minLibTask)) .concat(libs.map(babelMinLibTask)) - .concat(libs.map(babelTask))); + .concat(libs.map(babelTask)) + .concat(["ts:bundle"])); -gulp.task("dist:clean", libs.map(libCleanTask)); +gulp.task("dist:clean", libs.map(libCleanTask).concat("ts:bundle:clean")); -var buildDepends = ["dist", "test"]; -var cleanDepends = ["test:clean", "common:clean"]; +var buildDepends = ["dist", "test", "test:ts"]; +var cleanDepends = ["test:clean", "test:ts:clean", "common:clean"]; if(!useBinDist) { diff --git a/js/package-lock.json b/js/package-lock.json index 310e9d60b12..3b1d7168be6 100644 --- a/js/package-lock.json +++ b/js/package-lock.json @@ -27,6 +27,21 @@ "through2": "2.0.3" } }, + "@types/commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==", + "dev": true, + "requires": { + "commander": "2.15.1" + } + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -39,6 +54,19 @@ "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", @@ -116,6 +144,15 @@ "normalize-path": "2.1.1" } }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "requires": { + "buffer-equal": "1.0.0" + } + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -196,6 +233,22 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "2.1.2" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -208,6 +261,13 @@ "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", "dev": true }, + "async": { + "version": "1.0.0", + "resolved": "http://registry.npmjs.org/async/-/async-1.0.0.tgz", + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=", + "dev": true, + "optional": true + }, "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", @@ -215,12 +275,33 @@ "dev": true, "optional": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true, + "optional": true + }, "atob": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.0.tgz", "integrity": "sha512-SuiKH8vbsOyCALjA/+EINmt/Kdl+TQPrtFgW7XZZcwtryFu9e5kQoX3bjCW6mIvGH1fbeAZZuvwGR5IlBRznGw==", "dev": true }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true, + "optional": true + }, "babel-cli": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", @@ -861,6 +942,16 @@ } } }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, "beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", @@ -896,6 +987,19 @@ "repeat-element": "1.1.2" } }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true, + "optional": true + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -949,6 +1053,13 @@ "map-obj": "1.0.1" } }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true, + "optional": true + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -1009,12 +1120,20 @@ } }, "clean-css": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz", - "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", "dev": true, "requires": { - "source-map": "0.5.7" + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "cli": { @@ -1056,6 +1175,13 @@ "readable-stream": "2.3.6" } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "optional": true + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -1078,12 +1204,28 @@ "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", "dev": true }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "optional": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, + "commandpost": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.3.0.tgz", + "integrity": "sha512-T62tyrmYTkaRDbV2z1k2yXTyxk0cFptXYwo1cUbnfHtp7ThLgQ9/90jG1Ym5WLZgFhvOTaHA5VSARWJ9URpLDw==", + "dev": true + }, "commoner": { "version": "0.10.8", "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", @@ -1128,6 +1270,19 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "optional": true, + "requires": { + "buffer-from": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" + } + }, "concat-with-sourcemaps": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.5.tgz", @@ -1234,6 +1389,13 @@ "array-find-index": "1.0.2" } }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", + "dev": true, + "optional": true + }, "d": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", @@ -1243,6 +1405,16 @@ "es5-ext": "0.10.42" } }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + } + }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", @@ -1307,6 +1479,15 @@ "clone": "1.0.4" } }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "1.0.12" + } + }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -1381,6 +1562,12 @@ "rimraf": "2.6.2" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, "deprecated": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", @@ -1502,6 +1689,72 @@ } } }, + "duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", + "dev": true, + "requires": { + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "stream-shift": "1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "1.4.0" + } + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1", + "safer-buffer": "2.1.2" + } + }, + "editorconfig": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.0.tgz", + "integrity": "sha512-j7JBoj/bpNzvoTQylfRZSc85MlLNKWQiq5y6gwKhmqD2h1eZ+tH4AXbkhEJD468gjDna/XMx2YtSkCxBRX9OGg==", + "dev": true, + "requires": { + "@types/commander": "2.12.2", + "@types/semver": "5.5.0", + "commander": "2.15.1", + "lru-cache": "4.1.3", + "semver": "5.5.1", + "sigmund": "1.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "dev": true + } + } + }, "end-of-stream": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", @@ -1559,6 +1812,13 @@ "es6-symbol": "3.1.1" } }, + "es6-promise": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", + "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", + "dev": true, + "optional": true + }, "es6-symbol": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", @@ -1687,6 +1947,32 @@ "is-extglob": "1.0.0" } }, + "extract-zip": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", + "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "dev": true, + "optional": true, + "requires": { + "concat-stream": "1.6.2", + "debug": "2.6.9", + "mkdirp": "0.5.1", + "yauzl": "2.4.1" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "dev": true, + "optional": true + }, "fancy-log": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", @@ -1698,6 +1984,30 @@ "time-stamp": "1.1.0" } }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true, + "optional": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true, + "optional": true + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "optional": true, + "requires": { + "pend": "1.2.0" + } + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -2063,6 +2373,16 @@ "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", "dev": true }, + "flush-write-stream": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", + "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.6" + } + }, "follow-redirects": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz", @@ -2099,6 +2419,37 @@ "for-in": "1.0.2" } }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.20" + }, + "dependencies": { + "combined-stream": { + "version": "1.0.6", + "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "dev": true, + "optional": true, + "requires": { + "delayed-stream": "1.0.0" + } + } + } + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -2108,6 +2459,28 @@ "map-cache": "0.2.2" } }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1" + } + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "through2": "2.0.3" + } + }, "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -2120,6 +2493,12 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "gaze": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", @@ -2141,6 +2520,16 @@ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + } + }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", @@ -2419,12 +2808,12 @@ } }, "gulp-clean-css": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-3.9.3.tgz", - "integrity": "sha512-mw5Qrio7W3rvswmVlZ7eaxOhBIp6zQMBFLgcHoi/xbOtaKT5zmElkHt8mvbRre7fMt5eLgppIkW+j9Cm+O/UqQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-3.10.0.tgz", + "integrity": "sha512-7Isf9Y690o/Q5MVjEylH1H7L8WeZ89woW7DnhD5unTintOdZb67KdOayRgp9trUFo+f9UyJtuatV42e/+kghPg==", "dev": true, "requires": { - "clean-css": "4.1.11", + "clean-css": "4.2.1", "plugin-error": "1.0.1", "through2": "2.0.3", "vinyl-sourcemaps-apply": "0.2.1" @@ -2499,9 +2888,9 @@ } }, "gulp-ice-builder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gulp-ice-builder/-/gulp-ice-builder-2.0.1.tgz", - "integrity": "sha512-xLTCvST+B63mhCgUk8nHPcZMoXfkpNc/bBlzQyZsY9hal5yfIc4OhxNolNsZT708T0dME9zyscyam5q74tf1XQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gulp-ice-builder/-/gulp-ice-builder-2.0.2.tgz", + "integrity": "sha512-Av9RCpN82PPTChDAy/WsDUSFCvPMqPKk61JYapMPqJVGeQS9vlHGmSjtpL50Ms2RnRqxuIeG0VLswImtgHhxkQ==", "dev": true, "requires": { "fancy-log": "1.3.2", @@ -2685,6 +3074,163 @@ } } }, + "gulp-typescript": { + "version": "5.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-5.0.0-alpha.3.tgz", + "integrity": "sha512-6iSBjqBXAUqRsLUh/9XtlOnSzpPMbLrr5rqGj4UPLtGpDwFHW/fVTuRgv6LAWiKesLIUDDM0ourxvcpu2trecQ==", + "dev": true, + "requires": { + "ansi-colors": "2.0.5", + "plugin-error": "1.0.1", + "source-map": "0.7.3", + "through2": "2.0.3", + "vinyl": "2.2.0", + "vinyl-fs": "3.0.3" + }, + "dependencies": { + "ansi-colors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-2.0.5.tgz", + "integrity": "sha512-yAdfUZ+c2wetVNIFsNRn44THW+Lty6S5TwMpUfLA/UaGhiXbBv/F8E60/1hMLd0cnF/CDoWH8vzVaI5bAcHCjw==", + "dev": true + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "3.0.1", + "glob": "7.1.2", + "glob-parent": "3.1.0", + "is-negated-glob": "1.0.0", + "ordered-read-streams": "1.0.1", + "pumpify": "1.5.1", + "readable-stream": "2.3.6", + "remove-trailing-separator": "1.1.0", + "to-absolute-glob": "2.0.2", + "unique-stream": "2.2.1" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "2.3.6" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, + "requires": { + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" + } + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "2.1.2", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.1.2", + "remove-trailing-separator": "1.1.0", + "replace-ext": "1.0.0" + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "1.0.0", + "glob-stream": "6.1.0", + "graceful-fs": "4.1.11", + "is-valid-glob": "1.0.0", + "lazystream": "1.0.0", + "lead": "1.0.0", + "object.assign": "4.1.0", + "pumpify": "1.5.1", + "readable-stream": "2.3.6", + "remove-bom-buffer": "3.0.0", + "remove-bom-stream": "1.2.0", + "resolve-options": "1.1.0", + "through2": "2.0.3", + "to-through": "2.0.0", + "value-or-function": "3.0.0", + "vinyl": "2.2.0", + "vinyl-sourcemap": "1.1.0" + } + } + } + }, + "gulp-typescript-formatter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/gulp-typescript-formatter/-/gulp-typescript-formatter-0.1.3.tgz", + "integrity": "sha1-34CFez1Eiqh1PUmNRgI89jzw0AA=", + "dev": true, + "requires": { + "gulp-util": "3.0.8", + "through2": "2.0.3" + } + }, "gulp-uglifyes": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/gulp-uglifyes/-/gulp-uglifyes-0.1.3.tgz", @@ -2745,6 +3291,24 @@ "glogg": "1.0.1" } }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "optional": true + }, + "har-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "dev": true, + "optional": true, + "requires": { + "ajv": "5.5.2", + "har-schema": "2.0.0" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -2763,6 +3327,12 @@ "sparkles": "1.0.0" } }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -2823,6 +3393,17 @@ } } }, + "hasha": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", + "dev": true, + "optional": true, + "requires": { + "is-stream": "1.1.0", + "pinkie-promise": "2.0.1" + } + }, "hogan.js": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", @@ -2916,6 +3497,18 @@ "requires-port": "1.0.0" } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.2" + } + }, "iconv-lite": { "version": "0.4.21", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", @@ -3096,6 +3689,12 @@ "is-extglob": "1.0.0" } }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", @@ -3193,6 +3792,20 @@ "is-unc-path": "1.0.0" } }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "optional": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true, + "optional": true + }, "is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", @@ -3208,6 +3821,12 @@ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -3236,12 +3855,25 @@ "isarray": "1.0.0" } }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, "jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", @@ -3249,35 +3881,89 @@ "dev": true }, "jshint": { - "version": "2.9.5", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", - "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.6.tgz", + "integrity": "sha512-KO9SIAKTlJQOM4lE64GQUtGBRpTOuvbrRrSZw3AhUxMNG266nX9hK2cKA4SBhXOj0irJGyNyGSLT62HGOVDEOA==", "dev": true, "requires": { "cli": "1.0.1", "console-browserify": "1.1.0", "exit": "0.1.2", "htmlparser2": "3.8.3", - "lodash": "3.7.0", + "lodash": "4.17.10", "minimatch": "3.0.4", + "phantom": "4.0.12", + "phantomjs-prebuilt": "2.1.16", "shelljs": "0.3.0", - "strip-json-comments": "1.0.4" - }, - "dependencies": { - "lodash": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", - "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", - "dev": true - } + "strip-json-comments": "1.0.4", + "unicode-5.2.0": "0.7.5" + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true, + "optional": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" } }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true, + "optional": true + }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, + "jsonfile": { + "version": "2.4.0", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, "kew": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", @@ -3293,6 +3979,34 @@ "is-buffer": "1.1.6" } }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "2.3.6" + } + }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "requires": { + "flush-write-stream": "1.0.3" + } + }, "liftoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", @@ -3618,6 +4332,21 @@ "regex-cache": "0.4.4" } }, + "mime-db": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==", + "dev": true + }, + "mime-types": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", + "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "dev": true, + "requires": { + "mime-db": "1.36.0" + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -3760,12 +4489,28 @@ "remove-trailing-separator": "1.1.0" } }, + "now-and-later": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz", + "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "optional": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3794,6 +4539,12 @@ } } }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -3811,6 +4562,18 @@ } } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "1.1.3", + "function-bind": "1.1.1", + "has-symbols": "1.0.0", + "object-keys": "1.0.12" + } + }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -3989,6 +4752,12 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -4042,6 +4811,50 @@ "pinkie-promise": "2.0.1" } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true, + "optional": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true, + "optional": true + }, + "phantom": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/phantom/-/phantom-4.0.12.tgz", + "integrity": "sha512-Tz82XhtPmwCk1FFPmecy7yRGZG2btpzY2KI9fcoPT7zT9det0CcMyfBFPp1S8DqzsnQnm8ZYEfdy528mwVtksA==", + "dev": true, + "optional": true, + "requires": { + "phantomjs-prebuilt": "2.1.16", + "split": "1.0.1", + "winston": "2.4.4" + } + }, + "phantomjs-prebuilt": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", + "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", + "dev": true, + "optional": true, + "requires": { + "es6-promise": "4.2.5", + "extract-zip": "1.6.7", + "fs-extra": "1.0.0", + "hasha": "2.2.0", + "kew": "0.7.0", + "progress": "1.1.8", + "request": "2.88.0", + "request-progress": "2.0.1", + "which": "1.3.0" + } + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -4136,6 +4949,26 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true, + "optional": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "dev": true, + "optional": true + }, "pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", @@ -4157,12 +4990,58 @@ } } }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "3.6.0", + "inherits": "2.0.3", + "pump": "2.0.1" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + } + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true, + "optional": true + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "optional": true + }, "randomatic": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", @@ -4436,6 +5315,27 @@ } } }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "requires": { + "is-buffer": "1.1.6", + "is-utf8": "0.2.1" + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "requires": { + "remove-bom-buffer": "3.0.0", + "safe-buffer": "5.1.2", + "through2": "2.0.3" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -4469,6 +5369,54 @@ "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", "dev": true }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.8.0", + "caseless": "0.12.0", + "combined-stream": "1.0.7", + "extend": "3.0.2", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.1.0", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.20", + "oauth-sign": "0.9.0", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.4.3", + "tunnel-agent": "0.6.0", + "uuid": "3.3.2" + }, + "dependencies": { + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "optional": true + } + } + }, + "request-progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", + "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", + "dev": true, + "optional": true, + "requires": { + "throttleit": "1.0.0" + } + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -4494,6 +5442,15 @@ "global-modules": "1.0.0" } }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "requires": { + "value-or-function": "3.0.0" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -4791,6 +5748,16 @@ "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "optional": true, + "requires": { + "through": "2.3.8" + } + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -4800,6 +5767,31 @@ "extend-shallow": "3.0.2" } }, + "sshpk": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "dev": true, + "optional": true, + "requires": { + "asn1": "0.2.4", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.2", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.2", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "safer-buffer": "2.1.2", + "tweetnacl": "0.14.5" + } + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true, + "optional": true + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -4827,6 +5819,12 @@ "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==", "dev": true }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, "stream-to-array": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", @@ -4891,6 +5889,13 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true, + "optional": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -4907,6 +5912,16 @@ "xtend": "4.0.1" } }, + "through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "dev": true, + "requires": { + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, "tildify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", @@ -4932,6 +5947,16 @@ "next-tick": "1.0.0" } }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "1.0.0", + "is-negated-glob": "1.0.0" + } + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -4980,6 +6005,26 @@ } } }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "requires": { + "through2": "2.0.3" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "optional": true, + "requires": { + "psl": "1.1.29", + "punycode": "1.4.1" + } + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -4992,6 +6037,46 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true, + "optional": true + }, + "typescript": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.1.tgz", + "integrity": "sha512-Veu0w4dTc/9wlWNf2jeRInNodKlcdLgemvPsrNpfu5Pq39sgfFjvIIgTsvUHCoLBnMhPoUA+tFxsXjU6VexVRQ==", + "dev": true + }, + "typescript-formatter": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.2.2.tgz", + "integrity": "sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==", + "dev": true, + "requires": { + "commandpost": "1.3.0", + "editorconfig": "0.15.0" + } + }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -5022,6 +6107,12 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, + "unicode-5.2.0": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/unicode-5.2.0/-/unicode-5.2.0-0.7.5.tgz", + "integrity": "sha512-KVGLW1Bri30x00yv4HNM8kBxoqFXr0Sbo55735nvrlsx4PYBZol3UtoWgO492fSwmsetzPEZzy73rbU8OGXJcA==", + "dev": true + }, "union-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", @@ -5144,6 +6235,13 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true, + "optional": true + }, "v8flags": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", @@ -5163,6 +6261,24 @@ "spdx-expression-parse": "3.0.0" } }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, "vinyl": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", @@ -5260,6 +6376,55 @@ "through2": "2.0.3" } }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "requires": { + "append-buffer": "1.0.2", + "convert-source-map": "1.5.1", + "graceful-fs": "4.1.11", + "normalize-path": "2.1.1", + "now-and-later": "2.0.0", + "remove-bom-buffer": "3.0.0", + "vinyl": "2.2.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "2.1.2", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.1.2", + "remove-trailing-separator": "1.1.0", + "replace-ext": "1.0.0" + } + } + } + }, "vinyl-sourcemaps-apply": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", @@ -5278,6 +6443,30 @@ "isexe": "2.0.0" } }, + "winston": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.4.tgz", + "integrity": "sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q==", + "dev": true, + "optional": true, + "requires": { + "async": "1.0.0", + "colors": "1.0.3", + "cycle": "1.0.3", + "eyes": "0.1.8", + "isstream": "0.1.2", + "stack-trace": "0.0.10" + }, + "dependencies": { + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true, + "optional": true + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -5289,6 +6478,22 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "optional": true, + "requires": { + "fd-slicer": "1.0.1" + } } } } diff --git a/js/package.json b/js/package.json index b90ce36f278..49667bb8813 100644 --- a/js/package.json +++ b/js/package.json @@ -14,6 +14,7 @@ "rpc" ], "main": "src/index.js", + "types": "src/index.d.ts", "devDependencies": { "babel-cli": "^6.26.0", "babel-plugin-rewrite-require": "^1.14.5", @@ -25,25 +26,29 @@ "esprima": "^3.1.3", "gulp": "^3.9.1", "gulp-babel": "^6.1.3", - "gulp-clean-css": "^3.9.3", + "gulp-clean-css": "^3.10.0", "gulp-concat": "^2.6.1", "gulp-ext-replace": "^0.3.0", "gulp-gzip": "^1.4.2", - "gulp-ice-builder": "^2.0.0", + "gulp-ice-builder": "^2.0.2", "gulp-jshint": "^2.1.0", "gulp-newer": "^1.4.0", "gulp-open": "^2.1.0", "gulp-sourcemaps": "^2.6.4", + "gulp-typescript": "^5.0.0-alpha.3", + "gulp-typescript-formatter": "^0.1.3", "gulp-uglifyes": "^0.1.3", "gulp-util": "^3.0.8", "hogan.js": "^3.0.2", "http-proxy": "^1.16.2", - "jshint": "^2.9.5", + "jshint": "^2.9.6", "pump": "^1.0.3", "regenerator": "^0.9.7", "rollup": "^0.41.6", "source-map": "^0.5.7", "through2": "^2.0.3", + "typescript": "^3.1.1", + "typescript-formatter": "^7.2.2", "vinyl-paths": "^2.1.0" }, "scripts": { diff --git a/js/src/Glacier2/.gitignore b/js/src/Glacier2/.gitignore index bf696523d2d..8aa5e94f7c0 100644 --- a/js/src/Glacier2/.gitignore +++ b/js/src/Glacier2/.gitignore @@ -1,7 +1,14 @@ PermissionsVerifierF.js +PermissionsVerifierF.d.ts PermissionsVerifier.js +PermissionsVerifier.d.ts Router.js +Router.d.ts RouterF.js +RouterF.d.ts Session.js +Session.d.ts SSLInfo.js +SSLInfo.d.ts Metrics.js +Metrics.d.ts diff --git a/js/src/Glacier2/index.d.ts b/js/src/Glacier2/index.d.ts new file mode 100644 index 00000000000..3987c582165 --- /dev/null +++ b/js/src/Glacier2/index.d.ts @@ -0,0 +1,24 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** +// +// Ice version 3.7.1 +// + +/// <reference path="./Metrics.d.ts"/> +/// <reference path="./PermissionsVerifier.d.ts"/> +/// <reference path="./PermissionsVerifierF.d.ts"/> +/// <reference path="./Router.d.ts"/> +/// <reference path="./RouterF.d.ts"/> +/// <reference path="./Session.d.ts"/> +/// <reference path="./SSLInfo.d.ts"/> + +export namespace Glacier2 {} +export namespace IceMX {} + +declare module "ice" {} diff --git a/js/src/Ice/.gitignore b/js/src/Ice/.gitignore index de65df52734..d016235a5fb 100644 --- a/js/src/Ice/.gitignore +++ b/js/src/Ice/.gitignore @@ -1,22 +1,49 @@ # Ignore generated files BuiltinSequences.js +BuiltinSequences.d.ts +Communicator.d.ts Connection.js +Connection.d.ts ConnectionInfo.js +ConnectionInfo.d.ts Current.js +Current.d.ts Endpoint.js +Endpoint.d.ts +EndpointF.d.ts EndpointInfo.js +EndpointInfo.d.ts EndpointTypes.js +EndpointTypes.d.ts +FacetMap.d.ts Identity.js +Identity.d.ts +ImplicitContext.d.ts LocalException.js +LocalException.d.ts Locator.js +Locator.d.ts +Logger.d.ts Metrics.js +Metrics.d.ts +ObjectAdapter.d.ts +ObjectFactory.d.ts Process.js +Process.d.ts +Properties.d.ts PropertiesAdmin.js +PropertiesAdmin.d.ts RemoteLogger.js +RemoteLogger.d.ts Router.js +Router.d.ts ServantLocator.js +ServantLocator.d.ts SliceChecksumDict.js +SliceChecksumDict.d.ts +ValueFactory.d.ts Version.js +Version.d.ts ConnectionF.js EndpointF.js ObjectAdapterF.js diff --git a/js/src/Ice/Address.d.ts b/js/src/Ice/Address.d.ts new file mode 100644 index 00000000000..ab47dc5e702 --- /dev/null +++ b/js/src/Ice/Address.d.ts @@ -0,0 +1,22 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class Address + { + constructor(host:string, port:number); + + host:string; + port:number; + } + } +} diff --git a/js/src/Ice/ArrayUtil.d.ts b/js/src/Ice/ArrayUtil.d.ts new file mode 100644 index 00000000000..1bac362dfbc --- /dev/null +++ b/js/src/Ice/ArrayUtil.d.ts @@ -0,0 +1,21 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class ArrayUtil + { + static clone<T>(arr:T[]):T[]; + static equals(lhs:any[]|Uint8Array, rhs:any[]|Uint8Array, valuesEqual?:(v1:any, v2:any)=>boolean):boolean; + static shuffle(arr:any[]):void; + } + } +} diff --git a/js/src/Ice/AsyncResult.d.ts b/js/src/Ice/AsyncResult.d.ts new file mode 100644 index 00000000000..f3eb53ae301 --- /dev/null +++ b/js/src/Ice/AsyncResult.d.ts @@ -0,0 +1,25 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class AsyncResult<T> extends AsyncResultBase<T> + { + constructor(communicator:Communicator, operation:string, connection:Connection, proxy: ObjectPrx, adapter:ObjectAdapter, + completed:(result:AsyncResult<T>) => void); + cancel():void; + isCompleted():boolean; + isSent():boolean; + throwLocalException():void; + sentSynchronously():boolean; + } + } +} diff --git a/js/src/Ice/AsyncResultBase.d.ts b/js/src/Ice/AsyncResultBase.d.ts new file mode 100644 index 00000000000..697ef079eef --- /dev/null +++ b/js/src/Ice/AsyncResultBase.d.ts @@ -0,0 +1,24 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class AsyncResultBase<T> extends Promise<T> + { + constructor(communicator:Communicator, op:string, connection:Connection, proxy:ObjectPrx, adapter:ObjectAdapter); + readonly communicator:Communicator; + readonly connection:Connection; + readonly proxy:ObjectPrx; + readonly adapter:ObjectAdapter; + readonly operation:string; + } + } +} diff --git a/js/src/Ice/Buffer.js b/js/src/Ice/Buffer.js index 9db944350c3..464742dd00d 100644 --- a/js/src/Ice/Buffer.js +++ b/js/src/Ice/Buffer.js @@ -14,10 +14,6 @@ const bufferOverflowExceptionMsg = "BufferOverflowException"; const bufferUnderflowExceptionMsg = "BufferUnderflowException"; const indexOutOfBoundsExceptionMsg = "IndexOutOfBoundsException"; -// -// Buffer implementation to be used by web browsers, it uses ArrayBuffer as -// the store. -// class Buffer { constructor(buffer) diff --git a/js/src/Ice/Debug.d.ts b/js/src/Ice/Debug.d.ts new file mode 100644 index 00000000000..e3798eafba0 --- /dev/null +++ b/js/src/Ice/Debug.d.ts @@ -0,0 +1,19 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class Debug + { + static assert():void; + } + } +} diff --git a/js/src/Ice/Exception.d.ts b/js/src/Ice/Exception.d.ts new file mode 100644 index 00000000000..0ad6c3ec404 --- /dev/null +++ b/js/src/Ice/Exception.d.ts @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + /** + * Base class for all Ice exceptions. + */ + abstract class Exception extends Error + { + /** + * Returns the name of this exception. + * + * @return The name of this exception. + * + * @deprecated ice_name() is deprecated, use ice_id() instead. + **/ + ice_name():string; + + /** + * Returns the type id of this exception. + * + * @return The type id of this exception. + **/ + ice_id():string; + + /** + * Returns a string representation of this exception. + * + * @return A string representation of this exception. + **/ + toString():string; + } + + /** + * Base class for all Ice run-time exceptions. + */ + abstract class LocalException extends Exception {} + + /** + * Base class for all Ice user exceptions. + */ + abstract class UserException extends Exception + { + /** + * Obtains the sliced data associated with this instance. + * @return The sliced data if the exception has a preserved-slice base class and has been sliced during + * unmarshaling of the exception, nil otherwise. + */ + ice_getSlicedData():SlicedData; + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + static ice_staticId():string; + } + } +} diff --git a/js/src/Ice/FormatType.d.ts b/js/src/Ice/FormatType.d.ts new file mode 100644 index 00000000000..8c048ebc5a4 --- /dev/null +++ b/js/src/Ice/FormatType.d.ts @@ -0,0 +1,29 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class FormatType + { + static readonly DefaultFormat:FormatType; + static readonly CompactFormat:FormatType; + static readonly SlicedFormat:FormatType; + + static valueOf(value:number):FormatType; + equals(other:any):boolean; + hashCode():number; + toString():string; + + readonly name:string; + readonly value:number; + } + } +} diff --git a/js/src/Ice/HashMap.d.ts b/js/src/Ice/HashMap.d.ts new file mode 100644 index 00000000000..e9649da31a5 --- /dev/null +++ b/js/src/Ice/HashMap.d.ts @@ -0,0 +1,44 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + type HashMapKey = number | string | boolean | + { + equals(other: any):boolean; + hashCode():number + }; + + class HashMap<Key extends HashMapKey, Value> + { + constructor(); + constructor(other:HashMap<Key, Value>); + constructor(keyComparator: (k1:Key, k2:Key) => boolean, + valueComparator?: (v1:Value, v2:Value) => boolean); + + set(key:Key, value:Value):void; + get(key:Key):Value|undefined; + has(key:Key):boolean; + delete(key:Key):Value|undefined; + clear():void; + forEach(fn:(value:Value, key:Key)=>void, thisArg?:Object):void; + + entries(): IterableIterator<[Key, Value]>; + keys(): IterableIterator<Key>; + values(): IterableIterator<Value>; + + equals(other: HashMap<Key, Value>, valueComparator?: (v1:Value, v2:Value) => boolean): boolean; + merge(from: HashMap<Key, Value>):void; + + readonly size:number; + } + } +} diff --git a/js/src/Ice/Holder.d.ts b/js/src/Ice/Holder.d.ts new file mode 100644 index 00000000000..e5c2aacb252 --- /dev/null +++ b/js/src/Ice/Holder.d.ts @@ -0,0 +1,19 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class Holder<T> + { + value:T; + } + } +} diff --git a/js/src/Ice/IdentityUtil.d.ts b/js/src/Ice/IdentityUtil.d.ts new file mode 100644 index 00000000000..598ac2259e7 --- /dev/null +++ b/js/src/Ice/IdentityUtil.d.ts @@ -0,0 +1,19 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + function stringToIdentity(s:string):Identity; + function identityToString(ident:Identity, toStringMode?:ToStringMode):string; + function proxyIdentityCompare(lhs:ObjectPrx, rhs:ObjectPrx):number; + function proxyIdentityAndFacetCompare(lhs:ObjectPrx, rhs:ObjectPrx):number; + } +} diff --git a/js/src/Ice/Initialize.d.ts b/js/src/Ice/Initialize.d.ts new file mode 100644 index 00000000000..d7ee973d3b2 --- /dev/null +++ b/js/src/Ice/Initialize.d.ts @@ -0,0 +1,34 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class InitializationData + { + constructor(); + clone():InitializationData; + + properties:Properties; + logger:Logger; + valueFactoryManager:ValueFactoryManager; + } + + function initialize(initData?:InitializationData):Communicator; + function initialize(args:string[], initData?:InitializationData):Communicator; + + function createProperties(args?:string[], defaults?:Properties):Properties; + + function currentProtocol():ProtocolVersion; + function currentEncoding():EncodingVersion; + function stringVersion():string; + function intVersion():number; + } +} diff --git a/js/src/Ice/Initialize.js b/js/src/Ice/Initialize.js index 6d340ffc9d8..9d3f6b4cab7 100644 --- a/js/src/Ice/Initialize.js +++ b/js/src/Ice/Initialize.js @@ -21,20 +21,23 @@ const Protocol = Ice.Protocol; // // Ice.InitializationData // -Ice.InitializationData = function() +Ice.InitializationData = class { - this.properties = null; - this.logger = null; - this.valueFactoryManager = null; -}; + constructor() + { + this.properties = null; + this.logger = null; + this.valueFactoryManager = null; + } -Ice.InitializationData.prototype.clone = function() -{ - const r = new Ice.InitializationData(); - r.properties = this.properties; - r.logger = this.logger; - r.valueFactoryManager = this.valueFactoryManager; - return r; + clone() + { + const r = new Ice.InitializationData(); + r.properties = this.properties; + r.logger = this.logger; + r.valueFactoryManager = this.valueFactoryManager; + return r; + } }; // diff --git a/js/src/Ice/Long.d.ts b/js/src/Ice/Long.d.ts new file mode 100644 index 00000000000..42a442986c3 --- /dev/null +++ b/js/src/Ice/Long.d.ts @@ -0,0 +1,26 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class Long + { + constructor(high?:number, low?:number); + hashCode():number; + equals(rhs:Long):boolean; + toString():string; + toNumber():number; + + low:number; + high:number; + } + } +} diff --git a/js/src/Ice/MapUtil.d.ts b/js/src/Ice/MapUtil.d.ts new file mode 100644 index 00000000000..95a291132d2 --- /dev/null +++ b/js/src/Ice/MapUtil.d.ts @@ -0,0 +1,19 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class MapUtil + { + static equals<K, V>(lhs:Map<K,V>, rhs:Map<K, V>):boolean; + } + } +} diff --git a/js/src/Ice/Object.d.ts b/js/src/Ice/Object.d.ts new file mode 100644 index 00000000000..10cdd86f46b --- /dev/null +++ b/js/src/Ice/Object.d.ts @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class Object + { + /** + * Tests whether this object supports a specific Slice interface. + * @param typeID The type ID of the Slice interface to test against. + * @param current The Current object for the invocation. + * @return True if this object has the interface specified by typeID + * or derives from the interface specified by typeID. + */ + ice_isA(typeID:string, current?:Current):boolean|PromiseLike<boolean>; + + /** + * Tests whether this object can be reached. + * @param current The Current object for the invocation. + */ + ice_ping(current?:Current):void|PromiseLike<void>; + + /** + * Returns the Slice type IDs of the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return The Slice type IDs of the interfaces supported by this object, in base-to-derived + * order. The first element of the returned array is always "::Ice::Object". + */ + ice_ids(current?:Current):string[]|PromiseLike<string[]>; + + /** + * Returns the Slice type ID of the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return The Slice type ID of the most-derived interface. + */ + ice_id(current?:Current):string|PromiseLike<string>; + + /** + * Obtains the Slice type ID of this type. + * @return The return value is always "::Ice::Object". + */ + static ice_staticId():string; + } + } +} diff --git a/js/src/Ice/ObjectPrx.d.ts b/js/src/Ice/ObjectPrx.d.ts new file mode 100644 index 00000000000..a844009219e --- /dev/null +++ b/js/src/Ice/ObjectPrx.d.ts @@ -0,0 +1,427 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class ObjectPrx + { + static ice_staticId():string; + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ice_isA(id:string, context?:Map<string, string>):AsyncResult<boolean>; + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ice_id(context?:Map<string, string>):AsyncResult<string>; + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ice_ids(context?:Map<string, string>):AsyncResult<string[]>; + + /** + * Tests whether the target object of this proxy can be reached. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ice_ping(context?:Map<string, string>):AsyncResult<void>; + + /** + * Obtains the communicator that created this proxy. + * @return The communicator that created this proxy. + */ + ice_getCommunicator():Communicator; + + /** + * Obtains a stringified version of this proxy. + * @return A stringified proxy. + */ + ice_toString():string; + + /** + * Obtains a proxy that is identical to this proxy, except for the identity. + * @param id The identity for the new proxy. + * @return A proxy with the new identity. + */ + ice_identity(id:Identity):this; + + /** + * Obtains the identity embedded in this proxy. + * @return The identity of the target object. + */ + ice_getIdentity():Identity; + + /** + * Obtains a proxy that is identical to this proxy, except for the adapter ID. + * @param id The adapter ID for the new proxy. + * @return A proxy with the new adapter ID. + */ + ice_adapterId(id:string):this; + + /** + * Obtains the adapter ID for this proxy. + * @return The adapter ID. If the proxy does not have an adapter ID, the return value is the empty string. + */ + ice_getAdapterId():string; + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoints. + * @param endpoints The endpoints for the new proxy. + * @return A proxy with the new endpoints. + */ + ice_endpoints(endpoints:Endpoint[]):this; + + /** + * Obtains the endpoints used by this proxy. + * @return The endpoints used by this proxy. + */ + ice_getEndpoints():Endpoint[]; + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoint selection policy. + * @param type The new endpoint selection policy. + * @return A proxy with the specified endpoint selection policy. + */ + ice_endpointSelection(type:EndpointSelectionType):this; + + /** + * Obtains the endpoint selection policy for this proxy (randomly or ordered). + * @return The endpoint selection policy. + */ + ice_getEndpointSelection():EndpointSelectionType; + + /** + * Obtains a proxy that is identical to this proxy, except for the per-proxy context. + * @param context The context for the new proxy. + * @return A proxy with the new per-proxy context. + */ + ice_context(ctx:Map<string, string>):this; + + /** + * Obtains the per-proxy context for this proxy. + * @return The per-proxy context. + */ + ice_getContext():Map<string, string>; + + /** + * Obtains a proxy that is identical to this proxy, except for the facet. + * @param facet The facet for the new proxy. + * @return A proxy with the new facet. + */ + ice_facet(facet:string):this; + + /** + * Obtains the facet for this proxy. + * @return The facet for this proxy. If the proxy uses the default facet, the return value is the empty string. + */ + ice_getFacet():string; + + /** + * Obtains a proxy that is identical to this proxy, but uses twoway invocations. + * @return A proxy that uses twoway invocations. + */ + ice_twoway():this; + + /** + * Determines whether this proxy uses twoway invocations. + * @return True if this proxy uses twoway invocations, false otherwise. + */ + ice_isTwoway():boolean; + + /** + * Obtains a proxy that is identical to this proxy, but uses oneway invocations. + * @return A proxy that uses oneway invocations. + */ + ice_oneway():this; + + /** + * Determines whether this proxy uses oneway invocations. + * @return True if this proxy uses oneway invocations, false otherwise. + */ + ice_isOneway():boolean; + + /** + * Obtains a proxy that is identical to this proxy, but uses batch oneway invocations. + * @return A proxy that uses batch oneway invocations. + */ + ice_batchOneway():this; + + /** + * Determines whether this proxy uses batch oneway invocations. + * @return True if this proxy uses batch oneway invocations, false otherwise. + */ + ice_isBatchOneway():boolean; + + /** + * Obtains a proxy that is identical to this proxy, but uses datagram invocations. + * @return A proxy that uses datagram invocations. + */ + ice_datagram():this; + + /** + * Determines whether this proxy uses datagram invocations. + * @return True if this proxy uses datagram invocations, false otherwise. + */ + ice_isDatagram():boolean; + + /** + * Obtains a proxy that is identical to this proxy, but uses batch datagram invocations. + * @return A proxy that uses batch datagram invocations. + */ + ice_batchDatagram():this; + + /** + * Determines whether this proxy uses batch datagram invocations. + * @return True if this proxy uses batch datagram invocations, false otherwise. + */ + ice_isBatchDatagram():boolean; + + /** + * Obtains a proxy that is identical to this proxy, except for how it selects endpoints. + * @param secure If true, only endpoints that use a secure transport are used by the new proxy. + * If false, the returned proxy uses both secure and insecure endpoints. + * @return A proxy with the specified security policy. + */ + ice_secure(secure:boolean):this; + + /** + * Obtains the encoding version used to marshal request parameters. + * @return The encoding version. + */ + ice_getEncodingVersion():EncodingVersion; + + /** + * Obtains a proxy that is identical to this proxy, except for the encoding used to marshal + * parameters. + * @param version The encoding version to use to marshal request parameters. + * @return A proxy with the specified encoding version. + */ + ice_encodingVersion(encoding:EncodingVersion):this; + + /** + * Determines whether this proxy uses only secure endpoints. + * @return True if this proxy communicates only via secure endpoints, false otherwise. + */ + ice_isSecure():boolean; + + /** + * Obtains a proxy that is identical to this proxy, except for its endpoint selection policy. + * @param secure If true, the new proxy will use secure endpoints for invocations and only use + * insecure endpoints if an invocation cannot be made via secure endpoints. If false, the + * proxy prefers insecure endpoints to secure ones. + * @return A proxy with the specified selection policy. + */ + ice_preferSecure(secure:boolean):this; + + /** + * Determines whether this proxy prefers secure endpoints. + * @return True if the proxy always attempts to invoke via secure endpoints before it + * attempts to use insecure endpoints, false otherwise. + */ + ice_isPreferSecure():boolean; + + /** + * Obtains a proxy that is identical to this proxy, except for its compression setting which + * overrides the compression setting from the proxy endpoints. + * @param b True enables compression for the new proxy, false disables compression. + * @return A proxy with the specified compression override setting. + */ + ice_compress(compress:boolean):this; + + /** + * Obtains the compression override setting of this proxy. + * @return The compression override setting. If nullopt is returned, no override is set. Otherwise, true + * if compression is enabled, false otherwise. + */ + ice_getCompress():boolean; + + /** + * Obtains a proxy that is identical to this proxy, except for its connection timeout setting + * which overrides the timeot setting from the proxy endpoints. + * @param timeout The connection timeout override for the proxy (in milliseconds). + * @return A proxy with the specified timeout override. + */ + ice_timeout(timeout:number):this; + + /** + * Obtains the timeout override of this proxy. + * @return The timeout override. If nullopt is returned, no override is set. Otherwise, returns + * the timeout override value. + */ + ice_getTimeout():number; + + /** + * Obtains a proxy that is identical to this proxy, except for the router. + * @param router The router for the new proxy. + * @return A proxy with the specified router. + */ + ice_router(router:RouterPrx):this; + + /** + * Obtains the router for this proxy. + * @return The router for the proxy. If no router is configured for the proxy, the return value + * is nil. + */ + ice_getRouter():RouterPrx; + + /** + * Obtains a proxy that is identical to this proxy, except for the locator. + * @param locator The locator for the new proxy. + * @return A proxy with the specified locator. + */ + ice_locator(locator:LocatorPrx):this; + + /** + * Obtains the locator for this proxy. + * @return The locator for this proxy. If no locator is configured, the return value is nil. + */ + ice_getLocator():LocatorPrx; + + /** + * Obtains a proxy that is identical to this proxy, except for the locator cache timeout. + * @param timeout The new locator cache timeout (in seconds). + * @return A proxy with the new timeout. + */ + ice_locatorCacheTimeout(timeout:number):this; + + /** + * Obtains the locator cache timeout of this proxy. + * @return The locator cache timeout value (in seconds). + */ + ice_getLocatorCacheTimeout():number; + + /** + * Obtains a proxy that is identical to this proxy, except for collocation optimization. + * @param b True if the new proxy enables collocation optimization, false otherwise. + * @return A proxy with the specified collocation optimization. + */ + ice_collocationOptimized(b:boolean):this; + + /** + * Determines whether this proxy uses collocation optimization. + * @return True if the proxy uses collocation optimization, false otherwise. + */ + ice_isCollocationOptimized():boolean; + + /** + * Obtains a proxy that is identical to this proxy, except for the invocation timeout. + * @param timeout The new invocation timeout (in milliseconds). + * @return A proxy with the new timeout. + */ + ice_invocationTimeout(timeout:number):this; + + /** + * Obtains the invocation timeout of this proxy. + * @return The invocation timeout value (in milliseconds). + */ + ice_getInvocationTimeout():number; + + /** + * Obtains a proxy that is identical to this proxy, except for its connection ID. + * @param id The connection ID for the new proxy. An empty string removes the + * connection ID. + * @return A proxy with the specified connection ID. + */ + ice_connectionId(connectionId:string):this; + + /** + * Obtains the connection ID of this proxy. + * @return The connection ID. + */ + ice_getConnectionId():string; + + /** + * Obtains a proxy that is identical to this proxy, except it's a fixed proxy bound + * the given connection. + * @param connection The fixed proxy connection. + * @return A fixed proxy bound to the given connection. + */ + ice_fixed(conn:Connection):this; + + /** + * Obtains the Connection for this proxy. If the proxy does not yet have an established connection, + * it first attempts to create a connection. + * @return The asynchronous result object for the invocation. + */ + ice_getConnection():AsyncResult<Connection>; + + /** + * Obtains the cached Connection for this proxy. If the proxy does not yet have an established + * connection, it does not attempt to create a connection. + * @return The cached connection for this proxy, or nil if the proxy does not have + * an established connection. + */ + ice_getCachedConnection():Connection; + + /** + * Obtains a proxy that is identical to this proxy, except for connection caching. + * @param cache True if the new proxy should cache connections, false otherwise. + * @return A proxy with the specified caching policy. + */ + ice_connectionCached(cache:boolean):this; + + /** + * Determines whether this proxy caches connections. + * @return True if this proxy caches connections, false otherwise. + */ + ice_isConnectionCached():boolean; + + /** + * Flushes any pending batched requests for this communicator. The call blocks until the flush is complete. + * @return The asynchronous result object for the invocation. + */ + ice_flushBatchRequests():AsyncResult<void>; + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @return The asynchronous result object for the invocation . + */ + ice_invoke(operation:string, mode:OperationMode, inEncaps:Uint8Array):AsyncResult<[]>; + + /** + * Compare two proxies for equality + * @param rhs The proxy to compare with this proxy + * @returns True if the passed proxy have the same reference than this proxy. + */ + equals(rhs:any):boolean; + + /** + * Downcasts a proxy without confirming the target object's type via a remote invocation. + * @param prx The target proxy. + * @return A proxy with the requested type. + */ + static uncheckedCast(prx:ObjectPrx, facet?:string):ObjectPrx; + + /** + * Downcasts a proxy after confirming the target object's type via a remote invocation. + * @param prx The target proxy. + * @param facet A facet name. + * @param context The context map for the invocation. + * @return A proxy with the requested type and facet, or nil if the target proxy is nil or the target + * object does not support the requested type. + */ + static checkedCast(prx:ObjectPrx, facet?:string, contex?:Map<string, string>):AsyncResult<ObjectPrx>; + } + } +} diff --git a/js/src/Ice/OptionalFormat.d.ts b/js/src/Ice/OptionalFormat.d.ts new file mode 100644 index 00000000000..c9c4cfa91f1 --- /dev/null +++ b/js/src/Ice/OptionalFormat.d.ts @@ -0,0 +1,34 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class OptionalFormat + { + static readonly F1:OptionalFormat; + static readonly F2:OptionalFormat; + static readonly F4:OptionalFormat; + static readonly F8:OptionalFormat; + static readonly Size:OptionalFormat; + static readonly VSize:OptionalFormat; + static readonly FSize:OptionalFormat; + static readonly Class:OptionalFormat; + + static valueOf(value:number):OptionalFormat; + equals(other:any):boolean; + hashCode():number; + toString():string; + + readonly name:string; + readonly value:number; + } + } +} diff --git a/js/src/Ice/Promise.d.ts b/js/src/Ice/Promise.d.ts new file mode 100644 index 00000000000..15925e41464 --- /dev/null +++ b/js/src/Ice/Promise.d.ts @@ -0,0 +1,28 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +export class P<T> extends Promise<T> +{ + constructor(executor?:(resolve:(value:T|PromiseLike<T>)=>void, reject:(reason:any)=>void) => void); + finally(callback:() => void | PromiseLike<void>): T | PromiseLike<T>; + delay(ms:number): P<T>; + resolve<T>(value?:T|PromiseLike<T>):void; + reject<T>(reason:any):void; + static delay(ms:number):P<void>; + static delay<T>(ms:number, value:T):P<T>; + static try<T>(cb:()=>T|PromiseLike<T>):P<T>; +} + +declare module "ice" +{ + namespace Ice + { + export {P as Promise}; + } +} diff --git a/js/src/Ice/Protocol.d.ts b/js/src/Ice/Protocol.d.ts new file mode 100644 index 00000000000..138b1d97d6a --- /dev/null +++ b/js/src/Ice/Protocol.d.ts @@ -0,0 +1,148 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + const Encoding_1_0:EncodingVersion; + const Encoding_1_1:EncodingVersion; + + const Protocol_1_0:ProtocolVersion; + + class Protocol + { + // + // Size of the Ice protocol header + // + // Magic number (4 bytes) + // Protocol version major (Byte) + // Protocol version minor (Byte) + // Encoding version major (Byte) + // Encoding version minor (Byte) + // Message type (Byte) + // Compression status (Byte) + // Message size (Int) + // + static readonly headerSize:number; + + // + // The magic number at the front of each message ['I', 'c', 'e', 'P'] + // + static readonly magic:Uint8Array; + + // + // The current Ice protocol and encoding version + // + static readonly protocolMajor:number; + static readonly protocolMinor:number; + static readonly protocolEncodingMajor:number; + static readonly protocolEncodingMinor:number; + + static readonly encodingMajor:number; + static readonly encodingMinor:number; + + // + // The Ice protocol message types + // + static readonly requestMsg:number; + static readonly requestBatchMsg:number; + static readonly replyMsg:number; + static readonly validateConnectionMsg:number; + static readonly closeConnectionMsg:number; + + // + // Reply status + // + static readonly replyOK:number; + static readonly replyUserException:number; + static readonly replyObjectNotExist:number; + static readonly replyFacetNotExist:number; + static readonly replyOperationNotExist:number; + static readonly replyUnknownLocalException:number; + static readonly replyUnknownUserException:number; + static readonly replyUnknownException:number; + + static readonly requestHdr:Uint8Array; + + static readonly requestBatchHdr:Uint8Array; + + static readonly replyHdr:Uint8Array; + + static readonly currentProtocol:ProtocolVersion; + static readonly currentProtocolEncoding:EncodingVersion; + + static currentEncoding:EncodingVersion; + + static checkSupportedProtocol(v:ProtocolVersion):void; + static checkSupportedProtocolEncoding(v:EncodingVersion):void; + static checkSupportedEncoding(version:EncodingVersion):void; + + // + // Either return the given protocol if not compatible, or the greatest + // supported protocol otherwise. + // + static getCompatibleProtocol(version:ProtocolVersion):ProtocolVersion; + + // + // Either return the given encoding if not compatible, or the greatest + // supported encoding otherwise. + // + static getCompatibleEncoding(version:EncodingVersion):EncodingVersion; + + static isSupported(version:ProtocolVersion, supported:ProtocolVersion):boolean; + static isSupported(version:EncodingVersion, supported:EncodingVersion):boolean; + + static readonly OPTIONAL_END_MARKER:number; + static readonly FLAG_HAS_TYPE_ID_STRING:number; + static readonly FLAG_HAS_TYPE_ID_INDEX:number; + static readonly FLAG_HAS_TYPE_ID_COMPACT:number; + static readonly FLAG_HAS_OPTIONAL_MEMBERS:number; + static readonly FLAG_HAS_INDIRECTION_TABLE:number; + static readonly FLAG_HAS_SLICE_SIZE:number; + static readonly FLAG_IS_LAST_SLICE:number; + } + + /** + * Converts a string to a protocol version. + * + * @param version The string to convert. + * + * @return The converted protocol version. + **/ + function stringToProtocolVersion(version:string):ProtocolVersion; + + /** + * Converts a string to an encoding version. + * + * @param version The string to convert. + * + * @return The converted object identity. + **/ + function stringToEncodingVersion(version:string):EncodingVersion; + + /** + * Converts a protocol version to a string. + * + * @param v The protocol version to convert. + * + * @return The converted string. + **/ + function protocolVersionToString(version:ProtocolVersion):string; + + /** + * Converts an encoding version to a string. + * + * @param v The encoding version to convert. + * + * @return The converted string. + **/ + function encodingVersionToString(version:EncodingVersion):string; + } +} diff --git a/js/src/Ice/Stream.d.ts b/js/src/Ice/Stream.d.ts new file mode 100644 index 00000000000..cd3d123a526 --- /dev/null +++ b/js/src/Ice/Stream.d.ts @@ -0,0 +1,213 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + class ByteHelper + { + static validate(v:number):boolean; + } + + class ShortHelper + { + static validate(v:number):boolean; + } + + class IntHelper + { + static validate(v:number):boolean; + } + + class FloatHelper + { + static validate(v:number):boolean; + } + + class DoubleHelper + { + static validate(v:number):boolean; + } + + class LongHelper + { + static validate(v:Long):boolean; + } + + class InputStream + { + constructor(); + constructor(buffer:Uint8Array); + constructor(communicator:Communicator); + constructor(communicator:Communicator, buffer:Uint8Array); + constructor(encoding:EncodingVersion); + constructor(encoding:EncodingVersion, buffer:Uint8Array); + constructor(communicator:Communicator, encoding:EncodingVersion); + constructor(communicator:Communicator, encoding:EncodingVersion, buffer:Uint8Array); + + // + // This function allows this object to be reused, rather than reallocated. + // + reset():void; + clear():void; + swap(other:InputStream):void; + resetEncapsulation():void; + resize(sz:number):void; + startValue():void; + endValue(preserve:boolean):SlicedData; + startException():void; + endException(preserve:boolean):SlicedData; + startEncapsulation():EncodingVersion; + endEncapsulation():void; + skipEmptyEncapsulation():EncodingVersion; + readEncapsulation(encoding:EncodingVersion):Uint8Array; + getEncoding():EncodingVersion; + getEncapsulationSize():number; + skipEncapsulation():EncodingVersion; + startSlice():string; // Returns type ID of next slice + endSlice():void; + skipSlice():void; + readPendingValues():void; + readSize():number; + readAndCheckSeqSize(minSize:number):number; + readBlob(sz:number):Uint8Array; + readOptional(tag:number, expectedFormat:OptionalFormat):boolean; + readByte():number; + readByteSeq():Uint8Array; + readBool():boolean; + readShort():number; + readInt():number; + readLong():Ice.Long; + readFloat():number; + readDouble():number; + readString():string; + + readProxy<T extends ObjectPrx>(type:new()=>T):T; + readOptionalProxy<T extends ObjectPrx>(tag:number, type:new()=>T):T|undefined; + readEnum<T>(type:new()=>T):T; + readOptionalEnum<T>(tag:number, type:new()=>T):T|undefined; + readValue<T extends Value>(cb:(value:T) => void, type:new()=>T):void; + readOptionalValue<T extends Value>(tag:number, cb:(value:T) => void, type:new()=>T):void; + throwException():void; + skip(size:number):void; + skipSize():void; + isEmpty():boolean; + expand(n:number):void; + + // + // Sets the value factory manager to use when marshaling value instances. If the stream + // was initialized with a communicator, the communicator's value factory manager will + // be used by default. + // + valueFactoryManager:ValueFactoryManager; + + // + // Sets the logger to use when logging trace messages. If the stream + // was initialized with a communicator, the communicator's logger will + // be used by default. + // + logger:Logger; + + // + // Sets the compact ID resolver to use when unmarshaling value and exception + // instances. If the stream was initialized with a communicator, the communicator's + // resolver will be used by default. + // + compactIdResolver:(compactID:number) => string; + + // + // Determines the behavior of the stream when extracting instances of Slice classes. + // A instance is "sliced" when a factory cannot be found for a Slice type ID. + // The stream's default behavior is to slice instances. + // + // If slicing is disabled and the stream encounters a Slice type ID + // during decoding for which no value factory is installed, it raises + // NoValueFactoryException. + // + sliceValues:boolean; + + // + // Determines whether the stream logs messages about slicing instances of Slice values. + // + traceSlicing:boolean; + + pos:number; + + readonly size:number; + readonly buffer:Uint8Array; + } + + class OutputStream + { + constructor(communicator?:Ice.Communicator, encoding?:EncodingVersion, buffer?:Uint8Array); + + // + // This function allows this object to be reused, rather than reallocated. + // + reset():void; + clear():void; + finished():Uint8Array; + swap(other:OutputStream):void; + resetEncapsulation():void; + resize(sz:number):void; + prepareWrite():Uint8Array; + startValue(data:SlicedData):void; + endValue():void; + startException(data:SlicedData):void; + endException():void; + startEncapsulation():void; + startEncapsulation(encoding:EncodingVersion, format:FormatType):void; + endEncapsulation():void; + writeEmptyEncapsulation(encoding:EncodingVersion):void; + writeEncapsulation(buff:Uint8Array):void; + getEncoding():EncodingVersion; + startSlice(typeId:string, compactId:number, last:boolean):void; + endSlice():void; + writePendingValues():void; + writeSize(v:number):void; + startSize():number; + endSize(pos:number):void; + writeBlob(v:Uint8Array):void; + // Read/write format and tag for optionals + writeOptional(tag:number, format:OptionalFormat):void; + writeByte(v:number):void; + writeByteSeq(v:Uint8Array):void; + writeBool(v:boolean):void; + writeShort(v:number):void; + writeInt(v:number):void; + writeLong(v:Ice.Long):void; + writeFloat(v:number):void; + writeDouble(v:number):void; + writeString(v:string):void; + writeProxy(v:ObjectPrx):void; + writeOptionalProxy(tag:number, v?:ObjectPrx|undefined):void; + + /// TODO use a base enum type + writeEnum(v:any):void; + + writeValue(v:Ice.Value):void; + writeOptionalValue(tag:number, v?:Ice.Value|undefined):void; + writeException(e:UserException):void; + writeUserException(e:UserException):void; + + isEmpty():boolean; + + expand(n:number):void; + + // + // Sets the encoding format for class and exception instances. + // + format:FormatType; + pos:number; + readonly size:number; + readonly buffer:Uint8Array; + } + } +} diff --git a/js/src/Ice/UUID.d.ts b/js/src/Ice/UUID.d.ts new file mode 100644 index 00000000000..af5b9b02725 --- /dev/null +++ b/js/src/Ice/UUID.d.ts @@ -0,0 +1,20 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + /** + * Generates a universally unique identifier (UUID). + * @return The UUID. + */ + function generateUUID():string; + } +} diff --git a/js/src/Ice/UnknownSlicedValue.d.ts b/js/src/Ice/UnknownSlicedValue.d.ts new file mode 100644 index 00000000000..3c9ae7ae25a --- /dev/null +++ b/js/src/Ice/UnknownSlicedValue.d.ts @@ -0,0 +1,69 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + /** + * Encapsulates the details of a slice for an unknown class or exception type. + */ + class SliceInfo + { + /** + * The Slice type ID for this slice. + */ + typeId:string; + + /** + * The Slice compact type ID for this slice. + */ + compactId:number; + + /** + * The encoded bytes for this slice, including the leading size integer. + */ + bytes:Uint8Array; + + /** + * The class instances referenced by this slice. + */ + instances:Value[]; + + /** + * Whether or not the slice contains optional members. + */ + hasOptionalMembers:boolean; + + /** + * Whether or not this is the last slice. + */ + isLastSlice:boolean; + } + + /** + * Holds the slices of unknown types. + */ + class SlicedData + { + /** + * The slices of unknown types. + */ + slices:SliceInfo[]; + } + + class UnknownSlicedValue extends Ice.Value + { + constructor(unknownTypeId:string); + + ice_getSlicedData():SlicedData; + ice_id():string; + } + } +} diff --git a/js/src/Ice/Value.d.ts b/js/src/Ice/Value.d.ts new file mode 100644 index 00000000000..bcf6947db11 --- /dev/null +++ b/js/src/Ice/Value.d.ts @@ -0,0 +1,62 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +declare module "ice" +{ + namespace Ice + { + /** + * The base class for instances of Slice classes. + */ + class Value + { + /** + * The Ice run time invokes this method prior to marshaling an object's data members. This allows a subclass + * to override this method in order to validate its data members. + */ + ice_preMarshal():void; + + /** + * The Ice run time invokes this method vafter unmarshaling an object's data members. This allows a + * subclass to override this method in order to perform additional initialization. + */ + ice_postUnmarshal():void; + + /** + * Obtains the Slice type ID of the most-derived class supported by this object. + * @return The type ID. + */ + ice_id():string; + + /** + * Obtains the Slice type ID of this type. + * @return The return value is always "::Ice::Object". + */ + static ice_staticId():string; + + /** + * Returns a shallow copy of the object. + * @return The cloned value. + */ + ice_clone():this; + + /** + * Obtains the sliced data associated with this instance. + * @return The sliced data if the value has a preserved-slice base class and has been sliced during + * unmarshaling of the value, nil otherwise. + */ + ice_getSlicedData():SlicedData; + } + + class InterfaceByValue extends Value + { + constructor(id:string); + } + } +} diff --git a/js/src/Ice/index.d.ts b/js/src/Ice/index.d.ts new file mode 100644 index 00000000000..77dff580102 --- /dev/null +++ b/js/src/Ice/index.d.ts @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** +// +// Ice version 3.7.1 +// + +/// <reference path="./Address.d.ts"/> +/// <reference path="./ArrayUtil.d.ts"/> +/// <reference path="./AsyncResult.d.ts"/> +/// <reference path="./AsyncResultBase.d.ts"/> +/// <reference path="./BuiltinSequences.d.ts"/> +/// <reference path="./Communicator.d.ts"/> +/// <reference path="./Connection.d.ts"/> +/// <reference path="./ConnectionInfo.d.ts"/> +/// <reference path="./Current.d.ts"/> +/// <reference path="./Debug.d.ts"/> +/// <reference path="./Endpoint.d.ts"/> +/// <reference path="./EndpointF.d.ts"/> +/// <reference path="./EndpointInfo.d.ts"/> +/// <reference path="./EndpointTypes.d.ts"/> +/// <reference path="./Exception.d.ts"/> +/// <reference path="./FacetMap.d.ts"/> +/// <reference path="./FormatType.d.ts"/> +/// <reference path="./HashMap.d.ts"/> +/// <reference path="./Holder.d.ts"/> +/// <reference path="./Identity.d.ts"/> +/// <reference path="./IdentityUtil.d.ts"/> +/// <reference path="./ImplicitContext.d.ts"/> +/// <reference path="./Initialize.d.ts"/> +/// <reference path="./LocalException.d.ts"/> +/// <reference path="./Locator.d.ts"/> +/// <reference path="./Logger.d.ts"/> +/// <reference path="./Long.d.ts"/> +/// <reference path="./MapUtil.d.ts"/> +/// <reference path="./Metrics.d.ts"/> +/// <reference path="./Object.d.ts"/> +/// <reference path="./ObjectAdapter.d.ts"/> +/// <reference path="./ObjectFactory.d.ts"/> +/// <reference path="./ObjectPrx.d.ts"/> +/// <reference path="./OptionalFormat.d.ts"/> +/// <reference path="./Process.d.ts"/> +/// <reference path="./Promise.d.ts"/> +/// <reference path="./Properties.d.ts"/> +/// <reference path="./PropertiesAdmin.d.ts"/> +/// <reference path="./Protocol.d.ts"/> +/// <reference path="./RemoteLogger.d.ts"/> +/// <reference path="./Router.d.ts"/> +/// <reference path="./ServantLocator.d.ts"/> +/// <reference path="./SliceChecksumDict.d.ts"/> +/// <reference path="./Stream.d.ts"/> +/// <reference path="./UnknownSlicedValue.d.ts"/> +/// <reference path="./UUID.d.ts"/> +/// <reference path="./Value.d.ts"/> +/// <reference path="./ValueFactory.d.ts"/> +/// <reference path="./Version.d.ts"/> + +export namespace Ice {} +export namespace IceMX {} +export namespace IceSSL {} + +declare module "ice" {} diff --git a/js/src/Ice/sources.json b/js/src/Ice/sources.json index e44c94ad942..0f6ea95349c 100644 --- a/js/src/Ice/sources.json +++ b/js/src/Ice/sources.json @@ -1,6 +1,7 @@ { "modules": [ "Ice", "IceMX", "IceSSL"], + "slice":[ "Ice/BuiltinSequences.ice", "Ice/Connection.ice", @@ -24,6 +25,35 @@ "IceSSL/EndpointInfo.ice", "IceSSL/ConnectionInfo.ice"], + "typescriptSlice":[ + "Ice/BuiltinSequences.ice", + "Ice/Communicator.ice", + "Ice/Connection.ice", + "Ice/Current.ice", + "Ice/Endpoint.ice", + "Ice/EndpointF.ice", + "Ice/EndpointTypes.ice", + "Ice/FacetMap.ice", + "Ice/Identity.ice", + "Ice/ImplicitContext.ice", + "Ice/LocalException.ice", + "Ice/Locator.ice", + "Ice/Logger.ice", + "Ice/Metrics.ice", + "Ice/ObjectAdapter.ice", + "Ice/ObjectFactory.ice", + "Ice/Process.ice", + "Ice/Properties.ice", + "Ice/PropertiesAdmin.ice", + "Ice/RemoteLogger.ice", + "Ice/Router.ice", + "Ice/ServantLocator.ice", + "Ice/SliceChecksumDict.ice", + "Ice/ValueFactory.ice", + "Ice/Version.ice", + "IceSSL/EndpointInfo.ice", + "IceSSL/ConnectionInfo.ice"], + "common": [ "ACM.js", "Address.js", diff --git a/js/src/IceGrid/.gitignore b/js/src/IceGrid/.gitignore index 2cd3235f4ad..c58ae457f9f 100644 --- a/js/src/IceGrid/.gitignore +++ b/js/src/IceGrid/.gitignore @@ -1,10 +1,20 @@ Admin.js +Admin.d.ts Descriptor.js +Descriptor.d.ts Exception.js +Exception.d.ts FileParser.js +FileParser.d.ts Locator.js +Locator.d.ts Observer.js +Observer.d.ts Query.js +Query.d.ts Registry.js +Registry.d.ts Session.js +Session.d.ts UserAccountMapper.js +UserAccountMapper.d.ts diff --git a/js/src/IceGrid/index.d.ts b/js/src/IceGrid/index.d.ts new file mode 100644 index 00000000000..fed03b81f37 --- /dev/null +++ b/js/src/IceGrid/index.d.ts @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** +// +// Ice version 3.7.1 +// + +/// <reference path="./Admin.d.ts"/> +/// <reference path="./Descriptor.d.ts"/> +/// <reference path="./Exception.d.ts"/> +/// <reference path="./FileParser.d.ts"/> +/// <reference path="./Registry.d.ts"/> +/// <reference path="./Session.d.ts"/> +/// <reference path="./UserAccountMapper.d.ts"/> + +export namespace IceGrid {} + +declare module "ice" {} diff --git a/js/src/IceStorm/.gitignore b/js/src/IceStorm/.gitignore index 1e3e811ef95..01d778cc821 100644 --- a/js/src/IceStorm/.gitignore +++ b/js/src/IceStorm/.gitignore @@ -1,2 +1,4 @@ IceStorm.js +IceStorm.d.ts Metrics.js +Metrics.d.ts diff --git a/js/src/IceStorm/index.d.ts b/js/src/IceStorm/index.d.ts new file mode 100644 index 00000000000..5e6aca0fce9 --- /dev/null +++ b/js/src/IceStorm/index.d.ts @@ -0,0 +1,19 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** +// +// Ice version 3.7.1 +// + +/// <reference path="./Metrics.d.ts"/> +/// <reference path="./IceStorm.d.ts"/> + +export namespace IceStorm {} +export namespace IceMX {} + +declare module "ice" {} diff --git a/js/src/index.d.ts b/js/src/index.d.ts new file mode 100644 index 00000000000..59e42f73c32 --- /dev/null +++ b/js/src/index.d.ts @@ -0,0 +1,22 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +/// <reference path="./Ice/index.d.ts"/> +/// <reference path="./Glacier2/index.d.ts"/> +/// <reference path="./IceStorm/index.d.ts"/> +/// <reference path="./IceGrid/index.d.ts"/> + +export namespace Ice {} +export namespace IceMX {} +export namespace IceSSL {} +export namespace Glacier2 {} +export namespace IceStorm {} +export namespace IceGrid {} + +declare module "ice" {} diff --git a/js/test/Common/ControllerI.d.ts b/js/test/Common/ControllerI.d.ts new file mode 100644 index 00000000000..4b0ccc5e8c7 --- /dev/null +++ b/js/test/Common/ControllerI.d.ts @@ -0,0 +1,26 @@ + +export class DOMElement +{ + val(value:string):string; + scrollTop():void; +} + +export class Output +{ + constructor(output:DOMElement); + write(msg:string):void; + writeLine(msg:string):void; + get():string; + clear():void; +} + +export default class ControllerHelper +{ + constructor(exe:string, output:Output); + + serverReady(ex?:Error):void; + waitReady():PromiseLike<void>; + + write(msg:string):void; + writeLine(msg:string):void; +} diff --git a/js/test/Common/TestHelper.d.ts b/js/test/Common/TestHelper.d.ts new file mode 100644 index 00000000000..f1b250f96d5 --- /dev/null +++ b/js/test/Common/TestHelper.d.ts @@ -0,0 +1,29 @@ +import { Ice } from "ice"; +import ControllerHelper from "./ControllerI" + +export class TestHelper +{ + getTestEndpoint(protocol:string):string; + getTestEndpoint(num?:number, protocol?:string):string; + getTestEndpoint(properties:Ice.Properties, num?:number, protocol?:string):string; + + getTestHost(properties:Ice.Properties):string; + + getTestProtocol(properties:Ice.Properties):string; + getTestPort(num?:number):number; + + createTestProperties(args?:string[]):[Ice.Properties, string[]]; + + initialize(initData:Ice.InitializationData):[Ice.Communicator, string[]]; + initialize(args:Ice.Properties):[Ice.Communicator, string[]]; + initialize(args:string[]):[Ice.Communicator, string[]]; + + communicator():Ice.Communicator; + shutdown():void; + + getWriter():ControllerHelper; + + setControllerHelper(controllerHelper:ControllerHelper):void; + serverReady():void; + static test(value:boolean, ex?:Error):void; +} diff --git a/js/test/Common/TestHelper.js b/js/test/Common/TestHelper.js index b577c9ad2a6..c97f9d0cf34 100644 --- a/js/test/Common/TestHelper.js +++ b/js/test/Common/TestHelper.js @@ -29,7 +29,7 @@ num = args[1]; if(args.length > 2) { - num = args[2]; + protocol = args[2]; } } } diff --git a/js/test/Ice/adapterDeactivation/Client.js b/js/test/Ice/adapterDeactivation/Client.js index acb5a4a48d2..f6d525780b4 100644 --- a/js/test/Ice/adapterDeactivation/Client.js +++ b/js/test/Ice/adapterDeactivation/Client.js @@ -39,7 +39,7 @@ let adapter = await communicator.createObjectAdapter("TransientTestAdapter"); try { - await communicator.createObjectAdapterWithEndpoints("TransientTestAdapter"); + await communicator.createObjectAdapterWithEndpoints("TransientTestAdapter", ""); test(false); } catch(ex) @@ -51,7 +51,7 @@ // // Use a different port than the first adapter to avoid an "address already in use" error. // - adapter = await communicator.createObjectAdapterWithEndpoints("TransientTestAdapter"); + adapter = await communicator.createObjectAdapterWithEndpoints("TransientTestAdapter", ""); await adapter.destroy(); out.writeLine("ok"); } diff --git a/js/test/Ice/ami/Client.js b/js/test/Ice/ami/Client.js index f86ce217baa..4340a1bd242 100644 --- a/js/test/Ice/ami/Client.js +++ b/js/test/Ice/ami/Client.js @@ -39,7 +39,7 @@ const bf = b1.opBatch(); test(bf.isCompleted()); test(!bf.isSent()); - test(b1.opBatch()); + b1.opBatch(); await b1.ice_flushBatchRequests(); await p.waitForBatch(2); await b1.ice_flushBatchRequests(); diff --git a/js/test/Ice/binding/Client.js b/js/test/Ice/binding/Client.js index a5950a242ef..9be5252d6cf 100644 --- a/js/test/Ice/binding/Client.js +++ b/js/test/Ice/binding/Client.js @@ -231,7 +231,6 @@ await com.deactivateObjectAdapter(adapters[4]); --adapterCount; } - proxies = new Array(!0); for(let i = 0; i < proxies.length; ++i) { @@ -254,7 +253,7 @@ // ignore exception }); } - for(let i = 0; i < proxies.Length; i++) + for(let i = 0; i < proxies.length; i++) { try { diff --git a/js/test/Ice/hold/Client.js b/js/test/Ice/hold/Client.js index 07a02389cd7..9126131f3f5 100644 --- a/js/test/Ice/hold/Client.js +++ b/js/test/Ice/hold/Client.js @@ -38,7 +38,7 @@ { if(value != this.expected) { - this.condition.value = value; + this.condition.value = false; } } } diff --git a/js/test/Ice/operations/Server.js b/js/test/Ice/operations/Server.js index d4d9c5eaeb2..d0f46c27cbd 100644 --- a/js/test/Ice/operations/Server.js +++ b/js/test/Ice/operations/Server.js @@ -42,7 +42,7 @@ if(communicator) { - communicator.destroy(); + await communicator.destroy(); } } } diff --git a/js/test/Ice/operations/ServerAMD.js b/js/test/Ice/operations/ServerAMD.js index 9f738bf09b6..3fb2434a430 100644 --- a/js/test/Ice/operations/ServerAMD.js +++ b/js/test/Ice/operations/ServerAMD.js @@ -42,7 +42,7 @@ if(communicator) { - communicator.destroy(); + await communicator.destroy(); } } } diff --git a/js/test/Ice/optional/Server.js b/js/test/Ice/optional/Server.js index 07bec470976..63055e214ff 100644 --- a/js/test/Ice/optional/Server.js +++ b/js/test/Ice/optional/Server.js @@ -40,7 +40,7 @@ if(communicator) { - communicator.destroy(); + await communicator.destroy(); } } } diff --git a/js/test/Ice/optional/ServerAMD.js b/js/test/Ice/optional/ServerAMD.js index 399d757db41..3109875a0f7 100644 --- a/js/test/Ice/optional/ServerAMD.js +++ b/js/test/Ice/optional/ServerAMD.js @@ -40,7 +40,7 @@ if(communicator) { - communicator.destroy(); + await communicator.destroy(); } } } diff --git a/js/test/Ice/servantLocator/TestI.js b/js/test/Ice/servantLocator/TestI.js index 9e9f78d019b..b073c5d0ebb 100644 --- a/js/test/Ice/servantLocator/TestI.js +++ b/js/test/Ice/servantLocator/TestI.js @@ -38,7 +38,7 @@ { } - javaException(current) + jsException(current) { } diff --git a/js/test/Ice/stream/Client.js b/js/test/Ice/stream/Client.js index 8a59dd534e1..4cc31a9b3bf 100644 --- a/js/test/Ice/stream/Client.js +++ b/js/test/Ice/stream/Client.js @@ -198,8 +198,8 @@ } else { - test(o2.sh.Value == o.sh.Value); - test(o2.i.Value == o.i.Value); + test(o2.sh == o.sh); + test(o2.i == o.i); } } @@ -397,7 +397,7 @@ s.by = 1; s.sh = 2; s.i = 3; - s.l = 4; + s.l = new Ice.Long(4); s.f = 5.0; s.d = 6.0; s.str = "7"; @@ -443,8 +443,8 @@ inS = new Ice.InputStream(communicator, data); const arr2 = Test.MyClassSHelper.read(inS); inS.readPendingValues(); - test(arr2.Length == myClassArray.Length); - for(let i = 0; i < arr2.Length; ++i) + test(arr2.length == myClassArray.length); + for(let i = 0; i < arr2.length; ++i) { test(arr2[i] !== null); test(arr2[i].c == arr2[i]); @@ -481,17 +481,17 @@ inS = new Ice.InputStream(communicator, data); const arr2 = Test.MyInterfaceSHelper.read(inS); inS.readPendingValues(); - test(arr2.Length == myInterfaceArray.Length); + test(arr2.length == myInterfaceArray.length); const arrS = [myInterfaceArray, [], myInterfaceArray]; outS = new Ice.OutputStream(communicator); Test.MyInterfaceSSHelper.write(outS, arrS); data = outS.finished(); inS = new Ice.InputStream(communicator, data); const arr2S = Test.MyInterfaceSSHelper.read(inS); - test(arr2S.Length == arrS.Length); - test(arr2S[0].Length == arrS[0].Length); - test(arr2S[1].Length == arrS[1].Length); - test(arr2S[2].Length == arrS[2].Length); + test(arr2S.length == arrS.length); + test(arr2S[0].length == arrS[0].length); + test(arr2S[1].length == arrS[1].length); + test(arr2S[2].length == arrS[2].length); } { diff --git a/js/test/ts/Glacier2/router/Callback.ice b/js/test/ts/Glacier2/router/Callback.ice new file mode 100644 index 00000000000..ffa9fa4d225 --- /dev/null +++ b/js/test/ts/Glacier2/router/Callback.ice @@ -0,0 +1,39 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +exception CallbackException +{ + double someValue; + string someString; +} + +interface CallbackReceiver +{ + void callback(); + + void callbackEx() + throws CallbackException; +} + +interface Callback +{ + void initiateCallback(CallbackReceiver* proxy); + + void initiateCallbackEx(CallbackReceiver* proxy) + throws CallbackException; + + void shutdown(); +} + +} diff --git a/js/test/ts/Glacier2/router/Client.ts b/js/test/ts/Glacier2/router/Client.ts new file mode 100644 index 00000000000..199361e8655 --- /dev/null +++ b/js/test/ts/Glacier2/router/Client.ts @@ -0,0 +1,334 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice, Glacier2} from "ice"; +import {Test} from "./Callback"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; +const CallbackPrx = Test.CallbackPrx; +const CallbackReceiverPrx = Test.CallbackReceiverPrx; + +export class CallbackReceiverI extends Test.CallbackReceiver +{ + constructor() + { + super(); + this._callback = false; + this._p = new Ice.Promise(); + } + + callback(current:Ice.Current):void + { + test(!this._callback); + this._p.resolve(); + } + + callbackEx(current:Ice.Current):void + { + this.callback(current); + throw new Test.CallbackException(3.14, "3.14"); + } + + callbackOK():PromiseLike<void> + { + return this._p.then(() => + { + this._callback = false; + this._p = new Ice.Promise(); + }); + } + + _p:Ice.Promise<void>; + _callback:boolean; +} + +export class Client extends TestHelper +{ + async allTests(shutdown:boolean) + { + const out = this.getWriter(); + const communicator = this.communicator(); + + out.write("testing stringToProxy for router... "); + const routerBase = communicator.stringToProxy("Glacier2/router:" + this.getTestEndpoint(50)); + test(routerBase !== null); + out.writeLine("ok"); + + out.write("testing checked cast for router... "); + const router = await Glacier2.RouterPrx.checkedCast(routerBase); + test(router !== null); + out.writeLine("ok"); + + out.write("installing router with communicator... "); + communicator.setDefaultRouter(router); + out.writeLine("ok"); + + out.write("getting the session timeout... "); + const timeout = await router.getSessionTimeout(); + test(timeout.toNumber() === 30); + out.writeLine("ok"); + + out.write("testing stringToProxy for server object... "); + const base = communicator.stringToProxy("c1/callback:" + this.getTestEndpoint()); + out.writeLine("ok"); + + out.write("trying to ping server before session creation... "); + try + { + await base.ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ConnectionLostException, ex); + } + out.writeLine("ok"); + + out.write("trying to create session with wrong password... "); + try + { + await router.createSession("userid", "xxx"); + test(false); + } + catch(ex) + { + test(ex instanceof Glacier2.PermissionDeniedException, ex); + } + out.writeLine("ok"); + + out.write("trying to destroy non-existing session... "); + try + { + await router.destroySession(); + test(false); + } + catch(ex) + { + test(ex instanceof Glacier2.SessionNotExistException, ex); + } + out.writeLine("ok"); + + out.write("creating session with correct password... "); + await router.createSession("userid", "abc123"); + out.writeLine("ok"); + + out.write("trying to create a second session... "); + try + { + await router.createSession("userid", "abc123"); + test(false); + } + catch(ex) + { + test(ex instanceof Glacier2.CannotCreateSessionException, ex); + } + out.writeLine("ok"); + + out.write("pinging server after session creation... "); + await base.ice_ping(); + out.writeLine("ok"); + + { + out.write("pinging object with client endpoint... "); + const baseC = communicator.stringToProxy("collocated:" + this.getTestEndpoint(50)); + try + { + await baseC.ice_ping(); + } + catch(ex) + { + } + out.writeLine("ok"); + } + + out.write("testing checked cast for server object... "); + const twoway = await Test.CallbackPrx.checkedCast(base); + test(twoway !== null); + out.writeLine("ok"); + + out.write("creating and activating callback receiver adapter... "); + communicator.getProperties().setProperty("Ice.PrintAdapterReady", "0"); + const adapter = await communicator.createObjectAdapterWithRouter("CallbackReceiverAdapter", router); + await adapter.activate(); + out.writeLine("ok"); + + out.write("getting category from router... "); + const category = await router.getCategoryForClient(); + out.writeLine("ok"); + + out.write("creating and adding callback receiver object... "); + const callbackReceiverImpl = new CallbackReceiverI(); + const callbackReceiver = callbackReceiverImpl; + + const callbackReceiverIdent = new Ice.Identity(); + callbackReceiverIdent.name = "callbackReceiver"; + callbackReceiverIdent.category = category; + const twowayR = CallbackReceiverPrx.uncheckedCast(adapter.add(callbackReceiver, callbackReceiverIdent)); + + const fakeCallbackReceiverIdent = new Ice.Identity(); + fakeCallbackReceiverIdent.name = "callbackReceiver"; + fakeCallbackReceiverIdent.category = "dummy"; + const fakeTwowayR = CallbackReceiverPrx.uncheckedCast(adapter.add(callbackReceiver, fakeCallbackReceiverIdent)); + out.writeLine("ok"); + + out.write("testing oneway callback... "); + const oneway = CallbackPrx.uncheckedCast(twoway.ice_oneway()); + const onewayR = CallbackReceiverPrx.uncheckedCast(twowayR.ice_oneway()); + let context = new Ice.Context(); + context.set("_fwd", "o"); + await oneway.initiateCallback(onewayR, context); + await callbackReceiverImpl.callbackOK(); + out.writeLine("ok"); + + out.write("testing twoway callback... "); + context = new Ice.Context(); + context.set("_fwd", "t"); + await twoway.initiateCallback(twowayR, context); + await callbackReceiverImpl.callbackOK(); + out.writeLine("ok"); + + out.write("ditto, but with user exception... "); + context = new Ice.Context(); + context.set("_fwd", "t"); + try + { + await twoway.initiateCallbackEx(twowayR, context); + test(false); + } + catch(ex) + { + test(ex instanceof Test.CallbackException, ex); + test(ex.someValue == 3.14); + test(ex.someString == "3.14"); + } + + await callbackReceiverImpl.callbackOK(); + out.writeLine("ok"); + + out.write("trying twoway callback with fake category... "); + context = new Ice.Context(); + context.set("_fwd", "t"); + try + { + await twoway.initiateCallback(fakeTwowayR, context); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectNotExistException, ex); + } + out.writeLine("ok"); + + out.write("testing whether other allowed category is accepted... "); + context = new Ice.Context(); + context.set("_fwd", "t"); + let otherCategoryTwoway = CallbackPrx.uncheckedCast(twoway.ice_identity(Ice.stringToIdentity("c2/callback"))); + await otherCategoryTwoway.initiateCallback(twowayR, context); + await callbackReceiverImpl.callbackOK(); + out.writeLine("ok"); + + out.write("testing whether disallowed category gets rejected... "); + context = new Ice.Context(); + context.set("_fwd", "t"); + otherCategoryTwoway = CallbackPrx.uncheckedCast(twoway.ice_identity(Ice.stringToIdentity("c3/callback"))); + try + { + await otherCategoryTwoway.initiateCallback(twowayR, context); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectNotExistException, ex); + } + out.writeLine("ok"); + + out.write("testing whether user-id as category is accepted... "); + context = new Ice.Context(); + context.set("_fwd", "t"); + otherCategoryTwoway = CallbackPrx.uncheckedCast(twoway.ice_identity(Ice.stringToIdentity("_userid/callback"))); + await otherCategoryTwoway.initiateCallback(twowayR, context); + await callbackReceiverImpl.callbackOK(); + out.writeLine("ok"); + + if(shutdown) + { + out.write("testing server shutdown... "); + await twoway.shutdown(); + out.writeLine("ok"); + // No ping, otherwise the router prints a warning message if it's + // started with --Ice.Warn.Connections. + } + + out.write("destroying session... "); + await router.destroySession(); + out.writeLine("ok"); + + out.write("trying to ping server after session destruction... "); + try + { + await base.ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ConnectionLostException, ex); + } + out.writeLine("ok"); + + if(shutdown) + { + out.write("uninstalling router with communicator... "); + communicator.setDefaultRouter(null); + out.writeLine("ok"); + + out.write("testing stringToProxy for process object... "); + const processBase = communicator.stringToProxy("Glacier2/admin -f Process:" + this.getTestEndpoint(51)); + out.writeLine("ok"); + + out.write("testing checked cast for admin object... "); + const processPrx = await Ice.ProcessPrx.checkedCast(processBase); + test(processPrx !== null); + out.writeLine("ok"); + + out.write("testing Glacier2 shutdown... "); + await processPrx.shutdown(); + try + { + await processPrx.ice_timeout(500).ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.LocalException, ex); + } + out.writeLine("ok"); + } + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.Warn.Dispatch", "1"); + properties.setProperty("Ice.Warn.Connections", "0"); + [communicator] = this.initialize(properties); + await this.allTests(args.indexOf("--shutdown") > -1); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/acm/Client.ts b/js/test/ts/Ice/acm/Client.ts new file mode 100644 index 00000000000..d9a401ce1b8 --- /dev/null +++ b/js/test/ts/Ice/acm/Client.ts @@ -0,0 +1,553 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" + +const test = TestHelper.test; + +interface Output +{ + writeLine(data:string):void; + write(data:string):void; +} + +class LoggerI implements Ice.Logger +{ + constructor(out:Output) + { + this._messages = []; + this._out = out; + } + + print(msg:string):void + { + this._messages.push(msg); + } + + trace(category:string, message:string):void + { + this._messages.push("[" + category + "] " + message); + } + + warning(message:string):void + { + this._messages.push("warning: " + message); + } + + error(message:string):void + { + this._messages.push("error: " + message); + } + + cloneWithPrefix(prefix:string):Ice.Logger + { + return this; + } + + getPrefix():string + { + return ""; + } + + dump():void + { + this._messages.forEach(message => this._out.writeLine(message)); + this._messages = []; + } + + _messages:Array<string>; + _out:Output; +} + +abstract class TestCase +{ + constructor(name:string, com:Test.RemoteCommunicatorPrx, out:Output) + { + this._name = name; + this._com = com; + this._logger = new LoggerI(out); + this._msg = null; + + this._clientACMTimeout = -1; + this._clientACMClose = -1; + this._clientACMHeartbeat = -1; + + this._serverACMTimeout = -1; + this._serverACMClose = -1; + this._serverACMHeartbeat = -1; + + this._heartbeat = 0; + this._closed = false; + } + + async init() + { + const initData = new Ice.InitializationData(); + initData.properties = this._com.ice_getCommunicator().getProperties().clone(); + initData.logger = this._logger; + initData.properties.setProperty("Ice.ACM.Timeout", "2"); + if(this._clientACMTimeout >= 0) + { + initData.properties.setProperty("Ice.ACM.Client.Timeout", String(this._clientACMTimeout)); + } + if(this._clientACMClose >= 0) + { + initData.properties.setProperty("Ice.ACM.Client.Close", String(this._clientACMClose)); + } + if(this._clientACMHeartbeat >= 0) + { + initData.properties.setProperty("Ice.ACM.Client.Heartbeat", String(this._clientACMHeartbeat)); + } + this._communicator = Ice.initialize(initData); + + this._adapter = await this._com.createObjectAdapter(this._serverACMTimeout, + this._serverACMClose, + this._serverACMHeartbeat); + } + + async destroy() + { + await this._adapter.deactivate(); + await this._communicator.destroy(); + } + + join(out:Output) + { + this._logger.dump(); + out.write("testing " + this._name + "... "); + if(this._msg === null) + { + out.writeLine("ok"); + } + else + { + out.writeLine("failed! " + this._msg); + test(false); + } + } + + async start() + { + try + { + let prx = await this._adapter.getTestIntf(); + prx = Test.TestIntfPrx.uncheckedCast(this._communicator.stringToProxy(prx.toString())); + const con = await prx.ice_getConnection(); + con.setCloseCallback(connection => + { + this._closed = true; + }); + con.setHeartbeatCallback(connection => ++this._heartbeat); + await this.runTestCase(this._adapter, prx); + } + catch(ex) + { + this._msg = "unexpected exception:\n" + ex.toString() + "\n" + ex.stack; + } + } + + async waitForClosed() + { + const now = Date.now(); + while(!this._closed) + { + await Ice.Promise.delay(100); + if(Date.now() - now >= 2000) + { + test(false); // Waited for more than 2s for close, something's wrong. + } + } + } + + abstract runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx):void; + + setClientACM(timeout:number, close:number, heartbeat:number) + { + this._clientACMTimeout = timeout; + this._clientACMClose = close; + this._clientACMHeartbeat = heartbeat; + } + + setServerACM(timeout:number, close:number, heartbeat:number) + { + this._serverACMTimeout = timeout; + this._serverACMClose = close; + this._serverACMHeartbeat = heartbeat; + } + + _name:string; + _com:Test.RemoteCommunicatorPrx; + _adapter:Test.RemoteObjectAdapterPrx; + _logger:LoggerI; + _msg:string; + + _clientACMTimeout:number; + _clientACMClose:number; + _clientACMHeartbeat:number; + + _serverACMTimeout:number; + _serverACMClose:number; + _serverACMHeartbeat:number; + + _heartbeat:number; + _closed:boolean; + + _communicator:Ice.Communicator; +} + +class InvocationHeartbeatTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("invocation heartbeat", com, out); + this.setServerACM(1, -1, -1); // Faster ACM to make sure we receive enough ACM heartbeats + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + await proxy.sleep(4); + test(this._heartbeat >= 4); + } +} + +class InvocationHeartbeatOnHoldTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("invocation with heartbeat on hold", com, out); + // Use default ACM configuration. + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + // When the OA is put on hold, connections shouldn't + // send heartbeats, the invocation should therefore + // fail. + try + { + await proxy.sleepAndHold(10); + test(false); + } + catch(ex) + { + await adapter.activate(); + await proxy.interruptSleep(); + await this.waitForClosed(); + } + } +} + +class InvocationNoHeartbeatTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("invocation with no heartbeat", com, out); + this.setServerACM(2, 2, 0); // Disable heartbeat on invocations + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + // Heartbeats are disabled on the server, the + // invocation should fail since heartbeats are + // expected. + try + { + await proxy.sleep(10); + test(false); + } + catch(ex) + { + await proxy.interruptSleep(); + await this.waitForClosed(); + test(this._heartbeat === 0); + } + } +} + +class InvocationHeartbeatCloseOnIdleTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("invocation with no heartbeat and close on idle", com, out); + this.setClientACM(1, 1, 0); // Only close on idle. + this.setServerACM(1, 2, 0); // Disable heartbeat on invocations + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + // No close on invocation, the call should succeed this + // time. + await proxy.sleep(3); + test(this._heartbeat === 0); + test(!this._closed); + } +} + +class CloseOnIdleTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("close on idle", com, out); + this.setClientACM(1, 1, 0); // Only close on idle + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + await Ice.Promise.delay(3000); + await this.waitForClosed(); + test(this._heartbeat === 0); + } +} + +class CloseOnInvocationTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("close on invocation", com, out); + this.setClientACM(1, 2, 0); // Only close on invocation + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + await Ice.Promise.delay(3000); + test(this._heartbeat === 0); + test(!this._closed); + } +} + +class CloseOnIdleAndInvocationTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("close on idle and invocation", com, out); + this.setClientACM(1, 3, 0); // Only close on idle and invocation + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + // + // Put the adapter on hold. The server will not respond to + // the graceful close. This allows to test whether or not + // the close is graceful or forceful. + // + await adapter.hold(); + await Ice.Promise.delay(3000); + test(this._heartbeat === 0); + test(!this._closed); // Not closed yet because of graceful close. + await adapter.activate(); + await Ice.Promise.delay(1000); + await this.waitForClosed(); // Connection should be closed this time. + } +} + +class ForcefullCloseOnIdleAndInvocationTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("forcefull close on idle and invocation", com, out); + this.setClientACM(1, 4, 0); // Only close on idle and invocation + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + await adapter.hold(); + await Ice.Promise.delay(3000); + await this.waitForClosed(); + + test(this._heartbeat === 0); + } +} + +class HeartbeatOnIdleTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("heartbeat on idle", com, out); + this.setServerACM(1, -1, 2); // Enable server heartbeats. + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + await Ice.Promise.delay(3000); + return this._heartbeat >= 3; + } +} + +class HeartbeatAlwaysTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("heartbeat always", com, out); + this.setServerACM(1, -1, 3); // Enable server heartbeats. + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + for(let i = 0; i < 10; i++) + { + await proxy.ice_ping(); + await Ice.Promise.delay(300); + } + + test(this._heartbeat >= 3); + } +} + +class HeartbeatManualTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output) + { + super("manual heartbeats", com, out); + // + // Disable heartbeats. + // + this.setClientACM(10, -1, 0); + this.setServerACM(10, -1, 0); + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + await proxy.startHeartbeatCount(); + const con = await proxy.ice_getConnection(); + await con.heartbeat(); + await con.heartbeat(); + await con.heartbeat(); + await con.heartbeat(); + await con.heartbeat(); + await proxy.waitForHeartbeatCount(5); + } +} + +class SetACMTest extends TestCase +{ + constructor(com:Test.RemoteCommunicatorPrx, out:Output ) + { + super("setACM/getACM", com, out); + this.setClientACM(15, 4, 0); + } + + async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) + { + const con = proxy.ice_getCachedConnection(); + + try + { + con.setACM(-19, undefined, undefined); + test(false); + } + catch(ex) + { + } + + let acm = con.getACM(); + test(acm.timeout === 15); + test(acm.close === Ice.ACMClose.CloseOnIdleForceful); + test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOff); + + con.setACM(undefined, undefined, undefined); + acm = con.getACM(); + test(acm.timeout === 15); + test(acm.close === Ice.ACMClose.CloseOnIdleForceful); + test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOff); + + con.setACM(1, Ice.ACMClose.CloseOnInvocationAndIdle, Ice.ACMHeartbeat.HeartbeatAlways); + acm = con.getACM(); + test(acm.timeout === 1); + test(acm.close === Ice.ACMClose.CloseOnInvocationAndIdle); + test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatAlways); + + await proxy.startHeartbeatCount(); + await proxy.waitForHeartbeatCount(2); + + await new Promise( + (resolve, reject) => + { + con.setCloseCallback(() => resolve()); + con.close(Ice.ConnectionClose.Gracefully); + }); + + await new Promise( + (resolve, reject) => + { + con.setCloseCallback(() => resolve()); + }); + con.setHeartbeatCallback(c => test(false)); + } +} + +export class Client extends TestHelper +{ + async allTests() + { + const communicator = this.communicator(); + const out = this.getWriter(); + const ref = "communicator:" + this.getTestEndpoint(); + const com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + + const tests = []; + // + // Skip some tests with IE it opens too many connections and + // IE doesn't allow more than 6 connections. + // + if(typeof navigator !== "undefined" && + ["MSIE", "Trident/7.0", "Edge/12", "Edge/13"].some(value => navigator.userAgent.indexOf(value) !== -1)) + { + tests.push(new HeartbeatOnIdleTest(com, out)); + tests.push(new SetACMTest(com, out)); + } + else + { + tests.push(new InvocationHeartbeatTest(com, out)); + tests.push(new InvocationHeartbeatOnHoldTest(com, out)); + tests.push(new InvocationNoHeartbeatTest(com, out)); + tests.push(new InvocationHeartbeatCloseOnIdleTest(com, out)); + + tests.push(new CloseOnIdleTest(com, out)); + tests.push(new CloseOnInvocationTest(com, out)); + tests.push(new CloseOnIdleAndInvocationTest(com, out)); + tests.push(new ForcefullCloseOnIdleAndInvocationTest(com, out)); + + tests.push(new HeartbeatOnIdleTest(com, out)); + tests.push(new HeartbeatAlwaysTest(com, out)); + tests.push(new HeartbeatManualTest(com, out)); + tests.push(new SetACMTest(com, out)); + } + + await Promise.all(tests.map(test => test.init())); + await Promise.all(tests.map(test => test.start())); + for(const test of tests) + { + test.join(out); + } + await Promise.all(tests.map(test => test.destroy())); + + out.write("shutting down... "); + await com.shutdown(); + out.writeLine("ok"); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator, args] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/acm/Test.ice b/js/test/ts/Ice/acm/Test.ice new file mode 100644 index 00000000000..ebb38ff166b --- /dev/null +++ b/js/test/ts/Ice/acm/Test.ice @@ -0,0 +1,39 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +[["java:package:test.Ice.acm"]] +module Test +{ + +interface TestIntf +{ + void sleep(int seconds); + void sleepAndHold(int seconds); + void interruptSleep(); + void startHeartbeatCount(); + void waitForHeartbeatCount(int count); +} + +interface RemoteObjectAdapter +{ + TestIntf* getTestIntf(); + void activate(); + void hold(); + void deactivate(); +} + +interface RemoteCommunicator +{ + RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/adapterDeactivation/Client.ts b/js/test/ts/Ice/adapterDeactivation/Client.ts new file mode 100644 index 00000000000..7b1faec40e9 --- /dev/null +++ b/js/test/ts/Ice/adapterDeactivation/Client.ts @@ -0,0 +1,238 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + const out = this.getWriter(); + const communicator = this.communicator(); + + out.write("testing stringToProxy... "); + const ref = "test:" + this.getTestEndpoint(); + const base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + const obj = await Test.TestIntfPrx.checkedCast(base); + test(obj !== null); + test(obj.equals(base)); + out.writeLine("ok"); + + { + out.write("creating/destroying/recreating object adapter... "); + communicator.getProperties().setProperty("TransientTestAdapter.AdapterId", "dummy"); + let adapter = await communicator.createObjectAdapter("TransientTestAdapter"); + try + { + await communicator.createObjectAdapterWithEndpoints("TransientTestAdapter", ""); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.AlreadyRegisteredException); + } + await adapter.destroy(); + + // + // Use a different port than the first adapter to avoid an "address already in use" error. + // + adapter = await communicator.createObjectAdapterWithEndpoints("TransientTestAdapter", ""); + await adapter.destroy(); + out.writeLine("ok"); + } + + out.write("creating/activating/deactivating object adapter in one operation... "); + await obj.transient(); + out.writeLine("ok"); + + out.write("testing connection closure... "); + for(let i = 0; i < 10; ++i) + { + const initData = new Ice.InitializationData(); + initData.properties = communicator.getProperties().clone(); + const comm = Ice.initialize(initData); + comm.stringToProxy("test:" + this.getTestEndpoint()).ice_ping().catch(ex => {}); + await comm.destroy(); + } + out.writeLine("ok"); + + out.write("testing object adapter published endpoints... "); + { + communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 30000"); + const adapter = await communicator.createObjectAdapter("PAdapter"); + test(adapter.getPublishedEndpoints().length === 1); + const endpt = adapter.getPublishedEndpoints()[0]; + test(endpt.toString() == "tcp -h localhost -p 12345 -t 30000"); + const prx = + communicator.stringToProxy("dummy:tcp -h localhost -p 12346 -t 20000:tcp -h localhost -p 12347 -t 10000"); + adapter.setPublishedEndpoints(prx.ice_getEndpoints()); + test(adapter.getPublishedEndpoints().length === 2); + const id = new Ice.Identity("dummy"); + test(Ice.ArrayUtil.equals(adapter.createProxy(id).ice_getEndpoints(), prx.ice_getEndpoints())); + test(Ice.ArrayUtil.equals(adapter.getPublishedEndpoints(), prx.ice_getEndpoints())); + await adapter.refreshPublishedEndpoints(); + test(adapter.getPublishedEndpoints().length === 1); + test(adapter.getPublishedEndpoints()[0].equals(endpt)); + communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 20000"); + await adapter.refreshPublishedEndpoints(); + test(adapter.getPublishedEndpoints().length === 1); + test(adapter.getPublishedEndpoints()[0].toString() == "tcp -h localhost -p 12345 -t 20000"); + await adapter.destroy(); + test(adapter.getPublishedEndpoints().length === 0); + } + out.writeLine("ok"); + + test(obj.ice_getConnection() !== null); + { + out.write("testing object adapter with bi-dir connection... "); + const adapter = await communicator.createObjectAdapter(""); + (await obj.ice_getConnection()).setAdapter(adapter); + (await obj.ice_getConnection()).setAdapter(null); + await adapter.deactivate(); + try + { + (await obj.ice_getConnection()).setAdapter(adapter); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectAdapterDeactivatedException); + } + out.writeLine("ok"); + } + + out.write("testing object adapter with router... "); + { + const routerId = new Ice.Identity(); + routerId.name = "router"; + let router = Ice.RouterPrx.uncheckedCast(base.ice_identity(routerId).ice_connectionId("rc")); + const adapter = await communicator.createObjectAdapterWithRouter("", router); + test(adapter.getPublishedEndpoints().length == 1); + test(adapter.getPublishedEndpoints()[0].toString() == "tcp -h localhost -p 23456 -t 30000"); + await adapter.refreshPublishedEndpoints(); + test(adapter.getPublishedEndpoints().length == 1); + test(adapter.getPublishedEndpoints()[0].toString() == "tcp -h localhost -p 23457 -t 30000"); + try + { + adapter.setPublishedEndpoints(router.ice_getEndpoints()); + test(false); + } + catch(ex) + { + // Expected. + test(ex instanceof Error); + } + await adapter.destroy(); + + try + { + routerId.name = "test"; + router = Ice.RouterPrx.uncheckedCast(base.ice_identity(routerId)); + await communicator.createObjectAdapterWithRouter("", router); + test(false); + } + catch(ex) + { + // Expected: the "test" object doesn't implement Ice::Router! + test(ex instanceof Ice.OperationNotExistException); + } + + try + { + router = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("router:" + this.getTestEndpoint(1))); + await communicator.createObjectAdapterWithRouter("", router); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ConnectFailedException); + } + } + out.writeLine("ok"); + + out.write("deactivating object adapter in the server... "); + await obj.deactivate(); + out.writeLine("ok"); + + out.write("testing adapter states... "); + { + const adpt = await communicator.createObjectAdapter(""); + test(!adpt.isDeactivated()); + await adpt.activate(); + test(!adpt.isDeactivated()); + + let isHolding = false; + adpt.waitForHold().then(() => + { + isHolding = true; + }); + test(!isHolding); + adpt.hold(); + await adpt.waitForHold(); + await Ice.Promise.delay(10); // Relinquish the thread to allow the continuation to execute. + test(isHolding); + + isHolding = false; + adpt.waitForHold().then(() => + { + isHolding = true; + }); + + let isDeactivated = false; + adpt.waitForDeactivate().then(() => + { + isDeactivated = true; + }); + test(!isDeactivated); + await adpt.deactivate(); + await adpt.waitForDeactivate(); + await Ice.Promise.delay(10); // Relinquish the thread to allow the continuation to execute. + test(isDeactivated && isHolding); + test(adpt.isDeactivated()); + await adpt.destroy(); + } + out.writeLine("ok"); + + out.write("testing whether server is gone... "); + try + { + await obj.ice_timeout(100).ice_ping(); // Use timeout to speed up testing on Windows + throw new Error(); + } + catch(ex) + { + test(ex instanceof Ice.LocalException); + out.writeLine("ok"); + } + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator, args] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/adapterDeactivation/Test.ice b/js/test/ts/Ice/adapterDeactivation/Test.ice new file mode 100644 index 00000000000..16b6ba44592 --- /dev/null +++ b/js/test/ts/Ice/adapterDeactivation/Test.ice @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface TestIntf +{ + void transient(); + + void deactivate(); +} + +local class Cookie +{ + ["cpp:const"] string message(); +} + +} diff --git a/js/test/ts/Ice/ami/Client.ts b/js/test/ts/Ice/ami/Client.ts new file mode 100644 index 00000000000..f41db630d73 --- /dev/null +++ b/js/test/ts/Ice/ami/Client.ts @@ -0,0 +1,344 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + const communicator = this.communicator(); + const out = this.getWriter(); + + let sref = "test:" + this.getTestEndpoint(); + let obj = communicator.stringToProxy(sref); + test(obj !== null); + const p = Test.TestIntfPrx.uncheckedCast(obj); + + sref = "testController:" + this.getTestEndpoint(1); + obj = communicator.stringToProxy(sref); + test(obj !== null); + const testController = Test.TestIntfControllerPrx.uncheckedCast(obj); + + out.write("testing batch requests with proxy... "); + { + const count = await p.opBatchCount(); + test(count === 0); + const b1 = p.ice_batchOneway(); + const bf = b1.opBatch(); + test(bf.isCompleted()); + test(!bf.isSent()); + b1.opBatch(); + await b1.ice_flushBatchRequests(); + await p.waitForBatch(2); + await b1.ice_flushBatchRequests(); + } + out.writeLine("ok"); + + out.write("testing batch requests with connection... "); + { + test(await p.opBatchCount() === 0); + const b1 = p.ice_batchOneway(); + await b1.opBatch(); + const bf = b1.opBatch(); + test(bf.isCompleted()); + await b1.ice_flushBatchRequests(); + test(await p.waitForBatch(2)); + } + + if(await p.ice_getConnection() !== null) + { + test(await p.opBatchCount() == 0); + const b1 = p.ice_batchOneway(); + await b1.opBatch(); + await b1.ice_getConnection().then(conn => conn.close(Ice.ConnectionClose.GracefullyWithWait)); + await b1.ice_flushBatchRequests(); + test(await p.waitForBatch(1)); + } + out.writeLine("ok"); + + out.write("testing batch requests with communicator... "); + { + // + // Async task - 1 connection. + // + test(await p.opBatchCount() === 0); + const b1 = Test.TestIntfPrx.uncheckedCast( + await p.ice_getConnection().then(c => c.createProxy(p.ice_getIdentity()).ice_batchOneway())); + await b1.opBatch(); + await b1.opBatch(); + + await communicator.flushBatchRequests(Ice.CompressBatch.No); + test(await p.waitForBatch(2)); + } + + { + // + // Async task exception - 1 connection. + // + test(await p.opBatchCount() === 0); + const b1 = Test.TestIntfPrx.uncheckedCast( + await p.ice_getConnection().then(c => c.createProxy(p.ice_getIdentity()).ice_batchOneway())); + await b1.opBatch(); + await b1.ice_getConnection().then(c => c.close(Ice.ConnectionClose.GracefullyWithWait)); + + await communicator.flushBatchRequests(Ice.CompressBatch.No); + test(await p.opBatchCount() == 0); + } + + { + // + // Async task - 2 connections. + // + test(await p.opBatchCount() === 0); + const b1 = Test.TestIntfPrx.uncheckedCast( + await p.ice_getConnection().then(c => c.createProxy(p.ice_getIdentity()).ice_batchOneway())); + const b2 = Test.TestIntfPrx.uncheckedCast( + await p.ice_connectionId("2").ice_getConnection().then( + c => c.createProxy(p.ice_getIdentity()).ice_batchOneway())); + + await b2.ice_getConnection(); // Ensure connection is established. + await b1.opBatch(); + await b1.opBatch(); + await b2.opBatch(); + await b2.opBatch(); + + await communicator.flushBatchRequests(Ice.CompressBatch.No); + test(await p.waitForBatch(4)); + } + + { + // + // AsyncResult exception - 2 connections - 1 failure. + // + // All connections should be flushed even if there are failures on some connections. + // Exceptions should not be reported. + // + test(await p.opBatchCount() === 0); + const b1 = Test.TestIntfPrx.uncheckedCast( + await p.ice_getConnection().then(c => c.createProxy(p.ice_getIdentity()).ice_batchOneway())); + const b2 = Test.TestIntfPrx.uncheckedCast( + await p.ice_connectionId("2").ice_getConnection().then( + c => c.createProxy(p.ice_getIdentity()).ice_batchOneway())); + await b2.ice_getConnection(); // Ensure connection is established. + await b1.opBatch(); + await b2.opBatch(); + await b1.ice_getConnection().then(c => c.close(Ice.ConnectionClose.GracefullyWithWait)); + + await communicator.flushBatchRequests(Ice.CompressBatch.No); + test(await p.waitForBatch(1)); + } + + { + // + // Async task exception - 2 connections - 2 failures. + // + // The sent callback should be invoked even if all connections fail. + // + test(await p.opBatchCount() == 0); + const b1 = Test.TestIntfPrx.uncheckedCast( + await p.ice_getConnection().then(c => c.createProxy(p.ice_getIdentity()).ice_batchOneway())); + const b2 = Test.TestIntfPrx.uncheckedCast( + await p.ice_connectionId("2").ice_getConnection().then( + c => c.createProxy(p.ice_getIdentity()).ice_batchOneway())); + await b2.ice_getConnection(); // Ensure connection is established. + await b1.opBatch(); + await b2.opBatch(); + await b1.ice_getConnection().then(c => c.close(Ice.ConnectionClose.GracefullyWithWait)); + await b2.ice_getConnection().then(c => c.close(Ice.ConnectionClose.GracefullyWithWait)); + + await communicator.flushBatchRequests(Ice.CompressBatch.No); + test(await p.opBatchCount() === 0); + } + out.writeLine("ok"); + + out.write("testing AsyncResult operations... "); + { + await testController.holdAdapter(); + let r1:Ice.AsyncResult<void>; + let r2:Ice.AsyncResult<void>; + try + { + r1 = p.op(); + const seq = new Uint8Array(100000); + while(true) + { + r2 = p.opWithPayload(seq); + if(r2.sentSynchronously()) + { + await Ice.Promise.delay(0); + } + else + { + break; + } + } + + if(await p.ice_getConnection() !== null) + { + test(r1.sentSynchronously() && r1.isSent() && !r1.isCompleted() || + !r1.sentSynchronously() && !r1.isCompleted()); + + test(!r2.sentSynchronously() && !r2.isCompleted()); + + test(!r1.isCompleted()); + test(!r2.isCompleted()); + } + } + finally + { + await testController.resumeAdapter(); + } + + await r1; + test(r1.isSent()); + test(r1.isCompleted()); + + await r2; + test(r2.isSent()); + test(r2.isCompleted()); + + test(r1.operation == "op"); + test(r2.operation == "opWithPayload"); + + let r = p.ice_ping(); + test(r.operation === "ice_ping"); + test(r.connection === null); // Expected + test(r.communicator == communicator); + test(r.proxy == p); + + // + // Oneway + // + let p2 = p.ice_oneway(); + r = p2.ice_ping(); + test(r.operation === "ice_ping"); + test(r.connection === null); // Expected + test(r.communicator == communicator); + test(r.proxy == p2); + + // + // Batch request via proxy + // + p2 = p.ice_batchOneway(); + p2.ice_ping(); + { + let r2 = p2.ice_flushBatchRequests(); + test(r2.operation === "ice_flushBatchRequests"); + test(r2.connection === null); // Expected + test(r2.communicator == communicator); + test(r2.proxy == p2); + } + + const con = p.ice_getCachedConnection(); + p2 = p.ice_batchOneway(); + p2.ice_ping(); + { + let r2 = con.flushBatchRequests(Ice.CompressBatch.No); + test(r2.operation === "flushBatchRequests"); + test(r2.connection == con); + test(r2.communicator == communicator); + test(r2.proxy === null); + } + + p2 = p.ice_batchOneway(); + p2.ice_ping(); + { + let r2 = communicator.flushBatchRequests(Ice.CompressBatch.No); + test(r2.operation === "flushBatchRequests"); + test(r2.connection === null); + test(r2.communicator == communicator); + test(r2.proxy === null); + } + } + + { + await testController.holdAdapter(); + const seq = new Uint8Array(new Array(100000)); + let r; + while(true) + { + r = p.opWithPayload(seq); + if(r.sentSynchronously()) + { + await Ice.Promise.delay(0); + } + else + { + break; + } + } + + test(!r.isSent()); + + const r1 = p.ice_ping(); + r1.then( + () => test(false), + ex => test(ex instanceof Ice.InvocationCanceledException)); + + const r2 = p.ice_id(); + r2.then( + () => test(false), + ex => test(ex instanceof Ice.InvocationCanceledException)); + + r1.cancel(); + r2.cancel(); + + await testController.resumeAdapter(); + await p.ice_ping(); + + test(!r1.isSent() && r1.isCompleted()); + test(!r2.isSent() && r2.isCompleted()); + } + + { + await testController.holdAdapter(); + + const r1 = p.op(); + const r2 = p.ice_id(); + + await p.ice_oneway().ice_ping(); + + r1.cancel(); + r1.then( + () => test(false), + ex => test(ex instanceof Ice.InvocationCanceledException)); + + r2.cancel(); + r2.then( + () => test(false), + ex => test(ex instanceof Ice.InvocationCanceledException)); + + await testController.resumeAdapter(); + } + out.writeLine("ok"); + + await p.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator, args] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/ami/Test.ice b/js/test/ts/Ice/ami/Test.ice new file mode 100644 index 00000000000..27785cea8b9 --- /dev/null +++ b/js/test/ts/Ice/ami/Test.ice @@ -0,0 +1,62 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/BuiltinSequences.ice> +#include <Ice/Identity.ice> + +module Test +{ + +exception TestIntfException +{ +} + +enum CloseMode +{ + Forcefully, + Gracefully, + GracefullyWithWait +} + +interface PingReply +{ + void reply(); +} + +interface TestIntf +{ + void op(); + void opWithPayload(Ice::ByteSeq seq); + int opWithResult(); + void opWithUE() + throws TestIntfException; + void opBatch(); + int opBatchCount(); + bool waitForBatch(int count); + void close(CloseMode mode); + void sleep(int ms); + ["amd"] void startDispatch(); + void finishDispatch(); + void shutdown(); + + bool supportsAMD(); + bool supportsFunctionalTests(); + + void pingBidDir(Ice::Identity id); +} + +interface TestIntfController +{ + void holdAdapter(); + void resumeAdapter(); +} + +} diff --git a/js/test/ts/Ice/binding/Client.ts b/js/test/ts/Ice/binding/Client.ts new file mode 100644 index 00000000000..8a5838a5dc8 --- /dev/null +++ b/js/test/ts/Ice/binding/Client.ts @@ -0,0 +1,581 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +const isConnectionFailed = (ex:Error) => + (ex instanceof Ice.ConnectionRefusedException) || + (ex instanceof Ice.ConnectTimeoutException); + +export class Client extends TestHelper +{ + async allTests() + { + async function createTestIntfPrx(adapters:Test.RemoteObjectAdapterPrx[]) + { + let endpoints:Ice.Endpoint[] = []; + let obj = null; + for(const adapter of adapters) + { + obj = await adapter.getTestIntf(); + endpoints = endpoints.concat(obj.ice_getEndpoints()); + } + return Test.TestIntfPrx.uncheckedCast(obj.ice_endpoints(endpoints)); + } + + async function deactivate(communicator:Test.RemoteCommunicatorPrx, + adapters:Test.RemoteObjectAdapterPrx[]) + { + for(const adapter of adapters) + { + await communicator.deactivateObjectAdapter(adapter); + } + } + + const out = this.getWriter(); + let communicator = this.communicator(); + const properties = communicator.getProperties().clone(); + out.write("testing stringToProxy... "); + const ref = "communicator:" + this.getTestEndpoint(); + let com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + test(com !== null); + out.writeLine("ok"); + + out.write("testing binding with single endpoint... "); + { + const adapter = await com.createObjectAdapter("Adapter", "default"); + + const test1 = await adapter.getTestIntf(); + const test2 = await adapter.getTestIntf(); + test(await test1.ice_getConnection() === await test2.ice_getConnection()); + + await test1.ice_ping(); + await test2.ice_ping(); + + await com.deactivateObjectAdapter(adapter); + + const test3 = Test.TestIntfPrx.uncheckedCast(test1); + test(await test3.ice_getConnection() === await test1.ice_getConnection()); + test(await test3.ice_getConnection() === await test2.ice_getConnection()); + + try + { + await test3.ice_ping(); + test(false); + } + catch(ex) + { + test(isConnectionFailed(ex), ex); + } + + } + out.writeLine("ok"); + + await communicator.destroy(); + [communicator] = this.initialize(properties); + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + + out.write("testing binding with multiple endpoints... "); + { + const adapters = await Promise.all( + [ + com.createObjectAdapter("Adapter11", "default"), + com.createObjectAdapter("Adapter12", "default"), + com.createObjectAdapter("Adapter13", "default") + ]); + + // + // Ensure that when a connection is opened it's reused for new + // proxies and that all endpoints are eventually tried. + // + let names = ["Adapter11", "Adapter12", "Adapter13"]; + while(names.length > 0) + { + const adpts = Ice.ArrayUtil.clone(adapters); + const test1 = await createTestIntfPrx(adpts); + Ice.ArrayUtil.shuffle(adpts); + const test2 = await createTestIntfPrx(adpts); + Ice.ArrayUtil.shuffle(adpts); + const test3 = await createTestIntfPrx(adpts); + await test1.ice_ping(); + test(await test1.ice_getConnection() == await test2.ice_getConnection()); + test(await test2.ice_getConnection() == await test3.ice_getConnection()); + + const name = await test1.getAdapterName(); + const index = names.indexOf(name); + if(index !== -1) + { + names.splice(index, 1); + } + + const conn = await test1.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + } + // + // Ensure that the proxy correctly caches the connection (we + // always send the request over the same connection.) + // + { + for(const adpt of adapters) + { + const prx = await adpt.getTestIntf(); + await prx.ice_ping(); + } + + const t = await createTestIntfPrx(adapters); + const name = await t.getAdapterName(); + const nRetry = 10; + + let i; + /* eslint-disable curly */ + for(i = 0; i < nRetry && await t.getAdapterName() == name; i++); + /* eslint-enable curly */ + test(i == nRetry); + + for(const adpt of adapters) + { + const prx = await adpt.getTestIntf(); + const conn = await prx.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + } + } + // + // Deactivate an adapter and ensure that we can still + // establish the connection to the remaining adapters. + // + await com.deactivateObjectAdapter(adapters[0]); + names = ["Adapter12", "Adapter13"]; + while(names.length > 0) + { + const adpts = Ice.ArrayUtil.clone(adapters); + + const test1 = await createTestIntfPrx(adpts); + Ice.ArrayUtil.shuffle(adpts); + const test2 = await createTestIntfPrx(adpts); + Ice.ArrayUtil.shuffle(adpts); + const test3 = await createTestIntfPrx(adpts); + + test(await test1.ice_getConnection() == await test2.ice_getConnection()); + test(await test2.ice_getConnection() == await test3.ice_getConnection()); + + const name = await test1.getAdapterName(); + const index = names.indexOf(name); + if(index !== -1) + { + names.splice(index, 1); + } + const conn = await test1.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + } + // + // Deactivate an adapter and ensure that we can still + // establish the connection to the remaining adapter. + // + await com.deactivateObjectAdapter(adapters[2]); + const obj = await createTestIntfPrx(adapters); + test(await obj.getAdapterName() == "Adapter12"); + + await deactivate(com, adapters); + } + out.writeLine("ok"); + + await communicator.destroy(); + [communicator] = this.initialize(properties); + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + + out.write("testing binding with multiple random endpoints... "); + + const adapters = await Promise.all( + [ + com.createObjectAdapter("AdapterRandom11", "default"), + com.createObjectAdapter("AdapterRandom12", "default"), + com.createObjectAdapter("AdapterRandom13", "default"), + com.createObjectAdapter("AdapterRandom14", "default"), + com.createObjectAdapter("AdapterRandom15", "default") + ]); + + let count = 20; + let adapterCount = adapters.length; + while(--count > 0) + { + let proxies:Test.TestIntfPrx[] = []; + if(count == 1) + { + await com.deactivateObjectAdapter(adapters[4]); + --adapterCount; + } + + for(let i = 0; i < proxies.length; ++i) + { + let adpts = new Array(Math.floor(Math.random() * adapters.length)); + if(adpts.length == 0) + { + adpts = new Array(1); + } + for(let j = 0; j < adpts.length; ++j) + { + adpts[j] = adapters[Math.floor(Math.random() * adapters.length)]; + } + proxies[i] = await createTestIntfPrx(Ice.ArrayUtil.clone(adpts)); + } + + for(let i = 0; i < proxies.length; i++) + { + proxies[i].getAdapterName().catch( + ex => + { + // ignore exception + }); + } + for(let i = 0; i < proxies.length; i++) + { + try + { + await proxies[i].ice_ping(); + } + catch(ex) + { + test(ex instanceof Ice.LocalException, ex); + } + } + const connections = []; + for(let i = 0; i < proxies.length; i++) + { + if(proxies[i].ice_getCachedConnection() !== null) + { + if(connections.indexOf(proxies[i].ice_getCachedConnection()) === -1) + { + connections.push(proxies[i].ice_getCachedConnection()); + } + } + } + test(connections.length <= adapterCount); + + for(const a of adapters) + { + try + { + const prx = await a.getTestIntf(); + const conn = await prx.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + } + catch(ex) + { + // Expected if adapter is down. + test(ex instanceof Ice.LocalException, ex); + } + } + } + out.writeLine("ok"); + + await communicator.destroy(); + [communicator] = this.initialize(properties); + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + + out.write("testing random endpoint selection... "); + { + const adapters = await Promise.all( + [ + com.createObjectAdapter("Adapter21", "default"), + com.createObjectAdapter("Adapter22", "default"), + com.createObjectAdapter("Adapter23", "default") + ]); + + let obj = await createTestIntfPrx(adapters); + test(obj.ice_getEndpointSelection() == Ice.EndpointSelectionType.Random); + + let names = ["Adapter21", "Adapter22", "Adapter23"]; + while(names.length > 0) + { + const index = names.indexOf(await obj.getAdapterName()); + if(index !== -1) + { + names.splice(index, 1); + } + const conn = await obj.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + } + + obj = Test.TestIntfPrx.uncheckedCast(obj.ice_endpointSelection(Ice.EndpointSelectionType.Random)); + test(obj.ice_getEndpointSelection() == Ice.EndpointSelectionType.Random); + + names = ["Adapter21", "Adapter22", "Adapter23"]; + while(names.length > 0) + { + const index = names.indexOf(await obj.getAdapterName()); + if(index !== -1) + { + names.splice(index, 1); + } + const conn = await obj.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + } + + await deactivate(com, adapters); + } + out.writeLine("ok"); + + await communicator.destroy(); + [communicator] = this.initialize(properties); + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + + out.write("testing ordered endpoint selection... "); + { + let adapters:Test.RemoteObjectAdapterPrx[] = await Promise.all( + [ + com.createObjectAdapter("Adapter31", "default"), + com.createObjectAdapter("Adapter32", "default"), + com.createObjectAdapter("Adapter33", "default") + ]); + + let obj = await createTestIntfPrx(adapters); + obj = Test.TestIntfPrx.uncheckedCast(obj.ice_endpointSelection(Ice.EndpointSelectionType.Ordered)); + test(obj.ice_getEndpointSelection() == Ice.EndpointSelectionType.Ordered); + const nRetry = 3; + + // + // Ensure that endpoints are tried in order by deactiving the adapters + // one after the other. + // + /* eslint-disable curly */ + let i; + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter31"; i++); + test(i == nRetry); + await com.deactivateObjectAdapter(adapters[0]); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter32"; i++); + test(i == nRetry); + await com.deactivateObjectAdapter(adapters[1]); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter33"; i++); + test(i == nRetry); + await com.deactivateObjectAdapter(adapters[2]); + /* eslint-enable curly */ + + try + { + await obj.getAdapterName(); + } + catch(ex) + { + test(isConnectionFailed(ex), ex); + } + + const endpoints = obj.ice_getEndpoints(); + + adapters = []; + + // + // Now, re-activate the adapters with the same endpoints in the opposite + // order. + // + + /* eslint-disable curly */ + adapters.push(await com.createObjectAdapter("Adapter36", endpoints[2].toString())); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter36"; i++); + test(i == nRetry); + let conn = await obj.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + adapters.push(await com.createObjectAdapter("Adapter35", endpoints[1].toString())); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter35"; i++); + test(i == nRetry); + conn = await obj.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + adapters.push(await com.createObjectAdapter("Adapter34", endpoints[0].toString())); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter34"; i++); + test(i == nRetry); + /* eslint-enable curly */ + + await deactivate(com, adapters); + } + out.writeLine("ok"); + + await communicator.destroy(); + [communicator] = this.initialize(properties); + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + + out.write("testing per request binding with single endpoint... "); + { + const adapter = await com.createObjectAdapter("Adapter41", "default"); + + const test1 = Test.TestIntfPrx.uncheckedCast((await adapter.getTestIntf()).ice_connectionCached(false)); + const test2 = Test.TestIntfPrx.uncheckedCast((await adapter.getTestIntf()).ice_connectionCached(false)); + test(!test1.ice_isConnectionCached()); + test(!test2.ice_isConnectionCached()); + test(await test1.ice_getConnection() !== null && await test2.ice_getConnection() !== null); + test(await test1.ice_getConnection() == await test2.ice_getConnection()); + + await test1.ice_ping(); + + await com.deactivateObjectAdapter(adapter); + + const test3 = Test.TestIntfPrx.uncheckedCast(test1); + try + { + test(await test3.ice_getConnection() == await test1.ice_getConnection()); + test(false); + } + catch(ex) + { + test(isConnectionFailed(ex), ex); + } + } + out.writeLine("ok"); + + await communicator.destroy(); + [communicator] = this.initialize(properties); + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + + out.write("testing per request binding with multiple endpoints... "); + { + const adapters = await Promise.all( + [ + com.createObjectAdapter("Adapter51", "default"), + com.createObjectAdapter("Adapter52", "default"), + com.createObjectAdapter("Adapter53", "default") + ]); + + const obj = Test.TestIntfPrx.uncheckedCast( + (await createTestIntfPrx(adapters)).ice_connectionCached(false)); + test(!obj.ice_isConnectionCached()); + + let names = ["Adapter51", "Adapter52", "Adapter53"]; + while(names.length > 0) + { + const name = await obj.getAdapterName(); + const index = names.indexOf(name); + if(index !== -1) + { + names.splice(index, 1); + } + } + + await com.deactivateObjectAdapter(adapters[0]); + + names = ["Adapter52", "Adapter53"]; + while(names.length > 0) + { + const name = await obj.getAdapterName(); + const index = names.indexOf(name); + if(index !== -1) + { + names.splice(index, 1); + } + } + + await com.deactivateObjectAdapter(adapters[2]); + + test(await obj.getAdapterName() == "Adapter52"); + + await deactivate(com, adapters); + } + out.writeLine("ok"); + + if(typeof navigator === "undefined" || + ["Firefox", "MSIE", "Trident/7.0"].every(value => navigator.userAgent.indexOf(value) === -1)) + { + // + // Firefox adds a delay on websocket failed reconnects that causes this test to take too + // much time to complete. + // + // You can set network.websocket.delay-failed-reconnects to false in Firefox about:config + // to disable this behaviour + // + + await communicator.destroy(); + [communicator] = this.initialize(properties); + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); + + out.write("testing per request binding and ordered endpoint selection... "); + let adapters:Test.RemoteObjectAdapterPrx[] = await Promise.all( + [ + com.createObjectAdapter("Adapter61", "default"), + com.createObjectAdapter("Adapter62", "default"), + com.createObjectAdapter("Adapter63", "default") + ]); + + let obj = await createTestIntfPrx(adapters); + obj = Test.TestIntfPrx.uncheckedCast(obj.ice_endpointSelection(Ice.EndpointSelectionType.Ordered)); + test(obj.ice_getEndpointSelection() == Ice.EndpointSelectionType.Ordered); + obj = Test.TestIntfPrx.uncheckedCast(obj.ice_connectionCached(false)); + test(!obj.ice_isConnectionCached()); + const nRetry = 3; + let i; + + // + // Ensure that endpoints are tried in order by deactiving the adapters + // one after the other. + // + + /* eslint-disable curly */ + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter61"; i++); + test(i == nRetry); + await com.deactivateObjectAdapter(adapters[0]); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter62"; i++); + test(i == nRetry); + await com.deactivateObjectAdapter(adapters[1]); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter63"; i++); + test(i == nRetry); + com.deactivateObjectAdapter(adapters[2]); + /* eslint-enable curly */ + + try + { + await obj.getAdapterName(); + } + catch(ex) + { + test(isConnectionFailed(ex), ex); + } + + const endpoints = obj.ice_getEndpoints(); + + adapters = []; + + // + // Now, re-activate the adapters with the same endpoints in the opposite + // order. + // + /* eslint-disable curly */ + adapters.push(await com.createObjectAdapter("Adapter66", endpoints[2].toString())); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter66"; i++); + test(i == nRetry); + adapters.push(await com.createObjectAdapter("Adapter65", endpoints[1].toString())); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter65"; i++); + test(i == nRetry); + adapters.push(await com.createObjectAdapter("Adapter64", endpoints[0].toString())); + for(i = 0; i < nRetry && await obj.getAdapterName() == "Adapter64"; i++); + test(i == nRetry); + /* eslint-enable curly */ + await deactivate(com, adapters); + out.writeLine("ok"); + } + + await com.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + const out = this.getWriter(); + [communicator, args] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/binding/Test.ice b/js/test/ts/Ice/binding/Test.ice new file mode 100644 index 00000000000..b103ed272c5 --- /dev/null +++ b/js/test/ts/Ice/binding/Test.ice @@ -0,0 +1,36 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface TestIntf +{ + string getAdapterName(); +} + +interface RemoteObjectAdapter +{ + TestIntf* getTestIntf(); + + void deactivate(); +} + +interface RemoteCommunicator +{ + RemoteObjectAdapter* createObjectAdapter(string name, string endpoints); + + void deactivateObjectAdapter(RemoteObjectAdapter* adapter); + + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/defaultValue/Client.ts b/js/test/ts/Ice/defaultValue/Client.ts new file mode 100644 index 00000000000..4998f670618 --- /dev/null +++ b/js/test/ts/Ice/defaultValue/Client.ts @@ -0,0 +1,195 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + run() + { + const out = this.getWriter(); + out.write("testing default values... "); + { + const v = new Test.Struct1(); + test(!v.boolFalse); + test(v.boolTrue); + test(v.b === 254); + test(v.s === 16000); + test(v.i === 3); + test(v.l.equals(new Ice.Long(0, 4))); + test(v.f === 5.1); + test(v.d === 6.2); + test(v.str === "foo \\ \"bar\n \r\n\t\u000b\f\u0007\b?"); + test(v.c1 === Test.Color.red); + test(v.c2 === Test.Color.green); + test(v.c3 === Test.Color.blue); + test(v.nc1 === Test.Nested.Color.red); + test(v.nc2 === Test.Nested.Color.green); + test(v.nc3 === Test.Nested.Color.blue); + test(v.noDefault === ""); + test(v.zeroI === 0); + test(v.zeroL.equals(new Ice.Long(0, 0))); + test(v.zeroF === 0); + test(v.zeroDotF === 0); + test(v.zeroD === 0); + test(v.zeroDotD === 0); + } + + { + const v = new Test.Struct2(); + test(v.boolTrue === Test.ConstBool); + test(v.b === Test.ConstByte); + test(v.s === Test.ConstShort); + test(v.i === Test.ConstInt); + test(v.l.equals(Test.ConstLong)); + test(v.f === Test.ConstFloat); + test(v.d === Test.ConstDouble); + test(v.str === Test.ConstString); + test(v.c1 === Test.ConstColor1); + test(v.c2 === Test.ConstColor2); + test(v.c3 === Test.ConstColor3); + test(v.nc1 === Test.ConstNestedColor1); + test(v.nc2 === Test.ConstNestedColor2); + test(v.nc3 === Test.ConstNestedColor3); + } + + { + const v = new Test.Base(); + test(!v.boolFalse); + test(v.boolTrue); + test(v.b === 1); + test(v.s === 2); + test(v.i === 3); + test(v.l.equals(new Ice.Long(0, 4))); + test(v.f === 5.1); + test(v.d === 6.2); + test(v.str == "foo \\ \"bar\n \r\n\t\u000b\f\u0007\b?"); + test(v.noDefault === ""); + test(v.zeroI === 0); + test(v.zeroL.equals(new Ice.Long(0, 0))); + test(v.zeroF === 0); + test(v.zeroDotF === 0); + test(v.zeroD === 0); + test(v.zeroDotD === 0); + } + + { + const v = new Test.Derived(); + test(!v.boolFalse); + test(v.boolTrue); + test(v.b === 1); + test(v.s === 2); + test(v.i === 3); + test(v.l.equals(new Ice.Long(0, 4))); + test(v.f === 5.1); + test(v.d === 6.2); + test(v.str == "foo \\ \"bar\n \r\n\t\u000b\f\u0007\b?"); + test(v.c1 === Test.Color.red); + test(v.c2 === Test.Color.green); + test(v.c3 === Test.Color.blue); + test(v.nc1 === Test.Nested.Color.red); + test(v.nc2 === Test.Nested.Color.green); + test(v.nc3 === Test.Nested.Color.blue); + test(v.noDefault === ""); + test(v.zeroI === 0); + test(v.zeroL.equals(new Ice.Long(0, 0))); + test(v.zeroF === 0); + test(v.zeroDotF === 0); + test(v.zeroD === 0); + test(v.zeroDotD === 0); + } + + { + const v = new Test.BaseEx(); + test(!v.boolFalse); + test(v.boolTrue); + test(v.b === 1); + test(v.s === 2); + test(v.i === 3); + test(v.l.equals(new Ice.Long(0, 4))); + test(v.f === 5.1); + test(v.d === 6.2); + test(v.str == "foo \\ \"bar\n \r\n\t\u000b\f\u0007\b?"); + test(v.noDefault === ""); + test(v.zeroI === 0); + test(v.zeroL.equals(new Ice.Long(0, 0))); + test(v.zeroF === 0); + test(v.zeroDotF === 0); + test(v.zeroD === 0); + test(v.zeroDotD === 0); + } + + { + const v = new Test.DerivedEx(); + test(!v.boolFalse); + test(v.boolTrue); + test(v.b === 1); + test(v.s === 2); + test(v.i === 3); + test(v.l.equals(new Ice.Long(0, 4))); + test(v.f === 5.1); + test(v.d === 6.2); + test(v.str == "foo \\ \"bar\n \r\n\t\u000b\f\u0007\b?"); + test(v.noDefault === ""); + test(v.c1 === Test.Color.red); + test(v.c2 === Test.Color.green); + test(v.c3 === Test.Color.blue); + test(v.nc1 === Test.Nested.Color.red); + test(v.nc2 === Test.Nested.Color.green); + test(v.nc3 === Test.Nested.Color.blue); + test(v.zeroI === 0); + test(v.zeroL.equals(new Ice.Long(0, 0))); + test(v.zeroF === 0); + test(v.zeroDotF === 0); + test(v.zeroD === 0); + test(v.zeroDotD === 0); + } + out.writeLine("ok"); + + out.write("testing default constructor... "); + { + const v2 = new Test.StructNoDefaults(); + test(v2.bo === false); + test(v2.b === 0); + test(v2.s === 0); + test(v2.i === 0); + test(v2.l.equals(new Ice.Long(0, 0))); + test(v2.f === 0.0); + test(v2.d === 0.0); + test(v2.str === ""); + test(v2.c1 == Test.Color.red); + test(v2.bs === null); + test(v2.is === null); + test(v2.st !== null && v2.st instanceof Test.InnerStruct); + test(v2.dict === null); + } + + { + const e = new Test.ExceptionNoDefaults(); + test(e.str === ""); + test(e.c1 == Test.Color.red); + test(e.bs === null); + test(e.st !== null && e.st instanceof Test.InnerStruct); + test(e.dict === null); + } + + { + const cl = new Test.ClassNoDefaults(); + test(cl.str === ""); + test(cl.c1 == Test.Color.red); + test(cl.bs === null); + test(cl.st !== null && cl.st instanceof Test.InnerStruct); + test(cl.dict === null); + } + out.writeLine("ok"); + } +} diff --git a/js/test/ts/Ice/defaultValue/Test.ice b/js/test/ts/Ice/defaultValue/Test.ice new file mode 100644 index 00000000000..fb4004d85b9 --- /dev/null +++ b/js/test/ts/Ice/defaultValue/Test.ice @@ -0,0 +1,236 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +[["suppress-warning:deprecated"]] // For enumerator references + +module Test +{ + +enum Color { red, green, blue } + +module Nested +{ + +enum Color { red, green, blue } + +} + +struct Struct1 +{ + bool boolFalse = false; + bool boolTrue = true; + byte b = 254; + short s = 16000; + int i = 3; + long l = 4; + float f = 5.1; + double d = 6.2; + string str = "foo \\ \"bar\n \r\n\t\v\f\a\b\?"; + Color c1 = ::Test::Color::red; + Color c2 = Test::green; + Color c3 = blue; + Nested::Color nc1 = Test::Nested::Color::red; + Nested::Color nc2 = Nested::green; + Nested::Color nc3 = blue; + string noDefault; + int zeroI = 0; + long zeroL = 0; + float zeroF = 0; + float zeroDotF = 0.0; + double zeroD = 0; + double zeroDotD = 0; +} + +const bool ConstBool = true; +const byte ConstByte = 254; +const short ConstShort = 16000; +const int ConstInt = 3; +const long ConstLong = 4; +const float ConstFloat = 5.1; +const double ConstDouble = 6.2; +const string ConstString = "foo \\ \"bar\n \r\n\t\v\f\a\b\?"; +const Color ConstColor1 = ::Test::Color::red; +const Color ConstColor2 = Test::green; +const Color ConstColor3 = blue; +const Nested::Color ConstNestedColor1 = Test::Nested::Color::red; +const Nested::Color ConstNestedColor2 = Test::Nested::green; +const Nested::Color ConstNestedColor3 = blue; +const int ConstZeroI = 0; +const long ConstZeroL = 0; +const float ConstZeroF = 0; +const float ConstZeroDotF = 0.0; +const double ConstZeroD = 0; +const double ConstZeroDotD = 0; + +struct Struct2 +{ + bool boolTrue = ConstBool; + byte b = ConstByte; + short s = ConstShort; + int i = ConstInt; + long l = ConstLong; + float f = ConstFloat; + double d = ConstDouble; + string str = ConstString; + Color c1 = ConstColor1; + Color c2 = ConstColor2; + Color c3 = ConstColor3; + Nested::Color nc1 = ConstNestedColor1; + Nested::Color nc2 = ConstNestedColor2; + Nested::Color nc3 = ConstNestedColor3; + int zeroI = ConstZeroI; + long zeroL = ConstZeroL; + float zeroF = ConstZeroF; + float zeroDotF = ConstZeroDotF; + double zeroD = ConstZeroD; + double zeroDotD = ConstZeroDotD; +} + +["cpp:class"] +struct Struct3 +{ + bool boolFalse = false; + bool boolTrue = true; + byte b = 1; + short s = 2; + int i = 3; + long l = 4; + float f = 5.1; + double d = 6.2; + string str = "foo \\ \"bar\n \r\n\t\v\f\a\b\?"; + Color c1 = ::Test::Color::red; + Color c2 = Test::green; + Color c3 = blue; + Nested::Color nc1 = ::Test::Nested::Color::red; + Nested::Color nc2 = Nested::green; + Nested::Color nc3 = blue; + string noDefault; + int zeroI = 0; + long zeroL = 0; + float zeroF = 0; + float zeroDotF = 0.0; + double zeroD = 0; + double zeroDotD = 0; +} + +class Base +{ + bool boolFalse = false; + bool boolTrue = true; + byte b = 1; + short s = 2; + int i = 3; + long l = 4; + float f = 5.1; + double d = 6.2; + string str = "foo \\ \"bar\n \r\n\t\v\f\a\b\?"; + string noDefault; + int zeroI = 0; + long zeroL = 0; + float zeroF = 0; + float zeroDotF = 0.0; + double zeroD = 0; + double zeroDotD = 0; +} + +class Derived extends Base +{ + Color c1 = ::Test::Color::red; + Color c2 = Test::green; + Color c3 = blue; + Nested::Color nc1 = ::Test::Nested::Color::red; + Nested::Color nc2 = Nested::green; + Nested::Color nc3 = blue; +} + +exception BaseEx +{ + bool boolFalse = false; + bool boolTrue = true; + byte b = 1; + short s = 2; + int i = 3; + long l = 4; + float f = 5.1; + double d = 6.2; + string str = "foo \\ \"bar\n \r\n\t\v\f\a\b\?"; + string noDefault; + int zeroI = 0; + long zeroL = 0; + float zeroF = 0; + float zeroDotF = 0.0; + double zeroD = 0; + double zeroDotD = 0; +} + +exception DerivedEx extends BaseEx +{ + Color c1 = ConstColor1; + Color c2 = ConstColor2; + Color c3 = ConstColor3; + Nested::Color nc1 = ConstNestedColor1; + Nested::Color nc2 = ConstNestedColor2; + Nested::Color nc3 = ConstNestedColor3; +} + +sequence<byte> ByteSeq; +sequence<int> IntSeq; +dictionary<int, string> IntStringDict; + +struct InnerStruct +{ + int a; +} + +struct StructNoDefaults +{ + bool bo; + byte b; + short s; + int i; + long l; + float f; + double d; + string str; + Color c1; + ByteSeq bs; + IntSeq is; + InnerStruct st; + IntStringDict dict; +} + +exception ExceptionNoDefaultsBase +{ + string str; + Color c1; + ByteSeq bs; +} + +exception ExceptionNoDefaults extends ExceptionNoDefaultsBase +{ + InnerStruct st; + IntStringDict dict; +} + +class ClassNoDefaultsBase +{ + string str; + Color c1; + ByteSeq bs; +} + +class ClassNoDefaults extends ClassNoDefaultsBase +{ + InnerStruct st; + IntStringDict dict; +} + +} diff --git a/js/test/ts/Ice/enums/Client.ts b/js/test/ts/Ice/enums/Client.ts new file mode 100644 index 00000000000..5ac3eef79c7 --- /dev/null +++ b/js/test/ts/Ice/enums/Client.ts @@ -0,0 +1,187 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + const out = this.getWriter(); + const communicator = this.communicator(); + + out.write("testing stringToProxy... "); + const ref = "test:" + this.getTestEndpoint(); + const base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + const proxy = await Test.TestIntfPrx.checkedCast(base); + test(proxy !== null); + test(proxy.equals(base)); + out.writeLine("ok"); + + out.write("testing enum values... "); + test(Test.ByteEnum.benum1.value === 0); + test(Test.ByteEnum.benum2.value === 1); + test(Test.ByteEnum.benum3.value === Test.ByteConst1); + test(Test.ByteEnum.benum4.value === Test.ByteConst1 + 1); + test(Test.ByteEnum.benum5.value === Test.ShortConst1); + test(Test.ByteEnum.benum6.value === Test.ShortConst1 + 1); + test(Test.ByteEnum.benum7.value === Test.IntConst1); + test(Test.ByteEnum.benum8.value === Test.IntConst1 + 1); + test(Test.ByteEnum.benum9.value === Test.LongConst1.low); + test(Test.ByteEnum.benum10.value === Test.LongConst1.low + 1); + test(Test.ByteEnum.benum11.value === Test.ByteConst2); + + test(Test.ByteEnum.valueOf(0) === Test.ByteEnum.benum1); + test(Test.ByteEnum.valueOf(1) === Test.ByteEnum.benum2); + test(Test.ByteEnum.valueOf(Test.ByteConst1) === Test.ByteEnum.benum3); + test(Test.ByteEnum.valueOf(Test.ByteConst1 + 1) === Test.ByteEnum.benum4); + test(Test.ByteEnum.valueOf(Test.ShortConst1) === Test.ByteEnum.benum5); + test(Test.ByteEnum.valueOf(Test.ShortConst1 + 1) === Test.ByteEnum.benum6); + test(Test.ByteEnum.valueOf(Test.IntConst1) === Test.ByteEnum.benum7); + test(Test.ByteEnum.valueOf(Test.IntConst1 + 1) === Test.ByteEnum.benum8); + test(Test.ByteEnum.valueOf(Test.LongConst1.low) === Test.ByteEnum.benum9); + test(Test.ByteEnum.valueOf(Test.LongConst1.low + 1) === Test.ByteEnum.benum10); + test(Test.ByteEnum.valueOf(Test.ByteConst2) === Test.ByteEnum.benum11); + + test(Test.ShortEnum.senum1.value === 3); + test(Test.ShortEnum.senum2.value === 4); + test(Test.ShortEnum.senum3.value === Test.ByteConst1); + test(Test.ShortEnum.senum4.value === Test.ByteConst1 + 1); + test(Test.ShortEnum.senum5.value === Test.ShortConst1); + test(Test.ShortEnum.senum6.value === Test.ShortConst1 + 1); + test(Test.ShortEnum.senum7.value === Test.IntConst1); + test(Test.ShortEnum.senum8.value === Test.IntConst1 + 1); + test(Test.ShortEnum.senum9.value === Test.LongConst1.low); + test(Test.ShortEnum.senum10.value === Test.LongConst1.low + 1); + test(Test.ShortEnum.senum11.value === Test.ShortConst2); + + test(Test.ShortEnum.valueOf(3) === Test.ShortEnum.senum1); + test(Test.ShortEnum.valueOf(4) === Test.ShortEnum.senum2); + test(Test.ShortEnum.valueOf(Test.ByteConst1) === Test.ShortEnum.senum3); + test(Test.ShortEnum.valueOf(Test.ByteConst1 + 1) === Test.ShortEnum.senum4); + test(Test.ShortEnum.valueOf(Test.ShortConst1) === Test.ShortEnum.senum5); + test(Test.ShortEnum.valueOf(Test.ShortConst1 + 1) === Test.ShortEnum.senum6); + test(Test.ShortEnum.valueOf(Test.IntConst1) === Test.ShortEnum.senum7); + test(Test.ShortEnum.valueOf(Test.IntConst1 + 1) === Test.ShortEnum.senum8); + test(Test.ShortEnum.valueOf(Test.LongConst1.low) === Test.ShortEnum.senum9); + test(Test.ShortEnum.valueOf(Test.LongConst1.low + 1) === Test.ShortEnum.senum10); + test(Test.ShortEnum.valueOf(Test.ShortConst2) === Test.ShortEnum.senum11); + + test(Test.IntEnum.ienum1.value === 0); + test(Test.IntEnum.ienum2.value === 1); + test(Test.IntEnum.ienum3.value === Test.ByteConst1); + test(Test.IntEnum.ienum4.value === Test.ByteConst1 + 1); + test(Test.IntEnum.ienum5.value === Test.ShortConst1); + test(Test.IntEnum.ienum6.value === Test.ShortConst1 + 1); + test(Test.IntEnum.ienum7.value === Test.IntConst1); + test(Test.IntEnum.ienum8.value === Test.IntConst1 + 1); + test(Test.IntEnum.ienum9.value === Test.LongConst1.low); + test(Test.IntEnum.ienum10.value === Test.LongConst1.low + 1); + test(Test.IntEnum.ienum11.value === Test.IntConst2); + test(Test.IntEnum.ienum12.value === Test.LongConst2.low); + + test(Test.IntEnum.valueOf(0) === Test.IntEnum.ienum1); + test(Test.IntEnum.valueOf(1) === Test.IntEnum.ienum2); + test(Test.IntEnum.valueOf(Test.ByteConst1) === Test.IntEnum.ienum3); + test(Test.IntEnum.valueOf(Test.ByteConst1 + 1) === Test.IntEnum.ienum4); + test(Test.IntEnum.valueOf(Test.ShortConst1) === Test.IntEnum.ienum5); + test(Test.IntEnum.valueOf(Test.ShortConst1 + 1) === Test.IntEnum.ienum6); + test(Test.IntEnum.valueOf(Test.IntConst1) === Test.IntEnum.ienum7); + test(Test.IntEnum.valueOf(Test.IntConst1 + 1) === Test.IntEnum.ienum8); + test(Test.IntEnum.valueOf(Test.LongConst1.low) === Test.IntEnum.ienum9); + test(Test.IntEnum.valueOf(Test.LongConst1.low + 1) === Test.IntEnum.ienum10); + test(Test.IntEnum.valueOf(Test.IntConst2) === Test.IntEnum.ienum11); + test(Test.IntEnum.valueOf(Test.LongConst2.low) === Test.IntEnum.ienum12); + + test(Test.SimpleEnum.red.value === 0); + test(Test.SimpleEnum.green.value === 1); + test(Test.SimpleEnum.blue.value === 2); + + test(Test.SimpleEnum.valueOf(0) === Test.SimpleEnum.red); + test(Test.SimpleEnum.valueOf(1) === Test.SimpleEnum.green); + test(Test.SimpleEnum.valueOf(2) === Test.SimpleEnum.blue); + + out.writeLine("ok"); + + out.write("testing enum operations... "); + { + const [ret, b1] = await proxy.opByte(Test.ByteEnum.benum1); + test(ret === b1); + test(ret === Test.ByteEnum.benum1); + } + + { + const [ret, b11] = await proxy.opByte(Test.ByteEnum.benum11); + test(ret === b11); + test(ret === Test.ByteEnum.benum11); + } + + { + const [ret, s1] = await proxy.opShort(Test.ShortEnum.senum1); + test(ret === s1); + test(ret === Test.ShortEnum.senum1); + } + + { + const [ret, s11] = await proxy.opShort(Test.ShortEnum.senum11); + test(ret === s11); + test(ret === Test.ShortEnum.senum11); + } + + { + const [ret, i1] = await proxy.opInt(Test.IntEnum.ienum1); + test(ret === i1); + test(ret === Test.IntEnum.ienum1); + } + + { + const [ret, i11] = await proxy.opInt(Test.IntEnum.ienum11); + test(ret === i11); + test(ret === Test.IntEnum.ienum11); + } + + { + const [ret, i12] = await proxy.opInt(Test.IntEnum.ienum12); + test(ret === i12); + test(ret === Test.IntEnum.ienum12); + } + + { + const [ret, g] = await proxy.opSimple(Test.SimpleEnum.green); + test(ret === g); + test(ret === Test.SimpleEnum.green); + } + out.writeLine("ok"); + await proxy.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/enums/Test.ice b/js/test/ts/Ice/enums/Test.ice new file mode 100644 index 00000000000..f4395aff480 --- /dev/null +++ b/js/test/ts/Ice/enums/Test.ice @@ -0,0 +1,88 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +const byte ByteConst1 = 10; +const short ShortConst1 = 20; +const int IntConst1 = 30; +const long LongConst1 = 40; + +const byte ByteConst2 = 126; +const short ShortConst2 = 32766; +const int IntConst2 = 2147483647; +const long LongConst2 = 2147483646; + +enum ByteEnum +{ + benum1, + benum2, + benum3 = ByteConst1, + benum4, + benum5 = ShortConst1, + benum6, + benum7 = IntConst1, + benum8, + benum9 = LongConst1, + benum10, + benum11 = ByteConst2 +} + +enum ShortEnum +{ + senum1 = 3, + senum2, + senum3 = ByteConst1, + senum4, + senum5 = ShortConst1, + senum6, + senum7 = IntConst1, + senum8, + senum9 = LongConst1, + senum10, + senum11 = ShortConst2 +} + +enum IntEnum +{ + ienum1, + ienum2, + ienum3 = ByteConst1, + ienum4, + ienum5 = ShortConst1, + ienum6, + ienum7 = IntConst1, + ienum8, + ienum9 = LongConst1, + ienum10, + ienum11 = IntConst2, + ienum12 = LongConst2 +} + +enum SimpleEnum +{ + red, + green, + blue +} + +interface TestIntf +{ + ByteEnum opByte(ByteEnum b1, out ByteEnum b2); + ShortEnum opShort(ShortEnum s1, out ShortEnum s2); + IntEnum opInt(IntEnum i1, out IntEnum i2); + SimpleEnum opSimple(SimpleEnum s1, out SimpleEnum s2); + + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/exceptions/AMDThrowerI.ts b/js/test/ts/Ice/exceptions/AMDThrowerI.ts new file mode 100644 index 00000000000..588689635fe --- /dev/null +++ b/js/test/ts/Ice/exceptions/AMDThrowerI.ts @@ -0,0 +1,122 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class AMDThrowerI extends Test.Thrower +{ + shutdown(current:Ice.Current):void + { + current.adapter.getCommunicator().shutdown(); + } + + supportsUndeclaredExceptions(current:Ice.Current):boolean + { + return true; + } + + supportsAssertException(current:Ice.Current):boolean + { + return false; + } + + throwAasA(a:number, current:Ice.Current):void + { + throw new Test.A(a); + } + + throwAorDasAorD(a:number, current:Ice.Current):void + { + if(a > 0) + { + throw new Test.A(a); + } + else + { + throw new Test.D(a); + } + } + + throwBasA(a:number, b:number, current:Ice.Current):void + { + return this.throwBasB(a, b, current); + } + + throwBasB(a:number, b:number, current:Ice.Current):void + { + throw new Test.B(a, b); + } + + throwCasA(a:number, b:number, c:number, current:Ice.Current):void + { + return this.throwCasC(a, b, c, current); + } + + throwCasB(a:number, b:number, c:number, current:Ice.Current):void + { + return this.throwCasC(a, b, c, current); + } + + throwCasC(a:number, b:number, c:number, current:Ice.Current):void + { + throw new Test.C(a, b, c); + } + + throwUndeclaredA(a:number, current:Ice.Current):void + { + throw new Test.A(a); + } + + throwUndeclaredB(a:number, b:number, current:Ice.Current):void + { + throw new Test.B(a, b); + } + + throwUndeclaredC(a:number, b:number, c:number, current:Ice.Current):void + { + throw new Test.C(a, b, c); + } + + throwLocalException(current:Ice.Current):void + { + throw new Ice.TimeoutException(); + } + + throwLocalExceptionIdempotent(current:Ice.Current):void + { + throw new Ice.TimeoutException(); + } + + throwNonIceException(current:Ice.Current):void + { + throw new Error(); + } + + throwAssertException(current:Ice.Current):void + { + test(false); + } + + throwMemoryLimitException(seq:Uint8Array, current:Ice.Current):PromiseLike<Uint8Array> + { + return Promise.resolve(new Uint8Array(1024 * 20)); // 20KB is over the configured 10KB message size max. + } + + throwAfterResponse(current:Ice.Current):void + { + } + + throwAfterException(current:Ice.Current):void + { + throw new Test.A(); + } +} diff --git a/js/test/ts/Ice/exceptions/Client.ts b/js/test/ts/Ice/exceptions/Client.ts new file mode 100644 index 00000000000..eeb7339f559 --- /dev/null +++ b/js/test/ts/Ice/exceptions/Client.ts @@ -0,0 +1,491 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + class EmptyI extends Test.Empty + { + } + + class ServantLocatorI + { + locate(curr:Ice.Current, cookie:Object):Ice.Object + { + return null; + } + + finished(curr:Ice.Current, servant:Ice.Object, cookie:Object):void + { + } + + deactivate(category:string):void + { + } + } + + const out = this.getWriter(); + const communicator = this.communicator(); + out.write("testing object adapter registration exceptions... "); + try + { + await communicator.createObjectAdapter("TestAdapter0"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.InitializationException, ex); // Expected + } + + try + { + await communicator.createObjectAdapterWithEndpoints("TestAdapter0", "default"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.FeatureNotSupportedException, ex); // Expected + } + out.writeLine("ok"); + + out.write("testing servant registration exceptions... "); + { + const adapter = await communicator.createObjectAdapter(""); + adapter.add(new EmptyI(), Ice.stringToIdentity("x")); + try + { + adapter.add(new EmptyI(), Ice.stringToIdentity("x")); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.AlreadyRegisteredException, ex); + } + + try + { + adapter.add(new EmptyI(), Ice.stringToIdentity("")); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.IllegalIdentityException, ex); + test(ex.id.name === ""); + } + + try + { + adapter.add(null, Ice.stringToIdentity("x")); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.IllegalServantException, ex); + } + + adapter.remove(Ice.stringToIdentity("x")); + try + { + adapter.remove(Ice.stringToIdentity("x")); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.NotRegisteredException, ex); + } + await adapter.deactivate(); + } + out.writeLine("ok"); + + out.write("testing servant locator registration exceptions... "); + { + const adapter = await communicator.createObjectAdapter(""); + adapter.addServantLocator(new ServantLocatorI(), "x"); + try + { + adapter.addServantLocator(new ServantLocatorI(), "x"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.AlreadyRegisteredException, ex); + } + await adapter.deactivate(); + out.writeLine("ok"); + + out.write("testing value factory registration exception... "); + communicator.getValueFactoryManager().add(() => null, "::x"); + try + { + communicator.getValueFactoryManager().add(() => null, "::x"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.AlreadyRegisteredException, ex); + } + } + out.writeLine("ok"); + + out.write("testing stringToProxy... "); + const ref = "thrower:" + this.getTestEndpoint(); + const base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + const thrower = await Test.ThrowerPrx.checkedCast(base); + test(thrower !== null); + test(thrower.equals(base)); + out.writeLine("ok"); + + out.write("catching exact types... "); + try + { + await thrower.throwAasA(1); + test(false); + } + catch(ex) + { + test(ex instanceof Test.A, ex); + test(ex.aMem === 1); + } + + try + { + await thrower.throwAorDasAorD(1); + test(false); + } + catch(ex) + { + test(ex instanceof Test.A, ex); + test(ex.aMem === 1); + } + + try + { + await thrower.throwAorDasAorD(-1); + test(false); + } + catch(ex) + { + test(ex instanceof Test.D, ex); + test(ex.dMem === -1); + } + + try + { + await thrower.throwBasB(1, 2); + test(false); + } + catch(ex) + { + test(ex instanceof Test.B, ex); + test(ex.aMem == 1); + test(ex.bMem == 2); + } + + try + { + await thrower.throwCasC(1, 2, 3); + test(false); + } + catch(ex) + { + test(ex instanceof Test.C, ex); + test(ex.aMem == 1); + test(ex.bMem == 2); + test(ex.cMem == 3); + } + out.writeLine("ok"); + + out.write("catching base types... "); + try + { + await thrower.throwBasB(1, 2); + test(false); + } + catch(ex) + { + test(ex instanceof Test.A, ex); + test(ex.aMem == 1); + } + + try + { + await thrower.throwCasC(1, 2, 3); + test(false); + } + catch(ex) + { + test(ex instanceof Test.B, ex); + test(ex.aMem == 1); + test(ex.bMem == 2); + } + out.writeLine("ok"); + + out.write("catching derived types... "); + try + { + await thrower.throwBasA(1, 2); + test(false); + } + catch(ex) + { + test(ex instanceof Test.B, ex); + test(ex.aMem == 1); + test(ex.bMem == 2); + } + + try + { + await thrower.throwCasA(1, 2, 3); + test(false); + } + catch(ex) + { + test(ex instanceof Test.C, ex); + test(ex.aMem == 1); + test(ex.bMem == 2); + test(ex.cMem == 3); + } + + try + { + await thrower.throwCasB(1, 2, 3); + test(false); + } + catch(ex) + { + test(ex instanceof Test.C, ex); + test(ex.aMem == 1); + test(ex.bMem == 2); + test(ex.cMem == 3); + } + out.writeLine("ok"); + + if(await thrower.supportsUndeclaredExceptions()) + { + out.write("catching unknown user exception... "); + try + { + await thrower.throwUndeclaredA(1); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownUserException, ex); + } + + try + { + await thrower.throwUndeclaredB(1, 2); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownUserException, ex); + } + + try + { + await thrower.throwUndeclaredC(1, 2, 3); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownUserException, ex); + } + out.writeLine("ok"); + } + + if(await thrower.supportsAssertException()) + { + out.write("testing assert in the server... "); + try + { + await thrower.throwAssertException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ConnectionLostException || + ex instanceof Ice.UnknownException, ex); + } + out.writeLine("ok"); + } + + out.write("testing memory limit marshal exception..."); + try + { + await thrower.throwMemoryLimitException(null); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MemoryLimitException, ex); + } + + try + { + await thrower.throwMemoryLimitException(new Uint8Array(20 * 1024)); + test(false); + } + catch(ex) + { + test(ex.toString().indexOf("ConnectionLostException") > 0, ex); + } + out.writeLine("ok"); + + let retries = 10; + while(--retries > 0) + { + // The above test can cause a close connection between the echo server and + // bidir server, we need to wait until the bidir server has reopen the + // connection with the echo server. + + try + { + await thrower.ice_ping(); + break; + } + catch(ex) + { + if(ex instanceof Ice.ObjectNotExistException && retries > 0) + { + await Ice.Promise.delay(20); + } + else + { + throw ex; + } + } + } + + out.write("catching object not exist exception... "); + try + { + const thrower2 = Test.ThrowerPrx.uncheckedCast( + thrower.ice_identity(Ice.stringToIdentity("does not exist"))); + await thrower2.ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectNotExistException, ex); + test(ex.id.equals(Ice.stringToIdentity("does not exist"))); + } + out.writeLine("ok"); + + out.write("catching facet not exist exception... "); + try + { + const thrower2 = Test.ThrowerPrx.uncheckedCast(thrower, "no such facet"); + await thrower2.ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.FacetNotExistException, ex); + test(ex.facet == "no such facet"); + } + out.writeLine("ok"); + + out.write("catching operation not exist exception... "); + try + { + const thrower2 = Test.WrongOperationPrx.uncheckedCast(thrower); + await thrower2.noSuchOperation(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.OperationNotExistException, ex); + test(ex.operation == "noSuchOperation"); + } + out.writeLine("ok"); + + out.write("catching unknown local exception... "); + try + { + await thrower.throwLocalException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownLocalException, ex); + } + + try + { + await thrower.throwLocalExceptionIdempotent(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownLocalException || + ex instanceof Ice.OperationNotExistException, ex); + } + out.writeLine("ok"); + + out.write("catching unknown non-Ice exception... "); + try + { + await thrower.throwNonIceException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownException, ex); + } + out.writeLine("ok"); + + out.write("testing asynchronous exceptions... "); + await thrower.throwAfterResponse(); + try + { + await thrower.throwAfterException(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.A, ex); + } + out.writeLine("ok"); + + await thrower.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.MessageSizeMax", "10"); + properties.setProperty("Ice.Warn.Connections", "0"); + properties.setProperty("Ice.PrintStackTraces", "1"); + [communicator] = this.initialize(properties); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/exceptions/Server.ts b/js/test/ts/Ice/exceptions/Server.ts new file mode 100644 index 00000000000..0d0f844a8bf --- /dev/null +++ b/js/test/ts/Ice/exceptions/Server.ts @@ -0,0 +1,57 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +import {ThrowerI} from "./ThrowerI"; + +const test = TestHelper.test; + +export class Server extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo:Test.EchoPrx; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.MessageSizeMax", "10"); + properties.setProperty("Ice.Warn.Dispatch", "0"); + properties.setProperty("Ice.Warn.Connections", "0"); + [communicator] = this.initialize(properties); + + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter = await communicator.createObjectAdapter(""); + adapter.add(new ThrowerI(), Ice.stringToIdentity("thrower")); + await echo.setConnection(); + const connection = echo.ice_getCachedConnection(); + connection.setCloseCallback(con => { + // Re-establish connection if it fails (necessary for MemoryLimitException test) + echo.setConnection().then(() => echo.ice_getCachedConnection().setAdapter(adapter)); + }); + connection.setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/exceptions/ServerAMD.ts b/js/test/ts/Ice/exceptions/ServerAMD.ts new file mode 100644 index 00000000000..34e3f6e6a59 --- /dev/null +++ b/js/test/ts/Ice/exceptions/ServerAMD.ts @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +import {AMDThrowerI} from "./AMDThrowerI"; + +export class ServerAMD extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo:Test.EchoPrx; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.MessageSizeMax", "10"); + properties.setProperty("Ice.Warn.Dispatch", "0"); + properties.setProperty("Ice.Warn.Connections", "0"); + [communicator] = this.initialize(properties); + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter = await communicator.createObjectAdapter(""); + adapter.add(new AMDThrowerI(), Ice.stringToIdentity("thrower")); + await echo.setConnection(); + const connection = echo.ice_getCachedConnection(); + connection.setCloseCallback(con => { + // Re-establish connection if it fails (necessary for MemoryLimitException test) + echo.setConnection().then(() => echo.ice_getCachedConnection().setAdapter(adapter)); + }); + connection.setAdapter(adapter); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/exceptions/Test.ice b/js/test/ts/Ice/exceptions/Test.ice new file mode 100644 index 00000000000..674cb697d1e --- /dev/null +++ b/js/test/ts/Ice/exceptions/Test.ice @@ -0,0 +1,84 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/BuiltinSequences.ice> + +module Test +{ + +interface Empty +{ +} + +interface Thrower; + +exception A +{ + int aMem; +} + +exception B extends A +{ + int bMem; +} + +exception C extends B +{ + int cMem; +} + +exception D +{ + int dMem; +} + +interface Thrower +{ + void shutdown(); + bool supportsUndeclaredExceptions(); + bool supportsAssertException(); + + void throwAasA(int a) throws A; + void throwAorDasAorD(int a) throws A, D; + void throwBasA(int a, int b) throws A; + void throwCasA(int a, int b, int c) throws A; + void throwBasB(int a, int b) throws B; + void throwCasB(int a, int b, int c) throws B; + void throwCasC(int a, int b, int c) throws C; + + void throwUndeclaredA(int a); + void throwUndeclaredB(int a, int b); + void throwUndeclaredC(int a, int b, int c); + void throwLocalException(); + void throwNonIceException(); + void throwAssertException(); + Ice::ByteSeq throwMemoryLimitException(Ice::ByteSeq seq); + + idempotent void throwLocalExceptionIdempotent(); + + void throwAfterResponse(); + void throwAfterException() throws A; +} + +interface WrongOperation +{ + void noSuchOperation(); +} + +interface Echo +{ + void setConnection(); + void startBatch(); + void flushBatch(); + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/exceptions/ThrowerI.ts b/js/test/ts/Ice/exceptions/ThrowerI.ts new file mode 100644 index 00000000000..7f891cfd5bc --- /dev/null +++ b/js/test/ts/Ice/exceptions/ThrowerI.ts @@ -0,0 +1,128 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class ThrowerI extends Test.Thrower +{ + shutdown(current:Ice.Current):void + { + current.adapter.getCommunicator().shutdown(); + } + + supportsUndeclaredExceptions(current:Ice.Current):boolean + { + return true; + } + + supportsAssertException(current:Ice.Current):boolean + { + return false; + } + + throwAasA(a:number, current:Ice.Current):void + { + throw new Test.A(a); + } + + throwAorDasAorD(a:number, current:Ice.Current):void + { + if(a > 0) + { + throw new Test.A(a); + } + else + { + throw new Test.D(a); + } + } + + throwBasA(a:number, b:number, current:Ice.Current):void + { + this.throwBasB(a, b, current); + } + + throwBasB(a:number, b:number, current:Ice.Current):void + { + throw new Test.B(a, b); + } + + throwCasA(a:number, b:number, c:number, current:Ice.Current):void + { + this.throwCasC(a, b, c, current); + } + + throwCasB(a:number, b:number, c:number, current:Ice.Current):void + { + this.throwCasC(a, b, c, current); + } + + throwCasC(a:number, b:number, c:number, current:Ice.Current):void + { + throw new Test.C(a, b, c); + } + + throwUndeclaredA(a:number, current:Ice.Current):void + { + throw new Test.A(a); + } + + throwUndeclaredB(a:number, b:number, current:Ice.Current):void + { + throw new Test.B(a, b); + } + + throwUndeclaredC(a:number, b:number, c:number, current:Ice.Current):void + { + throw new Test.C(a, b, c); + } + + throwLocalException(current:Ice.Current):void + { + throw new Ice.TimeoutException(); + } + + throwLocalExceptionIdempotent(current:Ice.Current):void + { + throw new Ice.TimeoutException(); + } + + throwNonIceException(current:Ice.Current):void + { + throw new Error(); + } + + throwAssertException(current:Ice.Current):void + { + test(false); + } + + throwMemoryLimitException(seq:Uint8Array, current:Ice.Current):Uint8Array + { + return new Uint8Array(1024 * 20); // 20KB is over the configured 10KB message size max. + } + + throwAfterResponse(current:Ice.Current):void + { + // + // Only relevant for AMD. + // + } + + throwAfterException(current:Ice.Current):void + { + // + // Only relevant for AMD. + // + throw new Test.A(); + } +} diff --git a/js/test/ts/Ice/facets/Client.ts b/js/test/ts/Ice/facets/Client.ts new file mode 100644 index 00000000000..b4323beeec0 --- /dev/null +++ b/js/test/ts/Ice/facets/Client.ts @@ -0,0 +1,123 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + const communicator = this.communicator(); + const out = this.getWriter(); + + out.write("testing stringToProxy... "); + const ref = "d:" + this.getTestEndpoint(); + const db = communicator.stringToProxy(ref); + test(db !== null); + out.writeLine("ok"); + + out.write("testing unchecked cast... "); + let prx = Ice.ObjectPrx.uncheckedCast(db); + test(prx.ice_getFacet().length === 0); + prx = Ice.ObjectPrx.uncheckedCast(db, "facetABCD"); + test(prx.ice_getFacet() == "facetABCD"); + let prx2 = Ice.ObjectPrx.uncheckedCast(prx); + test(prx2.ice_getFacet() == "facetABCD"); + let prx3 = Ice.ObjectPrx.uncheckedCast(prx, ""); + test(prx3.ice_getFacet().length === 0); + let d = Test.DPrx.uncheckedCast(db); + test(d.ice_getFacet().length === 0); + let df = Test.DPrx.uncheckedCast(db, "facetABCD"); + test(df.ice_getFacet() == "facetABCD"); + let df2 = Test.DPrx.uncheckedCast(df); + test(df2.ice_getFacet() == "facetABCD"); + let df3 = Test.DPrx.uncheckedCast(df, ""); + test(df3.ice_getFacet().length === 0); + out.writeLine("ok"); + + out.write("testing checked cast... "); + prx = await Ice.ObjectPrx.checkedCast(db); + test(prx.ice_getFacet().length === 0); + prx = await Ice.ObjectPrx.checkedCast(db, "facetABCD"); + test(prx.ice_getFacet() == "facetABCD"); + prx2 = await Ice.ObjectPrx.checkedCast(prx); + test(prx2.ice_getFacet() == "facetABCD"); + prx3 = await Ice.ObjectPrx.checkedCast(prx, ""); + test(prx3.ice_getFacet().length === 0); + d = await Test.DPrx.checkedCast(db); + test(d.ice_getFacet().length === 0); + df = await Test.DPrx.checkedCast(db, "facetABCD"); + test(df.ice_getFacet() == "facetABCD"); + df2 = await Test.DPrx.checkedCast(df); + test(df2.ice_getFacet() == "facetABCD"); + df3 = await Test.DPrx.checkedCast(df, ""); + test(df3.ice_getFacet().length === 0); + out.writeLine("ok"); + + out.write("testing non-facets A, B, C, and D... "); + d = await Test.DPrx.checkedCast(db); + test(d !== null); + test(d.equals(db)); + test(await d.callA() == "A"); + test(await d.callB() == "B"); + test(await d.callC() == "C"); + test(await d.callD() == "D"); + out.writeLine("ok"); + + out.write("testing facets A, B, C, and D... "); + df = await Test.DPrx.checkedCast(d, "facetABCD"); + test(df !== null); + test(await df.callA() == "A"); + test(await df.callB() == "B"); + test(await df.callC() == "C"); + test(await df.callD() == "D"); + out.writeLine("ok"); + + out.write("testing facets E and F... "); + const ff = await Test.FPrx.checkedCast(d, "facetEF"); + test(await ff.callE() == "E"); + test(await ff.callF() == "F"); + out.writeLine("ok"); + + out.write("testing facet G... "); + const gf = await Test.GPrx.checkedCast(ff, "facetGH"); + test(gf !== null); + test(await gf.callG() == "G"); + out.writeLine("ok"); + + out.write("testing whether casting preserves the facet... "); + const hf = await Test.HPrx.checkedCast(gf); + test(hf !== null); + test(await hf.callG() == "G"); + test(await hf.callH() == "H"); + out.writeLine("ok"); + + await gf.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/facets/Server.ts b/js/test/ts/Ice/facets/Server.ts new file mode 100644 index 00000000000..16ff1221c64 --- /dev/null +++ b/js/test/ts/Ice/facets/Server.ts @@ -0,0 +1,114 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +import {DI, FI, HI, EmptyI} from "./TestI" + +const test = TestHelper.test; + +export class Server extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo; + try + { + [communicator] = this.initialize(args); + const out = this.getWriter(); + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + + out.write("testing facet registration exceptions... "); + let adapter = await communicator.createObjectAdapter(""); + + const obj = new EmptyI(); + adapter.add(obj, Ice.stringToIdentity("d")); + adapter.addFacet(obj, Ice.stringToIdentity("d"), "facetABCD"); + try + { + adapter.addFacet(obj, Ice.stringToIdentity("d"), "facetABCD"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.AlreadyRegisteredException); + } + + adapter.removeFacet(Ice.stringToIdentity("d"), "facetABCD"); + try + { + adapter.removeFacet(Ice.stringToIdentity("d"), "facetABCD"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.NotRegisteredException); + } + out.writeLine("ok"); + + out.write("testing removeAllFacets... "); + const obj1 = new EmptyI(); + const obj2 = new EmptyI(); + adapter.addFacet(obj1, Ice.stringToIdentity("id1"), "f1"); + adapter.addFacet(obj2, Ice.stringToIdentity("id1"), "f2"); + const obj3 = new EmptyI(); + adapter.addFacet(obj1, Ice.stringToIdentity("id2"), "f1"); + adapter.addFacet(obj2, Ice.stringToIdentity("id2"), "f2"); + adapter.addFacet(obj3, Ice.stringToIdentity("id2"), ""); + let fm = adapter.removeAllFacets(Ice.stringToIdentity("id1")); + test(fm.size === 2); + test(fm.get("f1") === obj1); + test(fm.get("f2") === obj2); + try + { + adapter.removeAllFacets(Ice.stringToIdentity("id1")); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.NotRegisteredException); + } + fm = adapter.removeAllFacets(Ice.stringToIdentity("id2")); + test(fm.size == 3); + test(fm.get("f1") === obj1); + test(fm.get("f2") === obj2); + test(fm.get("") === obj3); + out.writeLine("ok"); + + await adapter.deactivate(); + adapter = await communicator.createObjectAdapter(""); + + const di = new DI(); + adapter.add(di, Ice.stringToIdentity("d")); + adapter.addFacet(di, Ice.stringToIdentity("d"), "facetABCD"); + const fi = new FI(); + adapter.addFacet(fi, Ice.stringToIdentity("d"), "facetEF"); + const hi = new HI(); + adapter.addFacet(hi, Ice.stringToIdentity("d"), "facetGH"); + await echo.setConnection(); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/facets/Test.ice b/js/test/ts/Ice/facets/Test.ice new file mode 100644 index 00000000000..703499890b2 --- /dev/null +++ b/js/test/ts/Ice/facets/Test.ice @@ -0,0 +1,68 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface Empty +{ +} + +interface A +{ + string callA(); +} + +interface B extends A +{ + string callB(); +} + +interface C extends A +{ + string callC(); +} + +interface D extends B, C +{ + string callD(); +} + +interface E +{ + string callE(); +} + +interface F extends E +{ + string callF(); +} + +interface G +{ + void shutdown(); + string callG(); +} + +interface H extends G +{ + string callH(); +} + +interface Echo +{ + void setConnection(); + void startBatch(); + void flushBatch(); + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/facets/TestI.ts b/js/test/ts/Ice/facets/TestI.ts new file mode 100644 index 00000000000..173c23a2779 --- /dev/null +++ b/js/test/ts/Ice/facets/TestI.ts @@ -0,0 +1,71 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class DI extends Test.D +{ + callA(current:Ice.Current):string + { + return "A"; + } + + callB(current:Ice.Current):string + { + return "B"; + } + + callC(current:Ice.Current):string + { + return "C"; + } + + callD(current:Ice.Current):string + { + return "D"; + } +} + +export class EmptyI extends Test.Empty +{ +} + +export class FI extends Test.F +{ + callE(current:Ice.Current):string + { + return "E"; + } + + callF(current:Ice.Current):string + { + return "F"; + } +} + +export class HI extends Test.H +{ + callG(current:Ice.Current):string + { + return "G"; + } + + callH(current:Ice.Current):string + { + return "H"; + } + + shutdown(current:Ice.Current):void + { + current.adapter.getCommunicator().shutdown(); + } +} diff --git a/js/test/ts/Ice/hold/Client.ts b/js/test/ts/Ice/hold/Client.ts new file mode 100644 index 00000000000..7e6c3a28c9b --- /dev/null +++ b/js/test/ts/Ice/hold/Client.ts @@ -0,0 +1,285 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + class Condition + { + constructor(value:boolean) + { + this.value = value; + } + + value:boolean; + } + + class SetCB + { + constructor(condition:Condition, expected:number) + { + this.condition = condition; + this.expected = expected; + } + + response(value:number) + { + if(value != this.expected) + { + this.condition.value = false; + } + } + condition:Condition; + expected:number; + } + + const communicator = this.communicator(); + const out = this.getWriter(); + + const ref = "hold:" + this.getTestEndpoint(); + const hold = await Test.HoldPrx.checkedCast(communicator.stringToProxy(ref)); + test(hold !== null); + const holdOneway = Test.HoldPrx.uncheckedCast(hold.ice_oneway()); + + const refSerialized = "hold:" + this.getTestEndpoint(1); + const holdSerialized = await Test.HoldPrx.checkedCast(communicator.stringToProxy(refSerialized)); + test(holdSerialized !== null); + const holdSerializedOneway = Test.HoldPrx.uncheckedCast(holdSerialized.ice_oneway()); + + out.write("changing state between active and hold rapidly... "); + + for(let i = 0; i < 100; ++i) + { + await hold.putOnHold(0); + } + for(let i = 0; i < 100; ++i) + { + await holdOneway.putOnHold(0); + } + for(let i = 0; i < 100; ++i) + { + await holdSerialized.putOnHold(0); + } + for(let i = 0; i < 1; ++i) + { + await holdSerializedOneway.putOnHold(0); + } + out.writeLine("ok"); + + out.write("testing without serialize mode... "); + { + const condition = new Condition(true); + let value = 0; + let result; + const results = []; + while(condition.value) + { + const cb = new SetCB(condition, value); + result = hold.set(++value, value < 500 ? Math.floor((Math.random() * 5)) : 0); + results.push( + result.then( + v => + { + cb.response(v); + }, + () => + { + // Ignore exception + })); + + if(value % 100 === 0) + { + while(true) + { + if(result.isSent()) + { + break; + } + else if(result.isCompleted()) + { + await result; // This should throw the failure if the call wasn't sent but done. + test(result.isSent()); + } + await Ice.Promise.delay(10); + } + } + + if(value > 10000) + { + // Don't continue, it's possible that out-of-order dispatch doesn't occur + // after 100000 iterations and we don't want the test to last for too long + // when this occurs. + break; + } + } + test(value > 10000 || !condition.value); + while(true) + { + if(result.isSent()) + { + break; + } + else if(result.isCompleted()) + { + await result; // This should throw the failure if the call wasn't sent but done. + test(result.isSent()); + } + await Ice.Promise.delay(10); + } + await Promise.all(results); + } + out.writeLine("ok"); + + out.write("testing with serialize mode... "); + { + const condition = new Condition(true); + let value = 0; + let result; + const results = []; + while(value < 3000 && condition.value) + { + const cb = new SetCB(condition, value); + result = holdSerialized.set(++value, 0); + results.push( + result.then( + v => + { + cb.response(v); + }, + () => + { + // Ignore exceptions + })); + + if(value % 100 === 0) + { + while(true) + { + if(result.isSent()) + { + break; + } + else if(result.isCompleted()) + { + await result; // This should throw the failure if the call wasn't sent but done. + test(result.isSent()); + } + await Ice.Promise.delay(10); + } + } + } + await result; + test(condition.value); + + for(let i = 0; i < 10000; ++i) + { + await holdSerializedOneway.setOneway(value + 1, value); + ++value; + if((i % 100) == 0) + { + await holdSerializedOneway.putOnHold(1); + } + } + await Promise.all(results); + } + out.writeLine("ok"); + + out.write("testing serialization... "); + { + let value = 0; + let result; + const results = []; + await holdSerialized.set(value, 0); + + for(let i = 0; i < 10000; ++i) + { + // Create a new proxy for each request + result = holdSerialized.ice_oneway().setOneway(value + 1, value); + results.push(result); + ++value; + if((i % 100) === 0) + { + while(true) + { + if(result.isSent()) + { + break; + } + else if(result.isCompleted()) + { + await result; // This should throw the failure if the call wasn't sent but done. + test(result.isSent()); + } + await Ice.Promise.delay(10); + } + await holdSerialized.ice_ping(); // Ensure everything's dispatched. + const conn = await holdSerialized.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + } + } + await Promise.all(results); + } + out.writeLine("ok"); + + out.write("testing waitForHold... "); + await hold.waitForHold(); + await hold.waitForHold(); + for(let i = 0; i < 1000; ++i) + { + await holdOneway.ice_ping(); + if((i % 20) == 0) + { + await hold.putOnHold(0); + } + } + await hold.putOnHold(-1); + await hold.ice_ping(); + await hold.putOnHold(-1); + await hold.ice_ping(); + out.writeLine("ok"); + + out.write("changing state to hold and shutting down server... "); + await hold.shutdown(); + out.writeLine("ok"); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + const [properties] = this.createTestProperties(args); + // + // For this test, we want to disable retries. + // + properties.setProperty("Ice.RetryIntervals", "-1"); + + // + // We don't want connection warnings because of the timeout + // + properties.setProperty("Ice.Warn.Connections", "0"); + + [communicator] = this.initialize(properties); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/hold/Test.ice b/js/test/ts/Ice/hold/Test.ice new file mode 100644 index 00000000000..9d38fed4504 --- /dev/null +++ b/js/test/ts/Ice/hold/Test.ice @@ -0,0 +1,24 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface Hold +{ + void putOnHold(int seconds); + void waitForHold(); + void setOneway(int value, int expected); + int set(int value, int delay); + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/info/Client.ts b/js/test/ts/Ice/info/Client.ts new file mode 100644 index 00000000000..4964517712a --- /dev/null +++ b/js/test/ts/Ice/info/Client.ts @@ -0,0 +1,161 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +function getTCPEndpointInfo(info:Ice.EndpointInfo) +{ + for(let p = info; p; p = p.underlying) + { + if(p instanceof Ice.TCPEndpointInfo) + { + return p; + } + } + return null; +} + +function getTCPConnectionInfo(info:Ice.ConnectionInfo) +{ + for(let p = info; p; p = p.underlying) + { + if(p instanceof Ice.TCPConnectionInfo) + { + return p; + } + } + return null; +} + +export class Client extends TestHelper +{ + async allTests() + { + const out = this.getWriter(); + const communicator = this.communicator(); + const defaultHost = communicator.getProperties().getProperty("Ice.Default.Host"); + + out.write("testing proxy endpoint information... "); + { + const ref = + "test -t:default -h tcphost -p 10000 -t 1200 -z --sourceAddress 10.10.10.10:opaque -e 1.8 -t 100 -v ABCD"; + const p1 = communicator.stringToProxy(ref); + + const endps = p1.ice_getEndpoints(); + const endpoint = endps[0].getInfo(); + const ipEndpoint = getTCPEndpointInfo(endpoint); + test(ipEndpoint.host == "tcphost"); + test(ipEndpoint.port == 10000); + test(ipEndpoint.timeout == 1200); + test(ipEndpoint.sourceAddress == "10.10.10.10"); + test(ipEndpoint.compress); + test(!ipEndpoint.datagram()); + test(ipEndpoint.type() == Ice.TCPEndpointType && !ipEndpoint.secure() || + ipEndpoint.type() == Ice.WSEndpointType && !ipEndpoint.secure() || + ipEndpoint.type() == Ice.WSSEndpointType && ipEndpoint.secure()); + + test(ipEndpoint.type() == Ice.TCPEndpointType && endpoint instanceof Ice.TCPEndpointInfo || + ipEndpoint.type() == Ice.WSEndpointType && endpoint instanceof Ice.WSEndpointInfo || + ipEndpoint.type() == Ice.WSSEndpointType && endpoint instanceof Ice.WSEndpointInfo); + + const opaqueEndpoint = endps[1].getInfo() as Ice.OpaqueEndpointInfo; + test(opaqueEndpoint.rawEncoding.equals(new Ice.EncodingVersion(1, 8))); + } + out.writeLine("ok"); + + const base = communicator.stringToProxy("test:" + this.getTestEndpoint()); + const testIntf = Test.TestIntfPrx.uncheckedCast(base); + + out.write("testing connection endpoint information... "); + { + const endpointPort = this.getTestPort(0); + let conn = await base.ice_getConnection(); + let ipinfo = getTCPEndpointInfo(conn.getEndpoint().getInfo()); + test(ipinfo.port == endpointPort); + test(!ipinfo.compress); + test(ipinfo.host == defaultHost); + + let ctx = await testIntf.getEndpointInfoAsContext(); + test(ctx.get("host") == ipinfo.host); + test(ctx.get("compress") == "false"); + test(parseInt(ctx.get("port")) > 0); + } + out.writeLine("ok"); + + out.write("testing connection information... "); + { + const endpointPort = this.getTestPort(0); + let conn = await base.ice_getConnection(); + conn = await base.ice_getConnection(); + conn.setBufferSize(1024, 2048); + + const info:Ice.ConnectionInfo = conn.getInfo(); + let ipinfo:Ice.TCPConnectionInfo = getTCPConnectionInfo(info); + test(!info.incoming); + test(info.adapterName.length === 0); + if(conn.type() != "ws" && conn.type() != "wss") + { + test(ipinfo.localPort > 0); + } + test(ipinfo.remotePort == endpointPort); + if(defaultHost == "127.0.0.1") + { + test(ipinfo.remoteAddress == defaultHost); + if(conn.type() != "ws" && conn.type() != "wss") + { + test(ipinfo.localAddress == defaultHost); + } + } + test(ipinfo.sndSize >= 2048); + const ctx:Map<string, string> = await testIntf.getConnectionInfoAsContext(); + + test(ctx.get("incoming") == "true"); + test(ctx.get("adapterName") == "TestAdapter"); + if(conn.type() != "ws" && conn.type() != "wss") + { + test(ctx.get("remoteAddress") == ipinfo.localAddress); + test(ctx.get("localAddress") == ipinfo.remoteAddress); + test(parseInt(ctx.get("remotePort")) === ipinfo.localPort); + test(parseInt(ctx.get("localPort")) === ipinfo.remotePort); + } + + if(conn.type() == "ws" || conn.type() == "wss") + { + test(ctx.get("ws.Upgrade").toLowerCase() == "websocket"); + test(ctx.get("ws.Connection").indexOf("Upgrade") >= 0); + test(ctx.get("ws.Sec-WebSocket-Protocol") == "ice.zeroc.com"); + test(ctx.get("ws.Sec-WebSocket-Version") == "13"); + test(ctx.get("ws.Sec-WebSocket-Key") !== null); + } + } + out.writeLine("ok"); + + await testIntf.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/info/Test.ice b/js/test/ts/Ice/info/Test.ice new file mode 100644 index 00000000000..06d4d4d10e6 --- /dev/null +++ b/js/test/ts/Ice/info/Test.ice @@ -0,0 +1,26 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Current.ice> + +module Test +{ + +interface TestIntf +{ + void shutdown(); + + Ice::Context getEndpointInfoAsContext(); + + Ice::Context getConnectionInfoAsContext(); +} + +} diff --git a/js/test/ts/Ice/inheritance/Client.ts b/js/test/ts/Ice/inheritance/Client.ts new file mode 100644 index 00000000000..a758c000c18 --- /dev/null +++ b/js/test/ts/Ice/inheritance/Client.ts @@ -0,0 +1,236 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + const communicator = this.communicator(); + const out = this.getWriter(); + + out.write("testing stringToProxy... "); + const ref = "initial:" + this.getTestEndpoint(); + const base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + const initial = await Test.InitialPrx.checkedCast(base); + test(initial !== null); + test(initial.equals(base)); + out.writeLine("ok"); + + out.write("getting proxies for class hierarchy... "); + const ca = await initial.caop(); + const cb = await initial.cbop(); + const cc = await initial.ccop(); + const cd = await initial.cdop(); + test(ca != cb); + test(ca != cc); + test(ca != cd); + test(cb != cc); + test(cb != cd); + test(cc != cd); + out.writeLine("ok"); + + out.write("getting proxies for interface hierarchy... "); + const ia = await initial.iaop(); + const ib1 = await initial.ib1op(); + const ib2 = await initial.ib2op(); + const ic = await initial.icop(); + test(ia != ib1); + test(ia != ib2); + test(ia != ic); + test(ib1 != ic); + test(ib2 != ic); + out.writeLine("ok"); + + out.write("invoking proxy operations on class hierarchy... "); + + let cao = await ca.caop(ca); + test(cao.equals(ca)); + cao = await ca.caop(cb); + test(cao.equals(cb)); + cao = await ca.caop(cc); + test(cao.equals(cc)); + cao = await cb.caop(ca); + test(cao.equals(ca)); + cao = await cb.caop(cb); + test(cao.equals(cb)); + cao = await cb.caop(cc); + test(cao.equals(cc)); + cao = await cc.caop(ca); + test(cao.equals(ca)); + cao = await cc.caop(cb); + test(cao.equals(cb)); + cao = await cc.caop(cc); + test(cao.equals(cc)); + + cao = await cb.cbop(cb); + test(cao.equals(cb)); + let cbo = await cb.cbop(cb); + test(cbo.equals(cb)); + cao = await cb.cbop(cc); + test(cao.equals(cc)); + cbo = await cb.cbop(cc); + test(cbo.equals(cc)); + cao = await cc.cbop(cb); + test(cao.equals(cb)); + cbo = await cc.cbop(cb); + test(cbo.equals(cb)); + cao = await cc.cbop(cc); + test(cao.equals(cc)); + cbo = await cc.cbop(cc); + test(cbo.equals(cc)); + + cao = await cc.ccop(cc); + test(cao.equals(cc)); + cbo = await cc.ccop(cc); + test(cbo.equals(cc)); + let cco = await cc.ccop(cc); + test(cco.equals(cc)); + out.writeLine("ok"); + + out.write("ditto, but for interface hierarchy... "); + let iao; + let ib1o; + let ib2o; + + iao = await ia.iaop(ia); + test(iao.equals(ia)); + iao = await ia.iaop(ib1); + test(iao.equals(ib1)); + iao = await ia.iaop(ib2); + test(iao.equals(ib2)); + iao = await ia.iaop(ic); + test(iao.equals(ic)); + iao = await ib1.iaop(ia); + test(iao.equals(ia)); + iao = await ib1.iaop(ib1); + test(iao.equals(ib1)); + iao = await ib1.iaop(ib2); + test(iao.equals(ib2)); + iao = await ib1.iaop(ic); + test(iao.equals(ic)); + iao = await ib2.iaop(ia); + test(iao.equals(ia)); + iao = await ib2.iaop(ib1); + test(iao.equals(ib1)); + iao = await ib2.iaop(ib2); + test(iao.equals(ib2)); + iao = await ib2.iaop(ic); + test(iao.equals(ic)); + iao = await ic.iaop(ia); + test(iao.equals(ia)); + iao = await ic.iaop(ib1); + test(iao.equals(ib1)); + iao = await ic.iaop(ib2); + test(iao.equals(ib2)); + iao = await ic.iaop(ic); + test(iao.equals(ic)); + + iao = await ib1.ib1op(ib1); + test(iao.equals(ib1)); + ib1o = await ib1.ib1op(ib1); + test(ib1o.equals(ib1)); + iao = await ib1.ib1op(ic); + test(iao.equals(ic)); + ib1o = await ib1.ib1op(ic); + test(ib1o.equals(ic)); + iao = await ic.ib1op(ib1); + test(iao.equals(ib1)); + ib1o = await ic.ib1op(ib1); + test(ib1o.equals(ib1)); + iao = await ic.ib1op(ic); + test(iao.equals(ic)); + ib1o = await ic.ib1op(ic); + test(ib1o.equals(ic)); + + iao = await ib2.ib2op(ib2); + test(iao.equals(ib2)); + ib2o = await ib2.ib2op(ib2); + test(ib2o.equals(ib2)); + iao = await ib2.ib2op(ic); + test(iao.equals(ic)); + ib2o = await ib2.ib2op(ic); + test(ib2o.equals(ic)); + iao = await ic.ib2op(ib2); + test(iao.equals(ib2)); + ib2o = await ic.ib2op(ib2); + test(ib2o.equals(ib2)); + iao = await ic.ib2op(ic); + test(iao.equals(ic)); + ib2o = await ic.ib2op(ic); + test(ib2o.equals(ic)); + + iao = await ic.icop(ic); + test(iao.equals(ic)); + ib1o = await ic.icop(ic); + test(ib1o.equals(ic)); + ib2o = await ic.icop(ic); + test(ib2o.equals(ic)); + const ico = await ic.icop(ic); + test(ico.equals(ic)); + out.writeLine("ok"); + + out.write("ditto, but for class implementing interfaces... "); + cao = await cd.caop(cd); + test(cao.equals(cd)); + cbo = await cd.cbop(cd); + test(cbo.equals(cd)); + cco = await cd.ccop(cd); + test(cco.equals(cd)); + + iao = await cd.iaop(cd); + test(iao.equals(cd)); + ib1o = await cd.ib1op(cd); + test(ib1o.equals(cd)); + ib2o = await cd.ib2op(cd); + test(ib2o.equals(cd)); + + cao = await cd.cdop(cd); + test(cao.equals(cd)); + cbo = await cd.cdop(cd); + test(cbo.equals(cd)); + cco = await cd.cdop(cd); + test(cco.equals(cd)); + + iao = await cd.cdop(cd); + test(iao.equals(cd)); + ib1o = await cd.cdop(cd); + test(ib1o.equals(cd)); + ib2o = await cd.cdop(cd); + test(ib2o.equals(cd)); + out.writeLine("ok"); + + await initial.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/inheritance/InitialI.ts b/js/test/ts/Ice/inheritance/InitialI.ts new file mode 100644 index 00000000000..05dbd082928 --- /dev/null +++ b/js/test/ts/Ice/inheritance/InitialI.ts @@ -0,0 +1,216 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" + +export class CAI extends Test.MA.CADisp +{ + caop(p:Test.MA.CAPrx, current:Ice.Current):Test.MA.CAPrx + { + return p; + } +} + +export class CBI extends Test.MB.CBDisp +{ + caop(p:Test.MA.CAPrx, current:Ice.Current):Test.MA.CAPrx + { + return p; + } + + cbop(p:Test.MB.CBPrx, current:Ice.Current):Test.MB.CBPrx + { + return p; + } +} + +export class CCI extends Test.MA.CCDisp +{ + caop(p:Test.MA.CAPrx, current:Ice.Current):Test.MA.CAPrx + { + return p; + } + + cbop(p:Test.MB.CBPrx, current:Ice.Current):Test.MB.CBPrx + { + return p; + } + + ccop(p:Test.MA.CCPrx, current:Ice.Current):Test.MA.CCPrx + { + return p; + } +} + +export class CDI extends Test.MA.CDDisp +{ + caop(p:Test.MA.CAPrx, current:Ice.Current) + { + return p; + } + + ccop(p:Test.MA.CCPrx, current:Ice.Current):Test.MA.CCPrx + { + return p; + } + + cdop(p:Test.MA.CDPrx, current:Ice.Current):Test.MA.CDPrx + { + return p; + } + + iaop(p:Test.MA.IAPrx, current:Ice.Current):Test.MA.IAPrx + { + return p; + } + + cbop(p:Test.MB.CBPrx, current:Ice.Current):Test.MB.CBPrx + { + return p; + } + + ib1op(p:Test.MB.IB1Prx, current:Ice.Current):Test.MB.IB1Prx + { + return p; + } + + ib2op(p:Test.MB.IB2Prx, current:Ice.Current):Test.MB.IB2Prx + { + return p; + } +} + +export class IAI extends Test.MA.IA +{ + iaop(p:Test.MA.IAPrx, current:Ice.Current):Test.MA.IAPrx + { + return p; + } +} + +export class IB1I extends Test.MB.IB1 +{ + iaop(p:Test.MA.IAPrx, current:Ice.Current):Test.MA.IAPrx + { + return p; + } + + ib1op(p:Test.MB.IB1Prx, current:Ice.Current):Test.MB.IB1Prx + { + return p; + } +} + +export class IB2I extends Test.MB.IB2 +{ + iaop(p:Test.MA.IAPrx, current:Ice.Current):Test.MA.IAPrx + { + return p; + } + + ib2op(p:Test.MB.IB2Prx, current:Ice.Current):Test.MB.IB2Prx + { + return p; + } +} + +export class ICI extends Test.MA.IC +{ + iaop(p:Test.MA.IAPrx, current:Ice.Current):Test.MA.IAPrx + { + return p; + } + + icop(p:Test.MA.ICPrx, current:Ice.Current):Test.MA.ICPrx + { + return p; + } + + ib1op(p:Test.MB.IB1Prx, current:Ice.Current):Test.MB.IB1Prx + { + return p; + } + + ib2op(p:Test.MB.IB2Prx, current:Ice.Current):Test.MB.IB2Prx + { + return p; + } +} + +export class InitialI extends Test.Initial +{ + constructor(adapter:Ice.ObjectAdapter, obj:Ice.ObjectPrx) + { + super(); + const endpts = obj.ice_getEndpoints(); + this._ca = Test.MA.CAPrx.uncheckedCast(adapter.addWithUUID(new CAI()).ice_endpoints(endpts)); + this._cb = Test.MB.CBPrx.uncheckedCast(adapter.addWithUUID(new CBI()).ice_endpoints(endpts)); + this._cc = Test.MA.CCPrx.uncheckedCast(adapter.addWithUUID(new CCI()).ice_endpoints(endpts)); + this._cd = Test.MA.CDPrx.uncheckedCast(adapter.addWithUUID(new CDI()).ice_endpoints(endpts)); + this._ia = Test.MA.IAPrx.uncheckedCast(adapter.addWithUUID(new IAI()).ice_endpoints(endpts)); + this._ib1 = Test.MB.IB1Prx.uncheckedCast(adapter.addWithUUID(new IB1I()).ice_endpoints(endpts)); + this._ib2 = Test.MB.IB2Prx.uncheckedCast(adapter.addWithUUID(new IB2I()).ice_endpoints(endpts)); + this._ic = Test.MA.ICPrx.uncheckedCast(adapter.addWithUUID(new ICI()).ice_endpoints(endpts)); + } + + caop(current:Ice.Current):Test.MA.CAPrx + { + return this._ca; + } + + cbop(current:Ice.Current):Test.MB.CBPrx + { + return this._cb; + } + + ccop(current:Ice.Current):Test.MA.CCPrx + { + return this._cc; + } + + cdop(current:Ice.Current):Test.MA.CDPrx + { + return this._cd; + } + + iaop(current:Ice.Current):Test.MA.IAPrx + { + return this._ia; + } + + ib1op(current:Ice.Current):Test.MB.IB1Prx + { + return this._ib1; + } + + ib2op(current:Ice.Current):Test.MB.IB2Prx + { + return this._ib2; + } + + icop(current:Ice.Current):Test.MA.ICPrx + { + return this._ic; + } + + shutdown(current:Ice.Current):void + { + current.adapter.getCommunicator().shutdown(); + } + + _ca:Test.MA.CAPrx; + _cb:Test.MB.CBPrx; + _cc:Test.MA.CCPrx; + _cd:Test.MA.CDPrx; + _ia:Test.MA.IAPrx; + _ib1:Test.MB.IB1Prx; + _ib2:Test.MB.IB2Prx; + _ic:Test.MA.ICPrx; +} diff --git a/js/test/ts/Ice/inheritance/Server.ts b/js/test/ts/Ice/inheritance/Server.ts new file mode 100644 index 00000000000..b1964826bf1 --- /dev/null +++ b/js/test/ts/Ice/inheritance/Server.ts @@ -0,0 +1,46 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +import {InitialI} from "./InitialI"; + +export class Server extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo:Test.EchoPrx; + try + { + [communicator] = this.initialize(args); + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter:Ice.ObjectAdapter = await communicator.createObjectAdapter(""); + const base:Ice.ObjectPrx = communicator.stringToProxy("initial:" + this.getTestEndpoint()); + adapter.add(new InitialI(adapter, base), Ice.stringToIdentity("initial")); + await echo.setConnection(); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/inheritance/Test.ice b/js/test/ts/Ice/inheritance/Test.ice new file mode 100644 index 00000000000..073813dfa21 --- /dev/null +++ b/js/test/ts/Ice/inheritance/Test.ice @@ -0,0 +1,243 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +[["suppress-warning:deprecated"]] // For classes with operations + +module Test +{ + +module MA +{ + +interface IA +{ + IA* iaop(IA* p); +} + +class CA +{ + CA* caop(CA* p); +} + +} + +module MB +{ + +interface IB1 extends MA::IA +{ + IB1* ib1op(IB1* p); +} + +interface IB2 extends MA::IA +{ + IB2* ib2op(IB2* p); +} + +class CB extends MA::CA +{ + CB* cbop(CB* p); +} + +} + +module MA +{ + +interface IC extends MB::IB1, MB::IB2 +{ + IC* icop(IC* p); +} + +class CC extends MB::CB +{ + CC* ccop(CC* p); +} + +class CD extends CC implements MB::IB1, MB::IB2 +{ + CD* cdop(CD* p); +} + +} + +interface Initial +{ + void shutdown(); + MA::CA* caop(); + MB::CB* cbop(); + MA::CC* ccop(); + MA::CD* cdop(); + MA::IA* iaop(); + MB::IB1* ib1op(); + MB::IB2* ib2op(); + MA::IC* icop(); +} + +module MC +{ + +class A +{ + int aA; +} + +class B extends A +{ + int bB; +} + +class C extends B +{ + int cC; +} + +class D extends C +{ + int dD; +} + +} + +module MD +{ + +class A +{ + int aA; +} + +class B extends A +{ + int bB; +} + +class C extends B +{ + int cC; +} + +class D extends C +{ + int dD; +} + +} + +module ME +{ + +class A +{ + int aA; +} + +class B extends A +{ + int bB; +} + +class C extends B +{ + int cC; +} + +class D extends C +{ + int dD; +} + +} + +module MF +{ + +class A +{ + int aA; +} + +class B extends A +{ + int bB; +} + +class C extends B +{ + int cC; +} + +class D extends C +{ + int dD; +} + +} + +module MG +{ + +class A +{ + int aA; +} + +class B extends A +{ + int bB; +} + +class C extends B +{ + int cC; +} + +class D extends C +{ + int dD; +} + +} + +module MH +{ + +class A +{ + int aA; +} + +class B extends A +{ + int bB; +} + +class C extends B +{ + int cC; +} + +class D extends C +{ + int dD; +} + +} + +interface Echo +{ + void setConnection(); + void startBatch(); + void flushBatch(); + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/location/Client.ts b/js/test/ts/Ice/location/Client.ts new file mode 100644 index 00000000000..177bc2f2aad --- /dev/null +++ b/js/test/ts/Ice/location/Client.ts @@ -0,0 +1,518 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + const communicator = this.communicator(); + const out = this.getWriter(); + let base = communicator.stringToProxy("ServerManager:" + this.getTestEndpoint()); + const manager = Test.ServerManagerPrx.uncheckedCast(base); + test(manager !== null); + + const locator = Test.TestLocatorPrx.uncheckedCast(communicator.getDefaultLocator()); + test(locator !== null); + + const registry = Test.TestLocatorRegistryPrx.uncheckedCast(await locator.getRegistry()); + test(registry !== null); + + out.write("testing stringToProxy... "); + base = communicator.stringToProxy("test @ TestAdapter"); + const base2 = communicator.stringToProxy("test @ TestAdapter"); + const base3 = communicator.stringToProxy("test"); + const base4 = communicator.stringToProxy("ServerManager"); + const base5 = communicator.stringToProxy("test2"); + const base6 = communicator.stringToProxy("test @ ReplicatedAdapter"); + out.writeLine("ok"); + + out.write("testing ice_locator and ice_getLocator... "); + test(Ice.proxyIdentityCompare(base.ice_getLocator(), communicator.getDefaultLocator()) === 0); + const anotherLocator = Ice.LocatorPrx.uncheckedCast(communicator.stringToProxy("anotherLocator")); + base = base.ice_locator(anotherLocator); + test(Ice.proxyIdentityCompare(base.ice_getLocator(), anotherLocator) === 0); + communicator.setDefaultLocator(null); + base = communicator.stringToProxy("test @ TestAdapter"); + test(base.ice_getLocator() === null); + base = base.ice_locator(anotherLocator); + test(Ice.proxyIdentityCompare(base.ice_getLocator(), anotherLocator) === 0); + communicator.setDefaultLocator(locator); + base = communicator.stringToProxy("test @ TestAdapter"); + test(Ice.proxyIdentityCompare(base.ice_getLocator(), communicator.getDefaultLocator()) === 0); + + // + // We also test ice_router/ice_getRouter (perhaps we should add a + // test/Ice/router test?) + // + test(base.ice_getRouter() === null); + const anotherRouter = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("anotherRouter")); + base = base.ice_router(anotherRouter); + test(Ice.proxyIdentityCompare(base.ice_getRouter(), anotherRouter) === 0); + const router = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("dummyrouter")); + communicator.setDefaultRouter(router); + base = communicator.stringToProxy("test @ TestAdapter"); + test(Ice.proxyIdentityCompare(base.ice_getRouter(), communicator.getDefaultRouter()) === 0); + communicator.setDefaultRouter(null); + base = communicator.stringToProxy("test @ TestAdapter"); + test(base.ice_getRouter() === null); + out.writeLine("ok"); + + out.write("starting server... "); + await manager.startServer(); + out.writeLine("ok"); + + out.write("testing checked cast... "); + let obj = await Test.TestIntfPrx.checkedCast(base); + test(obj !== null); + + const obj2 = await Test.TestIntfPrx.checkedCast(base2); + test(obj2 !== null); + + const obj3 = await Test.TestIntfPrx.checkedCast(base3); + test(obj3 !== null); + + const obj4 = await Test.ServerManagerPrx.checkedCast(base4); + test(obj4 !== null); + + const obj5 = await Test.TestIntfPrx.checkedCast(base5); + test(obj5 !== null); + + const obj6 = await Test.TestIntfPrx.checkedCast(base6); + test(obj6 !== null); + out.writeLine("ok"); + + out.write("testing id@AdapterId indirect proxy... "); + await obj.shutdown(); + await manager.startServer(); + await obj2.ice_ping(); + out.writeLine("ok"); + + out.write("testing id@ReplicaGroupId indirect proxy... "); + await obj.shutdown(); + await manager.startServer(); + await obj6.ice_ping(); + out.writeLine("ok"); + + out.write("testing identity indirect proxy... "); + await obj.shutdown(); + await manager.startServer(); + await obj3.ice_ping(); + await obj2.ice_ping(); + await obj.shutdown(); + await manager.startServer(); + await obj2.ice_ping(); + await obj3.ice_ping(); + await obj.shutdown(); + await manager.startServer(); + await obj2.ice_ping(); + await obj.shutdown(); + await manager.startServer(); + await obj3.ice_ping(); + await obj.shutdown(); + await manager.startServer(); + await obj2.ice_ping(); + await obj.shutdown(); + await manager.startServer(); + await obj5.ice_ping(); + out.writeLine("ok"); + + out.write("testing proxy with unknown identity... "); + base = communicator.stringToProxy("unknown/unknown"); + try + { + await base.ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.NotRegisteredException, ex); + test(ex.kindOfObject == "object"); + test(ex.id == "unknown/unknown"); + } + out.writeLine("ok"); + + out.write("testing proxy with unknown adapter... "); + base = communicator.stringToProxy("test @ TestAdapterUnknown"); + try + { + await base.ice_ping(); + } + catch(ex) + { + test(ex instanceof Ice.NotRegisteredException, ex); + test(ex.kindOfObject == "object adapter"); + test(ex.id == "TestAdapterUnknown"); + } + out.writeLine("ok"); + + out.write("testing locator cache timeout... "); + let count = await locator.getRequestCount(); + const basencc = communicator.stringToProxy("test@TestAdapter").ice_connectionCached(false); + await basencc.ice_locatorCacheTimeout(0).ice_ping(); // No locator cache. + test(++count == await locator.getRequestCount()); + await basencc.ice_locatorCacheTimeout(0).ice_ping(); // No locator cache. + test(++count == await locator.getRequestCount()); + await basencc.ice_locatorCacheTimeout(1).ice_ping(); // 1s timeout. + test(count == await locator.getRequestCount()); + await Ice.Promise.delay(1200); // 1200ms + await basencc.ice_locatorCacheTimeout(1).ice_ping(); // 1s timeout. + test(++count == await locator.getRequestCount()); + + await communicator.stringToProxy("test").ice_locatorCacheTimeout(0).ice_ping(); // No locator cache. + count += 2; + test(count == await locator.getRequestCount()); + await communicator.stringToProxy("test").ice_locatorCacheTimeout(1).ice_ping(); // 1s timeout + test(count == await locator.getRequestCount()); + await Ice.Promise.delay(1200); // 1200ms + await communicator.stringToProxy("test").ice_locatorCacheTimeout(1).ice_ping(); // 1s timeout + count += 2; + test(count == await locator.getRequestCount()); + + await communicator.stringToProxy("test@TestAdapter").ice_locatorCacheTimeout(-1).ice_ping(); + test(count == await locator.getRequestCount()); + await communicator.stringToProxy("test").ice_locatorCacheTimeout(-1).ice_ping(); + test(count == await locator.getRequestCount()); + await communicator.stringToProxy("test@TestAdapter").ice_ping(); + test(count == await locator.getRequestCount()); + await communicator.stringToProxy("test").ice_ping(); + test(count == await locator.getRequestCount()); + + test(communicator.stringToProxy("test").ice_locatorCacheTimeout(99).ice_getLocatorCacheTimeout() === 99); + out.writeLine("ok"); + + out.write("testing proxy from server... "); + obj = await Test.TestIntfPrx.checkedCast(communicator.stringToProxy("test@TestAdapter")); + let hello = await obj.getHello(); + test(hello.ice_getAdapterId() == "TestAdapter"); + await hello.sayHello(); + hello = await obj.getReplicatedHello(); + test(hello.ice_getAdapterId() == "ReplicatedAdapter"); + await hello.sayHello(); + out.writeLine("ok"); + + out.write("testing locator request queuing... "); + hello = await obj.getReplicatedHello(); + hello = hello.ice_locatorCacheTimeout(0).ice_connectionCached(false); + count = await locator.getRequestCount(); + await hello.ice_ping(); + test(++count == await locator.getRequestCount()); + + let results = []; + for(let i = 0; i < 1000; i++) + { + results.push(hello.sayHello().catch( + ex => + { + test(false); + })); + } + await Promise.all(results); + + results = []; + test(await locator.getRequestCount() > count && + await locator.getRequestCount() < count + 999); + + if(await locator.getRequestCount() > count + 800) + { + out.write("queuing = " + (await locator.getRequestCount() - count)); + } + count = await locator.getRequestCount(); + hello = hello.ice_adapterId("unknown"); + for(let i = 0; i < 1000; i++) + { + results.push(hello.sayHello().then( + () => + { + test(false); + }, + ex => + { + test(ex instanceof Ice.NotRegisteredException, ex); + })); + } + await Promise.all(results); + results = []; + // XXX: + // Take into account the retries. + test(await locator.getRequestCount() > count && await locator.getRequestCount() < count + 1999); + if(await locator.getRequestCount() > count + 800) + { + out.write("queuing = " + (await locator.getRequestCount() - count)); + } + out.writeLine("ok"); + + out.write("testing adapter locator cache... "); + try + { + await communicator.stringToProxy("test@TestAdapter3").ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.NotRegisteredException, ex); + test(ex.kindOfObject == "object adapter"); + test(ex.id == "TestAdapter3"); + } + await registry.setAdapterDirectProxy("TestAdapter3", await locator.findAdapterById("TestAdapter")); + try + { + await communicator.stringToProxy("test@TestAdapter3").ice_ping(); + await registry.setAdapterDirectProxy("TestAdapter3", communicator.stringToProxy("dummy:default")); + await communicator.stringToProxy("test@TestAdapter3").ice_ping(); + } + catch(ex) + { + test(false, ex); + } + + try + { + await communicator.stringToProxy("test@TestAdapter3").ice_locatorCacheTimeout(0).ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.LocalException, ex); + } + try + { + await communicator.stringToProxy("test@TestAdapter3").ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.LocalException, ex); + } + await registry.setAdapterDirectProxy("TestAdapter3", await locator.findAdapterById("TestAdapter")); + try + { + await communicator.stringToProxy("test@TestAdapter3").ice_ping(); + } + catch(ex) + { + test(false, ex); + } + + out.writeLine("ok"); + + out.write("testing well-known object locator cache... "); + await registry.addObject(communicator.stringToProxy("test3@TestUnknown")); + try + { + await communicator.stringToProxy("test3").ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.NotRegisteredException, ex); + test(ex.kindOfObject == "object adapter"); + test(ex.id == "TestUnknown"); + } + await registry.addObject(communicator.stringToProxy("test3@TestAdapter4")); // Update + await registry.setAdapterDirectProxy("TestAdapter4", communicator.stringToProxy("dummy:default")); + try + { + await communicator.stringToProxy("test3").ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.LocalException, ex); + } + + await registry.setAdapterDirectProxy("TestAdapter4", await locator.findAdapterById("TestAdapter")); + try + { + await communicator.stringToProxy("test3").ice_ping(); + } + catch(ex) + { + test(false, ex); + } + + await registry.setAdapterDirectProxy("TestAdapter4", communicator.stringToProxy("dummy:default")); + try + { + await communicator.stringToProxy("test3").ice_ping(); + } + catch(ex) + { + test(false, ex); + } + + try + { + await communicator.stringToProxy("test@TestAdapter4").ice_locatorCacheTimeout(0).ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.LocalException, ex); + } + + try + { + await communicator.stringToProxy("test@TestAdapter4").ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.LocalException); + } + + try + { + await communicator.stringToProxy("test3").ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.LocalException, ex); + } + + await registry.addObject(communicator.stringToProxy("test3@TestAdapter")); + try + { + await communicator.stringToProxy("test3").ice_ping(); + } + catch(ex) + { + test(false, ex); + } + + await registry.addObject(communicator.stringToProxy("test4")); + try + { + await communicator.stringToProxy("test4").ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.NoEndpointException, ex); + } + out.writeLine("ok"); + + out.write("testing locator cache background updates... "); + { + const initData = new Ice.InitializationData(); + initData.properties = communicator.getProperties().clone(); + initData.properties.setProperty("Ice.BackgroundLocatorCacheUpdates", "1"); + const ic = Ice.initialize(initData); + + await registry.setAdapterDirectProxy("TestAdapter5", await locator.findAdapterById("TestAdapter")); + await registry.addObject(communicator.stringToProxy("test3@TestAdapter")); + + count = await locator.getRequestCount(); + await ic.stringToProxy("test@TestAdapter5").ice_locatorCacheTimeout(0).ice_ping(); // No locator cache. + await ic.stringToProxy("test3").ice_locatorCacheTimeout(0).ice_ping(); // No locator cache. + count += 3; + test(count == await locator.getRequestCount()); + await registry.setAdapterDirectProxy("TestAdapter5", null); + await registry.addObject(communicator.stringToProxy("test3:default")); + await ic.stringToProxy("test@TestAdapter5").ice_locatorCacheTimeout(10).ice_ping(); // 10s timeout. + await ic.stringToProxy("test3").ice_locatorCacheTimeout(10).ice_ping(); // 10s timeout. + test(count == await locator.getRequestCount()); + await Ice.Promise.delay(1200); + + // The following request should trigger the background + // updates but still use the cached endpoints and + // therefore succeed. + await ic.stringToProxy("test@TestAdapter5").ice_locatorCacheTimeout(1).ice_ping(); // 1s timeout. + await ic.stringToProxy("test3").ice_locatorCacheTimeout(1).ice_ping(); // 1s timeout. + + try + { + while(true) + { + await ic.stringToProxy("test@TestAdapter5").ice_locatorCacheTimeout(1).ice_ping(); // 1s timeout. + await Ice.Promise.delay(10); + } + } + catch(ex) + { + // Expected to fail once they endpoints have been updated in the background. + test(ex instanceof Ice.LocalException, ex); + } + try + { + while(true) + { + await ic.stringToProxy("test3").ice_locatorCacheTimeout(1).ice_ping(); // 1s timeout. + await Ice.Promise.delay(10); + } + } + catch(ex) + { + // Expected to fail once they endpoints have been updated in the background. + test(ex instanceof Ice.LocalException, ex); + } + await ic.destroy(); + } + out.writeLine("ok"); + + out.write("testing proxy from server after shutdown... "); + hello = await obj.getReplicatedHello(); + await obj.shutdown(); + await manager.startServer(); + await hello.sayHello(); + out.writeLine("ok"); + + out.write("testing object migration... "); + hello = await Test.HelloPrx.checkedCast(communicator.stringToProxy("hello")); + await obj.migrateHello(); + const conn = await hello.ice_getConnection(); + await conn.close(Ice.ConnectionClose.GracefullyWithWait); + await hello.sayHello(); + await obj.migrateHello(); + await hello.sayHello(); + await obj.migrateHello(); + await hello.sayHello(); + out.writeLine("ok"); + + out.write("testing locator encoding resolution... "); + hello = await Test.HelloPrx.checkedCast(communicator.stringToProxy("hello")); + count = await locator.getRequestCount(); + await communicator.stringToProxy("test@TestAdapter").ice_encodingVersion(Ice.Encoding_1_1).ice_ping(); + test(count == await locator.getRequestCount()); + await communicator.stringToProxy("test@TestAdapter10").ice_encodingVersion(Ice.Encoding_1_0).ice_ping(); + test(++count == await locator.getRequestCount()); + await communicator.stringToProxy("test -e 1.0@TestAdapter10-2").ice_ping(); + test(++count == await locator.getRequestCount()); + out.writeLine("ok"); + + out.write("shutdown server manager... "); + await manager.shutdown(); + out.writeLine("ok"); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + let properties:Ice.Properties; + [properties] = this.createTestProperties(args); + properties.setProperty("Ice.Default.Locator", "locator:" + this.getTestEndpoint(properties)); + [communicator] = this.initialize(properties); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/location/Test.ice b/js/test/ts/Ice/location/Test.ice new file mode 100644 index 00000000000..0240e2a8380 --- /dev/null +++ b/js/test/ts/Ice/location/Test.ice @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Locator.ice> + +module Test +{ + +interface TestLocatorRegistry extends ::Ice::LocatorRegistry +{ + // + // Allow remote addition of objects to the locator registry. + // + void addObject(Object* obj); +} + +interface TestLocator extends ::Ice::Locator +{ + // + // Returns the number of request on the locator interface. + // + idempotent int getRequestCount(); +} + +interface ServerManager +{ + void startServer(); + void shutdown(); +} + +interface Hello +{ + void sayHello(); +} + +interface TestIntf +{ + void shutdown(); + + Hello* getHello(); + + Hello* getReplicatedHello(); + + void migrateHello(); +} + +} diff --git a/js/test/ts/Ice/number/Client.ts b/js/test/ts/Ice/number/Client.ts new file mode 100644 index 00000000000..af0fd05b4c5 --- /dev/null +++ b/js/test/ts/Ice/number/Client.ts @@ -0,0 +1,90 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class Client extends TestHelper +{ + run(args:string[]) + { + const out = this.getWriter(); + out.write("Testing Ice.Long... "); + // + // Test positive numbers + // + test(new Ice.Long(0x00000000, 0x00000000).toNumber() === 0); // 0 + test(new Ice.Long(0x00000000, 0x00000001).toNumber() === 1); // 1 + test(new Ice.Long(0x00000000, 0x00000400).toNumber() === 1024); // 1024 + test(new Ice.Long(0x00000000, 0xFFFFFFFF).toNumber() === Math.pow(2, 32) - 1); // 2^32 - 1 + test(new Ice.Long(0x00000001, 0x00000000).toNumber() === Math.pow(2, 32)); // 2^32 + test(new Ice.Long(0x00000001, 0xFFFFFFFF).toNumber() === Math.pow(2, 33) - 1); // 2^33 - 1 + test(new Ice.Long(0x001FFFFF, 0xFFFFFFFF).toNumber() === Math.pow(2, 53) - 1); // 2^53 - 1 + test(new Ice.Long(0x00200000, 0x00000000).toNumber() === Number.POSITIVE_INFINITY); // 2^53 + + // + // Test negative numbers + // + test(new Ice.Long(0xFFFFFFFF, 0xFFFFFFFF).toNumber() === -1); + test(new Ice.Long(0xFFFFFFFF, 0xFFFFFFFE).toNumber() === -2); + test(new Ice.Long(0xFFFFFFFF, 0xFFFFFF9C).toNumber() === -100); + + test(new Ice.Long(0xFFFFFFFF, 0x00000000).toNumber() === -Math.pow(2, 32)); // -(2^32) + test(new Ice.Long(0xFFFFFFFE, 0x00000000).toNumber() === -Math.pow(2, 33)); // -(2^33) + test(new Ice.Long(0xFFFFFFFE, 0x00000001).toNumber() === -(Math.pow(2, 33) - 1)); // -(2^33 - 1) + test(new Ice.Long(0xFFF00000, 0x00000000).toNumber() === -Math.pow(2, 52)); // -(2^52) + test(new Ice.Long(0xFFF00000, 0x00000001).toNumber() === -(Math.pow(2, 52) - 1)); // -(2^52 - 1) + test(new Ice.Long(0xFFE00000, 0x00000001).toNumber() === -(Math.pow(2, 53) - 1)); // -(2^53 - 1) + test(new Ice.Long(0xFFE00000, 0x00000000).toNumber() === Number.NEGATIVE_INFINITY); // -(2^53) + + // + // Test conversion from positive number + // + test(new Ice.Long(0).toNumber() === 0); // 0 + test(new Ice.Long(1).toNumber() === 1); // 1 + test(new Ice.Long(1024).toNumber() === 1024); // 1024 + test(new Ice.Long(Math.pow(2, 32) - 1).toNumber() === Math.pow(2, 32) - 1); // 2^32 - 1 + test(new Ice.Long(Math.pow(2, 32)).toNumber() === Math.pow(2, 32)); // 2^32 + test(new Ice.Long(Math.pow(2, 33) - 1).toNumber() === Math.pow(2, 33) - 1); // 2^33 - 1 + test(new Ice.Long(Math.pow(2, 53) - 1).toNumber() === Math.pow(2, 53) - 1); // 2^53 - 1 + + test(Ice.LongHelper.validate(new Ice.Long(0))); // 0 + test(Ice.LongHelper.validate(new Ice.Long(1))); // 1 + test(Ice.LongHelper.validate(new Ice.Long(1024))); // 1024 + test(Ice.LongHelper.validate(new Ice.Long(Math.pow(2, 32) - 1))); // 2^32 - 1 + test(Ice.LongHelper.validate(new Ice.Long(Math.pow(2, 32)))); // 2^32 + test(Ice.LongHelper.validate(new Ice.Long(Math.pow(2, 33) - 1))); // 2^33 - 1 + test(Ice.LongHelper.validate(new Ice.Long(Math.pow(2, 53) - 1))); // 2^53 - 1 + + // + // Test conversion from negative number + // + test(new Ice.Long(-1).toNumber() === -1); + test(new Ice.Long(-2).toNumber() === -2); + test(new Ice.Long(-100).toNumber() === -100); + + test(new Ice.Long(-Math.pow(2, 32)).toNumber() === -Math.pow(2, 32)); // -(2^32) + test(new Ice.Long(-Math.pow(2, 33)).toNumber() === -Math.pow(2, 33)); // -(2^33) + test(new Ice.Long(-Math.pow(2, 33) - 1).toNumber() === -Math.pow(2, 33) - 1); // -(2^33 - 1) + test(new Ice.Long(-Math.pow(2, 52)).toNumber() === -Math.pow(2, 52)); // -(2^52) + test(new Ice.Long(-Math.pow(2, 52) - 1).toNumber() === -Math.pow(2, 52) - 1); // -(2^52 - 1) + + test(Ice.LongHelper.validate(new Ice.Long(-1))); + test(Ice.LongHelper.validate(new Ice.Long(-2))); + test(Ice.LongHelper.validate(new Ice.Long(-100))); + test(Ice.LongHelper.validate(new Ice.Long(-Math.pow(2, 32)))); // -(2^32) + test(Ice.LongHelper.validate(new Ice.Long(-Math.pow(2, 33)))); // -(2^33) + test(Ice.LongHelper.validate(new Ice.Long(-Math.pow(2, 33) - 1))); // -(2^33 - 1) + test(Ice.LongHelper.validate(new Ice.Long(-Math.pow(2, 52)))); // -(2^52) + test(Ice.LongHelper.validate(new Ice.Long(-Math.pow(2, 52) - 1))); // -(2^52 - 1) + + out.writeLine("ok"); + } +} diff --git a/js/test/ts/Ice/objects/Client.ts b/js/test/ts/Ice/objects/Client.ts new file mode 100644 index 00000000000..5acd9488a22 --- /dev/null +++ b/js/test/ts/Ice/objects/Client.ts @@ -0,0 +1,479 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +const test = TestHelper.test; + +export class BI extends Test.B +{ + ice_preMarshal():void + { + this.preMarshalInvoked = true; + } + + ice_postUnmarshal():void + { + this.postUnmarshalInvoked = true; + } +} + +export class CI extends Test.C +{ + ice_preMarshal():void + { + this.preMarshalInvoked = true; + } + + ice_postUnmarshal():void + { + this.postUnmarshalInvoked = true; + } +} + +export class DI extends Test.D +{ + ice_preMarshal():void + { + this.preMarshalInvoked = true; + } + + ice_postUnmarshal():void + { + this.postUnmarshalInvoked = true; + } +} + +export class EI extends Test.E +{ + constructor() + { + super(1, "hello"); + } + + checkValues():boolean + { + return this.i == 1 && this.s == "hello"; + } +} + +class FI extends Test.F +{ + constructor(e?:Test.E) + { + super(e, e); + } + + checkValues():boolean + { + return this.e1 !== null && this.e1 === this.e2; + } +} + +class HI extends Test.H +{ +} + +class II extends Ice.InterfaceByValue +{ + constructor() + { + super(Test.I.ice_staticId()); + } +} + +class JI extends Ice.InterfaceByValue +{ + constructor() + { + super(Test.J.ice_staticId()); + } +} + +function MyValueFactory(type:string):Ice.Value +{ + switch(type) + { + case "::Test::B": + return new BI(); + case "::Test::C": + return new CI(); + case "::Test::D": + return new DI(); + case "::Test::E": + return new EI(); + case "::Test::F": + return new FI(); + case "::Test::I": + return new II(); + case "::Test::J": + return new JI(); + case "::Test::H": + return new HI(); + case "::Test::Inner::A": + return new Test.Inner.A(); + case "::Test::Inner::Sub::A": + return new Test.Inner.Sub.A(); + default: + break; + } + return null; +} + +class MyObjectFactory implements Ice.ObjectFactory +{ + + create(type:string):Ice.Value + { + return null; + } + + destroy() + { + } +} + +export class Client extends TestHelper +{ + async allTests() + { + const out = this.getWriter(); + const communicator = this.communicator(); + + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::B"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::C"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::D"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::E"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::F"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::I"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::J"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::H"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::Inner::A"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::Inner::Sub::A"); + + communicator.addObjectFactory(new MyObjectFactory(), "TestOF"); + + out.write("testing stringToProxy... "); + let ref = "initial:" + this.getTestEndpoint(); + let base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + const initial = await Test.InitialPrx.checkedCast(base); + test(initial !== null); + test(initial.equals(base)); + out.writeLine("ok"); + + out.write("getting B1... "); + let b1 = await initial.getB1(); + test(b1 !== null); + out.writeLine("ok"); + + out.write("getting B2... "); + let b2 = await initial.getB2(); + test(b2 !== null); + out.writeLine("ok"); + + out.write("getting C... "); + let c = await initial.getC(); + test(c !== null); + out.writeLine("ok"); + + out.write("getting D... "); + let d = await initial.getD(); + test(d !== null); + out.writeLine("ok"); + + out.write("checking consistency... "); + test(b1 !== b2); + + test(b1.theB === b1); + test(b1.theC === null); + test(b1.theA instanceof Test.B); + test((b1.theA as Test.B).theA === b1.theA); + test(b1.theA.theB === b1); + test(b1.theA.theC instanceof Test.C); + test(b1.theA.theC.theB === b1.theA); + + test(b1.preMarshalInvoked); + test(b1.postUnmarshalInvoked); + test(b1.theA.preMarshalInvoked); + test(b1.theA.postUnmarshalInvoked); + test(b1.theA.theC.preMarshalInvoked); + test(b1.theA.theC.postUnmarshalInvoked); + + // More tests possible for b2 and d, but I think this is already + // sufficient. + test(b2.theA === b2); + test(d.theC === null); + out.writeLine("ok"); + out.write("getting B1, B2, C, and D all at once... "); + + [b1, b2, c, d] = await initial.getAll(); + + test(b1 !== null); + test(b2 !== null); + test(c !== null); + test(d !== null); + out.writeLine("ok"); + + out.write("checking consistency... "); + test(b1 !== b2); + test(b1.theA === b2); + test(b1.theB === b1); + test(b1.theC === null); + test(b2.theA === b2); + test(b2.theB === b1); + test(b2.theC === c); + test(c.theB === b2); + test(d.theA === b1); + test(d.theB === b2); + test(d.theC === null); + test(d.preMarshalInvoked); + test(d.postUnmarshalInvoked); + test(d.theA.preMarshalInvoked); + test(d.theA.postUnmarshalInvoked); + test(d.theB.preMarshalInvoked); + test(d.theB.postUnmarshalInvoked); + test(d.theB.theC.preMarshalInvoked); + test(d.theB.theC.postUnmarshalInvoked); + out.writeLine("ok"); + + out.write("testing protected members... "); + const e = await initial.getE() as EI; + test(e.checkValues()); + + const f = await initial.getF() as FI; + test(f.checkValues()); + test((f.e2 as EI).checkValues()); + out.writeLine("ok"); + + out.write("getting I, J and H... "); + const i = await initial.getI(); + test(i !== null); + const j = await initial.getJ(); + test(j !== null); + const h = await initial.getH(); + test(h !== null); + out.writeLine("ok"); + + out.write("getting K..."); + const k = await initial.getK(); + test(k !== null); + test((k.value as Test.L).data == "l"); + out.writeLine("ok"); + + out.write("test Value as parameter..."); + { + { + let [v1, v2] = await initial.opValue(new Test.L("l")); + test((v1 as Test.L).data == "l"); + test((v2 as Test.L).data == "l"); + } + + { + let [v1, v2] = await initial.opValueSeq([new Test.L("l")]); + test((v1[0] as Test.L).data == "l"); + test((v2[0] as Test.L).data == "l"); + } + + { + let [v1, v2] = await initial.opValueMap(new Map([["l", new Test.L("l")]])); + test((v1.get("l") as Test.L).data == "l"); + test((v2.get("l") as Test.L).data == "l"); + } + } + out.writeLine("ok"); + + out.write("getting D1... "); + const d1 = await initial.getD1(new Test.D1(new Test.A1("a1"), + new Test.A1("a2"), + new Test.A1("a3"), + new Test.A1("a4"))); + + test(d1.a1.name == "a1"); + test(d1.a2.name == "a2"); + test(d1.a3.name == "a3"); + test(d1.a4.name == "a4"); + out.writeLine("ok"); + + out.write("throw EDerived... "); + try + { + await initial.throwEDerived(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.EDerived, ex); + test(ex.a1.name == "a1"); + test(ex.a2.name == "a2"); + test(ex.a3.name == "a3"); + test(ex.a4.name == "a4"); + } + out.writeLine("ok"); + + out.write("setting G... "); + try + { + await initial.setG(new Test.G(new Test.S("hello"), "g")); + } + catch(ex) + { + test(ex instanceof Ice.OperationNotExistException, ex); + } + out.writeLine("ok"); + + out.write("setting I... "); + await initial.setI(i); + await initial.setI(j); + await initial.setI(h); + out.writeLine("ok"); + + out.write("testing sequences... "); + let [retS, outS] = await initial.opBaseSeq([]); + [retS, outS] = await initial.opBaseSeq([new Test.Base(new Test.S(), "")]); + test(retS.length === 1 && outS.length === 1); + out.writeLine("ok"); + + out.write("testing recursive types... "); + + const top = new Test.Recursive(); + let p = top; + let depth = 0; + + try + { + for(; depth <= 1000; ++depth) + { + p.v = new Test.Recursive(); + p = p.v; + if((depth < 10 && (depth % 10) == 0) || + (depth < 1000 && (depth % 100) == 0) || + (depth < 10000 && (depth % 1000) == 0) || + (depth % 10000) == 0) + { + await initial.setRecursive(top); + } + } + test(!(await initial.supportsClassGraphDepthMax())); + } + catch(ex) + { + // + // Ice.UnknownLocalException: Expected marshal exception from the server (max class graph depth reached) + // Ice.UnknownException: Expected stack overflow from the server (Java only) + // Error: Expected, JavaScript stack overflow + // + test((ex instanceof Ice.UnknownLocalException) || + (ex instanceof Ice.UnknownException) || + (ex instanceof Error), ex); + } + await initial.setRecursive(new Test.Recursive()); + out.writeLine("ok"); + + out.write("testing compact ID... "); + test(await initial.getCompact() !== null); + out.writeLine("ok"); + + out.write("testing marshaled results..."); + b1 = await initial.getMB(); + test(b1 !== null && b1.theB === b1); + b1 = await initial.getAMDMB(); + test(b1 !== null && b1.theB === b1); + out.writeLine("ok"); + + out.write("testing UnexpectedObjectException... "); + ref = "uoet:" + this.getTestEndpoint(); + base = communicator.stringToProxy(ref); + test(base !== null); + + const uoet = Test.UnexpectedObjectExceptionTestPrx.uncheckedCast(base); + test(uoet !== null); + try + { + await uoet.op(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnexpectedObjectException, ex); + test(ex.type == "::Test::AlsoEmpty"); + test(ex.expectedType == "::Test::Empty"); + } + out.writeLine("ok"); + + out.write("testing inner modules... "); + { + let innerA = await initial.getInnerA(); + test(innerA instanceof Test.Inner.A); + test(innerA.theA instanceof Test.B); + } + + { + let innerA = await initial.getInnerSubA(); + test(innerA instanceof Test.Inner.Sub.A); + test(innerA.theA instanceof Test.Inner.A); + } + + try + { + await initial.throwInnerEx(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.Inner.Ex, ex); + test(ex.reason == "Inner::Ex"); + } + + try + { + await initial.throwInnerSubEx(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.Inner.Sub.Ex, ex); + test(ex.reason == "Inner::Sub::Ex"); + } + out.writeLine("ok"); + + out.write("testing getting ObjectFactory... "); + test(communicator.findObjectFactory("TestOF") !== null); + out.writeLine("ok"); + + out.write("testing getting ObjectFactory as ValueFactory... "); + test(communicator.getValueFactoryManager().find("TestOF") !== null); + out.writeLine("ok"); + + await initial.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.Warn.Connections", "0"); + [communicator] = this.initialize(properties); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/objects/InitialI.ts b/js/test/ts/Ice/objects/InitialI.ts new file mode 100644 index 00000000000..8ea6dd4796f --- /dev/null +++ b/js/test/ts/Ice/objects/InitialI.ts @@ -0,0 +1,334 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICEthis._LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" + +export class BI extends Test.B +{ + ice_preMarshal():void + { + this.preMarshalInvoked = true; + } + + ice_postUnmarshal():void + { + this.postUnmarshalInvoked = true; + } +} + +export class CI extends Test.C +{ + ice_preMarshal():void + { + this.preMarshalInvoked = true; + } + + ice_postUnmarshal():void + { + this.postUnmarshalInvoked = true; + } +} + +export class DI extends Test.D +{ + ice_preMarshal():void + { + this.preMarshalInvoked = true; + } + + ice_postUnmarshal():void + { + this.postUnmarshalInvoked = true; + } +} + +export class EI extends Test.E +{ + constructor() + { + super(1, "hello"); + } + + checkValues():boolean + { + return this.i == 1 && this.s == "hello"; + } +} + +export class FI extends Test.F +{ + constructor(e?:Test.E) + { + super(e, e); + } + + checkValues():boolean + { + return this.e1 !== null && this.e1 === this.e2; + } +} + +export class HI extends Test.H +{ +} + +export class II extends Ice.InterfaceByValue +{ + constructor() + { + super(Test.I.ice_staticId()); + } +} + +export class JI extends Ice.InterfaceByValue +{ + constructor() + { + super(Test.J.ice_staticId()); + } +} + +export function MyValueFactory(type:string):Ice.Value +{ + switch(type) + { + case "::Test::B": + return new BI(); + case "::Test::C": + return new CI(); + case "::Test::D": + return new DI(); + case "::Test::E": + return new EI(); + case "::Test::F": + return new FI(); + case "::Test::I": + return new II(); + case "::Test::J": + return new JI(); + case "::Test::H": + return new HI(); + case "::Test::Inner::A": + return new Test.Inner.A(); + case "::Test::Inner::Sub::A": + return new Test.Inner.Sub.A(); + default: + break; + } + return null; +} + +export class InitialI extends Test.Initial +{ + constructor(communicator:Ice.Communicator) + { + super(); + if(communicator !== undefined) + { + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::B"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::C"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::D"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::E"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::F"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::I"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::J"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::H"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::Inner::A"); + communicator.getValueFactoryManager().add(MyValueFactory, "::Test::Inner::Sub::A"); + } + + this._b1 = new BI(); + this._b2 = new BI(); + this._c = new CI(); + this._d = new DI(); + this._e = new EI(); + this._f = new FI(this._e); + + this._b1.theA = this._b2; // Cyclic reference to another B + this._b1.theB = this._b1; // Self reference. + this._b1.theC = null; // Null reference. + + this._b2.theA = this._b2; // Self reference, using base. + this._b2.theB = this._b1; // Cyclic reference to another B + this._b2.theC = this._c; // Cyclic reference to a C. + + this._c.theB = this._b2; // Cyclic reference to a B. + + this._d.theA = this._b1; // Reference to a B. + this._d.theB = this._b2; // Reference to a B. + this._d.theC = null; // Reference to a C. + } + + getAll(current:Ice.Current):[Test.B, Test.B, Test.C, Test.D] + { + this._b1.preMarshalInvoked = false; + this._b2.preMarshalInvoked = false; + this._c.preMarshalInvoked = false; + this._d.preMarshalInvoked = false; + return [this._b1, this._b2, this._c, this._d]; + } + + getB1(current:Ice.Current):Test.B + { + this._b1.preMarshalInvoked = false; + this._b2.preMarshalInvoked = false; + this._c.preMarshalInvoked = false; + return this._b1; + } + + getB2(current:Ice.Current):Test.B + { + this._b1.preMarshalInvoked = false; + this._b2.preMarshalInvoked = false; + this._c.preMarshalInvoked = false; + return this._b2; + } + + getC(current:Ice.Current):Test.C + { + this._b1.preMarshalInvoked = false; + this._b2.preMarshalInvoked = false; + this._c.preMarshalInvoked = false; + return this._c; + } + + getD(current:Ice.Current):Test.D + { + this._b1.preMarshalInvoked = false; + this._b2.preMarshalInvoked = false; + this._c.preMarshalInvoked = false; + this._d.preMarshalInvoked = false; + return this._d; + } + + getE(current:Ice.Current):Test.E + { + return this._e; + } + + getF(current:Ice.Current):Test.F + { + return this._f; + } + + setRecursive(r:Test.Recursive, current:Ice.Current):void + { + } + + supportsClassGraphDepthMax(current:Ice.Current):boolean + { + return false; + } + + getMB(current:Ice.Current):Test.B + { + return this._b1; + } + + getAMDMB(current:Ice.Current):PromiseLike<Test.B> + { + return Promise.resolve(this._b1); + } + + getI(current:Ice.Current):Ice.Value + { + return new II(); + } + + getJ(current:Ice.Current):Ice.Value + { + return new JI(); + } + + getH(current:Ice.Current):Ice.Value + { + return new HI(); + } + + getK(current:Ice.Current) + { + return new Test.K(new Test.L("l")); + } + + opValue(v1:Ice.Value, current:Ice.Current):[Ice.Value, Ice.Value] + { + return [v1, v1]; + } + + opValueSeq(v1:Ice.Value[], current:Ice.Current):[Ice.Value[], Ice.Value[]] + { + return [v1, v1]; + } + + opValueMap(v1:Map<string, Ice.Value>, current:Ice.Current):[Map<string, Ice.Value>, Map<string, Ice.Value>] + { + return [v1, v1]; + } + + getD1(d1:Test.D1, current:Ice.Current):Test.D1 + { + return d1; + } + + throwEDerived(current:Ice.Current) + { + throw new Test.EDerived(new Test.A1("a1"), new Test.A1("a2"), new Test.A1("a3"), new Test.A1("a4")); + } + + setG(theG:Test.G, current:Ice.Current):void + { + } + + setI(theI:Ice.Value, current:Ice.Current):void + { + } + + opBaseSeq(inS:Test.BaseSeq, current:Ice.Current):[Test.BaseSeq, Test.BaseSeq] + { + return [inS, inS]; + } + + getCompact(current:Ice.Current):Test.Compact + { + return new Test.CompactExt(); + } + + getInnerA(current:Ice.Current):Test.Inner.A + { + return new Test.Inner.A(this._b1); + } + + getInnerSubA(current:Ice.Current):Test.Inner.Sub.A + { + return new Test.Inner.Sub.A(new Test.Inner.A(this._b1)); + } + + throwInnerEx(current:Ice.Current):void + { + throw new Test.Inner.Ex("Inner::Ex"); + } + + throwInnerSubEx(current:Ice.Current):void + { + throw new Test.Inner.Sub.Ex("Inner::Sub::Ex"); + } + + shutdown(current:Ice.Current):void + { + current.adapter.getCommunicator().shutdown(); + } + + _b1:BI; + _b2:BI; + _c:CI; + _d:DI; + _e:EI; + _f:FI; +} diff --git a/js/test/ts/Ice/objects/Server.ts b/js/test/ts/Ice/objects/Server.ts new file mode 100644 index 00000000000..fba711fa13b --- /dev/null +++ b/js/test/ts/Ice/objects/Server.ts @@ -0,0 +1,59 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +import {InitialI} from "./InitialI"; + +const test = TestHelper.test; + +class UnexpectedObjectExceptionTestI extends Test.UnexpectedObjectExceptionTest +{ + op(current:Ice.Current):Test.Empty + { + return new Test.AlsoEmpty(); + } +} + +export class Server extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.Warn.Dispatch", "0"); + properties.setProperty("Ice.Warn.Connections", "0"); + [communicator] = this.initialize(properties); + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter = await communicator.createObjectAdapter(""); + adapter.add(new InitialI(communicator), Ice.stringToIdentity("initial")); + adapter.add(new UnexpectedObjectExceptionTestI(), Ice.stringToIdentity("uoet")); + await echo.setConnection(); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/objects/Test.ice b/js/test/ts/Ice/objects/Test.ice new file mode 100644 index 00000000000..b7b6183b629 --- /dev/null +++ b/js/test/ts/Ice/objects/Test.ice @@ -0,0 +1,296 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +[["suppress-warning:deprecated"]] // For classes with operations + +module Test +{ + +struct S +{ + string str; +} + +class Base +{ + S theS; + string str; +} + +class AbstractBase extends Base +{ + void op(); +} + +class B; +class C; + +class A +{ + B theB; + C theC; + + bool preMarshalInvoked; + bool postUnmarshalInvoked; +} + +class B extends A +{ + A theA; +} + +class C +{ + B theB; + + bool preMarshalInvoked; + bool postUnmarshalInvoked; +} + +class D +{ + A theA; + B theB; + C theC; + + bool preMarshalInvoked; + bool postUnmarshalInvoked; +} + +["protected"] class E +{ + int i; + string s; +} + +class F +{ + ["protected"] E e1; + E e2; +} + +// Exercise empty class with non-empty base +class G extends Base +{ +} + +interface I +{ + void doI(); +} + +interface J extends I +{ + void doJ(); +} + +class H implements I +{ + void doH(); + void doH2(); +} + +sequence<Base> BaseSeq; + +class CompactExt; + +class Compact(1) +{ +} + +const int CompactExtId = 789; + +class CompactExt(CompactExtId) extends Compact +{ +} + +class A1 +{ + string name; +} + +class B1 +{ + A1 a1; + A1 a2; +} + +class D1 extends B1 +{ + A1 a3; + A1 a4; +} + +exception EBase +{ + A1 a1; + A1 a2; +} + +exception EDerived extends EBase +{ + A1 a3; + A1 a4; +} + +module Inner +{ + +class A +{ + ::Test::A theA; +} + +exception Ex +{ + string reason; +} + +module Sub +{ + +class A +{ + ::Test::Inner::A theA; +} + +exception Ex +{ + string reason; +} + +} + +} + +class Recursive +{ + Recursive v; +} + +class K +{ + Value value; +} + +class L +{ + string data; +} + +sequence<Value> ValueSeq; +dictionary<string, Value> ValueMap; + +interface Initial +{ + void shutdown(); + B getB1(); + B getB2(); + C getC(); + D getD(); + E getE(); + F getF(); + + void setRecursive(Recursive p); + bool supportsClassGraphDepthMax(); + + ["marshaled-result"] B getMB(); + ["amd", "marshaled-result"] B getAMDMB(); + + void getAll(out B b1, out B b2, out C theC, out D theD); + + I getH(); + I getI(); + I getJ(); + + K getK(); + + Value opValue(Value v1, out Value v2); + ValueSeq opValueSeq(ValueSeq v1, out ValueSeq v2); + ValueMap opValueMap(ValueMap v1, out ValueMap v2); + + D1 getD1(D1 d1); + void throwEDerived() throws EDerived; + + void setG(G theG); + void setI(I theI); + + BaseSeq opBaseSeq(BaseSeq inSeq, out BaseSeq outSeq); + + Compact getCompact(); + + Inner::A getInnerA(); + Inner::Sub::A getInnerSubA(); + + void throwInnerEx() throws Inner::Ex; + void throwInnerSubEx() throws Inner::Sub::Ex; +} + +class Empty +{ +} + +class AlsoEmpty +{ +} + +interface UnexpectedObjectExceptionTest +{ + Empty op(); +} + +// +// Remaining definitions are here to ensure that the generated code compiles. +// + +class COneMember +{ + Empty e; +} + +class CTwoMembers +{ + Empty e1; + Empty e2; +} + +exception EOneMember +{ + Empty e; +} + +exception ETwoMembers +{ + Empty e1; + Empty e2; +} + +struct SOneMember +{ + Empty e; +} + +struct STwoMembers +{ + Empty e1; + Empty e2; +} + +dictionary<int, COneMember> DOneMember; +dictionary<int, CTwoMembers> DTwoMembers; + +interface Echo +{ + void setConnection(); + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/operations/AMDMyDerivedClassI.ts b/js/test/ts/Ice/operations/AMDMyDerivedClassI.ts new file mode 100644 index 00000000000..d63f9a55e04 --- /dev/null +++ b/js/test/ts/Ice/operations/AMDMyDerivedClassI.ts @@ -0,0 +1,537 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** +import {Ice} from "ice";; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +const test = TestHelper.test; + +export class AMDMyDerivedClassI extends Test.MyDerivedClass +{ + // + // Override the Object "pseudo" operations to verify the operation mode. + // + constructor(endpoints:Ice.Endpoint[]) + { + super(); + this._opByteSOnewayCount = 0; + this._endpoints = endpoints; + } + + ice_isA(id:string, current:Ice.Current):boolean + { + test(current.mode === Ice.OperationMode.Nonmutating); + return Ice.Object.prototype.ice_isA.call(this, id, current); + } + + ice_ping(current:Ice.Current):void + { + test(current.mode === Ice.OperationMode.Nonmutating); + Ice.Object.prototype.ice_ping.call(this, current); + } + + ice_ids(current:Ice.Current):Ice.StringSeq + { + test(current.mode === Ice.OperationMode.Nonmutating); + return Ice.Object.prototype.ice_ids.call(this, current); + } + + ice_id(current:Ice.Current):string + { + test(current.mode === Ice.OperationMode.Nonmutating); + return Ice.Object.prototype.ice_id.call(this, current); + } + + shutdown(current:Ice.Current):void + { + current.adapter.getCommunicator().shutdown(); + } + + supportsCompress(current:Ice.Current):boolean + { + return false; + } + + opVoid(current:Ice.Current):void + { + test(current.mode === Ice.OperationMode.Normal); + } + + opBool(p1:boolean, p2:boolean, current:Ice.Current):[boolean, boolean] + { + return [p2, p1]; + } + + opBoolS(p1:Test.BoolS, p2:Test.BoolS, current:Ice.Current):[Test.BoolS, Test.BoolS] + { + const p3 = p1.concat(p2); + return [p1.reverse(), p3]; + } + + opBoolSS(p1:Test.BoolSS, p2:Test.BoolSS, current:Ice.Current):[Test.BoolSS, Test.BoolSS] + { + const p3 = p1.concat(p2); + return [p1.reverse(), p3]; + } + + opByte(p1:number, p2:number, current:Ice.Current):[number, number] + { + return [p1, (p1 ^ p2) & 0xff]; + } + + opByteBoolD(p1:Test.ByteBoolD, p2:Test.ByteBoolD, current:Ice.Current):[Test.ByteBoolD, Test.ByteBoolD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opByteS(p1:Test.ByteS, p2:Test.ByteS, current:Ice.Current):[Test.ByteS, Test.ByteS] + { + const p3 = new Uint8Array(p1.length); + for(let i = 0; i < p1.length; i++) + { + p3[i] = p1[p1.length - (i + 1)]; + } + + const r = new Uint8Array(p1.length + p2.length); + for(let i = 0; i < p1.length; ++i) + { + r[i] = p1[i]; + } + for(let i = 0; i < p2.length; ++i) + { + r[i + p1.length] = p2[i]; + } + return [r, p3]; + } + + opByteSS(p1:Test.ByteSS, p2:Test.ByteSS, current:Ice.Current):[Test.ByteSS, Test.ByteSS] + { + const r = p1.concat(p2); + return [r, p1.reverse()]; + } + + opFloatDouble(p1:number, p2:number, current:Ice.Current):[number, number, number] + { + return [p2, p1, p2]; + } + + opFloatDoubleS(p1:Test.FloatS, p2:Test.DoubleS, current:Ice.Current): + [Test.DoubleS, Test.FloatS, Test.DoubleS] + { + const r = p2.concat(p1); + const p4 = p2.reverse(); + return [r, p1, p4]; + } + + opFloatDoubleSS(p1:Test.FloatSS, p2:Test.DoubleSS, current:Ice.Current): + [Test.DoubleSS, Test.FloatSS, Test.DoubleSS] + { + const r = p2.concat(p2); + const p4 = p2.reverse(); + return [r, p1, p4]; + } + + opLongFloatD(p1:Test.LongFloatD, p2:Test.LongFloatD, current:Ice.Current):[Test.LongFloatD, Test.LongFloatD] + { + const r = new Ice.HashMap(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opMyClass(p1:Test.MyClassPrx, current:Ice.Current):[Test.MyClassPrx, Test.MyClassPrx, Test.MyClassPrx] + { + const p2 = p1; + const p3 = Test.MyClassPrx.uncheckedCast( + current.adapter.createProxy(Ice.stringToIdentity("noSuchIdentity"))); + const r = Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(current.id)); + return [r.ice_endpoints(this._endpoints), p2, p3.ice_endpoints(this._endpoints)]; + } + + opMyEnum(p1:Test.MyEnum, current:Ice.Current):[Test.MyEnum, Test.MyEnum] + { + return [Test.MyEnum.enum3, p1]; + } + + opShortIntD(p1:Test.ShortIntD, p2:Test.ShortIntD, current:Ice.Current):[Test.ShortIntD, Test.ShortIntD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opShortIntLong(p1:number, p2:number, p3:Ice.Long, current:Ice.Current): + [Ice.Long, number, number, Ice.Long] + { + return [p3, p1, p2, p3]; + } + + opShortIntLongS(p1:Test.ShortS, p2:Test.IntS, p3:Test.LongS, current:Ice.Current): + [Test.LongS, Test.ShortS, Test.IntS, Test.LongS] + { + return [p3, p1, p2.reverse(), p3.concat(p3)]; + } + + opShortIntLongSS(p1:Test.ShortSS, p2:Test.IntSS, p3:Test.LongSS, current:Ice.Current): + [Test.LongSS, Test.ShortSS, Test.IntSS, Test.LongSS] + { + return [p3, p1, p2.reverse(), p3.concat(p3)]; + } + + opString(p1:string, p2:string, current:Ice.Current):[string, string] + { + return [p1 + " " + p2, p2 + " " + p1]; + } + + opStringMyEnumD(p1:Test.StringMyEnumD, + p2:Test.StringMyEnumD, current:Ice.Current):[Test.StringMyEnumD, Test.StringMyEnumD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opMyEnumStringD(p1:Test.MyEnumStringD, + p2:Test.MyEnumStringD, current:Ice.Current):[Test.MyEnumStringD, Test.MyEnumStringD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opMyStructMyEnumD(p1:Test.MyStructMyEnumD, + p2:Test.MyStructMyEnumD, current:Ice.Current):[Test.MyStructMyEnumD, Test.MyStructMyEnumD] + { + const r = new Ice.HashMap(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opByteBoolDS(p1:Test.ByteBoolDS, p2:Test.ByteBoolDS, current:Ice.Current):[Test.ByteBoolDS, Test.ByteBoolDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opShortIntDS(p1:Test.ShortIntDS, p2:Test.ShortIntDS, current:Ice.Current):[Test.ShortIntDS, Test.ShortIntDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opLongFloatDS(p1:Test.LongFloatDS, p2:Test.LongFloatDS, current:Ice.Current):[Test.LongFloatDS, Test.LongFloatDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opStringStringDS(p1:Test.StringStringDS, + p2:Test.StringStringDS, current:Ice.Current):[Test.StringStringDS, Test.StringStringDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opStringMyEnumDS(p1:Test.StringMyEnumDS, + p2:Test.StringMyEnumDS, current:Ice.Current):[Test.StringMyEnumDS, Test.StringMyEnumDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opMyEnumStringDS(p1:Test.MyEnumStringDS, + p2:Test.MyEnumStringDS, current:Ice.Current):[Test.MyEnumStringDS, Test.MyEnumStringDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opMyStructMyEnumDS(p1:Test.MyStructMyEnumDS, + p2:Test.MyStructMyEnumDS, current:Ice.Current):[Test.MyStructMyEnumDS, Test.MyStructMyEnumDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opByteByteSD(p1:Test.ByteByteSD, p2:Test.ByteByteSD, current:Ice.Current):[Test.ByteByteSD, Test.ByteByteSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opBoolBoolSD(p1:Test.BoolBoolSD, p2:Test.BoolBoolSD, current:Ice.Current):[Test.BoolBoolSD, Test.BoolBoolSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opShortShortSD(p1:Test.ShortShortSD, p2:Test.ShortShortSD, current:Ice.Current):[Test.ShortShortSD, Test.ShortShortSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opIntIntSD(p1:Test.IntIntSD, p2:Test.IntIntSD, current:Ice.Current):[Test.IntIntSD, Test.IntIntSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opLongLongSD(p1:Test.LongLongSD, p2:Test.LongLongSD, current:Ice.Current):[Test.LongLongSD, Test.LongLongSD] + { + const r = new Ice.HashMap(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Ice.HashMap(p2); + return [r, p3]; + } + + opStringFloatSD(p1:Test.StringFloatSD, + p2:Test.StringFloatSD, current:Ice.Current):[Test.StringFloatSD, Test.StringFloatSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opStringDoubleSD(p1:Test.StringDoubleSD, + p2:Test.StringDoubleSD, current:Ice.Current):[Test.StringDoubleSD, Test.StringDoubleSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opStringStringSD(p1:Test.StringStringSD, + p2:Test.StringStringSD, current:Ice.Current):[Test.StringStringSD, Test.StringStringSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opMyEnumMyEnumSD(p1:Test.MyEnumMyEnumSD, + p2:Test.MyEnumMyEnumSD, current:Ice.Current):[Test.MyEnumMyEnumSD, Test.MyEnumMyEnumSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opIntS(s:Test.IntS, current:Ice.Current):Test.IntS + { + return s.map(v => -v); + } + + opByteSOneway(s:Test.ByteS, current:Ice.Current):void + { + this._opByteSOnewayCount += 1; + } + + opByteSOnewayCallCount(current:Ice.Current):number + { + const count = this._opByteSOnewayCount; + this._opByteSOnewayCount = 0; + return count; + } + + opContext(current:Ice.Current):Ice.Context + { + return current.ctx; + } + + opDoubleMarshaling(p1:number, p2:Test.DoubleS, current:Ice.Current):void + { + const d = 1278312346.0 / 13.0; + test(p1 === d); + for(let i = 0; i < p2.length; ++i) + { + test(p2[i] === d); + } + } + + opStringS(p1:Test.StringS, p2:Test.StringS, current:Ice.Current):[Test.StringS, Test.StringS] + { + const p3 = p1.concat(p2); + const r = p1.reverse(); + return [r, p3]; + } + + opStringSS(p1:Test.StringSS, p2:Test.StringSS, current:Ice.Current):[Test.StringSS, Test.StringSS] + { + const p3 = p1.concat(p2); + const r = p2.reverse(); + return [r, p3]; + } + + opStringSSS(p1:Test.StringSSS, p2:Test.StringSSS, current:Ice.Current):[Test.StringSSS, Test.StringSSS] + { + const p3 = p1.concat(p2); + const r = p2.reverse(); + return [r, p3]; + } + + opStringStringD(p1:Test.StringStringD, p2:Test.StringStringD, current:Ice.Current):[Test.StringStringD, Test.StringStringD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opStruct(p1:Test.Structure, p2:Test.Structure, current:Ice.Current):[Test.Structure, Test.Structure] + { + p1.s.s = "a new string"; + return [p2, p1]; + } + + opIdempotent(current:Ice.Current):void + { + test(current.mode === Ice.OperationMode.Idempotent); + } + + opNonmutating(current:Ice.Current):void + { + test(current.mode === Ice.OperationMode.Nonmutating); + } + + opDerived(current:Ice.Current):void + { + } + + opByte1(value:number, current:Ice.Current):number + { + return value; + } + + opShort1(value:number, current:Ice.Current):number + { + return value; + } + + opInt1(value:number, current:Ice.Current):number + { + return value; + } + + opLong1(value:Ice.Long, current:Ice.Current):Ice.Long + { + return value; + } + + opFloat1(value:number, current:Ice.Current):number + { + return value; + } + + opDouble1(value:number, current:Ice.Current):number + { + return value; + } + + opString1(value:string, current:Ice.Current):string + { + return value; + } + + opStringS1(value:Test.StringS, current:Ice.Current):Test.StringS + { + return value; + } + + opByteBoolD1(value:Test.ByteBoolD, current:Ice.Current):Test.ByteBoolD + { + return value; + } + + opStringS2(value:Test.StringS, current:Ice.Current):Test.StringS + { + return value; + } + + opByteBoolD2(value:Test.ByteBoolD, current:Ice.Current):Test.ByteBoolD + { + return value; + } + + opMyClass1(value:Test.MyClass1, current:Ice.Current):Test.MyClass1 + { + return value; + } + + opMyStruct1(value:Test.MyStruct1, current:Ice.Current):Test.MyStruct1 + { + return value; + } + + opStringLiterals(current:Ice.Current):Test.StringS + { + return [ + Test.s0, Test.s1, Test.s2, Test.s3, Test.s4, Test.s5, Test.s6, Test.s7, Test.s8, Test.s9, Test.s10, + Test.sw0, Test.sw1, Test.sw2, Test.sw3, Test.sw4, Test.sw5, Test.sw6, Test.sw7, Test.sw8, Test.sw9, Test.sw10, + Test.ss0, Test.ss1, Test.ss2, Test.ss3, Test.ss4, Test.ss5, + Test.su0, Test.su1, Test.su2 + ]; + } + + opWStringLiterals(current:Ice.Current):Test.WStringS + { + return this.opStringLiterals(current); + } + + opMStruct1(current:Ice.Current):Test.Structure + { + return new Test.Structure(); + } + + opMStruct2(p1:Test.Structure, current:Ice.Current):[Test.Structure, Test.Structure] + { + return [p1, p1]; + } + + opMSeq1(current:Ice.Current):Test.StringS + { + return []; + } + + opMSeq2(p1:Test.StringS, current:Ice.Current):[Test.StringS, Test.StringS] + { + return [p1, p1]; + } + + opMDict1(current:Ice.Current):Test.StringStringD + { + return new Map(); + } + + opMDict2(p1:Test.StringStringD, current:Ice.Current):[Test.StringStringD, Test.StringStringD] + { + return [p1, p1]; + } + + _opByteSOnewayCount:number; + _endpoints:Ice.Endpoint[]; +} diff --git a/js/test/ts/Ice/operations/BatchOneways.ts b/js/test/ts/Ice/operations/BatchOneways.ts new file mode 100644 index 00000000000..8f1b22cb8b1 --- /dev/null +++ b/js/test/ts/Ice/operations/BatchOneways.ts @@ -0,0 +1,75 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +const test = TestHelper.test; + +export async function run(communicator:Ice.Communicator, prx:Test.MyClassPrx, bidir:boolean) +{ + const bs1 = new Uint8Array(10 * 1024); + for(let i = 0; i < bs1.length; ++i) + { + bs1[i] = 0; + } + + const batch = Test.MyClassPrx.uncheckedCast(prx.ice_batchOneway()); + await batch.ice_flushBatchRequests(); + + test(batch.ice_flushBatchRequests().isCompleted()); // Empty flush + test(batch.ice_flushBatchRequests().isSent()); // Empty flush + test(batch.ice_flushBatchRequests().sentSynchronously()); // Empty flush + + for(let i = 0; i < 30; ++i) + { + await batch.opByteSOneway(bs1); + } + + let count = 0; + while(count < 27) // 3 * 9 requests auto-flushed. + { + count += await prx.opByteSOnewayCallCount(); + await Ice.Promise.delay(10); + } + + if(batch.ice_getConnection() !== null) + { + const batch1 = Test.MyClassPrx.uncheckedCast(prx.ice_batchOneway()); + const batch2 = Test.MyClassPrx.uncheckedCast(prx.ice_batchOneway()); + + batch1.ice_ping(); + batch2.ice_ping(); + await batch1.ice_flushBatchRequests(); + await batch1.ice_getConnection().then(c => c.close(Ice.ConnectionClose.GracefullyWithWait)); + batch1.ice_ping(); + batch2.ice_ping(); + + await batch1.ice_getConnection(); + await batch2.ice_getConnection(); + + batch1.ice_ping(); + await batch1.ice_getConnection().then(c => c.close(Ice.ConnectionClose.GracefullyWithWait)); + + batch1.ice_ping(); + batch2.ice_ping(); + } + + const identity = new Ice.Identity(); + identity.name = "invalid"; + const batch3 = batch.ice_identity(identity); + batch3.ice_ping(); + await batch3.ice_flushBatchRequests(); + + // Make sure that a bogus batch request doesn't cause troubles to other ones. + batch3.ice_ping(); + batch.ice_ping(); + await batch.ice_flushBatchRequests(); + await batch.ice_ping(); +} diff --git a/js/test/ts/Ice/operations/Client.ts b/js/test/ts/Ice/operations/Client.ts new file mode 100644 index 00000000000..72a9df26e63 --- /dev/null +++ b/js/test/ts/Ice/operations/Client.ts @@ -0,0 +1,79 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test" +import {TestHelper} from "../../../Common/TestHelper" +import * as Twoways from "./Twoways"; +import * as Oneways from "./Oneways"; +import * as BatchOneways from "./BatchOneways"; + +export class Client extends TestHelper +{ + async allTests(bidir:boolean) + { + const out = this.getWriter(); + const communicator = this.communicator(); + out.write("testing twoway operations... "); + const ref = "test:" + this.getTestEndpoint(); + const base = communicator.stringToProxy(ref); + const cl = await Test.MyClassPrx.checkedCast(base); + const derived = await Test.MyDerivedClassPrx.checkedCast(cl); + + await Twoways.run(communicator, cl, bidir, this); + await Twoways.run(communicator, derived, bidir, this); + out.writeLine("ok"); + + out.write("testing oneway operations... "); + await Oneways.run(communicator, cl, bidir); + out.writeLine("ok"); + + out.write("testing batch oneway operations... "); + await BatchOneways.run(communicator, cl, bidir); + out.writeLine("ok"); + + out.write("testing server shutdown... "); + await cl.shutdown(); + try + { + await cl.ice_timeout(100).ice_ping(); // Use timeout to speed up testing on Windows + throw new Error("test failed"); + } + catch(ex) + { + if(ex instanceof Ice.LocalException) + { + out.writeLine("ok"); + } + else + { + throw ex; + } + } + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.BatchAutoFlushSize", "100"); + [communicator] = this.initialize(properties); + await this.allTests(false); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/operations/MyDerivedClassI.ts b/js/test/ts/Ice/operations/MyDerivedClassI.ts new file mode 100644 index 00000000000..fb50f2be795 --- /dev/null +++ b/js/test/ts/Ice/operations/MyDerivedClassI.ts @@ -0,0 +1,537 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** +import {Ice} from "ice";; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +const test = TestHelper.test; + +export class MyDerivedClassI extends Test.MyDerivedClass +{ + // + // Override the Object "pseudo" operations to verify the operation mode. + // + constructor(endpoints:Ice.Endpoint[]) + { + super(); + this._opByteSOnewayCount = 0; + this._endpoints = endpoints; + } + + ice_isA(id:string, current:Ice.Current):boolean + { + test(current.mode === Ice.OperationMode.Nonmutating); + return Ice.Object.prototype.ice_isA.call(this, id, current); + } + + ice_ping(current:Ice.Current):void + { + test(current.mode === Ice.OperationMode.Nonmutating); + Ice.Object.prototype.ice_ping.call(this, current); + } + + ice_ids(current:Ice.Current):Ice.StringSeq + { + test(current.mode === Ice.OperationMode.Nonmutating); + return Ice.Object.prototype.ice_ids.call(this, current); + } + + ice_id(current:Ice.Current):string + { + test(current.mode === Ice.OperationMode.Nonmutating); + return Ice.Object.prototype.ice_id.call(this, current); + } + + shutdown(current:Ice.Current):void + { + current.adapter.getCommunicator().shutdown(); + } + + supportsCompress(current:Ice.Current):boolean + { + return false; + } + + opVoid(current:Ice.Current):void + { + test(current.mode === Ice.OperationMode.Normal); + } + + opBool(p1:boolean, p2:boolean, current:Ice.Current):[boolean, boolean] + { + return [p2, p1]; + } + + opBoolS(p1:Test.BoolS, p2:Test.BoolS, current:Ice.Current):[Test.BoolS, Test.BoolS] + { + const p3 = p1.concat(p2); + return [p1.reverse(), p3]; + } + + opBoolSS(p1:Test.BoolSS, p2:Test.BoolSS, current:Ice.Current):[Test.BoolSS, Test.BoolSS] + { + const p3 = p1.concat(p2); + return [p1.reverse(), p3]; + } + + opByte(p1:number, p2:number, current:Ice.Current):[number, number] + { + return [p1, (p1 ^ p2) & 0xff]; + } + + opByteBoolD(p1:Test.ByteBoolD, p2:Test.ByteBoolD, current:Ice.Current):[Test.ByteBoolD, Test.ByteBoolD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opByteS(p1:Test.ByteS, p2:Test.ByteS, current:Ice.Current):[Test.ByteS, Test.ByteS] + { + const p3 = new Uint8Array(p1.length); + for(let i = 0; i < p1.length; i++) + { + p3[i] = p1[p1.length - (i + 1)]; + } + + const r = new Uint8Array(p1.length + p2.length); + for(let i = 0; i < p1.length; ++i) + { + r[i] = p1[i]; + } + for(let i = 0; i < p2.length; ++i) + { + r[i + p1.length] = p2[i]; + } + return [r, p3]; + } + + opByteSS(p1:Test.ByteSS, p2:Test.ByteSS, current:Ice.Current):[Test.ByteSS, Test.ByteSS] + { + const r = p1.concat(p2); + return [r, p1.reverse()]; + } + + opFloatDouble(p1:number, p2:number, current:Ice.Current):[number, number, number] + { + return [p2, p1, p2]; + } + + opFloatDoubleS(p1:Test.FloatS, p2:Test.DoubleS, current:Ice.Current): + [Test.DoubleS, Test.FloatS, Test.DoubleS] + { + const r = p2.concat(p1); + const p4 = p2.reverse(); + return [r, p1, p4]; + } + + opFloatDoubleSS(p1:Test.FloatSS, p2:Test.DoubleSS, current:Ice.Current): + [Test.DoubleSS, Test.FloatSS, Test.DoubleSS] + { + const r = p2.concat(p2); + const p4 = p2.reverse(); + return [r, p1, p4]; + } + + opLongFloatD(p1:Test.LongFloatD, p2:Test.LongFloatD, current:Ice.Current):[Test.LongFloatD, Test.LongFloatD] + { + const r = new Ice.HashMap(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opMyClass(p1:Test.MyClassPrx, current:Ice.Current):[Test.MyClassPrx, Test.MyClassPrx, Test.MyClassPrx] + { + const p2 = p1; + const p3 = Test.MyClassPrx.uncheckedCast( + current.adapter.createProxy(Ice.stringToIdentity("noSuchIdentity"))); + const r = Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(current.id)); + return [r.ice_endpoints(this._endpoints), p2, p3.ice_endpoints(this._endpoints)]; + } + + opMyEnum(p1:Test.MyEnum, current:Ice.Current):[Test.MyEnum, Test.MyEnum] + { + return [Test.MyEnum.enum3, p1]; + } + + opShortIntD(p1:Test.ShortIntD, p2:Test.ShortIntD, current:Ice.Current):[Test.ShortIntD, Test.ShortIntD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opShortIntLong(p1:number, p2:number, p3:Ice.Long, current:Ice.Current): + [Ice.Long, number, number, Ice.Long] + { + return [p3, p1, p2, p3]; + } + + opShortIntLongS(p1:Test.ShortS, p2:Test.IntS, p3:Test.LongS, current:Ice.Current): + [Test.LongS, Test.ShortS, Test.IntS, Test.LongS] + { + return [p3, p1, p2.reverse(), p3.concat(p3)]; + } + + opShortIntLongSS(p1:Test.ShortSS, p2:Test.IntSS, p3:Test.LongSS, current:Ice.Current): + [Test.LongSS, Test.ShortSS, Test.IntSS, Test.LongSS] + { + return [p3, p1, p2.reverse(), p3.concat(p3)]; + } + + opString(p1:string, p2:string, current:Ice.Current):[string, string] + { + return [p1 + " " + p2, p2 + " " + p1]; + } + + opStringMyEnumD(p1:Test.StringMyEnumD, + p2:Test.StringMyEnumD, current:Ice.Current):[Test.StringMyEnumD, Test.StringMyEnumD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opMyEnumStringD(p1:Test.MyEnumStringD, + p2:Test.MyEnumStringD, current:Ice.Current):[Test.MyEnumStringD, Test.MyEnumStringD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opMyStructMyEnumD(p1:Test.MyStructMyEnumD, + p2:Test.MyStructMyEnumD, current:Ice.Current):[Test.MyStructMyEnumD, Test.MyStructMyEnumD] + { + const r = new Ice.HashMap(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opByteBoolDS(p1:Test.ByteBoolDS, p2:Test.ByteBoolDS, current:Ice.Current):[Test.ByteBoolDS, Test.ByteBoolDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opShortIntDS(p1:Test.ShortIntDS, p2:Test.ShortIntDS, current:Ice.Current):[Test.ShortIntDS, Test.ShortIntDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opLongFloatDS(p1:Test.LongFloatDS, p2:Test.LongFloatDS, current:Ice.Current):[Test.LongFloatDS, Test.LongFloatDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opStringStringDS(p1:Test.StringStringDS, + p2:Test.StringStringDS, current:Ice.Current):[Test.StringStringDS, Test.StringStringDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opStringMyEnumDS(p1:Test.StringMyEnumDS, + p2:Test.StringMyEnumDS, current:Ice.Current):[Test.StringMyEnumDS, Test.StringMyEnumDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opMyEnumStringDS(p1:Test.MyEnumStringDS, + p2:Test.MyEnumStringDS, current:Ice.Current):[Test.MyEnumStringDS, Test.MyEnumStringDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opMyStructMyEnumDS(p1:Test.MyStructMyEnumDS, + p2:Test.MyStructMyEnumDS, current:Ice.Current):[Test.MyStructMyEnumDS, Test.MyStructMyEnumDS] + { + const p3 = p2.concat(p1); + const r = p1.reverse(); + return [r, p3]; + } + + opByteByteSD(p1:Test.ByteByteSD, p2:Test.ByteByteSD, current:Ice.Current):[Test.ByteByteSD, Test.ByteByteSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opBoolBoolSD(p1:Test.BoolBoolSD, p2:Test.BoolBoolSD, current:Ice.Current):[Test.BoolBoolSD, Test.BoolBoolSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opShortShortSD(p1:Test.ShortShortSD, p2:Test.ShortShortSD, current:Ice.Current):[Test.ShortShortSD, Test.ShortShortSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opIntIntSD(p1:Test.IntIntSD, p2:Test.IntIntSD, current:Ice.Current):[Test.IntIntSD, Test.IntIntSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opLongLongSD(p1:Test.LongLongSD, p2:Test.LongLongSD, current:Ice.Current):[Test.LongLongSD, Test.LongLongSD] + { + const r = new Ice.HashMap(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Ice.HashMap(p2); + return [r, p3]; + } + + opStringFloatSD(p1:Test.StringFloatSD, + p2:Test.StringFloatSD, current:Ice.Current):[Test.StringFloatSD, Test.StringFloatSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opStringDoubleSD(p1:Test.StringDoubleSD, + p2:Test.StringDoubleSD, current:Ice.Current):[Test.StringDoubleSD, Test.StringDoubleSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opStringStringSD(p1:Test.StringStringSD, + p2:Test.StringStringSD, current:Ice.Current):[Test.StringStringSD, Test.StringStringSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opMyEnumMyEnumSD(p1:Test.MyEnumMyEnumSD, + p2:Test.MyEnumMyEnumSD, current:Ice.Current):[Test.MyEnumMyEnumSD, Test.MyEnumMyEnumSD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + const p3 = new Map(p2); + return [r, p3]; + } + + opIntS(s:Test.IntS, current:Ice.Current):Test.IntS + { + return s.map(v => -v); + } + + opByteSOneway(s:Test.ByteS, current:Ice.Current):void + { + this._opByteSOnewayCount += 1; + } + + opByteSOnewayCallCount(current:Ice.Current):number + { + const count = this._opByteSOnewayCount; + this._opByteSOnewayCount = 0; + return count; + } + + opContext(current:Ice.Current):Ice.Context + { + return current.ctx; + } + + opDoubleMarshaling(p1:number, p2:Test.DoubleS, current:Ice.Current):void + { + const d = 1278312346.0 / 13.0; + test(p1 === d); + for(let i = 0; i < p2.length; ++i) + { + test(p2[i] === d); + } + } + + opStringS(p1:Test.StringS, p2:Test.StringS, current:Ice.Current):[Test.StringS, Test.StringS] + { + const p3 = p1.concat(p2); + const r = p1.reverse(); + return [r, p3]; + } + + opStringSS(p1:Test.StringSS, p2:Test.StringSS, current:Ice.Current):[Test.StringSS, Test.StringSS] + { + const p3 = p1.concat(p2); + const r = p2.reverse(); + return [r, p3]; + } + + opStringSSS(p1:Test.StringSSS, p2:Test.StringSSS, current:Ice.Current):[Test.StringSSS, Test.StringSSS] + { + const p3 = p1.concat(p2); + const r = p2.reverse(); + return [r, p3]; + } + + opStringStringD(p1:Test.StringStringD, p2:Test.StringStringD, current:Ice.Current):[Test.StringStringD, Test.StringStringD] + { + const r = new Map(p1); + p2.forEach((value, key) => r.set(key, value)); + return [r, p1]; + } + + opStruct(p1:Test.Structure, p2:Test.Structure, current:Ice.Current):[Test.Structure, Test.Structure] + { + p1.s.s = "a new string"; + return [p2, p1]; + } + + opIdempotent(current:Ice.Current):void + { + test(current.mode === Ice.OperationMode.Idempotent); + } + + opNonmutating(current:Ice.Current):void + { + test(current.mode === Ice.OperationMode.Nonmutating); + } + + opDerived(current:Ice.Current):void + { + } + + opByte1(value:number, current:Ice.Current):number + { + return value; + } + + opShort1(value:number, current:Ice.Current):number + { + return value; + } + + opInt1(value:number, current:Ice.Current):number + { + return value; + } + + opLong1(value:Ice.Long, current:Ice.Current):Ice.Long + { + return value; + } + + opFloat1(value:number, current:Ice.Current):number + { + return value; + } + + opDouble1(value:number, current:Ice.Current):number + { + return value; + } + + opString1(value:string, current:Ice.Current):string + { + return value; + } + + opStringS1(value:Test.StringS, current:Ice.Current):Test.StringS + { + return value; + } + + opByteBoolD1(value:Test.ByteBoolD, current:Ice.Current):Test.ByteBoolD + { + return value; + } + + opStringS2(value:Test.StringS, current:Ice.Current):Test.StringS + { + return value; + } + + opByteBoolD2(value:Test.ByteBoolD, current:Ice.Current):Test.ByteBoolD + { + return value; + } + + opMyClass1(value:Test.MyClass1, current:Ice.Current):Test.MyClass1 + { + return value; + } + + opMyStruct1(value:Test.MyStruct1, current:Ice.Current):Test.MyStruct1 + { + return value; + } + + opStringLiterals(current:Ice.Current):Test.StringS + { + return [ + Test.s0, Test.s1, Test.s2, Test.s3, Test.s4, Test.s5, Test.s6, Test.s7, Test.s8, Test.s9, Test.s10, + Test.sw0, Test.sw1, Test.sw2, Test.sw3, Test.sw4, Test.sw5, Test.sw6, Test.sw7, Test.sw8, Test.sw9, Test.sw10, + Test.ss0, Test.ss1, Test.ss2, Test.ss3, Test.ss4, Test.ss5, + Test.su0, Test.su1, Test.su2 + ]; + } + + opWStringLiterals(current:Ice.Current):Test.WStringS + { + return this.opStringLiterals(current); + } + + opMStruct1(current:Ice.Current):Test.Structure + { + return new Test.Structure(); + } + + opMStruct2(p1:Test.Structure, current:Ice.Current):[Test.Structure, Test.Structure] + { + return [p1, p1]; + } + + opMSeq1(current:Ice.Current):Test.StringS + { + return []; + } + + opMSeq2(p1:Test.StringS, current:Ice.Current):[Test.StringS, Test.StringS] + { + return [p1, p1]; + } + + opMDict1(current:Ice.Current):Test.StringStringD + { + return new Map(); + } + + opMDict2(p1:Test.StringStringD, current:Ice.Current):[Test.StringStringD, Test.StringStringD] + { + return [p1, p1]; + } + + _opByteSOnewayCount:number; + _endpoints:Ice.Endpoint[]; +} diff --git a/js/test/ts/Ice/operations/Oneways.ts b/js/test/ts/Ice/operations/Oneways.ts new file mode 100644 index 00000000000..8fc1ff7e8ef --- /dev/null +++ b/js/test/ts/Ice/operations/Oneways.ts @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice";; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +const test = TestHelper.test; + +export async function run(communicator:Ice.Communicator, prx:Test.MyClassPrx, bidir:boolean) +{ + prx = prx.ice_oneway(); + await prx.ice_ping(); + + try + { + await prx.ice_isA(Test.MyClass.ice_staticId()); + test(false); + } + catch(ex) + { + // Expected: twoway proxy required + test(ex instanceof Ice.TwowayOnlyException, ex); + } + + try + { + await prx.ice_id(); + test(false); + } + catch(ex) + { + // Expected: twoway proxy required + test(ex instanceof Ice.TwowayOnlyException, ex); + } + + try + { + await prx.ice_ids(); + test(false); + } + catch(ex) + { + // Expected: twoway proxy required + test(ex instanceof Ice.TwowayOnlyException, ex); + } + + await prx.opVoid(); + await prx.opIdempotent(); + await prx.opNonmutating(); + + try + { + await prx.opByte(0xff, 0x0f); + test(false); + } + catch(ex) + { + // Expected: twoway proxy required + test(ex instanceof Ice.TwowayOnlyException, ex); + } +} diff --git a/js/test/ts/Ice/operations/Server.ts b/js/test/ts/Ice/operations/Server.ts new file mode 100644 index 00000000000..8e8c8e52136 --- /dev/null +++ b/js/test/ts/Ice/operations/Server.ts @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice";; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +import {MyDerivedClassI} from "./MyDerivedClassI"; + +export class Server extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo:Test.EchoPrx; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.BatchAutoFlushSize", "100"); + [communicator] = this.initialize(properties); + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter = await communicator.createObjectAdapter(""); + adapter.add(new MyDerivedClassI(echo.ice_getEndpoints()), Ice.stringToIdentity("test")); + await echo.setConnection(); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/operations/ServerAMD.ts b/js/test/ts/Ice/operations/ServerAMD.ts new file mode 100644 index 00000000000..c58a6bc7d14 --- /dev/null +++ b/js/test/ts/Ice/operations/ServerAMD.ts @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice";; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +import {AMDMyDerivedClassI} from "./AMDMyDerivedClassI"; + +export class ServerAMD extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo:Test.EchoPrx; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.BatchAutoFlushSize", "100"); + [communicator] = this.initialize(properties); + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter = await communicator.createObjectAdapter(""); + adapter.add(new AMDMyDerivedClassI(echo.ice_getEndpoints()), Ice.stringToIdentity("test")); + await echo.setConnection(); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/operations/Test.ice b/js/test/ts/Ice/operations/Test.ice new file mode 100644 index 00000000000..bd6b3d157ab --- /dev/null +++ b/js/test/ts/Ice/operations/Test.ice @@ -0,0 +1,379 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Current.ice> + +module Test +{ + +enum MyEnum +{ + enum1, + enum2, + enum3 +} + +interface MyClass; + +struct AnotherStruct +{ + string s; +} + +struct Structure +{ + MyClass* p; + MyEnum e; + AnotherStruct s; +} + +sequence<byte> ByteS; +sequence<bool> BoolS; +sequence<short> ShortS; +sequence<int> IntS; +sequence<long> LongS; +sequence<float> FloatS; +sequence<double> DoubleS; +sequence<string> StringS; +sequence<["cpp:type:wstring"]string> WStringS; +sequence<MyEnum> MyEnumS; +sequence<MyClass*> MyClassS; + +sequence<ByteS> ByteSS; +sequence<BoolS> BoolSS; +sequence<ShortS> ShortSS; +sequence<IntS> IntSS; +sequence<LongS> LongSS; +sequence<FloatS> FloatSS; +sequence<DoubleS> DoubleSS; +sequence<StringS> StringSS; +sequence<MyEnumS> MyEnumSS; +sequence<MyClassS> MyClassSS; + +sequence<StringSS> StringSSS; + +struct MyStruct +{ + int i; + int j; +} + +dictionary<byte, bool> ByteBoolD; +dictionary<short, int> ShortIntD; +dictionary<long, float> LongFloatD; +dictionary<string, string> StringStringD; +dictionary<string, MyEnum> StringMyEnumD; +dictionary<MyEnum, string> MyEnumStringD; +dictionary<MyStruct, MyEnum> MyStructMyEnumD; + +sequence<ByteBoolD> ByteBoolDS; +sequence<ShortIntD> ShortIntDS; +sequence<LongFloatD> LongFloatDS; +sequence<StringStringD> StringStringDS; +sequence<StringMyEnumD> StringMyEnumDS; +sequence<MyEnumStringD> MyEnumStringDS; +sequence<MyStructMyEnumD> MyStructMyEnumDS; + +dictionary<byte, ByteS> ByteByteSD; +dictionary<bool, BoolS> BoolBoolSD; +dictionary<short, ShortS> ShortShortSD; +dictionary<int, IntS> IntIntSD; +dictionary<long, LongS> LongLongSD; +dictionary<string, FloatS> StringFloatSD; +dictionary<string, DoubleS> StringDoubleSD; +dictionary<string, StringS> StringStringSD; +dictionary<MyEnum, MyEnumS> MyEnumMyEnumSD; + +interface MyClass +{ + void shutdown(); + + bool supportsCompress(); + + void opVoid(); + + byte opByte(byte p1, byte p2, + out byte p3); + + bool opBool(bool p1, bool p2, + out bool p3); + + long opShortIntLong(short p1, int p2, long p3, + out short p4, out int p5, out long p6); + + double opFloatDouble(float p1, double p2, + out float p3, out double p4); + + string opString(string p1, string p2, + out string p3); + + MyEnum opMyEnum(MyEnum p1, out MyEnum p2); + + MyClass* opMyClass(MyClass* p1, out MyClass* p2, out MyClass* p3); + + Structure opStruct(Structure p1, Structure p2, + out Structure p3); + + ByteS opByteS(ByteS p1, ByteS p2, + out ByteS p3); + + BoolS opBoolS(BoolS p1, BoolS p2, + out BoolS p3); + + LongS opShortIntLongS(Test::ShortS p1, IntS p2, LongS p3, + out ::Test::ShortS p4, out IntS p5, out LongS p6); + + DoubleS opFloatDoubleS(FloatS p1, DoubleS p2, + out FloatS p3, out DoubleS p4); + + StringS opStringS(StringS p1, StringS p2, + out StringS p3); + + ByteSS opByteSS(ByteSS p1, ByteSS p2, + out ByteSS p3); + + BoolSS opBoolSS(BoolSS p1, BoolSS p2, + out BoolSS p3); + + LongSS opShortIntLongSS(ShortSS p1, IntSS p2, LongSS p3, + out ShortSS p4, out IntSS p5, out LongSS p6); + + DoubleSS opFloatDoubleSS(FloatSS p1, DoubleSS p2, + out FloatSS p3, out DoubleSS p4); + + StringSS opStringSS(StringSS p1, StringSS p2, + out StringSS p3); + + StringSSS opStringSSS(StringSSS p1, StringSSS p2, + out StringSSS p3); + + ByteBoolD opByteBoolD(ByteBoolD p1, ByteBoolD p2, + out ByteBoolD p3); + + ShortIntD opShortIntD(ShortIntD p1, ShortIntD p2, + out ShortIntD p3); + + LongFloatD opLongFloatD(LongFloatD p1, LongFloatD p2, + out LongFloatD p3); + + StringStringD opStringStringD(StringStringD p1, StringStringD p2, + out StringStringD p3); + + StringMyEnumD opStringMyEnumD(StringMyEnumD p1, StringMyEnumD p2, + out StringMyEnumD p3); + + MyEnumStringD opMyEnumStringD(MyEnumStringD p1, MyEnumStringD p2, + out MyEnumStringD p3); + + MyStructMyEnumD opMyStructMyEnumD(MyStructMyEnumD p1, MyStructMyEnumD p2, + out MyStructMyEnumD p3); + + ByteBoolDS opByteBoolDS(ByteBoolDS p1, ByteBoolDS p2, + out ByteBoolDS p3); + + ShortIntDS opShortIntDS(ShortIntDS p1, ShortIntDS p2, + out ShortIntDS p3); + + LongFloatDS opLongFloatDS(LongFloatDS p1, LongFloatDS p2, + out LongFloatDS p3); + + StringStringDS opStringStringDS(StringStringDS p1, StringStringDS p2, + out StringStringDS p3); + + StringMyEnumDS opStringMyEnumDS(StringMyEnumDS p1, StringMyEnumDS p2, + out StringMyEnumDS p3); + + MyEnumStringDS opMyEnumStringDS(MyEnumStringDS p1, MyEnumStringDS p2, + out MyEnumStringDS p3); + + MyStructMyEnumDS opMyStructMyEnumDS(MyStructMyEnumDS p1, MyStructMyEnumDS p2, + out MyStructMyEnumDS p3); + + ByteByteSD opByteByteSD(ByteByteSD p1, ByteByteSD p2, + out ByteByteSD p3); + + BoolBoolSD opBoolBoolSD(BoolBoolSD p1, BoolBoolSD p2, + out BoolBoolSD p3); + + ShortShortSD opShortShortSD(ShortShortSD p1, ShortShortSD p2, + out ShortShortSD p3); + + IntIntSD opIntIntSD(IntIntSD p1, IntIntSD p2, + out IntIntSD p3); + + LongLongSD opLongLongSD(LongLongSD p1, LongLongSD p2, + out LongLongSD p3); + + StringFloatSD opStringFloatSD(StringFloatSD p1, StringFloatSD p2, + out StringFloatSD p3); + + StringDoubleSD opStringDoubleSD(StringDoubleSD p1, StringDoubleSD p2, + out StringDoubleSD p3); + + StringStringSD opStringStringSD(StringStringSD p1, StringStringSD p2, + out StringStringSD p3); + + MyEnumMyEnumSD opMyEnumMyEnumSD(MyEnumMyEnumSD p1, MyEnumMyEnumSD p2, + out MyEnumMyEnumSD p3); + + IntS opIntS(IntS s); + + void opByteSOneway(ByteS s); + int opByteSOnewayCallCount(); + + Ice::Context opContext(); + + void opDoubleMarshaling(double p1, DoubleS p2); + + idempotent void opIdempotent(); + + ["nonmutating"] idempotent void opNonmutating(); + + byte opByte1(byte opByte1); + short opShort1(short opShort1); + int opInt1(int opInt1); + long opLong1(long opLong1); + float opFloat1(float opFloat1); + double opDouble1(double opDouble1); + string opString1(string opString1); + StringS opStringS1(StringS opStringS1); + ByteBoolD opByteBoolD1(ByteBoolD opByteBoolD1); + StringS opStringS2(StringS stringS); + ByteBoolD opByteBoolD2(ByteBoolD byteBoolD); + + StringS opStringLiterals(); + WStringS opWStringLiterals(); + + ["marshaled-result"] Structure opMStruct1(); + ["marshaled-result"] Structure opMStruct2(Structure p1, out Structure p2); + + ["marshaled-result"] StringS opMSeq1(); + ["marshaled-result"] StringS opMSeq2(StringS p1, out StringS p2); + + ["marshaled-result"] StringStringD opMDict1(); + ["marshaled-result"] StringStringD opMDict2(StringStringD p1, out StringStringD p2); +} + +struct MyStruct1 +{ + string tesT; // Same name as the enclosing module + MyClass* myClass; // Same name as an already defined class + string myStruct1; // Same name as the enclosing struct +} + +class MyClass1 +{ + string tesT; // Same name as the enclosing module + MyClass* myClass; // Same name as an already defined class + string myClass1; // Same name as the enclosing class +} + +interface MyDerivedClass extends MyClass +{ + void opDerived(); + MyClass1 opMyClass1(MyClass1 opMyClass1); + MyStruct1 opMyStruct1(MyStruct1 opMyStruct1); +} + +interface Echo +{ + void setConnection(); + void startBatch(); + void flushBatch(); + void shutdown(); + +bool supportsCompress(); +} + +// +// String literals +// + +const string s0 = "\u005c"; // backslash +const string s1 = "\u0041"; // A +const string s2 = "\u0049\u0063\u0065"; // Ice +const string s3 = "\u004121"; // A21 +const string s4 = "\\u0041 \\U00000041"; // \\u0041 \\U00000041 +const string s5 = "\u00FF"; // ÿ +const string s6 = "\u03FF"; // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL (U+03FF) +const string s7 = "\u05F0"; // HEBREW LIGATURE YIDDISH DOUBLE VAV (U+05F0) +const string s8 = "\U00010000"; // LINEAR B SYLLABLE B008 A (U+10000) +const string s9 = "\U0001F34C"; // BANANA (U+1F34C) +const string s10 = "\u0DA7"; // Sinhala Letter Alpapraana Ttayanna + +const string sw0 = "\U0000005c"; // backslash +const string sw1 = "\U00000041"; // A +const string sw2 = "\U00000049\U00000063\U00000065"; // Ice +const string sw3 = "\U0000004121"; // A21 +const string sw4 = "\\u0041 \\U00000041"; // \\u0041 \\U00000041 +const string sw5 = "\U000000FF"; // ÿ +const string sw6 = "\U000003FF"; // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL (U+03FF) +const string sw7 = "\U000005F0"; // HEBREW LIGATURE YIDDISH DOUBLE VAV (U+05F0) +const string sw8 = "\U00010000"; // LINEAR B SYLLABLE B008 A (U+10000) +const string sw9 = "\U0001F34C"; // BANANA (U+1F34C) +const string sw10 = "\U00000DA7"; // Sinhala Letter Alpapraana Ttayanna + +/** +\' single quote byte 0x27 in ASCII encoding +\" double quote byte 0x22 in ASCII encoding +\? question mark byte 0x3f in ASCII encoding +\\ backslash byte 0x5c in ASCII encoding +\a audible bell byte 0x07 in ASCII encoding +\b backspace byte 0x08 in ASCII encoding +\f form feed - new page byte 0x0c in ASCII encoding +\n line feed - new line byte 0x0a in ASCII encoding +\r carriage return byte 0x0d in ASCII encoding +\t horizontal tab byte 0x09 in ASCII encoding +\v vertical tab byte 0x0b in ASCII encoding +**/ + +const string ss0 = "\'\"\?\\\a\b\f\n\r\t\v\6"; +const string ss1 = "\u0027\u0022\u003f\u005c\u0007\u0008\u000c\u000a\u000d\u0009\u000b\u0006"; +const string ss2 = "\U00000027\U00000022\U0000003f\U0000005c\U00000007\U00000008\U0000000c\U0000000a\U0000000d\U00000009\U0000000b\U00000006"; + +const string ss3 = "\\\\U\\u\\"; /* \\U\u\ */ +const string ss4 = "\\\u0041\\"; /* \A\ */ +const string ss5 = "\\u0041\\"; /* \u0041\ */ + +// +// Ĩ - Unicode Character 'LATIN CAPITAL LETTER I WITH TILDE' (U+0128) +// Ÿ - Unicode Character 'LATIN CAPITAL LETTER Y WITH DIAERESIS' (U+0178) +// ÿ - Unicode Character 'LATIN SMALL LETTER Y WITH DIAERESIS' (U+00FF) +// Ā - Unicode Character 'LATIN CAPITAL LETTER A WITH MACRON' (U+0100) +// ἀ - Unicode Character 'GREEK SMALL LETTER ALPHA WITH PSILI' (U+1F00) +// 𐆔 - Unicode Character 'ROMAN DIMIDIA SEXTULA SIGN' (U+10194) +// 𐅪 - Unicode Character 'GREEK ACROPHONIC THESPIAN ONE HUNDRED' (U+1016A) +// 𐆘 - Unicode Character 'ROMAN SESTERTIUS SIGN' (U+10198) +// 🍀 - Unicode Character 'FOUR LEAF CLOVER' (U+1F340) +// 🍁 - Unicode Character 'MAPLE LEAF' (U+1F341) +// 🍂 - Unicode Character 'FALLEN LEAF' (U+1F342) +// 🍃 - Unicode Character 'LEAF FLUTTERING IN WIND' (U+1F343) +// +const string su0 = "ĨŸÿĀἀ𐆔𐅪𐆘🍀🍁🍂🍃"; +const string su1 = "\u0128\u0178\u00FF\u0100\u1F00\U00010194\U0001016A\U00010198\U0001F340\U0001F341\U0001F342\U0001F343"; +const string su2 = "\U00000128\U00000178\U000000FF\U00000100\U00001F00\U00010194\U0001016A\U00010198\U0001F340\U0001F341\U0001F342\U0001F343"; + +} + +module Test2 +{ + +/** + * + * Makes sure that proxy operations are correctly generated when extending an interface from + * a different module (ICE-7639). + * + **/ +interface MyDerivedClass extends Test::MyClass +{ +} + +} diff --git a/js/test/ts/Ice/operations/Twoways.ts b/js/test/ts/Ice/operations/Twoways.ts new file mode 100644 index 00000000000..c9b707410ae --- /dev/null +++ b/js/test/ts/Ice/operations/Twoways.ts @@ -0,0 +1,1480 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +const test = TestHelper.test; + +export async function run(communicator:Ice.Communicator, prx:Test.MyClassPrx, bidir:boolean, helper:TestHelper) +{ + const literals = await prx.opStringLiterals(); + + test(Test.s0 == "\\" && + Test.s0 == Test.sw0 && + Test.s0 == literals[0] && + Test.s0 == literals[11]); + + test(Test.s1 == "A" && + Test.s1 == Test.sw1 && + Test.s1 == literals[1] && + Test.s1 == literals[12]); + + test(Test.s2 == "Ice" && + Test.s2 == Test.sw2 && + Test.s2 == literals[2] && + Test.s2 == literals[13]); + + test(Test.s3 == "A21" && + Test.s3 == Test.sw3 && + Test.s3 == literals[3] && + Test.s3 == literals[14]); + + test(Test.s4 == "\\u0041 \\U00000041" && + Test.s4 == Test.sw4 && + Test.s4 == literals[4] && + Test.s4 == literals[15]); + + test(Test.s5 == "\u00FF" && + Test.s5 == Test.sw5 && + Test.s5 == literals[5] && + Test.s5 == literals[16]); + + test(Test.s6 == "\u03FF" && + Test.s6 == Test.sw6 && + Test.s6 == literals[6] && + Test.s6 == literals[17]); + + test(Test.s7 == "\u05F0" && + Test.s7 == Test.sw7 && + Test.s7 == literals[7] && + Test.s7 == literals[18]); + + test(Test.s8 == "\uD800\uDC00" && + Test.s8 == Test.sw8 && + Test.s8 == literals[8] && + Test.s8 == literals[19]); + + test(Test.s9 == "\uD83C\uDF4C" && + Test.s9 == Test.sw9 && + Test.s9 == literals[9] && + Test.s9 == literals[20]); + + test(Test.s10 == "\u0DA7" && + Test.s10 == Test.sw10 && + Test.s10 == literals[10] && + Test.s10 == literals[21]); + + test(Test.ss0 == "'\"?\\\u0007\b\f\n\r\t\v\u0006" && + Test.ss0 == Test.ss1 && + Test.ss0 == Test.ss2 && + Test.ss0 == literals[22] && + Test.ss0 == literals[23] && + Test.ss0 == literals[24]); + + test(Test.ss3 == "\\\\U\\u\\" && + Test.ss3 == literals[25]); + + test(Test.ss4 == "\\A\\" && + Test.ss4 == literals[26]); + + test(Test.ss5 == "\\u0041\\" && + Test.ss5 == literals[27]); + + test(Test.su0 == Test.su1 && + Test.su0 == Test.su2 && + Test.su0 == literals[28] && + Test.su0 == literals[29] && + Test.su0 == literals[30]); + + await prx.ice_ping(); + + test(await prx.ice_isA(Test.MyClass.ice_staticId())); + + test((await prx.ice_id()) === Test.MyDerivedClass.ice_staticId()); + + test((await prx.ice_ids()).length === 3); + + await prx.opVoid(); + + { + const [retval, p3] = await prx.opByte(0xff, 0x0f); + test(p3 === 0xf0); + test(retval === 0xff); + } + + { + const [retval, p3] = await prx.opBool(true, false); + test(p3); + test(!retval); + } + + { + const lo = new Ice.Long(0, 12); + const [retval, s, i, l] = await prx.opShortIntLong(10, 11, lo); + + test(s === 10); + test(i === 11); + test(l.equals(lo)); + test(retval.equals(lo)); + } + + { + const [retval, f, d] = await prx.opFloatDouble(3.14, 1.1E10); + test((f - 3.14) <= 0.01); + test(d == 1.1E10); + test(retval == 1.1E10); + } + + try + { + await prx.opByte(0xffff, 0xff0f); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MarshalException, ex); + } + + try + { + await prx.opShortIntLong(-32768 - 1, 0, new Ice.Long(0)); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MarshalException, ex); + } + + try + { + await prx.opShortIntLong(32767 + 1, 0, new Ice.Long(0)); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MarshalException, ex); + } + + try + { + await prx.opShortIntLong(0, -2147483648 - 1, new Ice.Long(0)); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MarshalException, ex); + } + + try + { + await prx.opShortIntLong(0, 2147483647 + 1, new Ice.Long(0)); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MarshalException, ex); + } + + try + { + await prx.opShortIntLong(0, 0, new Ice.Long(0, 0xFFFFFFFF + 1)); + test(false); + } + catch(ex) + { + test(ex instanceof RangeError, ex); + } + + try + { + await prx.opShortIntLong(0, 0, new Ice.Long(0xFFFFFFFF + 1, 0)); + test(false); + } + catch(ex) + { + test(ex instanceof RangeError, ex); + } + + try + { + await prx.opShortIntLong(0, 0, new Ice.Long(0, -1)); + test(false); + } + catch(ex) + { + test(ex instanceof RangeError, ex); + } + + try + { + await prx.opShortIntLong(Number.NaN, 0, new Ice.Long(0, 0)); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MarshalException, ex); + } + + try + { + await prx.opFloatDouble(Number.MAX_VALUE, 0); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MarshalException, ex); + } + + try + { + await prx.opFloatDouble(-Number.MAX_VALUE, 0); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.MarshalException, ex); + } + + await prx.opFloatDouble(Number.NaN, Number.NaN); + await prx.opFloatDouble(-Number.NaN, -Number.NaN); + await prx.opFloatDouble(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); + await prx.opFloatDouble(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY); + + { + const [retval, p3] = await prx.opString("hello", "world"); + test(p3 === "world hello"); + test(retval === "hello world"); + } + + { + const [retval, p2] = await prx.opMyEnum(Test.MyEnum.enum2); + test(p2 === Test.MyEnum.enum2); + test(retval === Test.MyEnum.enum3); + } + + { + // Test null enum + const [retval, p2] = await prx.opMyEnum(null); + test(p2 === Test.MyEnum.enum1); + test(retval === Test.MyEnum.enum3); + } + + { + const [retval, p2, p3] = await prx.opMyClass(prx); + + test(p2.ice_getIdentity().equals(Ice.stringToIdentity("test"))); + test(p3.ice_getIdentity().equals(Ice.stringToIdentity("noSuchIdentity"))); + test(retval.ice_getIdentity().equals(Ice.stringToIdentity("test"))); + } + + { + const si1 = new Test.Structure(); + si1.p = prx; + si1.e = Test.MyEnum.enum3; + si1.s = new Test.AnotherStruct(); + si1.s.s = "abc"; + const si2 = new Test.Structure(); + si2.p = null; + si2.e = Test.MyEnum.enum2; + si2.s = new Test.AnotherStruct(); + si2.s.s = "def"; + + const [retval, p3] = await prx.opStruct(si1, si2); + test(retval.p === null); + test(retval.e === Test.MyEnum.enum2); + test(retval.s.s === "def"); + test(p3.p !== null); + test(p3.e === Test.MyEnum.enum3); + test(p3.s.s === "a new string"); + } + + { + const si1 = new Test.Structure(); + // Test null struct + const [retval, p3] = await prx.opStruct(si1, null); + + test(retval.p === null); + test(retval.e === Test.MyEnum.enum1); + test(retval.s.s === ""); + test(p3.p === null); + test(p3.e === Test.MyEnum.enum1); + test(p3.s.s === "a new string"); + } + + { + const bsi1 = new Uint8Array([0x01, 0x11, 0x12, 0x22]); + const bsi2 = new Uint8Array([0xf1, 0xf2, 0xf3, 0xf4]); + + const [retval, p3] = await prx.opByteS(bsi1, bsi2); + + test(p3.length === 4); + test(p3[0] === 0x22); + test(p3[1] === 0x12); + test(p3[2] === 0x11); + test(p3[3] === 0x01); + test(retval.length === 8); + test(retval[0] === 0x01); + test(retval[1] === 0x11); + test(retval[2] === 0x12); + test(retval[3] === 0x22); + test(retval[4] === 0xf1); + test(retval[5] === 0xf2); + test(retval[6] === 0xf3); + test(retval[7] === 0xf4); + } + + { + const bsi1 = [true, true, false]; + const bsi2 = [false]; + const [retval, p3] = await prx.opBoolS(bsi1, bsi2); + + test(p3.length == 4); + test(p3[0]); + test(p3[1]); + test(!p3[2]); + test(!p3[3]); + test(retval.length == 3); + test(!retval[0]); + test(retval[1]); + test(retval[2]); + } + + { + const ssi = [1, 2, 3]; + const isi = [5, 6, 7, 8]; + const l1 = new Ice.Long(0, 10); + const l2 = new Ice.Long(0, 30); + const l3 = new Ice.Long(0, 20); + const lsi = [l1, l2, l3]; + const [retval, sso, iso, lso] = await prx.opShortIntLongS(ssi, isi, lsi); + + test(sso.length === 3); + test(sso[0] === 1); + test(sso[1] === 2); + test(sso[2] === 3); + test(iso.length === 4); + test(iso[0] === 8); + test(iso[1] === 7); + test(iso[2] === 6); + test(iso[3] === 5); + test(lso.length === 6); + test(lso[0].equals(l1)); + test(lso[1].equals(l2)); + test(lso[2].equals(l3)); + test(lso[3].equals(l1)); + test(lso[4].equals(l2)); + test(lso[5].equals(l3)); + test(retval.length === 3); + test(retval[0].equals(l1)); + test(retval[1].equals(l2)); + test(retval[2].equals(l3)); + } + + { + const fsi = [3.14, 1.11]; + const dsi = [1.1E10, 1.2E10, 1.3E10]; + const [retval, fso, dso] = await prx.opFloatDoubleS(fsi, dsi); + + test(fso.length === 2); + test((fso[0] - 3.14) <= 0.01); + test((fso[1] - 1.11) <= 0.01); + test(dso.length === 3); + test(dso[0] === 1.3E10); + test(dso[1] === 1.2E10); + test(dso[2] === 1.1E10); + test(retval.length === 5); + test(retval[0] === 1.1E10); + test(retval[1] === 1.2E10); + test(retval[2] === 1.3E10); + test((retval[3] - 3.14) <= 0.01); + test((retval[4] - 1.11) <= 0.01); + } + + { + const ssi1 = ["abc", "de", "fghi"]; + const ssi2 = ["xyz"]; + const [retval, sso] = await prx.opStringS(ssi1, ssi2); + + test(sso.length === 4); + test(sso[0] === "abc"); + test(sso[1] === "de"); + test(sso[2] === "fghi"); + test(sso[3] === "xyz"); + test(retval.length === 3); + test(retval[0] === "fghi"); + test(retval[1] === "de"); + test(retval[2] === "abc"); + } + + { + const bsi1 = + [ + new Uint8Array([0x01, 0x11, 0x12]), + new Uint8Array([0xff]) + ]; + + const bsi2 = + [ + new Uint8Array([0x0e]), + new Uint8Array([0xf2, 0xf1]) + ]; + + const [retval, bso] = await prx.opByteSS(bsi1, bsi2); + + test(bso.length === 2); + test(bso[0].length === 1); + test(bso[0][0] === 0xff); + test(bso[1].length === 3); + test(bso[1][0] === 0x01); + test(bso[1][1] === 0x11); + test(bso[1][2] === 0x12); + test(retval.length === 4); + test(retval[0].length === 3); + test(retval[0][0] === 0x01); + test(retval[0][1] === 0x11); + test(retval[0][2] === 0x12); + test(retval[1].length === 1); + test(retval[1][0] === 0xff); + test(retval[2].length === 1); + test(retval[2][0] === 0x0e); + test(retval[3].length === 2); + test(retval[3][0] === 0xf2); + test(retval[3][1] === 0xf1); + } + + { + const bsi1 = + [ + [true], + [false], + [true, true] + ]; + + const bsi2 = + [ + [false, false, true] + ]; + + const [retval, bso] = await prx.opBoolSS(bsi1, bsi2); + + test(bso.length === 4); + test(bso[0].length === 1); + test(bso[0][0]); + test(bso[1].length === 1); + test(!bso[1][0]); + test(bso[2].length === 2); + test(bso[2][0]); + test(bso[2][1]); + test(bso[3].length === 3); + test(!bso[3][0]); + test(!bso[3][1]); + test(bso[3][2]); + test(retval.length === 3); + test(retval[0].length === 2); + test(retval[0][0]); + test(retval[0][1]); + test(retval[1].length === 1); + test(!retval[1][0]); + test(retval[2].length === 1); + test(retval[2][0]); + } + + { + const ssi = + [ + [1, 2, 5], + [13], + [] + ]; + + const isi = + [ + [24, 98], + [42] + ]; + + const l1 = new Ice.Long(0, 496); + const l2 = new Ice.Long(0, 1729); + + const lsi = + [ + [l1, l2] + ]; + + const [retval, sso, iso, lso] = await prx.opShortIntLongSS(ssi, isi, lsi); + + test(retval.length === 1); + test(retval[0].length === 2); + test(retval[0][0].equals(l1)); + test(retval[0][1].equals(l2)); + test(sso.length === 3); + test(sso[0].length === 3); + test(sso[0][0] === 1); + test(sso[0][1] === 2); + test(sso[0][2] === 5); + test(sso[1].length === 1); + test(sso[1][0] === 13); + test(sso[2].length === 0); + test(iso.length === 2); + test(iso[0].length === 1); + test(iso[0][0] === 42); + test(iso[1].length === 2); + test(iso[1][0] === 24); + test(iso[1][1] === 98); + test(lso.length === 2); + test(lso[0].length === 2); + test(lso[0][0].equals(l1)); + test(lso[0][1].equals(l2)); + test(lso[1].length === 2); + test(lso[1][0].equals(l1)); + test(lso[1][1].equals(l2)); + } + + { + const fsi = + [ + [3.14], + [1.11], + [] + ]; + + const dsi = + [ + [1.1E10, 1.2E10, 1.3E10] + ]; + + const [retval, fso, dso] = await prx.opFloatDoubleSS(fsi, dsi); + + test(fso.length === 3); + test(fso[0].length === 1); + test((fso[0][0] - 3.14) <= 0.01); + test(fso[1].length === 1); + test((fso[1][0] - 1.11) <= 0.01); + test(fso[2].length === 0); + test(dso.length === 1); + test(dso[0].length === 3); + test(dso[0][0] === 1.1E10); + test(dso[0][1] === 1.2E10); + test(dso[0][2] === 1.3E10); + test(retval.length === 2); + test(retval[0].length === 3); + test(retval[0][0] === 1.1E10); + test(retval[0][1] === 1.2E10); + test(retval[0][2] === 1.3E10); + test(retval[1].length === 3); + test(retval[1][0] === 1.1E10); + test(retval[1][1] === 1.2E10); + test(retval[1][2] === 1.3E10); + } + + { + const ssi1 = + [ + ["abc"], + ["de", "fghi"] + ]; + + const ssi2 = + [ + [], + [], + ["xyz"] + ]; + + const [retval, sso] = await prx.opStringSS(ssi1, ssi2); + test(sso.length === 5); + test(sso[0].length === 1); + test(sso[0][0] === "abc"); + test(sso[1].length === 2); + test(sso[1][0] === "de"); + test(sso[1][1] === "fghi"); + test(sso[2].length === 0); + test(sso[3].length === 0); + test(sso[4].length === 1); + test(sso[4][0] === "xyz"); + test(retval.length === 3); + test(retval[0].length === 1); + test(retval[0][0] === "xyz"); + test(retval[1].length === 0); + test(retval[2].length === 0); + } + + { + const sssi1 = + [ + [ + ["abc", "de"], + ["xyz"] + ], + [ + ["hello"] + ] + ]; + + const sssi2 = + [ + [ + ["", ""], + ["abcd"] + ], + [ + [""] + ], + [] + ]; + + const [retval, ssso] = await prx.opStringSSS(sssi1, sssi2); + + test(ssso.length === 5); + test(ssso[0].length === 2); + test(ssso[0][0].length === 2); + test(ssso[0][1].length === 1); + test(ssso[1].length === 1); + test(ssso[1][0].length === 1); + test(ssso[2].length === 2); + test(ssso[2][0].length === 2); + test(ssso[2][1].length === 1); + test(ssso[3].length === 1); + test(ssso[3][0].length === 1); + test(ssso[4].length === 0); + test(ssso[0][0][0] === "abc"); + test(ssso[0][0][1] === "de"); + test(ssso[0][1][0] === "xyz"); + test(ssso[1][0][0] === "hello"); + test(ssso[2][0][0] === ""); + test(ssso[2][0][1] === ""); + test(ssso[2][1][0] === "abcd"); + test(ssso[3][0][0] === ""); + + test(retval.length === 3); + test(retval[0].length === 0); + test(retval[1].length === 1); + test(retval[1][0].length === 1); + test(retval[2].length === 2); + test(retval[2][0].length === 2); + test(retval[2][1].length === 1); + test(retval[1][0][0] === ""); + test(retval[2][0][0] === ""); + test(retval[2][0][1] === ""); + test(retval[2][1][0] === "abcd"); + } + + { + const di1 = new Test.ByteBoolD(); + di1.set(10, true); + di1.set(100, false); + + const di2 = new Test.ByteBoolD(); + di2.set(10, true); + di2.set(11, false); + di2.set(101, true); + + const [retval, p3] = await prx.opByteBoolD(di1, di2); + test(Ice.MapUtil.equals(p3, di1)); + test(retval.size === 4); + test(retval.get(10) === true); + test(retval.get(11) === false); + test(retval.get(100) === false); + test(retval.get(101) === true); + } + + { + const di1 = new Test.ShortIntD(); + di1.set(110, -1); + di1.set(1100, 123123); + + const di2 = new Test.ShortIntD(); + di2.set(110, -1); + di2.set(111, -100); + di2.set(1101, 0); + + const [retval, p3] = await prx.opShortIntD(di1, di2); + test(Ice.MapUtil.equals(p3, di1)); + test(retval.size === 4); + test(retval.get(110) === -1); + test(retval.get(111) === -100); + test(retval.get(1100) === 123123); + test(retval.get(1101) === 0); + } + + { + const di1 = new Test.LongFloatD(); + di1.set(new Ice.Long(0, 999999110), -1.1); + di1.set(new Ice.Long(0, 999999111), 123123.2); + + const di2 = new Test.LongFloatD(); + di2.set(new Ice.Long(0, 999999110), -1.1); + di2.set(new Ice.Long(0, 999999120), -100.4); + di2.set(new Ice.Long(0, 999999130), 0.5); + + const [retval, p3] = await prx.opLongFloatD(di1, di2); + + test(p3.equals(di1, (v1, v2) => (Math.abs(v1) - Math.abs(v2)) <= 0.01)); + test(retval.size === 4); + test(Math.abs(retval.get(new Ice.Long(0, 999999110))) - Math.abs(-1.1) <= 0.01); + test(Math.abs(retval.get(new Ice.Long(0, 999999120))) - Math.abs(-100.4) <= 0.01); + test(retval.get(new Ice.Long(0, 999999111)) - 123123.2 <= 0.01); + test(retval.get(new Ice.Long(0, 999999130)) - 0.5 <= 0.01); + } + + { + const di1 = new Test.StringStringD(); + di1.set("foo", "abc -1.1"); + di1.set("bar", "abc 123123.2"); + + const di2 = new Test.StringStringD(); + di2.set("foo", "abc -1.1"); + di2.set("FOO", "abc -100.4"); + di2.set("BAR", "abc 0.5"); + + const [retval, p3] = await prx.opStringStringD(di1, di2); + test(Ice.MapUtil.equals(p3, di1)); + test(retval.size == 4); + test(retval.get("foo") === "abc -1.1"); + test(retval.get("FOO") === "abc -100.4"); + test(retval.get("bar") === "abc 123123.2"); + test(retval.get("BAR") === "abc 0.5"); + } + + { + const di1 = new Test.StringMyEnumD(); + di1.set("abc", Test.MyEnum.enum1); + di1.set("", Test.MyEnum.enum2); + + const di2 = new Test.StringMyEnumD(); + di2.set("abc", Test.MyEnum.enum1); + di2.set("qwerty", Test.MyEnum.enum3); + di2.set("Hello!!", Test.MyEnum.enum2); + + const [retval, p3] = await prx.opStringMyEnumD(di1, di2); + + test(Ice.MapUtil.equals(p3, di1)); + test(retval.size === 4); + test(retval.get("abc") === Test.MyEnum.enum1); + test(retval.get("qwerty") === Test.MyEnum.enum3); + test(retval.get("") === Test.MyEnum.enum2); + test(retval.get("Hello!!") === Test.MyEnum.enum2); + } + + { + const di1 = new Test.MyEnumStringD(); + di1.set(Test.MyEnum.enum1, "abc"); + + const di2 = new Test.MyEnumStringD(); + di2.set(Test.MyEnum.enum2, "Hello!!"); + di2.set(Test.MyEnum.enum3, "qwerty"); + + const [retval, p3] = await prx.opMyEnumStringD(di1, di2); + + test(Ice.MapUtil.equals(p3, di1)); + test(retval.size === 3); + test(retval.get(Test.MyEnum.enum1) === "abc"); + test(retval.get(Test.MyEnum.enum2) === "Hello!!"); + test(retval.get(Test.MyEnum.enum3) === "qwerty"); + } + + { + const s11 = new Test.MyStruct(1, 1); + const s12 = new Test.MyStruct(1, 2); + const di1 = new Test.MyStructMyEnumD(); + di1.set(s11, Test.MyEnum.enum1); + di1.set(s12, Test.MyEnum.enum2); + const s22 = new Test.MyStruct(2, 2); + const s23 = new Test.MyStruct(2, 3); + const di2 = new Test.MyStructMyEnumD(); + di2.set(s11, Test.MyEnum.enum1); + di2.set(s22, Test.MyEnum.enum3); + di2.set(s23, Test.MyEnum.enum2); + + const [retval, p3] = await prx.opMyStructMyEnumD(di1, di2); + test(p3.equals(di1)); + + test(retval.size === 4); + test(retval.get(s11) === Test.MyEnum.enum1); + test(retval.get(s12) === Test.MyEnum.enum2); + test(retval.get(s22) === Test.MyEnum.enum3); + test(retval.get(s23) === Test.MyEnum.enum2); + } + + { + const ds1 = new Test.ByteBoolD(); + ds1.set(10, true); + ds1.set(100, false); + const ds2 = new Test.ByteBoolD(); + ds2.set(10, true); + ds2.set(11, false); + ds2.set(101, true); + const ds3 = new Test.ByteBoolD(); + ds3.set(100, false); + ds3.set(101, false); + + const [retval, p3] = await prx.opByteBoolDS([ds1, ds2], [ds3]); + test(retval.length == 2); + test(retval[0].size == 3); + test(retval[0].get(10) === true); + test(retval[0].get(11) === false); + test(retval[0].get(101) === true); + test(retval[1].size === 2); + test(retval[1].get(10) === true); + test(retval[1].get(100) === false); + test(p3.length == 3); + test(p3[0].size == 2); + test(p3[0].get(100) === false); + test(p3[0].get(101) === false); + test(p3[1].size == 2); + test(p3[1].get(10) === true); + test(p3[1].get(100) === false); + test(p3[2].size == 3); + test(p3[2].get(10) === true); + test(p3[2].get(11) === false); + test(p3[2].get(101) === true); + } + + { + const di1 = new Test.ShortIntD(); + di1.set(110, -1); + di1.set(1100, 123123); + const di2 = new Test.ShortIntD(); + di2.set(110, -1); + di2.set(111, -100); + di2.set(1101, 0); + const di3 = new Test.ShortIntD(); + di3.set(100, -1001); + + const [retval, p3] = await prx.opShortIntDS([di1, di2], [di3]); + test(retval.length == 2); + test(retval[0].size == 3); + test(retval[0].get(110) === -1); + test(retval[0].get(111) === -100); + test(retval[0].get(1101) === 0); + test(retval[1].size === 2); + test(retval[1].get(110) === -1); + test(retval[1].get(1100) === 123123); + + test(p3.length === 3); + test(p3[0].size === 1); + test(p3[0].get(100) === -1001); + test(p3[1].size === 2); + test(p3[1].get(110) === -1); + test(p3[1].get(1100) === 123123); + test(p3[2].size === 3); + test(p3[2].get(110) === -1); + test(p3[2].get(111) === -100); + test(p3[2].get(1101) === 0); + } + + { + const di1 = new Test.LongFloatD(); + di1.set(new Ice.Long(0, 999999110), -1.1); + di1.set(new Ice.Long(0, 999999111), 123123.2); + const di2 = new Test.LongFloatD(); + di2.set(new Ice.Long(0, 999999110), -1.1); + di2.set(new Ice.Long(0, 999999120), -100.4); + di2.set(new Ice.Long(0, 999999130), 0.5); + const di3 = new Test.LongFloatD(); + di3.set(new Ice.Long(0, 999999140), 3.14); + + const [retval, p3] = await prx.opLongFloatDS([di1, di2], [di3]); + test(retval.length == 2); + test(retval[0].size == 3); + test(retval[0].get(new Ice.Long(0, 999999110)) - Math.abs(-1.1) <= 0.1); + test(retval[0].get(new Ice.Long(0, 999999120)) - Math.abs(-100.4) <= 0.1); + test(retval[0].get(new Ice.Long(0, 999999130)) - 0.5 <= 0.1); + test(retval[1].size == 2); + test(retval[1].get(new Ice.Long(0, 999999110)) - Math.abs(-1.1) <= 0.1); + test(retval[1].get(new Ice.Long(0, 999999111)) - 123123.2 <= 0.1); + + test(p3.length == 3); + test(p3[0].size == 1); + test(p3[0].get(new Ice.Long(0, 999999140)) - 3.14 <= 0.1); + test(p3[1].size == 2); + test(p3[1].get(new Ice.Long(0, 999999110)) - Math.abs(-1.1) <= 0.1); + test(p3[1].get(new Ice.Long(0, 999999111)) - 123123.2 <= 0.1); + test(p3[2].size == 3); + test(p3[2].get(new Ice.Long(0, 999999110)) - Math.abs(-1.1) <= 0.1); + test(p3[2].get(new Ice.Long(0, 999999120)) - Math.abs(-100.4) <= 0.1); + test(p3[2].get(new Ice.Long(0, 999999130)) - 0.5 <= 0.1); + } + + { + const di1 = new Test.StringStringD(); + di1.set("foo", "abc -1.1"); + di1.set("bar", "abc 123123.2"); + const di2 = new Test.StringStringD(); + di2.set("foo", "abc -1.1"); + di2.set("FOO", "abc -100.4"); + di2.set("BAR", "abc 0.5"); + const di3 = new Test.StringStringD(); + di3.set("f00", "ABC -3.14"); + + const [retval, p3] = await prx.opStringStringDS([di1, di2], [di3]); + test(retval.length === 2); + test(retval[0].size === 3); + test(retval[0].get("foo") === "abc -1.1"); + test(retval[0].get("FOO") === "abc -100.4"); + test(retval[0].get("BAR") === "abc 0.5"); + test(retval[1].size === 2); + test(retval[1].get("foo") === "abc -1.1"); + test(retval[1].get("bar") === "abc 123123.2"); + + test(p3.length === 3); + test(p3[0].size === 1); + test(p3[0].get("f00") === "ABC -3.14"); + test(p3[1].size === 2); + test(p3[1].get("foo") === "abc -1.1"); + test(p3[1].get("bar") === "abc 123123.2"); + test(p3[2].size === 3); + test(p3[2].get("foo") === "abc -1.1"); + test(p3[2].get("FOO") === "abc -100.4"); + test(p3[2].get("BAR") === "abc 0.5"); + } + + { + const di1 = new Test.StringMyEnumD(); + di1.set("abc", Test.MyEnum.enum1); + di1.set("", Test.MyEnum.enum2); + const di2 = new Test.StringMyEnumD(); + di2.set("abc", Test.MyEnum.enum1); + di2.set("qwerty", Test.MyEnum.enum3); + di2.set("Hello!!", Test.MyEnum.enum2); + const di3 = new Test.StringMyEnumD(); + di3.set("Goodbye", Test.MyEnum.enum1); + + const [retval, p3] = await prx.opStringMyEnumDS([di1, di2], [di3]); + + test(retval.length == 2); + test(retval[0].size == 3); + test(retval[0].get("abc") == Test.MyEnum.enum1); + test(retval[0].get("qwerty") == Test.MyEnum.enum3); + test(retval[0].get("Hello!!") == Test.MyEnum.enum2); + test(retval[1].size == 2); + test(retval[1].get("abc") == Test.MyEnum.enum1); + test(retval[1].get("") == Test.MyEnum.enum2); + + test(p3.length == 3); + test(p3[0].size == 1); + test(p3[0].get("Goodbye") == Test.MyEnum.enum1); + test(p3[1].size == 2); + test(p3[1].get("abc") == Test.MyEnum.enum1); + test(p3[1].get("") == Test.MyEnum.enum2); + test(p3[2].size == 3); + test(p3[2].get("abc") == Test.MyEnum.enum1); + test(p3[2].get("qwerty") == Test.MyEnum.enum3); + test(p3[2].get("Hello!!") == Test.MyEnum.enum2); + } + + { + const di1 = new Test.MyEnumStringD(); + di1.set(Test.MyEnum.enum1, "abc"); + const di2 = new Test.MyEnumStringD(); + di2.set(Test.MyEnum.enum2, "Hello!!"); + di2.set(Test.MyEnum.enum3, "qwerty"); + const di3 = new Test.MyEnumStringD(); + di3.set(Test.MyEnum.enum1, "Goodbye"); + + const [retval, p3] = await prx.opMyEnumStringDS([di1, di2], [di3]); + test(retval.length == 2); + test(retval[0].size == 2); + test(retval[0].get(Test.MyEnum.enum2) === "Hello!!"); + test(retval[0].get(Test.MyEnum.enum3) === "qwerty"); + test(retval[1].size == 1); + test(retval[1].get(Test.MyEnum.enum1) === "abc"); + + test(p3.length == 3); + test(p3[0].size == 1); + test(p3[0].get(Test.MyEnum.enum1) === "Goodbye"); + test(p3[1].size == 1); + test(p3[1].get(Test.MyEnum.enum1) === "abc"); + test(p3[2].size == 2); + test(p3[2].get(Test.MyEnum.enum2) === "Hello!!"); + test(p3[2].get(Test.MyEnum.enum3) === "qwerty"); + } + + { + const s11 = new Test.MyStruct(1, 1); + const s12 = new Test.MyStruct(1, 2); + const di1 = new Test.MyStructMyEnumD(); + di1.set(s11, Test.MyEnum.enum1); + di1.set(s12, Test.MyEnum.enum2); + + const s22 = new Test.MyStruct(2, 2); + const s23 = new Test.MyStruct(2, 3); + const di2 = new Test.MyStructMyEnumD(); + di2.set(s11, Test.MyEnum.enum1); + di2.set(s22, Test.MyEnum.enum3); + di2.set(s23, Test.MyEnum.enum2); + + const di3 = new Test.MyStructMyEnumD(); + di3.set(s23, Test.MyEnum.enum3); + + const [retval, p3] = await prx.opMyStructMyEnumDS([di1, di2], [di3]); + test(retval.length == 2); + test(retval[0].size == 3); + test(retval[0].get(s11) === Test.MyEnum.enum1); + test(retval[0].get(s22) === Test.MyEnum.enum3); + test(retval[0].get(s23) === Test.MyEnum.enum2); + test(retval[1].size == 2); + test(retval[1].get(s11) === Test.MyEnum.enum1); + test(retval[1].get(s12) === Test.MyEnum.enum2); + + test(p3.length == 3); + test(p3[0].size == 1); + test(p3[0].get(s23) === Test.MyEnum.enum3); + test(p3[1].size == 2); + test(p3[1].get(s11) === Test.MyEnum.enum1); + test(p3[1].get(s12) === Test.MyEnum.enum2); + test(p3[2].size == 3); + test(p3[2].get(s11) === Test.MyEnum.enum1); + test(p3[2].get(s22) === Test.MyEnum.enum3); + test(p3[2].get(s23) === Test.MyEnum.enum2); + } + + { + const sdi1 = new Test.ByteByteSD(); + sdi1.set(0x01, new Uint8Array([0x01, 0x11])); + sdi1.set(0x22, new Uint8Array([0x12])); + const sdi2 = new Test.ByteByteSD(); + sdi2.set(0xf1, new Uint8Array([0xf2, 0xf3])); + + const [retval, p3] = await prx.opByteByteSD(sdi1, sdi2); + test(p3.size == 1); + test(p3.get(0xf1).length === 2); + test(p3.get(0xf1)[0] === 0xf2); + test(p3.get(0xf1)[1] === 0xf3); + test(retval.size === 3); + test(retval.get(0x01).length === 2); + test(retval.get(0x01)[0] === 0x01); + test(retval.get(0x01)[1] === 0x11); + test(retval.get(0x22).length === 1); + test(retval.get(0x22)[0] === 0x12); + test(retval.get(0xf1).length === 2); + test(retval.get(0xf1)[0] === 0xf2); + test(retval.get(0xf1)[1] === 0xf3); + } + + { + const si1 = [true, false]; + const si2 = [false, true, true]; + const sdi1 = new Test.BoolBoolSD(); + sdi1.set(false, si1); + sdi1.set(true, si2); + const sdi2 = new Test.BoolBoolSD(); + sdi2.set(false, si1); + + const [retval, p3] = await prx.opBoolBoolSD(sdi1, sdi2); + test(p3.size === 1); + test(p3.get(false).length === 2); + test(p3.get(false)[0] === true); + test(p3.get(false)[1] === false); + test(retval.size === 2); + test(retval.get(false).length === 2); + test(retval.get(false)[0] === true); + test(retval.get(false)[1] === false); + test(retval.get(true).length === 3); + test(retval.get(true)[0] === false); + test(retval.get(true)[1] === true); + test(retval.get(true)[2] === true); + } + + { + const sdi1 = new Test.ShortShortSD(); + const sdi2 = new Test.ShortShortSD(); + + const si1 = [1, 2, 3]; + const si2 = [4, 5]; + const si3 = [6, 7]; + + sdi1.set(1, si1); + sdi1.set(2, si2); + sdi2.set(4, si3); + + const [retval, p3] = await prx.opShortShortSD(sdi1, sdi2); + test(p3.size === 1); + test(p3.get(4).length === 2); + test(p3.get(4)[0] === 6); + test(p3.get(4)[1] === 7); + test(retval.size === 3); + test(retval.get(1).length === 3); + test(retval.get(1)[0] === 1); + test(retval.get(1)[1] === 2); + test(retval.get(1)[2] === 3); + test(retval.get(2).length === 2); + test(retval.get(2)[0] === 4); + test(retval.get(2)[1] === 5); + test(retval.get(4).length === 2); + test(retval.get(4)[0] === 6); + test(retval.get(4)[1] === 7); + } + + { + const sdi1 = new Test.IntIntSD(); + const sdi2 = new Test.IntIntSD(); + + const si1 = [100, 200, 300]; + const si2 = [400, 500]; + const si3 = [600, 700]; + + sdi1.set(100, si1); + sdi1.set(200, si2); + sdi2.set(400, si3); + + const [retval, p3] = await prx.opIntIntSD(sdi1, sdi2); + test(p3.size === 1); + test(p3.get(400).length === 2); + test(p3.get(400)[0] === 600); + test(p3.get(400)[1] === 700); + test(retval.size === 3); + test(retval.get(100).length === 3); + test(retval.get(100)[0] === 100); + test(retval.get(100)[1] === 200); + test(retval.get(100)[2] === 300); + test(retval.get(200).length === 2); + test(retval.get(200)[0] === 400); + test(retval.get(200)[1] === 500); + test(retval.get(400).length === 2); + test(retval.get(400)[0] === 600); + test(retval.get(400)[1] === 700); + } + + { + const sdi1 = new Test.LongLongSD(); + const sdi2 = new Test.LongLongSD(); + + const si1 = [new Ice.Long(0, 999999110), new Ice.Long(0, 999999111), new Ice.Long(0, 999999110)]; + const si2 = [new Ice.Long(0, 999999120), new Ice.Long(0, 999999130)]; + const si3 = [new Ice.Long(0, 999999110), new Ice.Long(0, 999999120)]; + + sdi1.set(new Ice.Long(0, 999999990), si1); + sdi1.set(new Ice.Long(0, 999999991), si2); + sdi2.set(new Ice.Long(0, 999999992), si3); + + const [retval, p3] = await prx.opLongLongSD(sdi1, sdi2); + test(p3.size == 1); + test(p3.get(new Ice.Long(0, 999999992)).length === 2); + test(p3.get(new Ice.Long(0, 999999992))[0].equals(new Ice.Long(0, 999999110))); + test(p3.get(new Ice.Long(0, 999999992))[1].equals(new Ice.Long(0, 999999120))); + test(retval.size == 3); + test(retval.get(new Ice.Long(0, 999999990)).length === 3); + test(retval.get(new Ice.Long(0, 999999990))[0].equals(new Ice.Long(0, 999999110))); + test(retval.get(new Ice.Long(0, 999999990))[1].equals(new Ice.Long(0, 999999111))); + test(retval.get(new Ice.Long(0, 999999990))[2].equals(new Ice.Long(0, 999999110))); + test(retval.get(new Ice.Long(0, 999999991)).length === 2); + test(retval.get(new Ice.Long(0, 999999991))[0].equals(new Ice.Long(0, 999999120))); + test(retval.get(new Ice.Long(0, 999999991))[1].equals(new Ice.Long(0, 999999130))); + test(retval.get(new Ice.Long(0, 999999992)).length === 2); + test(retval.get(new Ice.Long(0, 999999992))[0].equals(new Ice.Long(0, 999999110))); + test(retval.get(new Ice.Long(0, 999999992))[1].equals(new Ice.Long(0, 999999120))); + } + + { + const sdi1 = new Test.StringFloatSD(); + const sdi2 = new Test.StringFloatSD(); + + const si1 = [-1.1, 123123.2, 100.0]; + const si2 = [42.24, -1.61]; + const si3 = [-3.14, 3.14]; + + sdi1.set("abc", si1); + sdi1.set("ABC", si2); + sdi2.set("aBc", si3); + + const [retval, p3] = await prx.opStringFloatSD(sdi1, sdi2); + + test(p3.size === 1); + test(p3.get("aBc").length === 2); + test(p3.get("aBc")[0] - Math.abs(3.14) <= 0.1); + test(p3.get("aBc")[1] - 3.14 <= 0.1); + test(retval.size === 3); + test(retval.get("abc").length === 3); + test(retval.get("abc")[0] - Math.abs(1.1) <= 0.1); + test(retval.get("abc")[1] - 123123.2 <= 0.1); + test(retval.get("abc")[2] - 100.0 <= 0.1); + test(retval.get("ABC").length === 2); + test(retval.get("ABC")[0] - 42.24 <= 0.1); + test(retval.get("ABC")[1] - Math.abs(1.61) <= 0.1); + test(retval.get("aBc").length === 2); + test(retval.get("aBc")[0] - Math.abs(3.14) <= 0.1); + test(retval.get("aBc")[1] - 3.14 <= 0.1); + } + + { + const sdi1 = new Test.StringDoubleSD(); + const sdi2 = new Test.StringDoubleSD(); + + const si1 = [1.1E10, 1.2E10, 1.3E10]; + const si2 = [1.4E10, 1.5E10]; + const si3 = [1.6E10, 1.7E10]; + + sdi1.set("Hello!!", si1); + sdi1.set("Goodbye", si2); + sdi2.set("", si3); + + const [retval, p3] = await prx.opStringDoubleSD(sdi1, sdi2); + + test(p3.size === 1); + test(p3.get("").length === 2); + test(p3.get("")[0] === 1.6E10); + test(p3.get("")[1] === 1.7E10); + test(retval.size === 3); + test(retval.get("Hello!!").length === 3); + test(retval.get("Hello!!")[0] === 1.1E10); + test(retval.get("Hello!!")[1] === 1.2E10); + test(retval.get("Hello!!")[2] === 1.3E10); + test(retval.get("Goodbye").length === 2); + test(retval.get("Goodbye")[0] === 1.4E10); + test(retval.get("Goodbye")[1] === 1.5E10); + test(retval.get("").length === 2); + test(retval.get("")[0] === 1.6E10); + test(retval.get("")[1] === 1.7E10); + } + + { + const sdi1 = new Test.StringStringSD(); + const sdi2 = new Test.StringStringSD(); + + const si1 = ["abc", "de", "fghi"]; + const si2 = ["xyz", "or"]; + const si3 = ["and", "xor"]; + + sdi1.set("abc", si1); + sdi1.set("def", si2); + sdi2.set("ghi", si3); + + const [retval, p3] = await prx.opStringStringSD(sdi1, sdi2); + + test(p3.size === 1); + test(p3.get("ghi").length === 2); + test(p3.get("ghi")[0] === "and"); + test(p3.get("ghi")[1] === "xor"); + test(retval.size === 3); + test(retval.get("abc").length === 3); + test(retval.get("abc")[0] === "abc"); + test(retval.get("abc")[1] === "de"); + test(retval.get("abc")[2] === "fghi"); + test(retval.get("def").length === 2); + test(retval.get("def")[0] === "xyz"); + test(retval.get("def")[1] === "or"); + test(retval.get("ghi").length === 2); + test(retval.get("ghi")[0] === "and"); + test(retval.get("ghi")[1] === "xor"); + } + + { + const sdi1 = new Test.MyEnumMyEnumSD(); + const sdi2 = new Test.MyEnumMyEnumSD(); + + const si1 = [Test.MyEnum.enum1, Test.MyEnum.enum1, Test.MyEnum.enum2]; + const si2 = [Test.MyEnum.enum1, Test.MyEnum.enum2]; + const si3 = [Test.MyEnum.enum3, Test.MyEnum.enum3]; + + sdi1.set(Test.MyEnum.enum3, si1); + sdi1.set(Test.MyEnum.enum2, si2); + sdi2.set(Test.MyEnum.enum1, si3); + + const [retval, p3] = await prx.opMyEnumMyEnumSD(sdi1, sdi2); + test(p3.size == 1); + test(p3.get(Test.MyEnum.enum1).length == 2); + test(p3.get(Test.MyEnum.enum1)[0] == Test.MyEnum.enum3); + test(p3.get(Test.MyEnum.enum1)[1] == Test.MyEnum.enum3); + test(retval.size === 3); + test(retval.get(Test.MyEnum.enum3).length == 3); + test(retval.get(Test.MyEnum.enum3)[0] == Test.MyEnum.enum1); + test(retval.get(Test.MyEnum.enum3)[1] == Test.MyEnum.enum1); + test(retval.get(Test.MyEnum.enum3)[2] == Test.MyEnum.enum2); + test(retval.get(Test.MyEnum.enum2).length == 2); + test(retval.get(Test.MyEnum.enum2)[0] == Test.MyEnum.enum1); + test(retval.get(Test.MyEnum.enum2)[1] == Test.MyEnum.enum2); + test(retval.get(Test.MyEnum.enum1).length == 2); + test(retval.get(Test.MyEnum.enum1)[0] == Test.MyEnum.enum3); + test(retval.get(Test.MyEnum.enum1)[1] == Test.MyEnum.enum3); + } + + { + const lengths = [0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000]; + + for(const l of lengths) + { + const s = new Array(l); + for(let i = 0; i < l; ++i) + { + s[i] = i; + } + + const r = await prx.opIntS(s); + test(r.length == l); + for(let j = 0; j < r.length; ++j) + { + test(r[j] == -j); + } + } + } + + { + const ctx = new Ice.Context(); + ctx.set("one", "ONE"); + ctx.set("two", "TWO"); + ctx.set("three", "THREE"); + { + test(prx.ice_getContext().size === 0); + const r = await prx.opContext(); + test(!Ice.MapUtil.equals(r, ctx)); + } + + { + const r = await prx.opContext(ctx); + test(prx.ice_getContext().size === 0); + test(Ice.MapUtil.equals(r, ctx)); + } + + { + const p2 = await Test.MyClassPrx.checkedCast(prx.ice_context(ctx)); + test(Ice.MapUtil.equals(p2.ice_getContext(), ctx)); + let r = await p2.opContext(); + test(Ice.MapUtil.equals(r, ctx)); + r = await p2.opContext(ctx); + test(Ice.MapUtil.equals(r, ctx)); + } + } + + if(!bidir) + { + // + // Test implicit context propagation + // + const initData = new Ice.InitializationData(); + initData.properties = communicator.getProperties().clone(); + initData.properties.setProperty("Ice.ImplicitContext", "Shared"); + + const ic = Ice.initialize(initData); + + let ctx = new Ice.Context(); + ctx.set("one", "ONE"); + ctx.set("two", "TWO"); + ctx.set("three", "THREE"); + + let p3 = Test.MyClassPrx.uncheckedCast(ic.stringToProxy("test:" + helper.getTestEndpoint())); + + ic.getImplicitContext().setContext(ctx); + test(Ice.MapUtil.equals(ic.getImplicitContext().getContext(), ctx)); + test(Ice.MapUtil.equals(await p3.opContext(), ctx)); + + test(ic.getImplicitContext().containsKey("zero") == false); + const r = ic.getImplicitContext().put("zero", "ZERO"); + test(r === undefined); + test(ic.getImplicitContext().get("zero") == "ZERO"); + + ctx = ic.getImplicitContext().getContext(); + test(Ice.MapUtil.equals(await p3.opContext(), ctx)); + + const prxContext = new Ice.Context(); + prxContext.set("one", "UN"); + prxContext.set("four", "QUATRE"); + + const combined = new Ice.Context(prxContext); + for(const [key, value] of ctx) + { + if(!combined.has(key)) + { + combined.set(key, value); + } + } + + test(combined.get("one") == "UN"); + + p3 = Test.MyClassPrx.uncheckedCast(p3.ice_context(prxContext)); + + ic.getImplicitContext().setContext(null); + test(Ice.MapUtil.equals(await p3.opContext(), prxContext)); + + ic.getImplicitContext().setContext(ctx); + test(Ice.MapUtil.equals(await p3.opContext(), combined)); + + test(ic.getImplicitContext().remove("one") == "ONE"); + + await ic.destroy(); + } + + { + const d = 1278312346.0 / 13.0; + const ds = []; + for(let i = 0; i < 5; i++) + { + ds[i] = d; + } + + await prx.opDoubleMarshaling(d, ds); + await prx.opIdempotent(); + await prx.opNonmutating(); + } + + { + + test(await prx.opByte1(0xFF) == 0xFF); + test(await prx.opShort1(0x7FFF) == 0x7FFF); + test(await prx.opInt1(0x7FFFFFFF) == 0x7FFFFFFF); + test((await prx.opLong1(new Ice.Long(0x7FFFFFFF, 0xFFFFFFFF))).equals(new Ice.Long(0x7FFFFFFF, 0xFFFFFFFF))); + test(await prx.opFloat1(1.0) == 1.0); + test(await prx.opDouble1(1.0) == 1.0); + test(await prx.opString1("opString1") == "opString1"); + test((await prx.opStringS1(null)).length === 0); + test((await prx.opByteBoolD1(null)).size === 0); + test((await prx.opStringS2(null)).length === 0); + test((await prx.opByteBoolD2(null)).size === 0); + + const d = Test.MyDerivedClassPrx.uncheckedCast(prx); + let s = new Test.MyStruct1(); + s.tesT = "Test.MyStruct1.s"; + s.myClass = null; + s.myStruct1 = "Test.MyStruct1.myStruct1"; + s = await d.opMyStruct1(s); + test(s.tesT == "Test.MyStruct1.s"); + test(s.myClass === null); + test(s.myStruct1 == "Test.MyStruct1.myStruct1"); + let c = new Test.MyClass1(); + c.tesT = "Test.MyClass1.testT"; + c.myClass = null; + c.myClass1 = "Test.MyClass1.myClass1"; + c = await d.opMyClass1(c); + test(c.tesT == "Test.MyClass1.testT"); + test(c.myClass === null); + test(c.myClass1 == "Test.MyClass1.myClass1"); + } + + { + const p1 = await prx.opMStruct1(); + p1.e = Test.MyEnum.enum3; + const [p2, p3] = await prx.opMStruct2(p1); + test(p2.equals(p1) && p3.equals(p1)); + } + + { + await prx.opMSeq1(); + const p1 = ["test"]; + const [p2, p3] = await prx.opMSeq2(p1); + test(Ice.ArrayUtil.equals(p2, p1) && Ice.ArrayUtil.equals(p3, p1)); + } + + { + await prx.opMDict1(); + const p1 = new Map(); + p1.set("test", "test"); + const [p2, p3] = await prx.opMDict2(p1); + test(Ice.MapUtil.equals(p2, p1) && Ice.MapUtil.equals(p3, p1)); + } + + { + const ds = []; + for(let i = 0; i < 5; i++) + { + ds[i] = 1278312346.0 / 13.0; + } + await prx.opDoubleMarshaling(1278312346.0 / 13.0, ds); + } +} diff --git a/js/test/ts/Ice/optional/AMDInitialI.ts b/js/test/ts/Ice/optional/AMDInitialI.ts new file mode 100644 index 00000000000..25be33d9706 --- /dev/null +++ b/js/test/ts/Ice/optional/AMDInitialI.ts @@ -0,0 +1,340 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; + +export class AMDInitialI extends Test.Initial +{ + shutdown(current:Ice.Current) + { + current.adapter.getCommunicator().shutdown(); + } + + pingPong(obj:Ice.Value, current:Ice.Current):Ice.Value + { + return obj; + } + + opOptionalException(a:number, b:string, o:Test.OneOptional, current:Ice.Current):void + { + const ex = new Test.OptionalException(); + if(a !== undefined) + { + ex.a = a; + } + else + { + ex.a = undefined; // The member "a" has a default value. + } + if(b !== undefined) + { + ex.b = b; + } + if(o !== undefined) + { + ex.o = o; + } + throw ex; + } + + opDerivedException(a:number, b:string, o:Test.OneOptional, current:Ice.Current):void + { + const ex = new Test.DerivedException(); + if(a !== undefined) + { + ex.a = a; + } + else + { + ex.a = undefined; // The member "a" has a default value. + } + if(b !== undefined) + { + ex.b = b; + ex.ss = b; + } + else + { + ex.ss = undefined; // The member "ss" has a default value. + } + if(o !== undefined) + { + ex.o = o; + ex.o2 = o; + } + throw ex; + } + + opRequiredException(a:number, b:string, o:Test.OneOptional, current:Ice.Current):void + { + const ex = new Test.RequiredException(); + if(a !== undefined) + { + ex.a = a; + } + else + { + ex.a = undefined; // The member "a" has a default value. + } + if(b !== undefined) + { + ex.b = b; + ex.ss = b; + } + if(o !== undefined) + { + ex.o = o; + ex.o2 = o; + } + throw ex; + } + + opByte(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opBool(p1:boolean, current:Ice.Current):[boolean, boolean] + { + return [p1, p1]; + } + + opShort(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opInt(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opLong(p1:Ice.Long, current:Ice.Current):[Ice.Long, Ice.Long] + { + return [p1, p1]; + } + + opFloat(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opDouble(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opString(p1:string, current:Ice.Current):[string, string] + { + return [p1, p1]; + } + + opMyEnum(p1:Test.MyEnum, current:Ice.Current):[Test.MyEnum, Test.MyEnum] + { + return [p1, p1]; + } + + opSmallStruct(p1:Test.SmallStruct, current:Ice.Current):[Test.SmallStruct, Test.SmallStruct] + { + return [p1, p1]; + } + + opFixedStruct(p1:Test.FixedStruct, current:Ice.Current):[Test.FixedStruct, Test.FixedStruct] + { + return [p1, p1]; + } + + opVarStruct(p1:Test.VarStruct, current:Ice.Current):[Test.VarStruct, Test.VarStruct] + { + return [p1, p1]; + } + + opOneOptional(p1:Test.OneOptional, current:Ice.Current):[Test.OneOptional, Test.OneOptional] + { + return [p1, p1]; + } + + opOneOptionalProxy(p1:Test.OneOptionalPrx, current:Ice.Current):[Test.OneOptionalPrx, Test.OneOptionalPrx] + { + return [p1, p1]; + } + + opByteSeq(p1:Test.ByteSeq, current:Ice.Current):[Test.ByteSeq, Test.ByteSeq] + { + return [p1, p1]; + } + + opBoolSeq(p1:Test.BoolSeq, current:Ice.Current):[Test.BoolSeq, Test.BoolSeq] + { + return [p1, p1]; + } + + opShortSeq(p1:Test.ShortSeq, current:Ice.Current):[Test.ShortSeq, Test.ShortSeq] + { + return [p1, p1]; + } + + opIntSeq(p1:Test.IntSeq, current:Ice.Current):[Test.IntSeq, Test.IntSeq] + { + return [p1, p1]; + } + + opLongSeq(p1:Test.LongSeq, current:Ice.Current):[Test.LongSeq, Test.LongSeq] + { + return [p1, p1]; + } + + opFloatSeq(p1:Test.FloatSeq, current:Ice.Current):[Test.FloatSeq, Test.FloatSeq] + { + return [p1, p1]; + } + + opDoubleSeq(p1:Test.DoubleSeq, current:Ice.Current):[Test.DoubleSeq, Test.DoubleSeq] + { + return [p1, p1]; + } + + opStringSeq(p1:Test.StringSeq, current:Ice.Current):[Test.StringSeq, Test.StringSeq] + { + return [p1, p1]; + } + + opSmallStructSeq(p1:Test.SmallStructSeq, current:Ice.Current):[Test.SmallStructSeq, Test.SmallStructSeq] + { + return [p1, p1]; + } + + opSmallStructList(p1:Test.SmallStructList, current:Ice.Current):[Test.SmallStructList, Test.SmallStructList] + { + return [p1, p1]; + } + + opFixedStructSeq(p1:Test.FixedStructSeq, current:Ice.Current):[Test.FixedStructSeq, Test.FixedStructSeq] + { + return [p1, p1]; + } + + opFixedStructList(p1:Test.FixedStructList, current:Ice.Current):[Test.FixedStructList, Test.FixedStructList] + { + return [p1, p1]; + } + + opVarStructSeq(p1:Test.VarStructSeq, current:Ice.Current):[Test.VarStructSeq, Test.VarStructSeq] + { + return [p1, p1]; + } + + opSerializable(p1:Test.Serializable, current:Ice.Current):[Test.Serializable, Test.Serializable] + { + return [p1, p1]; + } + + opIntIntDict(p1:Test.IntIntDict, current:Ice.Current):[Test.IntIntDict, Test.IntIntDict] + { + return [p1, p1]; + } + + opStringIntDict(p1:Test.StringIntDict, current:Ice.Current):[Test.StringIntDict, Test.StringIntDict] + { + return [p1, p1]; + } + + opIntOneOptionalDict(p1:Test.IntOneOptionalDict, current:Ice.Current):[Test.IntOneOptionalDict, Test.IntOneOptionalDict] + { + return [p1, p1]; + } + + opClassAndUnknownOptional(p:Test.A, current:Ice.Current):void + { + } + + sendOptionalClass(req:boolean, one:Test.OneOptional, current:Ice.Current):void + { + } + + returnOptionalClass(req:boolean, current:Ice.Current):Test.OneOptional + { + return new Test.OneOptional(53); + } + + opG(g:Test.G, current:Ice.Current):Test.G + { + return g; + } + + opVoid(current:Ice.Current):void + { + } + + opMStruct1(current:Ice.Current):Test.SmallStruct + { + return new Test.SmallStruct(); + } + + opMStruct2(p1:Test.SmallStruct, current:Ice.Current):[Test.SmallStruct, Test.SmallStruct] + { + return [p1, p1]; + } + + opMSeq1(current:Ice.Current):Test.StringSeq + { + return []; + } + + opMSeq2(p1:Test.StringSeq, current:Ice.Current):[Test.StringSeq, Test.StringSeq] + { + return [p1, p1]; + } + + opMDict1(current:Ice.Current):Test.StringIntDict + { + return new Map(); + } + + opMDict2(p1:Test.StringIntDict, current:Ice.Current):[Test.StringIntDict, Test.StringIntDict] + { + return [p1, p1]; + } + + opMG1(current:Ice.Current):Test.G + { + return new Test.G(); + } + + opMG2(p1:Test.G, current:Ice.Current):[Test.G, Test.G] + { + return [p1, p1]; + } + + supportsRequiredParams(current:Ice.Current):boolean + { + return false; + } + + supportsJavaSerializable(current:Ice.Current):boolean + { + return false; + } + + supportsCsharpSerializable(current:Ice.Current):boolean + { + return false; + } + + supportsCppStringView(current:Ice.Current):boolean + { + return false; + } + + supportsNullOptional(current:Ice.Current):boolean + { + return true; + } +} diff --git a/js/test/ts/Ice/optional/Client.ts b/js/test/ts/Ice/optional/Client.ts new file mode 100644 index 00000000000..198981b5d9c --- /dev/null +++ b/js/test/ts/Ice/optional/Client.ts @@ -0,0 +1,884 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +import {Test as ClientPrivate} from "./ClientPrivate"; + +const test = TestHelper.test; +const ArrayUtil = Ice.ArrayUtil; + +export class Client extends TestHelper +{ + async allTests() + { + const communicator = this.communicator(); + const out = this.getWriter(); + out.write("testing stringToProxy... "); + const ref = "initial:" + this.getTestEndpoint(); + const base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + let oo1 = new Test.OneOptional(); + oo1.a = 15; + + out.write("testing checked cast... "); + const initial = await Test.InitialPrx.checkedCast(base); + test(initial !== null); + test(initial.equals(base)); + out.writeLine("ok"); + + out.write("testing marshaling... "); + + const oo4 = await initial.pingPong(new Test.OneOptional()) as Test.OneOptional; + test(oo4.a === undefined); + + const oo5 = await initial.pingPong(oo1) as Test.OneOptional; + test(oo5.a === oo1.a); + + const mo4 = await initial.pingPong(new Test.MultiOptional()) as Test.MultiOptional; + test(mo4.a === undefined); + test(mo4.b === undefined); + test(mo4.c === undefined); + test(mo4.d === undefined); + test(mo4.e === undefined); + test(mo4.f === undefined); + test(mo4.g === undefined); + test(mo4.h === undefined); + test(mo4.i === undefined); + test(mo4.j === undefined); + test(mo4.k === undefined); + test(mo4.bs === undefined); + test(mo4.ss === undefined); + test(mo4.iid === undefined); + test(mo4.sid === undefined); + test(mo4.fs === undefined); + test(mo4.vs === undefined); + + test(mo4.shs === undefined); + test(mo4.es === undefined); + test(mo4.fss === undefined); + test(mo4.vss === undefined); + test(mo4.oos === undefined); + test(mo4.oops === undefined); + + test(mo4.ied === undefined); + test(mo4.ifsd === undefined); + test(mo4.ivsd === undefined); + test(mo4.iood === undefined); + test(mo4.ioopd === undefined); + + test(mo4.bos === undefined); + + test(mo4.ser === undefined); + + const mo1 = new Test.MultiOptional(); + mo1.a = 15; + mo1.b = true; + mo1.c = 19; + mo1.d = 78; + mo1.e = new Ice.Long(0, 99); + mo1.f = 5.5; + mo1.g = 1.0; + mo1.h = "test"; + mo1.i = Test.MyEnum.MyEnumMember; + mo1.j = communicator.stringToProxy("test"); + mo1.k = mo1; + mo1.bs = new Uint8Array([5]); + mo1.ss = ["test", "test2"]; + mo1.iid = new Map(); + mo1.iid.set(4, 3); + mo1.sid = new Map(); + mo1.sid.set("test", 10); + mo1.fs = new Test.FixedStruct(); + mo1.fs.m = 78; + mo1.vs = new Test.VarStruct(); + mo1.vs.m = "hello"; + + mo1.shs = [1]; + mo1.es = [Test.MyEnum.MyEnumMember, Test.MyEnum.MyEnumMember]; + mo1.fss = [mo1.fs]; + mo1.vss = [mo1.vs]; + mo1.oos = [oo1]; + mo1.oops = [communicator.stringToProxy("test")]; + + mo1.ied = new Map(); + mo1.ied.set(4, Test.MyEnum.MyEnumMember); + mo1.ifsd = new Map(); + mo1.ifsd.set(4, mo1.fs); + mo1.ivsd = new Map(); + mo1.ivsd.set(5, mo1.vs); + mo1.iood = new Map(); + mo1.iood.set(5, new Test.OneOptional(15)); + mo1.ioopd = new Map(); + mo1.ioopd.set(5, communicator.stringToProxy("test")); + + mo1.bos = [false, true, false]; + + const mo5 = await initial.pingPong(mo1) as Test.MultiOptional; + + test(mo1.a == mo5.a); + test(mo1.b == mo5.b); + test(mo1.c == mo5.c); + test(mo1.d == mo5.d); + test(mo1.e.equals(mo5.e)); + test(mo1.f == mo5.f); + test(mo1.g == mo5.g); + test(mo1.h == mo5.h); + test(mo1.i == mo5.i); + test(mo1.j.equals(mo5.j)); + test(mo5.k == mo5); + test(ArrayUtil.equals(mo5.bs, mo1.bs)); + test(ArrayUtil.equals(mo5.ss, mo1.ss)); + test(mo5.iid.get(4) == 3); + test(mo5.sid.get("test") == 10); + test(mo5.fs.equals(mo1.fs)); + test(mo5.vs.equals(mo1.vs)); + test(ArrayUtil.equals(mo5.shs, mo1.shs)); + test(mo5.es[0] == Test.MyEnum.MyEnumMember && mo5.es[1] == Test.MyEnum.MyEnumMember); + test(mo5.fss[0].equals(new Test.FixedStruct(78))); + test(mo5.vss[0].equals(new Test.VarStruct("hello"))); + test(mo5.oos[0].a == 15); + test(mo5.oops[0].equals(communicator.stringToProxy("test"))); + + test(mo5.ied.get(4) == Test.MyEnum.MyEnumMember); + test(mo5.ifsd.get(4).equals(new Test.FixedStruct(78))); + test(mo5.ivsd.get(5).equals(new Test.VarStruct("hello"))); + test(mo5.iood.get(5).a == 15); + test(mo5.ioopd.get(5).equals(communicator.stringToProxy("test"))); + + test(ArrayUtil.equals(mo5.bos, [false, true, false])); + + // Clear the first half of the optional parameters + const mo6 = new Test.MultiOptional(); + mo6.b = mo5.b; + mo6.d = mo5.d; + mo6.f = mo5.f; + mo6.h = mo5.h; + mo6.j = mo5.j; + mo6.bs = mo5.bs; + mo6.iid = mo5.iid; + mo6.fs = mo5.fs; + mo6.shs = mo5.shs; + mo6.fss = mo5.fss; + mo6.oos = mo5.oos; + mo6.ifsd = mo5.ifsd; + mo6.iood = mo5.iood; + mo6.bos = mo5.bos; + + const mo7 = await initial.pingPong(mo6) as Test.MultiOptional; + test(mo7.a === undefined); + test(mo7.b == mo1.b); + test(mo7.c === undefined); + test(mo7.d == mo1.d); + test(mo7.e === undefined); + test(mo7.f == mo1.f); + test(mo7.g === undefined); + test(mo7.h == mo1.h); + test(mo7.i === undefined); + test(mo7.j.equals(mo1.j)); + test(mo7.k === undefined); + test(ArrayUtil.equals(mo7.bs, mo1.bs)); + test(mo7.ss === undefined); + test(mo7.iid.get(4) == 3); + test(mo7.sid === undefined); + test(mo7.fs.equals(mo1.fs)); + test(mo7.vs === undefined); + test(ArrayUtil.equals(mo7.shs, mo1.shs)); + test(mo7.es === undefined); + test(mo7.fss[0].equals(new Test.FixedStruct(78))); + test(mo7.vss === undefined); + test(mo7.oos[0].a == 15); + test(mo7.oops === undefined); + + test(mo7.ied === undefined); + test(mo7.ifsd.get(4).equals(new Test.FixedStruct(78))); + test(mo7.ivsd === undefined); + test(mo7.iood.get(5).a == 15); + test(mo7.ioopd === undefined); + + test(ArrayUtil.equals(mo7.bos, [false, true, false])); + + // Clear the second half of the optional parameters + const mo8 = new Test.MultiOptional(); + mo8.a = mo1.a; + mo8.c = mo1.c; + mo8.e = mo1.e; + mo8.g = mo1.g; + mo8.i = mo1.i; + mo8.k = mo8; + mo8.ss = mo1.ss; + mo8.sid = mo1.sid; + mo8.vs = mo1.vs; + + mo8.es = mo1.es; + mo8.vss = mo1.vss; + mo8.oops = mo1.oops; + + mo8.ied = mo1.ied; + mo8.ivsd = mo1.ivsd; + mo8.ioopd = mo1.ioopd; + + const mo9 = await initial.pingPong(mo8) as Test.MultiOptional; + + test(mo9.a == mo1.a); + test(mo9.b === undefined); + test(mo9.c == mo1.c); + test(mo9.d === undefined); + test(mo9.e.equals(mo1.e)); + test(mo9.f === undefined); + test(mo9.g == mo1.g); + test(mo9.h === undefined); + test(mo9.i == mo1.i); + test(mo9.j === undefined); + test(mo9.k == mo9); + test(mo9.bs === undefined); + test(ArrayUtil.equals(mo9.ss, mo1.ss)); + test(mo9.iid === undefined); + test(mo9.sid.get("test") == 10); + test(mo9.fs === undefined); + test(mo9.vs.equals(mo1.vs)); + + test(mo9.shs === undefined); + test(mo9.es[0] == Test.MyEnum.MyEnumMember && mo9.es[1] == Test.MyEnum.MyEnumMember); + test(mo9.fss === undefined); + test(mo9.vss[0].equals(new Test.VarStruct("hello"))); + test(mo9.oos === undefined); + test(mo9.oops[0].equals(communicator.stringToProxy("test"))); + + test(mo9.ied.get(4) == Test.MyEnum.MyEnumMember); + test(mo9.ifsd === undefined); + test(mo9.ivsd.get(5).equals(new Test.VarStruct("hello"))); + test(mo9.iood === undefined); + test(mo9.ioopd.get(5).equals(communicator.stringToProxy("test"))); + + test(mo9.bos === undefined); + + // + // Use the 1.0 encoding with operations whose only class parameters are optional. + // + const initial2 = initial.ice_encodingVersion(Ice.Encoding_1_0); + const oo = new Test.OneOptional(53); + + await initial.sendOptionalClass(true, oo); + await initial2.sendOptionalClass(true, oo); + oo1 = await initial.returnOptionalClass(true); + test(oo1 !== undefined && oo1.a == 53); + oo1 = await initial2.returnOptionalClass(true); + test(oo1 === undefined); + + const recursive1 = [new Test.Recursive()]; + const recursive2 = [new Test.Recursive()]; + recursive1[0].value = recursive2; + const outer = new Test.Recursive(); + outer.value = recursive1; + await initial.pingPong(outer); + + let g = new Test.G(); + g.gg1Opt = new Test.G1("gg1Opt"); + g.gg2 = new Test.G2(new Ice.Long(0, 10)); + g.gg2Opt = new Test.G2(new Ice.Long(0, 20)); + g.gg1 = new Test.G1("gg1"); + + g = await initial.opG(g); + + test(g.gg1Opt.a == "gg1Opt"); + test(g.gg2.a.equals(new Ice.Long(0, 10))); + test(g.gg2Opt.a.equals(new Ice.Long(0, 20))); + test(g.gg1.a == "gg1"); + + const init2 = ClientPrivate.Initial2Prx.uncheckedCast(initial); + await init2.opVoid(5, "test"); + out.writeLine("ok"); + + out.write("testing marshaling of large containers with fixed size elements... "); + let mc = new Test.MultiOptional(); + + mc.bs = new Uint8Array(1000); + mc.shs = new Array(300); + + mc.fss = []; + for(let i = 0; i < 300; ++i) + { + mc.fss[i] = new Test.FixedStruct(); + } + + mc.ifsd = new Map(); + for(let i = 0; i < 300; ++i) + { + mc.ifsd.set(i, new Test.FixedStruct()); + } + mc = await initial.pingPong(mc) as Test.MultiOptional; + + test(mc.bs.length == 1000); + test(mc.shs.length == 300); + test(mc.fss.length == 300); + test(mc.ifsd.size == 300); + + out.writeLine("ok"); + + out.write("testing tag marshaling... "); + let b = await initial.pingPong(new Test.B()) as Test.B; + + test(b.ma === undefined); + test(b.mb === undefined); + test(b.mc === undefined); + + b.ma = 10; + b.mb = 11; + b.mc = 12; + b.md = 13; + + b = await initial.pingPong(b) as Test.B; + + test(b.ma == 10); + test(b.mb == 11); + test(b.mc == 12); + test(b.md == 13); + out.writeLine("ok"); + + out.write("testing marshaling of objects with optional objects... "); + let f = new Test.F(); + f.af = new Test.A(); + f.ae = f.af; + f = await initial.pingPong(f) as Test.F; + test(f.ae === f.af); + out.writeLine("ok"); + + out.write("testing optional with default values... "); + + let wd = await initial.pingPong(new Test.WD()) as Test.WD; + test(wd.a == 5); + test(wd.s == "test"); + wd.a = undefined; + wd.s = undefined; + wd = await initial.pingPong(wd) as Test.WD; + + test(wd.a === undefined); + test(wd.s === undefined); + out.writeLine("ok"); + + out.write("testing optional parameters... "); + { + let [p1, p2] = await initial.opByte(); // same as initial.opByte(undefined); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opByte(56); + test(p1 === 56); + test(p2 === 56); + } + + { + let [p1, p2] = await initial.opBool(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opBool(true); + test(p1 === true); + test(p2 === true); + } + + { + let [p1, p2] = await initial.opShort(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opShort(56); + test(p1 === 56); + test(p2 === 56); + } + + { + let [p1, p2] = await initial.opInt(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opInt(56); + test(p1 === 56); + test(p2 === 56); + } + + { + let [p1, p2] = await initial.opLong(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opLong(new Ice.Long(0, 56)); + test(p1.equals(new Ice.Long(0, 56))); + test(p2.equals(new Ice.Long(0, 56))); + } + + { + let [p1, p2] = await initial.opFloat(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opFloat(1.0); + test(p1 === 1.0); + test(p2 === 1.0); + } + + { + let [p1, p2] = await initial.opDouble(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opDouble(1.0); + test(p1 === 1.0); + test(p2 === 1.0); + } + + { + let [p1, p2] = await initial.opString(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opString("test"); + test(p1 === "test"); + test(p2 === "test"); + } + + { + let [p1, p2] = await initial.opMyEnum(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opMyEnum(Test.MyEnum.MyEnumMember); + test(p1 === Test.MyEnum.MyEnumMember); + test(p2 === Test.MyEnum.MyEnumMember); + [p1, p2] = await initial.opMyEnum(null); // Test null enum + test(p1 === Test.MyEnum.MyEnumMember); + test(p2 === Test.MyEnum.MyEnumMember); + } + + { + let [p1, p2] = await initial.opSmallStruct(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opSmallStruct(new Test.SmallStruct(56)); + test(p1.equals(new Test.SmallStruct(56))); + test(p2.equals(new Test.SmallStruct(56))); + [p1, p2] = await initial.opSmallStruct(null); // Test null struct + test(p1.equals(new Test.SmallStruct(0))); + test(p2.equals(new Test.SmallStruct(0))); + } + + { + let [p1, p2] = await initial.opFixedStruct(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opFixedStruct(new Test.FixedStruct(56)); + test(p1.equals(new Test.FixedStruct(56))); + test(p2.equals(new Test.FixedStruct(56))); + } + + { + let [p1, p2] = await initial.opVarStruct(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opVarStruct(new Test.VarStruct("test")); + test(p1.equals(new Test.VarStruct("test"))); + test(p2.equals(new Test.VarStruct("test"))); + } + + { + let [p1, p2] = await initial.opOneOptional(); + test(p1 === undefined); + test(p2 === undefined); + if(await initial.supportsNullOptional()) + { + + [p1, p2] = await initial.opOneOptional(null); + test(p1 === null); + test(p2 === null); + } + [p1, p2] = await initial.opOneOptional(new Test.OneOptional(58)); + test(p1 === p2); + test(p2.a === 58); + } + + { + let [p1, p2] = await initial.opOneOptionalProxy(); + test(p1 === undefined); + test(p2 === undefined); + [p1, p2] = await initial.opOneOptionalProxy(communicator.stringToProxy("test")); + test(p1.equals(communicator.stringToProxy("test"))); + test(p2.equals(communicator.stringToProxy("test"))); + } + + { + let [p1, p2] = await initial.opByteSeq(); + test(p1 === undefined); + test(p2 === undefined); + + let data:number[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = 56; + } + [p1, p2] = await initial.opByteSeq(new Uint8Array(data)); + + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i] === 56); + test(p2[i] === 56); + } + } + + { + let [p1, p2] = await initial.opBoolSeq(); + test(p1 === undefined); + test(p2 === undefined); + + let data:boolean[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = true; + } + [p1, p2] = await initial.opBoolSeq(data); + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i] === true); + test(p2[i] === true); + } + } + + { + let [p1, p2] = await initial.opShortSeq(); + test(p1 === undefined); + test(p2 === undefined); + + let data:number[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = 56; + } + [p1, p2] = await initial.opShortSeq(data); + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i] === 56); + test(p2[i] === 56); + } + } + + { + let [p1, p2] = await initial.opIntSeq(); + test(p1 === undefined); + test(p2 === undefined); + + let data:number[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = 56; + } + [p1, p2] = await initial.opIntSeq(data); + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i] === 56); + test(p2[i] === 56); + } + } + + { + let [p1, p2] = await initial.opLongSeq(); + test(p1 === undefined); + test(p2 === undefined); + let data:Ice.Long[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = new Ice.Long(0, 56); + } + [p1, p2] = await initial.opLongSeq(data); + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i].equals(new Ice.Long(0, 56))); + test(p2[i].equals(new Ice.Long(0, 56))); + } + } + + { + let [p1, p2] = await initial.opFloatSeq(); + test(p1 === undefined); + test(p2 === undefined); + let data:number[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = 1.0; + } + [p1, p2] = await initial.opFloatSeq(data); + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i] === 1.0); + test(p2[i] === 1.0); + } + } + + { + let [p1, p2] = await initial.opDoubleSeq(); + test(p1 === undefined); + test(p2 === undefined); + let data:number[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = 1.0; + } + [p1, p2] = await initial.opDoubleSeq(data); + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i] === 1.0); + test(p2[i] === 1.0); + } + } + + { + let [p1, p2] = await initial.opStringSeq(); + test(p1 === undefined); + test(p2 === undefined); + let data:string[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = "test1"; + } + [p1, p2] = await initial.opStringSeq(data); + + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i] == "test1"); + test(p2[i] == "test1"); + } + } + + { + let [p1, p2] = await initial.opSmallStructSeq(); + test(p1 === undefined); + test(p2 === undefined); + let data:Test.SmallStruct[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = new Test.SmallStruct(); + } + [p1, p2] = await initial.opSmallStructSeq(data); + + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i].equals(new Test.SmallStruct())); + test(p2[i].equals(new Test.SmallStruct())); + } + } + + { + let [p1, p2] = await initial.opFixedStructSeq(); + test(p1 === undefined); + test(p2 === undefined); + let data:Test.FixedStruct[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = new Test.FixedStruct(); + } + [p1, p2] = await initial.opFixedStructSeq(data); + + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i].equals(new Test.FixedStruct())); + test(p2[i].equals(new Test.FixedStruct())); + } + } + + { + let [p1, p2] = await initial.opVarStructSeq(); + test(p1 === undefined); + test(p2 === undefined); + let data:Test.VarStruct[] = []; + for(let i = 0; i < 100; ++i) + { + data[i] = new Test.VarStruct(""); + } + [p1, p2] = await initial.opVarStructSeq(data); + test(p1.length === 100); + test(p2.length === 100); + for(let i = 0; i < 100; ++i) + { + test(p1[i].equals(new Test.VarStruct(""))); + test(p2[i].equals(new Test.VarStruct(""))); + } + } + + { + let [p1, p2] = await initial.opIntIntDict(); + test(p1 === undefined); + test(p2 === undefined); + let data = new Test.IntIntDict(); + data.set(1, 2); + data.set(2, 3); + [p1, p2] = await initial.opIntIntDict(data); + test(Ice.MapUtil.equals(p1, p2)); + } + + { + let [p1, p2] = await initial.opStringIntDict(); + test(p1 === undefined); + test(p2 === undefined); + let data = new Test.StringIntDict(); + data.set("1", 1); + data.set("2", 2); + [p1, p2] = await initial.opStringIntDict(data); + test(Ice.MapUtil.equals(p1, p2)); + } + + { + let [p1, p2] = await initial.opIntOneOptionalDict(); + test(p1 === undefined); + test(p2 === undefined); + let data = new Test.IntOneOptionalDict(); + data.set(1, new Test.OneOptional(58)); + data.set(2, new Test.OneOptional(59)); + [p1, p2] = await initial.opIntOneOptionalDict(data); + test(p1.get(1).a === 58 && p2.get(2).a === 59); + } + out.writeLine("ok"); + + out.write("testing exception optionals... "); + + try + { + await initial.opOptionalException(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.OptionalException, ex); + test(ex.a === undefined); + test(ex.b === undefined); + test(ex.o === undefined); + } + + try + { + await initial.opOptionalException(30, "test", new Test.OneOptional(53)); + test(false); + } + catch(ex) + { + test(ex instanceof Test.OptionalException, ex); + test(ex.a === 30); + test(ex.b == "test"); + test(ex.o.a == 53); + } + + try + { + await initial.opDerivedException(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.DerivedException, ex); + test(ex.a === undefined); + test(ex.b === undefined); + test(ex.o === undefined); + test(ex.ss === undefined); + test(ex.o2 === undefined); + } + + try + { + await initial.opDerivedException(30, "test2", new Test.OneOptional(53)); + test(false); + } + catch(ex) + { + test(ex instanceof Test.DerivedException, ex); + test(ex.a === 30); + test(ex.b == "test2"); + test(ex.o.a === 53); + test(ex.ss == "test2"); + test(ex.o2.a === 53); + } + + out.writeLine("ok"); + + out.write("testing optionals with marshaled results... "); + + test(await initial.opMStruct1() !== undefined); + test(await initial.opMDict1() !== undefined); + test(await initial.opMSeq1() !== undefined); + test(await initial.opMG1() !== undefined); + + { + let [p3, p2] = await initial.opMStruct2(); + test(p3 === undefined && p2 == undefined); + + const p1 = new Test.SmallStruct(); + [p3, p2] = await initial.opMStruct2(p1); + test(p2.equals(p1) && p3.equals(p1)); + } + + { + let [p3, p2] = await initial.opMSeq2(); + test(p2 === undefined && p3 === undefined); + + const p1 = ["hello"]; + [p3, p2] = await initial.opMSeq2(p1); + test(ArrayUtil.equals(p2, p1) && ArrayUtil.equals(p3, p1)); + } + + { + let [p3, p2] = await initial.opMDict2(); + test(p2 === undefined && p3 === undefined); + + const p1 = new Map(); + p1.set("test", 54); + [p3, p2] = await initial.opMDict2(p1); + test(Ice.MapUtil.equals(p2, p1) && Ice.MapUtil.equals(p3, p1)); + } + { + let [p3, p2] = await initial.opMG2(); + test(p2 === undefined && p3 === undefined); + + const p1 = new Test.G(); + [p3, p2] = await initial.opMG2(p1); + test(p3 !== undefined && p2 !== undefined && p3 === p2); + } + + out.writeLine("ok"); + + await initial.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/optional/ClientPrivate.ice b/js/test/ts/Ice/optional/ClientPrivate.ice new file mode 100644 index 00000000000..63f984e1ba8 --- /dev/null +++ b/js/test/ts/Ice/optional/ClientPrivate.ice @@ -0,0 +1,43 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Test.ice> + +module Test +{ + +// +// The server doesn't know this class. +// +// We don't define it in JavaScript to allow the cross tests to work when running +// only the JavaScript server within the browser (which loads ClientPrivate.js for +// the server as well) +// +// class D extends B +// { +// string ds; +// optional(990) StringSeq seq; +// optional(1000) A ao; +// } + +// +// This class is a hack that allows us to invoke the opClassAndUnknownOptional operation +// on the server and pass an optional argument. This isn't necessary in other language +// mappings where the public stream API is available. +// +interface Initial2 +{ + void opClassAndUnknownOptional(A p, optional(1) Object o); + + void opVoid(optional(1) int a, optional(2) string v); +} + +} diff --git a/js/test/ts/Ice/optional/InitialI.ts b/js/test/ts/Ice/optional/InitialI.ts new file mode 100644 index 00000000000..c30547b4a28 --- /dev/null +++ b/js/test/ts/Ice/optional/InitialI.ts @@ -0,0 +1,340 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; + +export class InitialI extends Test.Initial +{ + shutdown(current:Ice.Current) + { + current.adapter.getCommunicator().shutdown(); + } + + pingPong(obj:Ice.Value, current:Ice.Current):Ice.Value + { + return obj; + } + + opOptionalException(a:number, b:string, o:Test.OneOptional, current:Ice.Current):void + { + const ex = new Test.OptionalException(); + if(a !== undefined) + { + ex.a = a; + } + else + { + ex.a = undefined; // The member "a" has a default value. + } + if(b !== undefined) + { + ex.b = b; + } + if(o !== undefined) + { + ex.o = o; + } + throw ex; + } + + opDerivedException(a:number, b:string, o:Test.OneOptional, current:Ice.Current):void + { + const ex = new Test.DerivedException(); + if(a !== undefined) + { + ex.a = a; + } + else + { + ex.a = undefined; // The member "a" has a default value. + } + if(b !== undefined) + { + ex.b = b; + ex.ss = b; + } + else + { + ex.ss = undefined; // The member "ss" has a default value. + } + if(o !== undefined) + { + ex.o = o; + ex.o2 = o; + } + throw ex; + } + + opRequiredException(a:number, b:string, o:Test.OneOptional, current:Ice.Current):void + { + const ex = new Test.RequiredException(); + if(a !== undefined) + { + ex.a = a; + } + else + { + ex.a = undefined; // The member "a" has a default value. + } + if(b !== undefined) + { + ex.b = b; + ex.ss = b; + } + if(o !== undefined) + { + ex.o = o; + ex.o2 = o; + } + throw ex; + } + + opByte(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opBool(p1:boolean, current:Ice.Current):[boolean, boolean] + { + return [p1, p1]; + } + + opShort(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opInt(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opLong(p1:Ice.Long, current:Ice.Current):[Ice.Long, Ice.Long] + { + return [p1, p1]; + } + + opFloat(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opDouble(p1:number, current:Ice.Current):[number, number] + { + return [p1, p1]; + } + + opString(p1:string, current:Ice.Current):[string, string] + { + return [p1, p1]; + } + + opMyEnum(p1:Test.MyEnum, current:Ice.Current):[Test.MyEnum, Test.MyEnum] + { + return [p1, p1]; + } + + opSmallStruct(p1:Test.SmallStruct, current:Ice.Current):[Test.SmallStruct, Test.SmallStruct] + { + return [p1, p1]; + } + + opFixedStruct(p1:Test.FixedStruct, current:Ice.Current):[Test.FixedStruct, Test.FixedStruct] + { + return [p1, p1]; + } + + opVarStruct(p1:Test.VarStruct, current:Ice.Current):[Test.VarStruct, Test.VarStruct] + { + return [p1, p1]; + } + + opOneOptional(p1:Test.OneOptional, current:Ice.Current):[Test.OneOptional, Test.OneOptional] + { + return [p1, p1]; + } + + opOneOptionalProxy(p1:Test.OneOptionalPrx, current:Ice.Current):[Test.OneOptionalPrx, Test.OneOptionalPrx] + { + return [p1, p1]; + } + + opByteSeq(p1:Test.ByteSeq, current:Ice.Current):[Test.ByteSeq, Test.ByteSeq] + { + return [p1, p1]; + } + + opBoolSeq(p1:Test.BoolSeq, current:Ice.Current):[Test.BoolSeq, Test.BoolSeq] + { + return [p1, p1]; + } + + opShortSeq(p1:Test.ShortSeq, current:Ice.Current):[Test.ShortSeq, Test.ShortSeq] + { + return [p1, p1]; + } + + opIntSeq(p1:Test.IntSeq, current:Ice.Current):[Test.IntSeq, Test.IntSeq] + { + return [p1, p1]; + } + + opLongSeq(p1:Test.LongSeq, current:Ice.Current):[Test.LongSeq, Test.LongSeq] + { + return [p1, p1]; + } + + opFloatSeq(p1:Test.FloatSeq, current:Ice.Current):[Test.FloatSeq, Test.FloatSeq] + { + return [p1, p1]; + } + + opDoubleSeq(p1:Test.DoubleSeq, current:Ice.Current):[Test.DoubleSeq, Test.DoubleSeq] + { + return [p1, p1]; + } + + opStringSeq(p1:Test.StringSeq, current:Ice.Current):[Test.StringSeq, Test.StringSeq] + { + return [p1, p1]; + } + + opSmallStructSeq(p1:Test.SmallStructSeq, current:Ice.Current):[Test.SmallStructSeq, Test.SmallStructSeq] + { + return [p1, p1]; + } + + opSmallStructList(p1:Test.SmallStructList, current:Ice.Current):[Test.SmallStructList, Test.SmallStructList] + { + return [p1, p1]; + } + + opFixedStructSeq(p1:Test.FixedStructSeq, current:Ice.Current):[Test.FixedStructSeq, Test.FixedStructSeq] + { + return [p1, p1]; + } + + opFixedStructList(p1:Test.FixedStructList, current:Ice.Current):[Test.FixedStructList, Test.FixedStructList] + { + return [p1, p1]; + } + + opVarStructSeq(p1:Test.VarStructSeq, current:Ice.Current):[Test.VarStructSeq, Test.VarStructSeq] + { + return [p1, p1]; + } + + opSerializable(p1:Test.Serializable, current:Ice.Current):[Test.Serializable, Test.Serializable] + { + return [p1, p1]; + } + + opIntIntDict(p1:Test.IntIntDict, current:Ice.Current):[Test.IntIntDict, Test.IntIntDict] + { + return [p1, p1]; + } + + opStringIntDict(p1:Test.StringIntDict, current:Ice.Current):[Test.StringIntDict, Test.StringIntDict] + { + return [p1, p1]; + } + + opIntOneOptionalDict(p1:Test.IntOneOptionalDict, current:Ice.Current):[Test.IntOneOptionalDict, Test.IntOneOptionalDict] + { + return [p1, p1]; + } + + opClassAndUnknownOptional(p:Test.A, current:Ice.Current):void + { + } + + sendOptionalClass(req:boolean, one:Test.OneOptional, current:Ice.Current):void + { + } + + returnOptionalClass(req:boolean, current:Ice.Current):Test.OneOptional + { + return new Test.OneOptional(53); + } + + opG(g:Test.G, current:Ice.Current):Test.G + { + return g; + } + + opVoid(current:Ice.Current):void + { + } + + opMStruct1(current:Ice.Current):Test.SmallStruct + { + return new Test.SmallStruct(); + } + + opMStruct2(p1:Test.SmallStruct, current:Ice.Current):[Test.SmallStruct, Test.SmallStruct] + { + return [p1, p1]; + } + + opMSeq1(current:Ice.Current):Test.StringSeq + { + return []; + } + + opMSeq2(p1:Test.StringSeq, current:Ice.Current):[Test.StringSeq, Test.StringSeq] + { + return [p1, p1]; + } + + opMDict1(current:Ice.Current):Test.StringIntDict + { + return new Map(); + } + + opMDict2(p1:Test.StringIntDict, current:Ice.Current):[Test.StringIntDict, Test.StringIntDict] + { + return [p1, p1]; + } + + opMG1(current:Ice.Current):Test.G + { + return new Test.G(); + } + + opMG2(p1:Test.G, current:Ice.Current):[Test.G, Test.G] + { + return [p1, p1]; + } + + supportsRequiredParams(current:Ice.Current):boolean + { + return false; + } + + supportsJavaSerializable(current:Ice.Current):boolean + { + return false; + } + + supportsCsharpSerializable(current:Ice.Current):boolean + { + return false; + } + + supportsCppStringView(current:Ice.Current):boolean + { + return false; + } + + supportsNullOptional(current:Ice.Current):boolean + { + return true; + } +} diff --git a/js/test/ts/Ice/optional/Server.ts b/js/test/ts/Ice/optional/Server.ts new file mode 100644 index 00000000000..813a6468a5e --- /dev/null +++ b/js/test/ts/Ice/optional/Server.ts @@ -0,0 +1,45 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +import {InitialI} from "./InitialI"; + +export class Server extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo:Test.EchoPrx; + try + { + [communicator] = this.initialize(args); + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter = await communicator.createObjectAdapter(""); + adapter.add(new InitialI(), Ice.stringToIdentity("initial")); + await echo.setConnection(); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/optional/ServerAMD.ts b/js/test/ts/Ice/optional/ServerAMD.ts new file mode 100644 index 00000000000..dde7e5b1d55 --- /dev/null +++ b/js/test/ts/Ice/optional/ServerAMD.ts @@ -0,0 +1,45 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +import {AMDInitialI} from "./AMDInitialI"; + +export class ServerAMD extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo:Test.EchoPrx; + try + { + [communicator] = this.initialize(args); + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter = await communicator.createObjectAdapter(""); + adapter.add(new AMDInitialI(), Ice.stringToIdentity("initial")); + await echo.setConnection(); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await communicator.waitForShutdown(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/optional/Test.ice b/js/test/ts/Ice/optional/Test.ice new file mode 100644 index 00000000000..f6b5dd5eff2 --- /dev/null +++ b/js/test/ts/Ice/optional/Test.ice @@ -0,0 +1,324 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +[["suppress-warning:deprecated"]] + +module Test +{ + +class OneOptional +{ + optional(1) int a; +} + +enum MyEnum +{ + MyEnumMember +} + +struct SmallStruct +{ + byte m; +} + +struct FixedStruct +{ + int m; +} + +struct VarStruct +{ + string m; +} + +struct ClassVarStruct +{ + int a; +} + +sequence<byte> ByteSeq; +sequence<bool> BoolSeq; +sequence<short> ShortSeq; +sequence<int> IntSeq; +sequence<long> LongSeq; +sequence<float> FloatSeq; +sequence<double> DoubleSeq; +sequence<string> StringSeq; +sequence<MyEnum> MyEnumSeq; +sequence<SmallStruct> SmallStructSeq; +sequence<SmallStruct> SmallStructList; +sequence<FixedStruct> FixedStructSeq; +sequence<FixedStruct> FixedStructList; +sequence<VarStruct> VarStructSeq; +sequence<OneOptional> OneOptionalSeq; +sequence<OneOptional*> OneOptionalPrxSeq; + +sequence<byte> Serializable; + +dictionary<int, int> IntIntDict; +dictionary<string, int> StringIntDict; +dictionary<int, MyEnum> IntEnumDict; +dictionary<int, FixedStruct> IntFixedStructDict; +dictionary<int, VarStruct> IntVarStructDict; +dictionary<int, OneOptional> IntOneOptionalDict; +dictionary<int, OneOptional*> IntOneOptionalPrxDict; + +class MultiOptional +{ + optional(1) byte a; + optional(2) bool b; + optional(3) short c; + optional(4) int d; + optional(5) long e; + optional(6) float f; + optional(7) double g; + optional(8) string h; + optional(9) MyEnum i; + optional(10) MultiOptional* j; + optional(11) MultiOptional k; + optional(12) ByteSeq bs; + optional(13) StringSeq ss; + optional(14) IntIntDict iid; + optional(15) StringIntDict sid; + optional(16) FixedStruct fs; + optional(17) VarStruct vs; + + optional(18) ShortSeq shs; + optional(19) MyEnumSeq es; + optional(20) FixedStructSeq fss; + optional(21) VarStructSeq vss; + optional(22) OneOptionalSeq oos; + optional(23) OneOptionalPrxSeq oops; + + optional(24) IntEnumDict ied; + optional(25) IntFixedStructDict ifsd; + optional(26) IntVarStructDict ivsd; + optional(27) IntOneOptionalDict iood; + optional(28) IntOneOptionalPrxDict ioopd; + + optional(29) BoolSeq bos; + + optional(30) Serializable ser; +} + +class A +{ + int requiredA; + optional(1) int ma; + optional(50) int mb; + optional(500) int mc; +} + +["preserve-slice"] +class B extends A +{ + int requiredB; + optional(10) int md; +} + +class C extends B +{ + string ss; + optional(890) string ms; +} + +class WD +{ + optional(1) int a = 5; + optional(2) string s = "test"; +} + +exception OptionalException +{ + bool req = false; + optional(1) int a = 5; + optional(2) string b; + optional(50) OneOptional o; +} + +exception DerivedException extends OptionalException +{ + optional(600) string ss = "test"; + optional(601) OneOptional o2; +} + +exception RequiredException extends OptionalException +{ + string ss = "test"; + OneOptional o2; +} + +class OptionalWithCustom +{ + optional(1) SmallStructList l; + ["protected"] optional(2) SmallStructList lp; + optional(3) ClassVarStruct s; +} + +class E +{ + A ae; +} + +class F extends E +{ + optional(1) A af; +} + +class G1 +{ + string a; +} + +class G2 +{ + long a; +} + +class G +{ + optional(1) G1 gg1Opt; + G2 gg2; + optional(0) G2 gg2Opt; + G1 gg1; +} + +class Recursive; +sequence<Recursive> RecursiveSeq; + +class Recursive +{ + optional(0) RecursiveSeq value; +} + +interface Initial +{ + void shutdown(); + + Object pingPong(Object o); + + void opOptionalException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + void opDerivedException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + void opRequiredException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + optional(1) byte opByte(optional(2) byte p1, out optional(3) byte p3); + + optional(1) bool opBool(optional(2) bool p1, out optional(3) bool p3); + + optional(1) short opShort(optional(2) short p1, out optional(3) short p3); + + optional(1) int opInt(optional(2) int p1, out optional(3) int p3); + + optional(3) long opLong(optional(1) long p1, out optional(2) long p3); + + optional(1) float opFloat(optional(2) float p1, out optional(3) float p3); + + optional(1) double opDouble(optional(2) double p1, out optional(3) double p3); + + optional(1) string opString(optional(2) string p1, out optional(3) string p3); + + optional(1) MyEnum opMyEnum(optional(2) MyEnum p1, out optional(3) MyEnum p3); + + optional(1) SmallStruct opSmallStruct(optional(2) SmallStruct p1, out optional(3) SmallStruct p3); + + optional(1) FixedStruct opFixedStruct(optional(2) FixedStruct p1, out optional(3) FixedStruct p3); + + optional(1) VarStruct opVarStruct(optional(2) VarStruct p1, out optional(3) VarStruct p3); + + optional(1) OneOptional opOneOptional(optional(2) OneOptional p1, out optional(3) OneOptional p3); + + optional(1) OneOptional* opOneOptionalProxy(optional(2) OneOptional* p1, out optional(3) OneOptional* p3); + + optional(1) ByteSeq opByteSeq(optional(2) ByteSeq p1, out optional(3) ByteSeq p3); + + optional(1) BoolSeq opBoolSeq(optional(2) BoolSeq p1, out optional(3) BoolSeq p3); + + optional(1) ShortSeq opShortSeq(optional(2) ShortSeq p1, out optional(3) ShortSeq p3); + + optional(1) IntSeq opIntSeq(optional(2) IntSeq p1, out optional(3) IntSeq p3); + + optional(1) LongSeq opLongSeq(optional(2) LongSeq p1, out optional(3) LongSeq p3); + + optional(1) FloatSeq opFloatSeq(optional(2) FloatSeq p1, out optional(3) FloatSeq p3); + + optional(1) DoubleSeq opDoubleSeq(optional(2) DoubleSeq p1, out optional(3) DoubleSeq p3); + + optional(1) StringSeq opStringSeq(optional(2) StringSeq p1, out optional(3) StringSeq p3); + + optional(1) SmallStructSeq opSmallStructSeq(optional(2) SmallStructSeq p1, out optional(3) SmallStructSeq p3); + + optional(1) SmallStructList opSmallStructList(optional(2) SmallStructList p1, out optional(3) SmallStructList p3); + + optional(1) FixedStructSeq opFixedStructSeq(optional(2) FixedStructSeq p1, out optional(3) FixedStructSeq p3); + + optional(1) FixedStructList opFixedStructList(optional(2) FixedStructList p1, out optional(3) FixedStructList p3); + + optional(1) VarStructSeq opVarStructSeq(optional(2) VarStructSeq p1, out optional(3) VarStructSeq p3); + + optional(1) Serializable opSerializable(optional(2) Serializable p1, out optional(3) Serializable p3); + + optional(1) IntIntDict opIntIntDict(optional(2) IntIntDict p1, out optional(3) IntIntDict p3); + + optional(1) StringIntDict opStringIntDict(optional(2) StringIntDict p1, out optional(3) StringIntDict p3); + + optional(1) IntOneOptionalDict opIntOneOptionalDict(optional(2) IntOneOptionalDict p1, + out optional(3) IntOneOptionalDict p3); + + void opClassAndUnknownOptional(A p); + + void sendOptionalClass(bool req, optional(1) OneOptional o); + + void returnOptionalClass(bool req, out optional(1) OneOptional o); + + G opG(G g); + + void opVoid(); + + ["marshaled-result"] optional(1) SmallStruct opMStruct1(); + ["marshaled-result"] optional(1) SmallStruct opMStruct2(optional(2) SmallStruct p1, + out optional(3)SmallStruct p2); + + ["marshaled-result"] optional(1) StringSeq opMSeq1(); + ["marshaled-result"] optional(1) StringSeq opMSeq2(optional(2) StringSeq p1, + out optional(3) StringSeq p2); + + ["marshaled-result"] optional(1) StringIntDict opMDict1(); + ["marshaled-result"] optional(1) StringIntDict opMDict2(optional(2) StringIntDict p1, + out optional(3) StringIntDict p2); + + ["marshaled-result"] optional(1) G opMG1(); + ["marshaled-result"] optional(1) G opMG2(optional(2) G p1, out optional(3) G p2); + + bool supportsRequiredParams(); + + bool supportsJavaSerializable(); + + bool supportsCsharpSerializable(); + + bool supportsCppStringView(); + + bool supportsNullOptional(); +} + +interface Echo +{ + void setConnection(); + void startBatch(); + void flushBatch(); + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/proxy/Client.ts b/js/test/ts/Ice/proxy/Client.ts new file mode 100644 index 00000000000..5733241d51a --- /dev/null +++ b/js/test/ts/Ice/proxy/Client.ts @@ -0,0 +1,1168 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + class TestError extends Error + { + } + + const communicator = this.communicator(); + const out = this.getWriter(); + + const defaultProtocol = communicator.getProperties().getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + + out.write("testing stringToProxy... "); + const ref = "test:" + this.getTestEndpoint(); + const base = communicator.stringToProxy(ref); + test(base !== null); + + let b1 = communicator.stringToProxy("test"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getAdapterId().length === 0 && b1.ice_getFacet().length === 0); + b1 = communicator.stringToProxy("test "); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet().length === 0); + b1 = communicator.stringToProxy(" test "); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet().length === 0); + b1 = communicator.stringToProxy(" test"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet().length === 0); + b1 = communicator.stringToProxy("'test -f facet'"); + test(b1.ice_getIdentity().name === "test -f facet" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet().length === 0); + + try + { + b1 = communicator.stringToProxy("\"test -f facet'"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ProxyParseException, ex); + } + + b1 = communicator.stringToProxy("\"test -f facet\""); + test(b1.ice_getIdentity().name === "test -f facet" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet().length === 0); + b1 = communicator.stringToProxy("\"test -f facet@test\""); + test(b1.ice_getIdentity().name === "test -f facet@test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet().length === 0); + b1 = communicator.stringToProxy("\"test -f facet@test @test\""); + test(b1.ice_getIdentity().name === "test -f facet@test @test" && + b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet().length === 0); + + try + { + b1 = communicator.stringToProxy("test test"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ProxyParseException, ex); + } + + b1 = communicator.stringToProxy("test\\040test"); + test(b1.ice_getIdentity().name === "test test" && b1.ice_getIdentity().category.length === 0); + + try + { + b1 = communicator.stringToProxy("test\\777"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.IdentityParseException, ex); + } + + b1 = communicator.stringToProxy("test\\40test"); + test(b1.ice_getIdentity().name === "test test"); + + // Test some octal and hex corner cases. + b1 = communicator.stringToProxy("test\\4test"); + test(b1.ice_getIdentity().name === "test\x04test"); + b1 = communicator.stringToProxy("test\\04test"); + test(b1.ice_getIdentity().name === "test\x04test"); + b1 = communicator.stringToProxy("test\\004test"); + test(b1.ice_getIdentity().name === "test\x04test"); + b1 = communicator.stringToProxy("test\\1114test"); + test(b1.ice_getIdentity().name === "test\x494test"); + + b1 = communicator.stringToProxy("test\\b\\f\\n\\r\\t\\'\\\"\\\\test"); + test(b1.ice_getIdentity().name === "test\b\f\n\r\t'\"\\test" && + b1.ice_getIdentity().category.length === 0); + + b1 = communicator.stringToProxy("category/test"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category === "category" && + b1.ice_getAdapterId().length === 0); + + b1 = communicator.stringToProxy(""); + test(b1 === null); + b1 = communicator.stringToProxy("\"\""); + test(b1 === null); + try + { + b1 = communicator.stringToProxy("\"\" test"); // Invalid trailing characters. + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ProxyParseException, ex); + } + + try + { + b1 = communicator.stringToProxy("test:"); // Missing endpoint. + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + b1 = communicator.stringToProxy("test@adapter"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getAdapterId() === "adapter"); + try + { + b1 = communicator.stringToProxy("id@adapter test"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ProxyParseException, ex); + } + + b1 = communicator.stringToProxy("category/test@adapter"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category === "category" && + b1.ice_getAdapterId() === "adapter"); + b1 = communicator.stringToProxy("category/test@adapter:" + defaultProtocol); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category === "category" && + b1.ice_getAdapterId() === "adapter:" + defaultProtocol); + b1 = communicator.stringToProxy("'category 1/test'@adapter"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category === "category 1" && + b1.ice_getAdapterId() === "adapter"); + b1 = communicator.stringToProxy("'category/test 1'@adapter"); + test(b1.ice_getIdentity().name === "test 1" && b1.ice_getIdentity().category === "category" && + b1.ice_getAdapterId() === "adapter"); + b1 = communicator.stringToProxy("'category/test'@'adapter 1'"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category === "category" && + b1.ice_getAdapterId() === "adapter 1"); + b1 = communicator.stringToProxy("\"category \\/test@foo/test\"@adapter"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category === "category /test@foo" && + b1.ice_getAdapterId() === "adapter"); + b1 = communicator.stringToProxy("\"category \\/test@foo/test\"@\"adapter:" + defaultProtocol + "\""); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category === "category /test@foo" && + b1.ice_getAdapterId() === "adapter:" + defaultProtocol); + + b1 = communicator.stringToProxy("id -f facet"); + test(b1.ice_getIdentity().name === "id" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet() === "facet"); + b1 = communicator.stringToProxy("id -f 'facet x'"); + test(b1.ice_getIdentity().name === "id" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet() === "facet x"); + b1 = communicator.stringToProxy("id -f \"facet x\""); + test(b1.ice_getIdentity().name === "id" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet() === "facet x"); + + try + { + b1 = communicator.stringToProxy("id -f \"facet x"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ProxyParseException, ex); + } + + try + { + b1 = communicator.stringToProxy("id -f 'facet x"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ProxyParseException, ex); + } + + b1 = communicator.stringToProxy("test -f facet:" + defaultProtocol); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet() === "facet" && b1.ice_getAdapterId().length === 0); + b1 = communicator.stringToProxy("test -f \"facet:" + defaultProtocol + "\""); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet() === "facet:" + defaultProtocol && b1.ice_getAdapterId().length === 0); + b1 = communicator.stringToProxy("test -f facet@test"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet() === "facet" && b1.ice_getAdapterId() === "test"); + b1 = communicator.stringToProxy("test -f 'facet@test'"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet() === "facet@test" && b1.ice_getAdapterId().length === 0); + b1 = communicator.stringToProxy("test -f 'facet@test'@test"); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getFacet() === "facet@test" && b1.ice_getAdapterId() === "test"); + + try + { + b1 = communicator.stringToProxy("test -f facet@test @test"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ProxyParseException, ex); + } + b1 = communicator.stringToProxy("test"); + test(b1.ice_isTwoway()); + b1 = communicator.stringToProxy("test -t"); + test(b1.ice_isTwoway()); + b1 = communicator.stringToProxy("test -o"); + test(b1.ice_isOneway()); + b1 = communicator.stringToProxy("test -O"); + test(b1.ice_isBatchOneway()); + b1 = communicator.stringToProxy("test -d"); + test(b1.ice_isDatagram()); + b1 = communicator.stringToProxy("test -D"); + test(b1.ice_isBatchDatagram()); + b1 = communicator.stringToProxy("test"); + test(!b1.ice_isSecure()); + b1 = communicator.stringToProxy("test -s"); + test(b1.ice_isSecure()); + + test(b1.ice_getEncodingVersion().equals(Ice.currentEncoding())); + + b1 = communicator.stringToProxy("test -e 1.0"); + test(b1.ice_getEncodingVersion().major === 1 && b1.ice_getEncodingVersion().minor === 0); + + b1 = communicator.stringToProxy("test -e 6z.5"); + test(b1.ice_getEncodingVersion().major === 6 && b1.ice_getEncodingVersion().minor === 5); + + b1 = communicator.stringToProxy("test -p 1.0 -e 1.0"); + test(b1.toString() === "test -t -e 1.0"); + + b1 = communicator.stringToProxy("test -p 6.5 -e 1.0"); + test(b1.toString() === "test -t -p 6.5 -e 1.0"); + + try + { + b1 = communicator.stringToProxy("test:" + defaultProtocol + "@adapterId"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + b1 = communicator.stringToProxy("test::" + defaultProtocol); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + // + // Test for bug ICE-5543: escaped escapes in stringToIdentity + // + + let id = new Ice.Identity("test", ",X2QNUAzSBcJ_e$AV;E\\"); + let id2 = Ice.stringToIdentity(Ice.identityToString(id)); + test(id.equals(id2)); + + id = new Ice.Identity("test", ",X2QNUAz\\SB\\/cJ_e$AV;E\\\\"); + id2 = Ice.stringToIdentity(Ice.identityToString(id)); + test(id.equals(id2)); + + id = new Ice.Identity("/test", "cat/"); + let idStr = Ice.identityToString(id); + test(idStr === "cat\\//\\/test"); + id2 = Ice.stringToIdentity(idStr); + test(id.equals(id2)); + + // Input string with various pitfalls + // id = Ice.stringToIdentity("\\342\\x82\\254\\60\\x9\\60\\"); + // test(id.name === "€0\t0\\" && id.category.isEmpty()); + + try + { + // Illegal character < 32 + id = Ice.stringToIdentity("xx\x01FooBar"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.IdentityParseException); + } + + try + { + // Illegal surrogate + id = Ice.stringToIdentity("xx\\ud911"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.IdentityParseException, ex); + } + + // Testing bytes 127 (\x7F) and € + id = new Ice.Identity("test", "\x7F€"); + + idStr = Ice.identityToString(id, Ice.ToStringMode.Unicode); + test(idStr === "\\u007f€/test"); + id2 = Ice.stringToIdentity(idStr); + test(id.equals(id2)); + test(Ice.identityToString(id) === idStr); + + idStr = Ice.identityToString(id, Ice.ToStringMode.ASCII); + test(idStr === "\\u007f\\u20ac/test"); + id2 = Ice.stringToIdentity(idStr); + test(id.equals(id2)); + + idStr = Ice.identityToString(id, Ice.ToStringMode.Compat); + test(idStr === "\\177\\342\\202\\254/test"); + id2 = Ice.stringToIdentity(idStr); + test(id.equals(id2)); + + id2 = Ice.stringToIdentity(communicator.identityToString(id)); + test(id.equals(id2)); + + // More unicode characters + + id = new Ice.Identity("banana \x0e-\ud83c\udf4c\u20ac\u00a2\u0024", "greek \ud800\udd6a"); + + idStr = Ice.identityToString(id, Ice.ToStringMode.Unicode); + test(idStr === "greek \ud800\udd6a/banana \\u000e-\ud83c\udf4c\u20ac\u00a2$"); + id2 = Ice.stringToIdentity(idStr); + test(id.equals(id2)); + + idStr = Ice.identityToString(id, Ice.ToStringMode.ASCII); + test(idStr === "greek \\U0001016a/banana \\u000e-\\U0001f34c\\u20ac\\u00a2$"); + id2 = Ice.stringToIdentity(idStr); + test(id.equals(id2)); + + idStr = Ice.identityToString(id, Ice.ToStringMode.Compat); + test(idStr === "greek \\360\\220\\205\\252/banana \\016-\\360\\237\\215\\214\\342\\202\\254\\302\\242$"); + id2 = Ice.stringToIdentity(idStr); + test(id.equals(id2)); + + out.writeLine("ok"); + + out.write("testing propertyToProxy... "); + const prop = communicator.getProperties(); + const propertyPrefix = "Foo.Proxy"; + prop.setProperty(propertyPrefix, "test:" + this.getTestEndpoint()); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getIdentity().name === "test" && b1.ice_getIdentity().category.length === 0 && + b1.ice_getAdapterId().length === 0 && b1.ice_getFacet().length === 0); + + let property = propertyPrefix + ".Locator"; + test(b1.ice_getLocator() === null); + prop.setProperty(property, "locator:default -p 10000"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getLocator() !== null && b1.ice_getLocator().ice_getIdentity().name === "locator"); + prop.setProperty(property, ""); + + property = propertyPrefix + ".LocatorCacheTimeout"; + test(b1.ice_getLocatorCacheTimeout() === -1); + prop.setProperty(property, "1"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getLocatorCacheTimeout() === 1); + prop.setProperty(property, ""); + + // Now retest with an indirect proxy. + prop.setProperty(propertyPrefix, "test"); + property = propertyPrefix + ".Locator"; + prop.setProperty(property, "locator:default -p 10000"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getLocator() !== null && b1.ice_getLocator().ice_getIdentity().name === "locator"); + prop.setProperty(property, ""); + + property = propertyPrefix + ".LocatorCacheTimeout"; + test(b1.ice_getLocatorCacheTimeout() === -1); + prop.setProperty(property, "1"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getLocatorCacheTimeout() === 1); + prop.setProperty(property, ""); + + prop.setProperty(propertyPrefix, "test:" + this.getTestEndpoint()); + + property = propertyPrefix + ".Router"; + test(b1.ice_getRouter() === null); + prop.setProperty(property, "router:default -p 10000"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getRouter() !== null && b1.ice_getRouter().ice_getIdentity().name === "router"); + prop.setProperty(property, ""); + + property = propertyPrefix + ".PreferSecure"; + test(!b1.ice_isPreferSecure()); + prop.setProperty(property, "1"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_isPreferSecure()); + prop.setProperty(property, ""); + + property = propertyPrefix + ".ConnectionCached"; + test(b1.ice_isConnectionCached()); + prop.setProperty(property, "0"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(!b1.ice_isConnectionCached()); + prop.setProperty(property, ""); + + property = propertyPrefix + ".InvocationTimeout"; + test(b1.ice_getInvocationTimeout() == -1); + prop.setProperty(property, "1000"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getInvocationTimeout() == 1000); + prop.setProperty(property, ""); + + property = propertyPrefix + ".EndpointSelection"; + test(b1.ice_getEndpointSelection() === Ice.EndpointSelectionType.Random); + prop.setProperty(property, "Random"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getEndpointSelection() === Ice.EndpointSelectionType.Random); + prop.setProperty(property, "Ordered"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getEndpointSelection() === Ice.EndpointSelectionType.Ordered); + prop.setProperty(property, ""); + + out.writeLine("ok"); + + out.write("testing proxyToProperty... "); + + b1 = communicator.stringToProxy("test"); + b1 = b1.ice_connectionCached(true); + b1 = b1.ice_preferSecure(false); + b1 = b1.ice_endpointSelection(Ice.EndpointSelectionType.Ordered); + b1 = b1.ice_locatorCacheTimeout(100); + b1 = b1.ice_invocationTimeout(1234); + b1 = b1.ice_encodingVersion(new Ice.EncodingVersion(1, 0)); + + let router = communicator.stringToProxy("router"); + router = router.ice_connectionCached(true); + router = router.ice_preferSecure(true); + router = router.ice_endpointSelection(Ice.EndpointSelectionType.Random); + router = router.ice_locatorCacheTimeout(200); + router = router.ice_invocationTimeout(1500); + + let locator = communicator.stringToProxy("locator"); + locator = locator.ice_connectionCached(false); + locator = locator.ice_preferSecure(true); + locator = locator.ice_endpointSelection(Ice.EndpointSelectionType.Random); + locator = locator.ice_locatorCacheTimeout(300); + locator = locator.ice_invocationTimeout(1500); + + locator = locator.ice_router(Ice.RouterPrx.uncheckedCast(router)); + b1 = b1.ice_locator(Ice.LocatorPrx.uncheckedCast(locator)); + + const proxyProps = communicator.proxyToProperty(b1, "Test"); + test(proxyProps.size === 21); + test(proxyProps.get("Test") === "test -t -e 1.0"); + test(proxyProps.get("Test.CollocationOptimized") === "0"); + test(proxyProps.get("Test.ConnectionCached") === "1"); + test(proxyProps.get("Test.PreferSecure") === "0"); + test(proxyProps.get("Test.EndpointSelection") === "Ordered"); + test(proxyProps.get("Test.LocatorCacheTimeout") === "100"); + test(proxyProps.get("Test.InvocationTimeout") === "1234"); + + test(proxyProps.get("Test.Locator") === "locator -t -e " + + Ice.encodingVersionToString(Ice.currentEncoding())); + test(proxyProps.get("Test.Locator.CollocationOptimized") === "0"); + test(proxyProps.get("Test.Locator.ConnectionCached") === "0"); + test(proxyProps.get("Test.Locator.PreferSecure") === "1"); + test(proxyProps.get("Test.Locator.EndpointSelection") === "Random"); + test(proxyProps.get("Test.Locator.LocatorCacheTimeout") === "300"); + test(proxyProps.get("Test.Locator.InvocationTimeout") === "1500"); + + test(proxyProps.get("Test.Locator.Router") === "router -t -e " + + Ice.encodingVersionToString(Ice.currentEncoding())); + test(proxyProps.get("Test.Locator.Router.CollocationOptimized") === "0"); + test(proxyProps.get("Test.Locator.Router.ConnectionCached") === "1"); + test(proxyProps.get("Test.Locator.Router.PreferSecure") === "1"); + test(proxyProps.get("Test.Locator.Router.EndpointSelection") === "Random"); + test(proxyProps.get("Test.Locator.Router.LocatorCacheTimeout") === "200"); + test(proxyProps.get("Test.Locator.Router.InvocationTimeout") === "1500"); + + out.writeLine("ok"); + + out.write("testing ice_getCommunicator... "); + test(base.ice_getCommunicator() === communicator); + out.writeLine("ok"); + + out.write("testing proxy methods... "); + test(communicator.identityToString( + base.ice_identity(Ice.stringToIdentity("other")).ice_getIdentity()) === "other"); + test(Ice.identityToString( + base.ice_identity(Ice.stringToIdentity("other")).ice_getIdentity()) === "other"); + test(base.ice_facet("facet").ice_getFacet() === "facet"); + test(base.ice_adapterId("id").ice_getAdapterId() === "id"); + test(base.ice_twoway().ice_isTwoway()); + test(base.ice_oneway().ice_isOneway()); + test(base.ice_batchOneway().ice_isBatchOneway()); + test(base.ice_datagram().ice_isDatagram()); + test(base.ice_batchDatagram().ice_isBatchDatagram()); + test(base.ice_secure(true).ice_isSecure()); + test(!base.ice_secure(false).ice_isSecure()); + test(base.ice_preferSecure(true).ice_isPreferSecure()); + test(!base.ice_preferSecure(false).ice_isPreferSecure()); + test(base.ice_encodingVersion(Ice.Encoding_1_0).ice_getEncodingVersion().equals(Ice.Encoding_1_0)); + test(base.ice_encodingVersion(Ice.Encoding_1_1).ice_getEncodingVersion().equals(Ice.Encoding_1_1)); + test(!base.ice_encodingVersion(Ice.Encoding_1_0).ice_getEncodingVersion().equals(Ice.Encoding_1_1)); + + try + { + base.ice_timeout(0); + test(false); + } + catch(ex) + { + test(!(ex instanceof TestError), ex); + } + + try + { + base.ice_timeout(-1); + } + catch(ex) + { + test(false, ex); + } + + try + { + base.ice_timeout(-2); + test(false); + } + catch(ex) + { + test(!(ex instanceof TestError), ex); + } + + try + { + base.ice_invocationTimeout(0); + test(false); + } + catch(ex) + { + test(!(ex instanceof TestError), ex); + } + + try + { + base.ice_invocationTimeout(-1); + } + catch(ex) + { + test(false); + } + + try + { + base.ice_invocationTimeout(-2); + test(false); + } + catch(ex) + { + test(!(ex instanceof TestError), ex); + } + + try + { + base.ice_locatorCacheTimeout(0); + } + catch(ex) + { + test(false, ex); + } + + try + { + base.ice_locatorCacheTimeout(-1); + } + catch(ex) + { + test(false, ex); + } + + try + { + base.ice_locatorCacheTimeout(-2); + test(false); + } + catch(ex) + { + test(!(ex instanceof TestError), ex); + } + + out.writeLine("ok"); + + out.write("testing proxy comparison... "); + + test(communicator.stringToProxy("foo").equals(communicator.stringToProxy("foo"))); + test(!communicator.stringToProxy("foo").equals(communicator.stringToProxy("foo2"))); + + const compObj = communicator.stringToProxy("foo"); + + test(compObj.ice_facet("facet").equals(compObj.ice_facet("facet"))); + test(!compObj.ice_facet("facet").equals(compObj.ice_facet("facet1"))); + + test(compObj.ice_oneway().equals(compObj.ice_oneway())); + test(!compObj.ice_oneway().equals(compObj.ice_twoway())); + + test(compObj.ice_secure(true).equals(compObj.ice_secure(true))); + test(!compObj.ice_secure(false).equals(compObj.ice_secure(true))); + + test(compObj.ice_connectionCached(true).equals(compObj.ice_connectionCached(true))); + test(!compObj.ice_connectionCached(false).equals(compObj.ice_connectionCached(true))); + + test(compObj.ice_endpointSelection(Ice.EndpointSelectionType.Random).equals( + compObj.ice_endpointSelection(Ice.EndpointSelectionType.Random))); + test(!compObj.ice_endpointSelection(Ice.EndpointSelectionType.Random).equals( + compObj.ice_endpointSelection(Ice.EndpointSelectionType.Ordered))); + + test(compObj.ice_connectionId("id2").equals(compObj.ice_connectionId("id2"))); + test(!compObj.ice_connectionId("id1").equals(compObj.ice_connectionId("id2"))); + + test(compObj.ice_connectionId("id1").ice_getConnectionId() === "id1"); + test(compObj.ice_connectionId("id2").ice_getConnectionId() === "id2"); + + test(compObj.ice_timeout(20).equals(compObj.ice_timeout(20))); + test(!compObj.ice_timeout(10).equals(compObj.ice_timeout(20))); + + test(compObj.ice_getTimeout() === undefined); + test(compObj.ice_timeout(10).ice_getTimeout() == 10); + test(compObj.ice_timeout(20).ice_getTimeout() == 20); + + const loc1 = Ice.LocatorPrx.uncheckedCast(communicator.stringToProxy("loc1:default -p 10000")); + const loc2 = Ice.LocatorPrx.uncheckedCast(communicator.stringToProxy("loc2:default -p 10000")); + test(compObj.ice_locator(null).equals(compObj.ice_locator(null))); + test(compObj.ice_locator(loc1).equals(compObj.ice_locator(loc1))); + test(!compObj.ice_locator(loc1).equals(compObj.ice_locator(null))); + test(!compObj.ice_locator(null).equals(compObj.ice_locator(loc2))); + test(!compObj.ice_locator(loc1).equals(compObj.ice_locator(loc2))); + + const rtr1 = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("rtr1:default -p 10000")); + const rtr2 = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("rtr2:default -p 10000")); + test(compObj.ice_router(null).equals(compObj.ice_router(null))); + test(compObj.ice_router(rtr1).equals(compObj.ice_router(rtr1))); + test(!compObj.ice_router(rtr1).equals(compObj.ice_router(null))); + test(!compObj.ice_router(null).equals(compObj.ice_router(rtr2))); + test(!compObj.ice_router(rtr1).equals(compObj.ice_router(rtr2))); + + const ctx1 = new Map(); + ctx1.set("ctx1", "v1"); + const ctx2 = new Map(); + ctx2.set("ctx2", "v2"); + test(compObj.ice_context(null).equals(compObj.ice_context(null))); + test(compObj.ice_context(ctx1).equals(compObj.ice_context(ctx1))); + test(!compObj.ice_context(ctx1).equals(compObj.ice_context(null))); + test(!compObj.ice_context(null).equals(compObj.ice_context(ctx2))); + test(!compObj.ice_context(ctx1).equals(compObj.ice_context(ctx2))); + + test(compObj.ice_preferSecure(true).equals(compObj.ice_preferSecure(true))); + test(!compObj.ice_preferSecure(true).equals(compObj.ice_preferSecure(false))); + + let compObj1 = communicator.stringToProxy("foo:" + defaultProtocol + " -h 127.0.0.1 -p 10000"); + let compObj2 = communicator.stringToProxy("foo:" + defaultProtocol + " -h 127.0.0.1 -p 10001"); + test(!compObj1.equals(compObj2)); + + compObj1 = communicator.stringToProxy("foo@MyAdapter1"); + compObj2 = communicator.stringToProxy("foo@MyAdapter2"); + test(!compObj1.equals(compObj2)); + + test(compObj1.ice_locatorCacheTimeout(20).equals(compObj1.ice_locatorCacheTimeout(20))); + test(!compObj1.ice_locatorCacheTimeout(10).equals(compObj1.ice_locatorCacheTimeout(20))); + + test(compObj1.ice_invocationTimeout(20).equals(compObj1.ice_invocationTimeout(20))); + test(!compObj1.ice_invocationTimeout(10).equals(compObj1.ice_invocationTimeout(20))); + + compObj1 = communicator.stringToProxy("foo:" + defaultProtocol + " -h 127.0.0.1 -p 1000"); + compObj2 = communicator.stringToProxy("foo@MyAdapter1"); + test(!compObj1.equals(compObj2)); + + const endpts1 = + communicator.stringToProxy(`foo:${defaultProtocol} -h 127.0.0.1 -p 10000`).ice_getEndpoints(); + const endpts2 = + communicator.stringToProxy(`foo:${defaultProtocol} -h 127.0.0.1 -p 10001`).ice_getEndpoints(); + test(!endpts1[0].equals(endpts2[0])); + test(endpts1[0].equals( + communicator.stringToProxy(`foo:${defaultProtocol} -h 127.0.0.1 -p 10000`).ice_getEndpoints()[0])); + + test(compObj1.ice_encodingVersion(Ice.Encoding_1_0).equals(compObj1.ice_encodingVersion(Ice.Encoding_1_0))); + test(!compObj1.ice_encodingVersion(Ice.Encoding_1_0).equals( + compObj1.ice_encodingVersion(Ice.Encoding_1_1))); + + const baseConnection = await base.ice_getConnection(); + if(baseConnection !== null) + { + const baseConnection2 = await base.ice_connectionId("base2").ice_getConnection(); + compObj1 = compObj1.ice_fixed(baseConnection); + compObj2 = compObj2.ice_fixed(baseConnection2); + test(!compObj1.equals(compObj2)); + } + out.writeLine("ok"); + + out.write("testing checked cast... "); + const cl = await Test.MyClassPrx.checkedCast(base); + test(cl !== null); + let derived = await Test.MyDerivedClassPrx.checkedCast(cl); + test(derived !== null); + test(cl.equals(base)); + test(derived.equals(base)); + test(cl.equals(derived)); + out.writeLine("ok"); + + out.write("testing checked cast with context... "); + let c = await cl.getContext(); + test(c === null || c.size == 0); + c = new Map(); + c.set("one", "hello"); + c.set("two", "world"); + const clc = await Test.MyClassPrx.checkedCast(base, undefined, c); + const c2 = await clc.getContext(); + test(Ice.MapUtil.equals(c, c2)); + out.writeLine("ok"); + + out.write("testing ice_fixed... "); + { + const connection = await cl.ice_getConnection(); + if(connection !== null) + { + await cl.ice_fixed(connection).getContext(); + test(cl.ice_secure(true).ice_fixed(connection).ice_isSecure()); + test(cl.ice_facet("facet").ice_fixed(connection).ice_getFacet() == "facet"); + test(cl.ice_oneway().ice_fixed(connection).ice_isOneway()); + const ctx = new Map(); + ctx.set("one", "hello"); + ctx.set("two", "world"); + test(cl.ice_fixed(connection).ice_getContext().size == 0); + test(cl.ice_context(ctx).ice_fixed(connection).ice_getContext().size == 2); + test(cl.ice_fixed(connection).ice_getInvocationTimeout() == -1); + test(cl.ice_invocationTimeout(10).ice_fixed(connection).ice_getInvocationTimeout() == 10); + test(await cl.ice_fixed(connection).ice_getConnection() == connection); + test(await cl.ice_fixed(connection).ice_fixed(connection).ice_getConnection() == connection); + test(cl.ice_fixed(connection).ice_getTimeout() === undefined); + const fixedConnection = await cl.ice_connectionId("ice_fixed").ice_getConnection(); + test(await cl.ice_fixed(connection).ice_fixed(fixedConnection).ice_getConnection() == + fixedConnection); + try + { + await cl.ice_secure(!connection.getEndpoint().getInfo().secure()).ice_fixed(connection).ice_ping(); + } + catch(ex) + { + test(ex instanceof Ice.NoEndpointException); + } + try + { + await cl.ice_datagram().ice_fixed(connection).ice_ping(); + } + catch(ex) + { + test(ex instanceof Ice.NoEndpointException); + } + + } + else + { + try + { + cl.ice_fixed(connection); + test(false); + } + catch(ex) + { + // Expected with null connection. + } + } + } + out.writeLine("ok"); + + out.write("testing encoding versioning... "); + + let ref20 = "test -e 2.0:" + this.getTestEndpoint(); + let cl20 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref20)); + try + { + await cl20.ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnsupportedEncodingException, ex); + } + + let ref10 = "test -e 1.0:" + this.getTestEndpoint(); + let cl10 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref10)); + + await cl10.ice_ping(); + await cl10.ice_encodingVersion(Ice.Encoding_1_0).ice_ping(); + await cl.ice_encodingVersion(Ice.Encoding_1_0).ice_ping(); + + // 1.3 isn't supported but since a 1.3 proxy supports 1.1, the + // call will use the 1.1 encoding + let ref13 = "test -e 1.3:" + this.getTestEndpoint(); + let cl13 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref13)); + await cl13.ice_ping(); + + // TODO port ice_invoke test + out.writeLine("ok"); + + out.write("testing protocol versioning... "); + ref20 = "test -p 2.0:" + this.getTestEndpoint(); + cl20 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref20)); + try + { + await cl20.ice_ping(); + test(false); + } + catch(ex) + { + // Server 2.0 proxy doesn't support 1.0 version. + test(ex instanceof Ice.UnsupportedProtocolException, ex); + } + + ref10 = "test -p 1.0:" + this.getTestEndpoint(); + cl10 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref10)); + await cl10.ice_ping(); + + // 1.3 isn't supported but since a 1.3 proxy supports 1.1, the + // call will use the 1.1 protocol + ref13 = "test -p 1.3:" + this.getTestEndpoint(); + cl13 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref13)); + await cl13.ice_ping(); + out.writeLine("ok"); + + out.write("testing opaque endpoints... "); + + try + { + // Invalid -x option + communicator.stringToProxy("id:opaque -t 99 -v abc -x abc"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Missing -t and -v + communicator.stringToProxy("id:opaque"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Repeated -t + communicator.stringToProxy("id:opaque -t 1 -t 1 -v abc"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Repeated -v + communicator.stringToProxy("id:opaque -t 1 -v abc -v abc"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Missing -t + communicator.stringToProxy("id:opaque -v abc"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Missing -v + communicator.stringToProxy("id:opaque -t 1"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Missing arg for -t + communicator.stringToProxy("id:opaque -t -v abc"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Missing arg for -v + communicator.stringToProxy("id:opaque -t 1 -v"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Not a number for -t + communicator.stringToProxy("id:opaque -t x -v abc"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // < 0 for -t + communicator.stringToProxy("id:opaque -t -1 -v abc"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + try + { + // Invalid char for -v + communicator.stringToProxy("id:opaque -t 99 -v x?c"); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.EndpointParseException, ex); + } + + // Legal TCP endpoint expressed as opaque endpoint + let p1 = communicator.stringToProxy("test -e 1.1:opaque -e 1.0 -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA=="); + let pstr = communicator.proxyToString(p1); + test(pstr === "test -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 10000"); + + // Legal WS endpoint expressed as opaque endpoint + p1 = communicator.stringToProxy("test -e 1.1:opaque -t 4 -e 1.0 -v CTEyNy4wLjAuMeouAAAQJwAAAAA="); + pstr = communicator.proxyToString(p1); + test(pstr === "test -t -e 1.1:ws -h 127.0.0.1 -p 12010 -t 10000"); + + // Opaque endpoint encoded with 1.1 encoding. + + let p2 = communicator.stringToProxy("test:opaque -e 1.1 -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA=="); + test(communicator.proxyToString(p2) === "test -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 10000"); + + p2 = communicator.stringToProxy("test:opaque -e 1.1 -t 4 -v CTEyNy4wLjAuMeouAAAQJwAAAAA="); + test(communicator.proxyToString(p2) === "test -t -e 1.1:ws -h 127.0.0.1 -p 12010 -t 10000"); + + if(communicator.getProperties().getPropertyAsInt("Ice.IPv6") === 0) + { + const ref = "test:" + this.getTestEndpoint(); + + const ssl = communicator.getProperties().getProperty("Ice.Default.Protocol") === "ssl"; + // TODO: p1 contains 127.0.0.1 - OK to invoke? + // if(!ssl) + // { + // p1.ice_encodingVersion(Ice.Util.Encoding_1_0).ice_ping(); + // } + + // Two legal TCP endpoints expressed as opaque endpoints + p1 = communicator.stringToProxy("test -e 1.0:opaque -e 1.0 -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==:opaque -e 1.0 -t 1 -v CTEyNy4wLjAuMusuAAAQJwAAAA=="); + pstr = communicator.proxyToString(p1); + test(pstr === "test -t -e 1.0:tcp -h 127.0.0.1 -p 12010 -t 10000:tcp -h 127.0.0.2 -p 12011 -t 10000"); + + p1 = communicator.stringToProxy("test -e 1.0:opaque -t 4 -e 1.0 -v CTEyNy4wLjAuMeouAAAQJwAAAAA=:opaque -t 4 -e 1.0 -v CTEyNy4wLjAuMusuAAAQJwAAAAA="); + pstr = communicator.proxyToString(p1); + test(pstr === "test -t -e 1.0:ws -h 127.0.0.1 -p 12010 -t 10000:ws -h 127.0.0.2 -p 12011 -t 10000"); + + // + // Test that an SSL endpoint and a nonsense endpoint get + // written back out as an opaque endpoint. + // + p1 = communicator.stringToProxy("test -e 1.0:opaque -e 1.0 -t 2 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -e 1.0 -v abch"); + pstr = communicator.proxyToString(p1); + test(pstr === "test -t -e 1.0:ssl -h 127.0.0.1 -p 10001 -t infinite:opaque -t 99 -e 1.0 -v abch"); + + // + // Try to invoke on the SSL endpoint to verify that we get a + // NoEndpointException (or ConnectFailedException when + // running with SSL). + // + try + { + await p1.ice_encodingVersion(Ice.Encoding_1_0).ice_ping(); + test(false); + } + catch(ex) + { + if(ex instanceof Ice.NoEndpointException) + { + test(!ssl); + } + else if(ex instanceof Ice.ConnectFailedException) + { + test(ssl); + } + else + { + throw ex; + } + } + // + // Test that the proxy with an SSL endpoint and a nonsense + // endpoint (which the server doesn't understand either) can + // be sent over the wire and returned by the server without + // losing the opaque endpoints. + // + derived = Test.MyDerivedClassPrx.uncheckedCast( + communicator.stringToProxy("test -e 1.0:" + this.getTestEndpoint())); + p2 = await derived.echo(p1); + + pstr = communicator.proxyToString(p2); + test(pstr === "test -t -e 1.0:ssl -h 127.0.0.1 -p 10001 -t infinite:opaque -t 99 -e 1.0 -v abch"); + + let p = communicator.stringToProxy("test:" + this.getTestEndpoint()); + if(defaultProtocol === "tcp") + { + test(p.ice_getEndpoints()[0].getInfo() instanceof Ice.TCPEndpointInfo); + } + else if(defaultProtocol === "ws" || defaultProtocol === "wss") + { + test(p.ice_getEndpoints()[0].getInfo() instanceof Ice.WSEndpointInfo); + } + + let con = await p.ice_getConnection(); + if(defaultProtocol === "tcp") + { + test(con.getInfo() instanceof Ice.TCPConnectionInfo); + } + else if(defaultProtocol === "ws" || defaultProtocol === "wss") + { + test(con.getInfo() instanceof Ice.WSConnectionInfo); + } + + // + // Ensure that non connectable endpoints are skipped. + // + p = communicator.stringToProxy("test:" + this.getTestEndpoint("ws") + ":" + this.getTestEndpoint()); + + p = p.ice_endpointSelection(Ice.EndpointSelectionType.Ordered); + await p.ice_ping(); + + out.writeLine("ok"); + + out.write("testing proxyToString... "); + b1 = communicator.stringToProxy(ref); + let b2 = communicator.stringToProxy(communicator.proxyToString(b1)); + test(b1.equals(b2)); + + con = await b1.ice_getConnection(); + b2 = con.createProxy(Ice.stringToIdentity("fixed")); + const str = communicator.proxyToString(b2); + test(b2.toString() === str); + const str2 = b1.ice_identity(b2.ice_getIdentity()).ice_secure(b2.ice_isSecure()).toString(); + + // Verify that the stringified fixed proxy is the same as a regular stringified proxy + // but without endpoints + test(str2.startsWith(str)); + test(str2.charAt(str.length) === ':'); + + out.writeLine("ok"); + + if(defaultProtocol === "ws" || defaultProtocol === "wss") + { + out.write("testing ping invalid WS proxies... "); + // + // Invocation in a WS or WSS proxy that has not hostname set + // will fail creating the WebSocket object. + // + const communicator2 = Ice.initialize(); + const invalid = communicator2.stringToProxy("test:" + this.getTestEndpoint()); + try + { + await invalid.ice_ping(); + test(false); + } + catch(ex) + { + // expected + } + finally + { + await communicator2.destroy(); + } + out.writeLine("ok"); + } + + out.write("testing communicator shutdown/destroy... "); + { + const c = Ice.initialize(); + c.shutdown(); + test(c.isShutdown()); + await c.waitForShutdown(); + await c.destroy(); + c.shutdown(); + test(c.isShutdown()); + await c.waitForShutdown(); + await c.destroy(); + } + out.writeLine("ok"); + + derived = Test.MyDerivedClassPrx.uncheckedCast( + communicator.stringToProxy("test:" + this.getTestEndpoint())); + await derived.shutdown(); + } + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/proxy/Test.ice b/js/test/ts/Ice/proxy/Test.ice new file mode 100644 index 00000000000..f6a3233d3cf --- /dev/null +++ b/js/test/ts/Ice/proxy/Test.ice @@ -0,0 +1,29 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Current.ice> + +module Test +{ + +interface MyClass +{ + void shutdown(); + + Ice::Context getContext(); +} + +interface MyDerivedClass extends MyClass +{ + Object* echo(Object* obj); +} + +} diff --git a/js/test/ts/Ice/retry/Client.ts b/js/test/ts/Ice/retry/Client.ts new file mode 100644 index 00000000000..ab29719b1ed --- /dev/null +++ b/js/test/ts/Ice/retry/Client.ts @@ -0,0 +1,137 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests(communicator:Ice.Communicator, communicator2:Ice.Communicator) + { + const out = this.getWriter(); + out.write("testing stringToProxy... "); + const ref = "retry:" + this.getTestEndpoint(); + const base1 = communicator.stringToProxy(ref); + test(base1 !== null); + const base2 = communicator.stringToProxy(ref); + test(base2 !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + const retry1 = await Test.RetryPrx.checkedCast(base1); + test(retry1 !== null); + test(retry1.equals(base1)); + let retry2 = await Test.RetryPrx.checkedCast(base2); + test(retry2 !== null); + test(retry2.equals(base2)); + out.writeLine("ok"); + + out.write("calling regular operation with first proxy... "); + await retry1.op(false); + out.writeLine("ok"); + + out.write("calling operation to kill connection with second proxy... "); + try + { + await retry2.op(true); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ConnectionLostException, ex); + out.writeLine("ok"); + } + + out.write("calling regular operation with first proxy again... "); + await retry1.op(false); + out.writeLine("ok"); + + out.write("testing idempotent operation... "); + const count = await retry1.opIdempotent(4); + test(count === 4); + out.writeLine("ok"); + + out.write("testing non-idempotent operation... "); + try + { + await retry1.opNotIdempotent(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.LocalException, ex); + } + out.writeLine("ok"); + + out.write("testing invocation timeout and retries... "); + retry2 = Test.RetryPrx.uncheckedCast(communicator2.stringToProxy(retry1.toString())); + try + { + await retry2.ice_invocationTimeout(500).opIdempotent(4); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.InvocationTimeoutException, ex); + } + + await retry2.opIdempotent(-1); + out.writeLine("ok"); + + await retry1.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + let communicator2:Ice.Communicator; + try + { + let [properties] = this.createTestProperties(args); + + // + // For this test, we want to disable retries. + // + properties.setProperty("Ice.RetryIntervals", "0 1 10 1"); + + // + // We don't want connection warnings because of the timeout + // + properties.setProperty("Ice.Warn.Connections", "0"); + + [communicator] = this.initialize(properties); + + // + // Configure a second communicator for the invocation timeout + // + retry test, we need to configure a large retry interval + // to avoid time-sensitive failures. + // + properties = communicator.getProperties().clone(); + properties.setProperty("Ice.RetryIntervals", "0 1 10000"); + [communicator2] = this.initialize(properties); + + await this.allTests(communicator, communicator2); + } + finally + { + if(communicator2) + { + await communicator2.destroy(); + } + + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/retry/Test.ice b/js/test/ts/Ice/retry/Test.ice new file mode 100644 index 00000000000..25059836e84 --- /dev/null +++ b/js/test/ts/Ice/retry/Test.ice @@ -0,0 +1,26 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface Retry +{ + void op(bool kill); + + idempotent int opIdempotent(int c); + void opNotIdempotent(); + void opSystemException(); + + idempotent void shutdown(); +} + +} diff --git a/js/test/ts/Ice/scope/Client.ts b/js/test/ts/Ice/scope/Client.ts new file mode 100644 index 00000000000..d733301e57c --- /dev/null +++ b/js/test/ts/Ice/scope/Client.ts @@ -0,0 +1,185 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test, Inner} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + const out = this.getWriter(); + const communicator = this.communicator(); + + out.write("test same Slice type name in different scopes... "); + + { + const i1 = await Test.IPrx.checkedCast(communicator.stringToProxy("i1:" + this.getTestEndpoint())); + const s1 = new Test.S(0); + + const [s2, s3] = await i1.opS(s1); + test(s2.equals(s1)); + test(s3.equals(s1)); + + const [sseq2, sseq3] = await i1.opSSeq([s1]); + test(sseq2[0].equals(s1)); + test(sseq3[0].equals(s1)); + + const smap1 = new Map([["a", s1]]); + const [smap2, smap3] = await i1.opSMap(smap1); + test(smap2.get("a").equals(s1)); + test(smap3.get("a").equals(s1)); + + const c1 = new Test.C(s1); + + const [c2, c3] = await i1.opC(c1); + test(c2.s.equals(s1)); + test(c3.s.equals(s1)); + + const [cseq2, cseq3] = await i1.opCSeq([c1]); + test(cseq2[0].s.equals(s1)); + test(cseq3[0].s.equals(s1)); + + const cmap1 = new Map([["a", c1]]); + const [cmap2, cmap3] = await i1.opCMap(cmap1); + test(cmap2.get("a").s.equals(s1)); + test(cmap3.get("a").s.equals(s1)); + } + + { + const i2 = await Test.Inner.Inner2.IPrx.checkedCast( + communicator.stringToProxy("i2:" + this.getTestEndpoint())); + const s1 = new Test.Inner.Inner2.S(0); + + const [s2, s3] = await i2.opS(s1); + test(s2.equals(s1)); + test(s3.equals(s1)); + + const [sseq2, sseq3] = await i2.opSSeq([s1]); + test(sseq2[0].equals(s1)); + test(sseq3[0].equals(s1)); + + const smap1 = new Map([["a", s1]]); + const [smap2, smap3] = await i2.opSMap(smap1); + test(smap2.get("a").equals(s1)); + test(smap3.get("a").equals(s1)); + + const c1 = new Test.Inner.Inner2.C(s1); + + const [c2, c3] = await i2.opC(c1); + test(c2.s.equals(s1)); + test(c3.s.equals(s1)); + + const [cseq2, cseq3] = await i2.opCSeq([c1]); + test(cseq2[0].s.equals(s1)); + test(cseq3[0].s.equals(s1)); + + const cmap1 = new Map([["a", c1]]); + const [cmap2, cmap3] = await i2.opCMap(cmap1); + test(cmap2.get("a").s.equals(s1)); + test(cmap3.get("a").s.equals(s1)); + } + + { + const i3 = await Test.Inner.IPrx.checkedCast( + communicator.stringToProxy("i3:" + this.getTestEndpoint())); + const s1 = new Test.Inner.Inner2.S(0); + + const [s2, s3] = await i3.opS(s1); + test(s2.equals(s1)); + test(s3.equals(s1)); + + const [sseq2, sseq3] = await i3.opSSeq([s1]); + test(sseq2[0].equals(s1)); + test(sseq3[0].equals(s1)); + + const smap1 = new Map([["a", s1]]); + const [smap2, smap3] = await i3.opSMap(smap1); + test(smap2.get("a").equals(s1)); + test(smap3.get("a").equals(s1)); + + const c1 = new Test.Inner.Inner2.C(s1); + + const [c2, c3] = await i3.opC(c1); + test(c2.s.equals(s1)); + test(c3.s.equals(s1)); + + const [cseq2, cseq3] = await i3.opCSeq([c1]); + test(cseq2[0].s.equals(s1)); + test(cseq3[0].s.equals(s1)); + + const cmap1 = new Map([["a", c1]]); + const [cmap2, cmap3] = await i3.opCMap(cmap1); + test(cmap2.get("a").s.equals(s1)); + test(cmap3.get("a").s.equals(s1)); + } + + { + const i4 = await Inner.Test.Inner2.IPrx.checkedCast( + communicator.stringToProxy("i4:" + this.getTestEndpoint())); + const s1 = new Test.S(0); + + const [s2, s3] = await i4.opS(s1); + test(s2.equals(s1)); + test(s3.equals(s1)); + + const [sseq2, sseq3] = await i4.opSSeq([s1]); + test(sseq2[0].equals(s1)); + test(sseq3[0].equals(s1)); + + const smap1 = new Map([["a", s1]]); + const [smap2, smap3] = await i4.opSMap(smap1); + test(smap2.get("a").equals(s1)); + test(smap3.get("a").equals(s1)); + + const c1 = new Test.C(s1); + + const [c2, c3] = await i4.opC(c1); + test(c2.s.equals(s1)); + test(c3.s.equals(s1)); + + const [cseq2, cseq3] = await i4.opCSeq([c1]); + test(cseq2[0].s.equals(s1)); + test(cseq3[0].s.equals(s1)); + + const cmap1 = new Map([["a", c1]]); + const [cmap2, cmap3] = await i4.opCMap(cmap1); + test(cmap2.get("a").s.equals(s1)); + test(cmap3.get("a").s.equals(s1)); + } + + { + const i1 = await Test.IPrx.checkedCast(communicator.stringToProxy("i1:" + this.getTestEndpoint())); + await i1.shutdown(); + } + + out.writeLine("ok"); + } + + async run(args:string[]) + { + let x; + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/scope/Test.ice b/js/test/ts/Ice/scope/Test.ice new file mode 100644 index 00000000000..e40116886d3 --- /dev/null +++ b/js/test/ts/Ice/scope/Test.ice @@ -0,0 +1,141 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + struct S + { + int v; + } + + dictionary<string, S> SMap; + sequence<S> SSeq; + + class C + { + S s; + } + + dictionary<string, C> CMap; + sequence<C> CSeq; + + interface I + { + S opS(S s1, out S s2); + SSeq opSSeq(SSeq s1, out SSeq s2); + SMap opSMap(SMap s1, out SMap s2); + + C opC(C c1, out C c2); + CSeq opCSeq(CSeq s1, out CSeq s2); + CMap opCMap(CMap c1, out CMap c2); + + void shutdown(); + } + + dictionary<string, I*> IMap; + sequence<I*> ISeq; + + module Inner + { + struct S + { + int v; + } + + module Inner2 + { + struct S + { + int v; + } + + dictionary<string, S> SMap; + sequence<S> SSeq; + + class C + { + S s; + } + + dictionary<string, C> CMap; + sequence<C> CSeq; + + interface I + { + S opS(S s1, out S s2); + SSeq opSSeq(SSeq s1, out SSeq s2); + SMap opSMap(SMap s1, out SMap s2); + + C opC(C c1, out C c2); + CSeq opCSeq(CSeq c1, out CSeq c2); + CMap opCMap(CMap c1, out CMap c2); + + void shutdown(); + } + + dictionary<string, I*> IMap; + sequence<I*> ISeq; + } + + class C + { + S s; + } + + sequence<Inner2::S> SSeq; + dictionary<string, Inner2::S> SMap; + + dictionary<string, Inner2::C> CMap; + sequence<Inner2::C> CSeq; + + interface I + { + Inner2::S opS(Inner2::S s1, out Inner2::S s2); + Inner2::SSeq opSSeq(Inner2::SSeq s1, out Inner2::SSeq s2); + Inner2::SMap opSMap(Inner2::SMap s1, out Inner2::SMap s2); + + Inner2::C opC(Inner2::C c1, out Inner2::C c2); + Inner2::CSeq opCSeq(Inner2::CSeq c1, out Inner2::CSeq c2); + Inner2::CMap opCMap(Inner2::CMap c1, out Inner2::CMap c2); + + void shutdown(); + } + + dictionary<string, I*> IMap; + sequence<I*> ISeq; + } +} + +module Inner +{ + +module Test +{ + +module Inner2 +{ + interface I + { + Test::S opS(Test::S s1, out Test::S s2); + Test::SSeq opSSeq(Test::SSeq s1, out Test::SSeq s2); + Test::SMap opSMap(Test::SMap s1, out Test::SMap s2); + + Test::C opC(Test::C c1, out Test::C c2); + Test::CSeq opCSeq(Test::CSeq c1, out Test::CSeq c2); + Test::CMap opCMap(Test::CMap c1, out Test::CMap c2); + + void shutdown(); + } +} + +} + +} diff --git a/js/test/ts/Ice/servantLocator/Client.ts b/js/test/ts/Ice/servantLocator/Client.ts new file mode 100644 index 00000000000..e4e9e725c1c --- /dev/null +++ b/js/test/ts/Ice/servantLocator/Client.ts @@ -0,0 +1,316 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + async function testExceptions(obj:Test.TestIntfPrx) + { + try + { + await obj.requestFailedException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectNotExistException, ex); + test(ex.id.equals(obj.ice_getIdentity())); + test(ex.facet == obj.ice_getFacet()); + test(ex.operation == "requestFailedException"); + } + + try + { + await obj.unknownUserException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownUserException, ex); + test(ex.unknown == "reason"); + } + + try + { + await obj.unknownLocalException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownLocalException, ex); + test(ex.unknown == "reason"); + } + + try + { + await obj.unknownException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownException, ex); + test(ex.unknown == "reason"); + } + + try + { + await obj.userException(); + test(false); + } + catch(ex) + { + test((ex instanceof Ice.OperationNotExistException) || + (ex instanceof Ice.UnknownUserException && + ex.unknown == "::Test::TestIntfUserException"), ex); + } + + console.log("localException"); + try + { + await obj.localException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownLocalException, ex); + test(ex.unknown.indexOf("Ice::SocketException") >= 0 || + ex.unknown.indexOf("Ice.SocketException") >= 0); + } + console.log("localException ok"); + + console.log("jsException"); + try + { + await obj.jsException(); + test(false); + } + catch(ex) + { + test((ex instanceof Ice.OperationNotExistException) || + (ex instanceof Ice.UnknownException || ex.unknown.indexOf("") >= 0), ex); + } + console.log("jsException ok"); + + try + { + await obj.unknownExceptionWithServantException(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownException, ex); + test(ex.unknown == "reason"); + } + + try + { + await obj.impossibleException(false); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownUserException, ex); + } + + try + { + await obj.impossibleException(true); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownUserException, ex); + } + + try + { + await obj.intfUserException(false); + test(false); + } + catch(ex) + { + test(ex instanceof Test.TestImpossibleException, ex); + } + + try + { + await obj.intfUserException(true); + test(false); + } + catch(ex) + { + test(ex instanceof Test.TestImpossibleException, ex); + } + } + + const out = this.getWriter(); + const communicator = this.communicator(); + out.write("testing stringToProxy... "); + const ref = "asm:" + this.getTestEndpoint(); + let base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + let obj = await Test.TestIntfPrx.checkedCast(base); + test(obj !== null); + test(obj.equals(base)); + out.writeLine("ok"); + + out.write("testing ice_ids... "); + try + { + const o = communicator.stringToProxy("category/locate:" + this.getTestEndpoint()); + await o.ice_ids(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownUserException && ex.unknown == "::Test::TestIntfUserException", ex); + } + + try + { + const o = communicator.stringToProxy("category/finished:" + this.getTestEndpoint()); + await o.ice_ids(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnknownUserException && ex.unknown == "::Test::TestIntfUserException", ex); + } + out.writeLine("ok"); + + out.write("testing servant locator... "); + base = communicator.stringToProxy("category/locate:" + this.getTestEndpoint()); + obj = await Test.TestIntfPrx.checkedCast(base); + + try + { + await Test.TestIntfPrx.checkedCast( + communicator.stringToProxy("category/unknown:" + this.getTestEndpoint())); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectNotExistException, ex); + } + out.writeLine("ok"); + + out.write("testing default servant locator... "); + base = communicator.stringToProxy("anothercat/locate:" + this.getTestEndpoint()); + obj = await Test.TestIntfPrx.checkedCast(base); + base = communicator.stringToProxy("locate:" + this.getTestEndpoint()); + obj = await Test.TestIntfPrx.checkedCast(base); + try + { + await Test.TestIntfPrx.checkedCast( + communicator.stringToProxy("anothercat/unknown:" + this.getTestEndpoint())); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectNotExistException, ex); + } + + try + { + await Test.TestIntfPrx.checkedCast(communicator.stringToProxy("unknown:" + this.getTestEndpoint())); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectNotExistException, ex); + } + out.writeLine("ok"); + + out.write("testing locate exceptions... "); + base = communicator.stringToProxy("category/locate:" + this.getTestEndpoint()); + obj = await Test.TestIntfPrx.checkedCast(base); + await testExceptions(obj); + out.writeLine("ok"); + + out.write("testing finished exceptions... "); + base = communicator.stringToProxy("category/finished:" + this.getTestEndpoint()); + obj = await Test.TestIntfPrx.checkedCast(base); + await testExceptions(obj); + + try + { + // + // Only call these for category/finished. + // + await obj.asyncResponse(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.TestImpossibleException, ex); // Called by finished(). + } + + try + { + await obj.asyncException(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.TestImpossibleException, ex); // Called by finished(). + } + out.writeLine("ok"); + + out.write("testing servant locator removal... "); + base = communicator.stringToProxy("test/activation:" + this.getTestEndpoint()); + const activation = await Test.TestActivationPrx.checkedCast(base); + await activation.activateServantLocator(false); + try + { + await obj.ice_ping(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ObjectNotExistException, ex); + } + out.writeLine("ok"); + + out.write("testing servant locator addition... "); + await activation.activateServantLocator(true); + await obj.ice_ping(); + out.writeLine("ok"); + + out.write("shuting down server...") + await obj.shutdown(); + out.writeLine("ok"); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/servantLocator/ServantLocatorI.ts b/js/test/ts/Ice/servantLocator/ServantLocatorI.ts new file mode 100644 index 00000000000..fa2e251e3c6 --- /dev/null +++ b/js/test/ts/Ice/servantLocator/ServantLocatorI.ts @@ -0,0 +1,151 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestI} from "./TestI"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; + +class MyError +{ +} + +class CookieI +{ + message() + { + return "blahblah"; + } +} + +export class ServantLocatorI implements Ice.ServantLocator +{ + constructor(category:string) + { + this._category = category; + this._deactivated = false; + this._requestId = -1; + } + + locate(current:Ice.Current, cookie:Ice.Holder<Object>):Ice.Object + { + test(!this._deactivated); + + test(current.id.category == this._category || this._category.length == 0); + + if(current.id.name == "unknown") + { + return null; + } + + test(current.id.name == "locate" || current.id.name == "finished"); + if(current.id.name == "locate") + { + this.exception(current); + } + + // + // Ensure locate() is only called once per request. + // + test(this._requestId == -1); + this._requestId = current.requestId; + cookie.value = new CookieI(); + return new TestI(); + } + + finished(current:Ice.Current, servant:Ice.Object, cookie:Object):void + { + console.log("finished", new Error().stack); + test(!this._deactivated); + + // + // Ensure finished() is only called once per request. + // + test(this._requestId == current.requestId); + this._requestId = -1; + + test(current.id.category == this._category || this._category.length == 0); + test(current.id.name == "locate" || current.id.name == "finished"); + + if(current.id.name == "finished") + { + this.exception(current); + } + + test((cookie as CookieI).message() == "blahblah"); + } + + deactivate(category:string):void + { + test(!this._deactivated); + this._deactivated = true; + } + + exception(current:Ice.Current):void + { + if(current.operation == "ice_ids") + { + throw new Test.TestIntfUserException(); + } + else if(current.operation == "requestFailedException") + { + throw new Ice.ObjectNotExistException(); + } + else if(current.operation == "unknownUserException") + { + throw new Ice.UnknownUserException("reason"); + } + else if(current.operation == "unknownLocalException") + { + throw new Ice.UnknownLocalException("reason"); + } + else if(current.operation == "unknownException") + { + throw new Ice.UnknownException("reason"); + } + else if(current.operation == "userException") + { + throw new Test.TestIntfUserException(); + } + else if(current.operation == "localException") + { + throw new Ice.SocketException(0); + } + else if(current.operation == "jsException") + { + throw new MyError(); + } + else if(current.operation == "unknownExceptionWithServantException") + { + throw new Ice.UnknownException("reason"); + } + else if(current.operation == "impossibleException") + { + throw new Test.TestIntfUserException(); // Yes, it really is meant to be TestIntfUserException. + } + else if(current.operation == "intfUserException") + { + throw new Test.TestImpossibleException(); // Yes, it really is meant to be TestImpossibleException. + } + else if(current.operation == "asyncResponse") + { + throw new Test.TestImpossibleException(); + } + else if(current.operation == "asyncException") + { + throw new Test.TestImpossibleException(); + } + } + + _category:string; + _deactivated:boolean; + _requestId:number; +} diff --git a/js/test/ts/Ice/servantLocator/Server.ts b/js/test/ts/Ice/servantLocator/Server.ts new file mode 100644 index 00000000000..68279e674a4 --- /dev/null +++ b/js/test/ts/Ice/servantLocator/Server.ts @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; +import {TestI} from "./TestI"; +import {TestActivationI} from "./TestActivationI"; +import {ServantLocatorI} from "./ServantLocatorI"; + +export class Server extends TestHelper +{ + async run(args:string[]) + { + let communicator:Ice.Communicator; + let echo:Test.EchoPrx; + try + { + const [properties] = this.createTestProperties(args); + properties.setProperty("Ice.Warn.Dispatch", "1"); + properties.setProperty("Ice.Trace.Protocol", "1"); + [communicator] = this.initialize(properties); + + echo = await Test.EchoPrx.checkedCast(communicator.stringToProxy("__echo:" + this.getTestEndpoint())); + const adapter = await communicator.createObjectAdapter(""); + adapter.addServantLocator(new ServantLocatorI("category"), "category"); + adapter.addServantLocator(new ServantLocatorI(""), ""); + adapter.add(new TestI(), Ice.stringToIdentity("asm")); + adapter.add(new TestActivationI(), Ice.stringToIdentity("test/activation")); + await echo.setConnection(); + echo.ice_getCachedConnection().setAdapter(adapter); + this.serverReady(); + await adapter.waitForDeactivate(); + } + finally + { + if(echo) + { + await echo.shutdown(); + } + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/servantLocator/Test.ice b/js/test/ts/Ice/servantLocator/Test.ice new file mode 100644 index 00000000000..8b79c510ab6 --- /dev/null +++ b/js/test/ts/Ice/servantLocator/Test.ice @@ -0,0 +1,63 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +[["java:package:test.Ice.servantLocator"]] +module Test +{ + +exception TestIntfUserException +{ +} + +exception TestImpossibleException +{ +} + +interface TestIntf +{ + void requestFailedException(); + void unknownUserException(); + void unknownLocalException(); + void unknownException(); + void localException(); + void userException(); + void jsException(); + + void unknownExceptionWithServantException(); + + string impossibleException(bool throw) throws TestImpossibleException; + string intfUserException(bool throw) throws TestIntfUserException, TestImpossibleException; + + void asyncResponse() throws TestIntfUserException, TestImpossibleException; + void asyncException() throws TestIntfUserException, TestImpossibleException; + + void shutdown(); +} + +interface TestActivation +{ + void activateServantLocator(bool activate); +} + +local class Cookie +{ + ["cpp:const"] string message(); +} + +interface Echo +{ + void setConnection(); + void startBatch(); + void flushBatch(); + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/servantLocator/TestActivationI.ts b/js/test/ts/Ice/servantLocator/TestActivationI.ts new file mode 100644 index 00000000000..a7f4f11426d --- /dev/null +++ b/js/test/ts/Ice/servantLocator/TestActivationI.ts @@ -0,0 +1,31 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {ServantLocatorI} from "./ServantLocatorI"; + +export class TestActivationI extends Test.TestActivation +{ + activateServantLocator(activate:boolean, current:Ice.Current):void + { + if(activate) + { + current.adapter.addServantLocator(new ServantLocatorI(""), ""); + current.adapter.addServantLocator(new ServantLocatorI("category"), "category"); + } + else + { + let locator = current.adapter.removeServantLocator(""); + locator.deactivate(""); + locator = current.adapter.removeServantLocator("category"); + locator.deactivate("category"); + } + } +} diff --git a/js/test/ts/Ice/servantLocator/TestI.ts b/js/test/ts/Ice/servantLocator/TestI.ts new file mode 100644 index 00000000000..1b33b3043ff --- /dev/null +++ b/js/test/ts/Ice/servantLocator/TestI.ts @@ -0,0 +1,95 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; + +export class TestI extends Test.TestIntf +{ + requestFailedException(current:Ice.Current):void + { + } + + unknownUserException(current:Ice.Current):void + { + } + + unknownLocalException(current:Ice.Current):void + { + } + + unknownException(current:Ice.Current):void + { + } + + localException(current:Ice.Current):void + { + } + + userException(current:Ice.Current):void + { + } + + jsException(current:Ice.Current):void + { + throw new Error(); + } + + javaException(current:Ice.Current):void + { + } + + unknownExceptionWithServantException(current:Ice.Current):void + { + throw new Ice.ObjectNotExistException(); + } + + impossibleException(throwEx:boolean, current:Ice.Current):string + { + if(throwEx) + { + throw new Test.TestImpossibleException(); + } + + // + // Return a value so we can be sure that the stream position + // is reset correctly if finished() throws. + // + return "Hello"; + } + + intfUserException(throwEx:boolean, current:Ice.Current):string + { + if(throwEx) + { + throw new Test.TestIntfUserException(); + } + + // + // Return a value so we can be sure that the stream position + // is reset correctly if finished() throws. + // + return "Hello"; + } + + asyncResponse(current:Ice.Current):void + { + throw new Ice.ObjectNotExistException(); + } + + asyncException(current:Ice.Current):void + { + throw new Ice.ObjectNotExistException(); + } + + shutdown(current:Ice.Current):void + { + current.adapter.deactivate(); + } +} diff --git a/js/test/ts/Ice/slicing/exceptions/Client.ts b/js/test/ts/Ice/slicing/exceptions/Client.ts new file mode 100644 index 00000000000..985e9bdc34d --- /dev/null +++ b/js/test/ts/Ice/slicing/exceptions/Client.ts @@ -0,0 +1,328 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + const out = this.getWriter(); + const communicator = this.communicator(); + + out.write("testing stringToProxy... "); + const ref = "Test:" + this.getTestEndpoint() + " -t 10000"; + const base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + const prx = await Test.TestIntfPrx.checkedCast(base); + test(prx !== null); + test(prx.equals(base)); + out.writeLine("ok"); + + out.write("base... "); + try + { + await prx.baseAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.Base, ex); + test(ex.b == "Base.b"); + test(ex.ice_id() == "::Test::Base"); + } + out.writeLine("ok"); + + out.write("slicing of unknown derived... "); + try + { + await prx.unknownDerivedAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.Base, ex); + test(ex.b == "UnknownDerived.b"); + test(ex.ice_id() == "::Test::Base"); + } + out.writeLine("ok"); + + out.write("non-slicing of known derived as base... "); + try + { + await prx.knownDerivedAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownDerived, ex); + test(ex.b == "KnownDerived.b"); + test(ex.kd == "KnownDerived.kd"); + test(ex.ice_id() == "::Test::KnownDerived"); + } + out.writeLine("ok"); + + out.write("non-slicing of known derived as derived... "); + try + { + await prx.knownDerivedAsKnownDerived(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownDerived, ex); + test(ex.b == "KnownDerived.b"); + test(ex.kd == "KnownDerived.kd"); + test(ex.ice_id() == "::Test::KnownDerived"); + } + out.writeLine("ok"); + + out.write("slicing of unknown intermediate as base... "); + try + { + await prx.unknownIntermediateAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.Base, ex); + test(ex.b == "UnknownIntermediate.b"); + test(ex.ice_id() == "::Test::Base"); + } + out.writeLine("ok"); + + out.write("slicing of known intermediate as base... "); + try + { + await prx.knownIntermediateAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownIntermediate, ex); + test(ex.b == "KnownIntermediate.b"); + test(ex.ki == "KnownIntermediate.ki"); + test(ex.ice_id() == "::Test::KnownIntermediate"); + } + out.writeLine("ok"); + + out.write("slicing of known most derived as base... "); + try + { + await prx.knownMostDerivedAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownMostDerived, ex); + test(ex.b == "KnownMostDerived.b"); + test(ex.ki == "KnownMostDerived.ki"); + test(ex.kmd == "KnownMostDerived.kmd"); + test(ex.ice_id() == "::Test::KnownMostDerived"); + } + out.writeLine("ok"); + + out.write("non-slicing of known intermediate as intermediate... "); + try + { + await prx.knownIntermediateAsKnownIntermediate(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownIntermediate, ex); + test(ex.b == "KnownIntermediate.b"); + test(ex.ki == "KnownIntermediate.ki"); + test(ex.ice_id() == "::Test::KnownIntermediate"); + } + out.writeLine("ok"); + + out.write("non-slicing of known most derived as intermediate... "); + try + { + await prx.knownMostDerivedAsKnownIntermediate(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownMostDerived, ex); + test(ex.b == "KnownMostDerived.b"); + test(ex.ki == "KnownMostDerived.ki"); + test(ex.kmd == "KnownMostDerived.kmd"); + test(ex.ice_id() == "::Test::KnownMostDerived"); + } + out.writeLine("ok"); + + out.write("non-slicing of known most derived as most derived... "); + try + { + await prx.knownMostDerivedAsKnownMostDerived(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownMostDerived, ex); + test(ex.b == "KnownMostDerived.b"); + test(ex.ki == "KnownMostDerived.ki"); + test(ex.kmd == "KnownMostDerived.kmd"); + test(ex.ice_id() == "::Test::KnownMostDerived"); + } + out.writeLine("ok"); + + out.write("slicing of unknown most derived, known intermediate as base... "); + try + { + await prx.unknownMostDerived1AsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownIntermediate, ex); + test(ex.b == "UnknownMostDerived1.b"); + test(ex.ki == "UnknownMostDerived1.ki"); + test(ex.ice_id() == "::Test::KnownIntermediate"); + } + out.writeLine("ok"); + + out.write("slicing of unknown most derived, known intermediate as intermediate... "); + try + { + await prx.unknownMostDerived1AsKnownIntermediate(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownIntermediate, ex); + test(ex.b == "UnknownMostDerived1.b"); + test(ex.ki == "UnknownMostDerived1.ki"); + test(ex.ice_id() == "::Test::KnownIntermediate"); + } + out.writeLine("ok"); + + out.write("slicing of unknown most derived, unknown intermediate thrown as base... "); + try + { + await prx.unknownMostDerived2AsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.Base, ex); + test(ex.b == "UnknownMostDerived2.b"); + test(ex.ice_id() == "::Test::Base"); + } + out.writeLine("ok"); + + out.write("unknown most derived in compact format... "); + try + { + await prx.unknownMostDerived2AsBaseCompact(); + test(false); + } + catch(ex) + { + if(ex instanceof Test.Base) + { + // + // For the 1.0 encoding, the unknown exception is sliced to Base. + // + test(prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)); + } + else if(ex instanceof Ice.UnknownUserException) + { + // + // An UnknownUserException is raised for the compact format because the + // most-derived type is unknown and the exception cannot be sliced. + // + test(!prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)); + } + else if(ex instanceof Ice.OperationNotExistException) + { + // Ignore + } + else + { + test(false, ex); + } + } + out.writeLine("ok"); + + out.write("preserved exceptions..."); + try + { + await prx.unknownPreservedAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.Base, ex); + if(prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)) + { + test(ex.ice_getSlicedData() === null); + } + else + { + const slicedData = ex.ice_getSlicedData(); + test(slicedData !== null); + test(slicedData.slices.length == 2); + test(slicedData.slices[1].typeId == "::Test::SPreserved1"); + test(slicedData.slices[0].typeId == "::Test::SPreserved2"); + } + } + + try + { + await prx.unknownPreservedAsKnownPreserved(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.KnownPreserved, ex); + test(ex.kp == "preserved"); + if(prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)) + { + test(ex.ice_getSlicedData() === null); + } + else + { + const slicedData = ex.ice_getSlicedData(); + test(slicedData !== null); + test(slicedData.slices.length == 2); + test(slicedData.slices[1].typeId == "::Test::SPreserved1"); + test(slicedData.slices[0].typeId == "::Test::SPreserved2"); + } + } + out.writeLine("ok"); + await prx.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/slicing/exceptions/Test.ice b/js/test/ts/Ice/slicing/exceptions/Test.ice new file mode 100644 index 00000000000..c6d5710bd49 --- /dev/null +++ b/js/test/ts/Ice/slicing/exceptions/Test.ice @@ -0,0 +1,98 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +exception Base +{ + string b; +} + +exception KnownDerived extends Base +{ + string kd; +} + +exception KnownIntermediate extends Base +{ + string ki; +} + +exception KnownMostDerived extends KnownIntermediate +{ + string kmd; +} + +["preserve-slice"] +exception KnownPreserved extends Base +{ + string kp; +} + +exception KnownPreservedDerived extends KnownPreserved +{ + string kpd; +} + +["preserve-slice"] +class BaseClass +{ + string bc; +} + +["format:sliced"] +interface Relay +{ + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; +} + +["format:sliced"] +interface TestIntf +{ + void baseAsBase() throws Base; + void unknownDerivedAsBase() throws Base; + void knownDerivedAsBase() throws Base; + void knownDerivedAsKnownDerived() throws KnownDerived; + + void unknownIntermediateAsBase() throws Base; + void knownIntermediateAsBase() throws Base; + void knownMostDerivedAsBase() throws Base; + void knownIntermediateAsKnownIntermediate() throws KnownIntermediate; + void knownMostDerivedAsKnownIntermediate() throws KnownIntermediate; + void knownMostDerivedAsKnownMostDerived() throws KnownMostDerived; + + void unknownMostDerived1AsBase() throws Base; + void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate; + void unknownMostDerived2AsBase() throws Base; + + ["format:compact"] void unknownMostDerived2AsBaseCompact() throws Base; + + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayKnownPreservedAsBase(Relay* r) throws Base; + void relayKnownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayUnknownPreservedAsBase(Relay* r) throws Base; + void relayUnknownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + + void shutdown(); +} + +} diff --git a/js/test/ts/Ice/slicing/objects/Client.ts b/js/test/ts/Ice/slicing/objects/Client.ts new file mode 100644 index 00000000000..7acdeede413 --- /dev/null +++ b/js/test/ts/Ice/slicing/objects/Client.ts @@ -0,0 +1,793 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + class PreservedI extends Test.Preserved + { + constructor() + { + super(); + ++PreservedI.counter; + } + + static counter:number; + } + + function PreservedFactoryI(id:string) + { + return id === Test.Preserved.ice_staticId() ? new PreservedI() : null; + } + + const out = this.getWriter(); + const communicator = this.communicator(); + + out.write("testing stringToProxy... "); + const ref = "Test:" + this.getTestEndpoint() + " -t 10000"; + const base = communicator.stringToProxy(ref); + test(base !== null); + out.writeLine("ok"); + + out.write("testing checked cast... "); + const prx = await Test.TestIntfPrx.checkedCast(base); + test(prx !== null); + test(prx.equals(base)); + out.writeLine("ok"); + + out.write("base as Object... "); + { + const sb = await prx.SBaseAsObject() as Test.SBase; + test(sb !== null); + test(sb.ice_id() == "::Test::SBase"); + test(sb.sb == "SBase.sb"); + } + out.writeLine("ok"); + + out.write("base as base... "); + { + const sb = await prx.SBaseAsSBase(); + test(sb.sb == "SBase.sb"); + } + out.writeLine("ok"); + + out.write("base with known derived as base... "); + { + const sb = await prx.SBSKnownDerivedAsSBase() as Test.SBSKnownDerived; + test(sb !== null); + test(sb.sb == "SBSKnownDerived.sb"); + test(sb.sbskd == "SBSKnownDerived.sbskd"); + } + out.writeLine("ok"); + + out.write("base with known derived as known derived... "); + { + const sb = await prx.SBSKnownDerivedAsSBSKnownDerived(); + test(sb.sbskd == "SBSKnownDerived.sbskd"); + } + out.writeLine("ok"); + + out.write("base with unknown derived as base... "); + { + const sb = await prx.SBSUnknownDerivedAsSBase(); + test(sb.sb == "SBSUnknownDerived.sb"); + } + + if(prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)) + { + try + { + const sb = await prx.SBSUnknownDerivedAsSBaseCompact(); + test(sb.sb == "SBSUnknownDerived.sb"); + } + catch(ex) + { + test(ex instanceof Ice.OperationNotExistException, ex); + } + } + else + { + try + { + await prx.SBSUnknownDerivedAsSBaseCompact(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.OperationNotExistException || + ex instanceof Ice.NoValueFactoryException, ex); + } + } + out.writeLine("ok"); + + out.write("unknown with Object as Object... "); + try + { + const obj = await prx.SUnknownAsObject(); + test(!prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)); + test(obj instanceof Ice.UnknownSlicedValue); + test(obj.ice_id() == "::Test::SUnknown"); + test(obj.ice_getSlicedData() !== null); + await prx.checkSUnknown(obj); + } + catch(ex) + { + test(ex instanceof Ice.NoValueFactoryException, ex); + test(prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)); + } + out.writeLine("ok"); + + out.write("one-element cycle... "); + { + const b = await prx.oneElementCycle(); + test(b !== null); + test(b.ice_id() == "::Test::B"); + test(b.sb == "B1.sb"); + test(b.pb === b); + } + out.writeLine("ok"); + + out.write("two-element cycle... "); + { + const b1 = await prx.twoElementCycle(); + test(b1 !== null); + test(b1.ice_id() == "::Test::B"); + test(b1.sb == "B1.sb"); + + const b2 = b1.pb; + test(b2 !== null); + test(b2.ice_id() == "::Test::B"); + test(b2.sb == "B2.sb"); + test(b2.pb == b1); + } + out.writeLine("ok"); + + out.write("known derived pointer slicing as derived... "); + { + const d1 = await prx.D1AsD1(); + + test(d1 !== null); + test(d1.ice_id() == "::Test::D1"); + test(d1.sb == "D1.sb"); + test(d1.pb !== null); + test(d1.pb !== d1); + + const b2 = d1.pb; + test(b2 !== null); + test(b2.ice_id() == "::Test::B"); + test(b2.sb == "D2.sb"); + test(b2.pb === d1); + } + out.writeLine("ok"); + + out.write("unknown derived pointer slicing as base... "); + { + const b2 = await prx.D2AsB() as Test.B; + + test(b2 !== null); + test(b2.ice_id() == "::Test::B"); + test(b2.sb == "D2.sb"); + test(b2.pb !== null); + test(b2.pb !== b2); + + const b1 = b2.pb; + test(b1 !== null); + test(b1.ice_id() == "::Test::D1"); + test(b1.sb == "D1.sb"); + test(b1.pb == b2); + const d1 = b1 as Test.D1; + test(d1.sd1 == "D1.sd1"); + test(d1.pd1 === b2); + } + out.writeLine("ok"); + + out.write("param ptr slicing with known first... "); + { + const [b1, b2] = await prx.paramTest1(); + test(b1 !== null); + test(b1.ice_id() == "::Test::D1"); + test(b1.sb == "D1.sb"); + test(b1.pb == b2); + test(b1 !== null); + const d1:Test.D1 = b1 as Test.D1; + test(d1.sd1 == "D1.sd1"); + test(d1.pd1 === b2); + + test(b2 !== null); + test(b2.ice_id() == "::Test::B"); // No factory, must be sliced + test(b2.sb == "D2.sb"); + test(b2.pb === b1); + } + out.writeLine("ok"); + + out.write("param ptr slicing with unknown first... "); + { + const [b2, b1] = await prx.paramTest2(); + test(b1 !== null); + test(b1.ice_id() == "::Test::D1"); + test(b1.sb == "D1.sb"); + test(b1.pb === b2); + test(b1 !== null); + const d1:Test.D1 = b1 as Test.D1; + test(d1.sd1 == "D1.sd1"); + test(d1.pd1 == b2); + + test(b2 !== null); + test(b2.ice_id() == "::Test::B"); // No factory, must be sliced + test(b2.sb == "D2.sb"); + test(b2.pb == b1); + } + out.writeLine("ok"); + + out.write("return value identity with known first... "); + { + const [ret, p1] = await prx.returnTest1(); + test(ret === p1); + } + out.writeLine("ok"); + + out.write("return value identity with unknown first... "); + { + const [ret, p1] = await prx.returnTest2(); + test(ret == p1); + } + out.writeLine("ok"); + + out.write("return value identity for input params known first... "); + { + const d1 = new Test.D1(); + d1.sb = "D1.sb"; + d1.sd1 = "D1.sd1"; + const d3 = new Test.D3(); + d3.pb = d1; + d3.sb = "D3.sb"; + d3.sd3 = "D3.sd3"; + d3.pd3 = d1; + d1.pb = d3; + d1.pd1 = d3; + + const b1 = await prx.returnTest3(d1, d3); + test(b1 !== null); + test(b1.sb == "D1.sb"); + test(b1.ice_id() == "::Test::D1"); + const p1 = b1 as Test.D1; + test(p1 !== null); + test(p1.sd1 == "D1.sd1"); + test(p1.pd1 == b1.pb); + + const b2 = b1.pb; + test(b2 !== null); + test(b2.sb == "D3.sb"); + test(b2.ice_id() == "::Test::B"); // Sliced by server + test(b2.pb == b1); + + test(!(b2 instanceof Test.D3)); + test(b1 !== d1); + test(b1 !== d3); + test(b2 !== d1); + test(b2 !== d3); + } + out.writeLine("ok"); + + out.write("return value identity for input params unknown first... "); + { + const d1 = new Test.D1(); + d1.sb = "D1.sb"; + d1.sd1 = "D1.sd1"; + const d3 = new Test.D3(); + d3.pb = d1; + d3.sb = "D3.sb"; + d3.sd3 = "D3.sd3"; + d3.pd3 = d1; + d1.pb = d3; + d1.pd1 = d3; + + const b1 = await prx.returnTest3(d3, d1); + + test(b1 !== null); + test(b1.sb == "D3.sb"); + test(b1.ice_id() == "::Test::B"); // Sliced by server + test(!(b1 instanceof Test.D3)); + + const b2 = b1.pb; + test(b2 !== null); + test(b2.sb == "D1.sb"); + test(b2.ice_id() == "::Test::D1"); + test(b2.pb == b1); + + const p3:Test.D1 = b2 as Test.D1; + test(p3 !== null); + test(p3.sd1 == "D1.sd1"); + test(p3.pd1 === b1); + + test(b1 !== d1); + test(b1 !== d3); + test(b2 !== d1); + test(b2 !== d3); + } + out.writeLine("ok"); + + out.write("remainder unmarshaling (3 instances)... "); + { + const [ret, p1, p2] = await prx.paramTest3(); + test(p1 !== null); + test(p1.sb == "D2.sb (p1 1)"); + test(p1.pb === null); + test(p1.ice_id() == "::Test::B"); + + test(p2 !== null); + test(p2.sb == "D2.sb (p2 1)"); + test(p2.pb === null); + test(p2.ice_id() == "::Test::B"); + + test(ret !== null); + test(ret.sb == "D1.sb (p2 2)"); + test(ret.pb === null); + test(ret.ice_id() == "::Test::D1"); + } + out.writeLine("ok"); + + out.write("remainder unmarshaling (4 instances)... "); + { + const [ret, b] = await prx.paramTest4(); + test(b !== null); + test(b.sb == "D4.sb (1)"); + test(b.pb === null); + test(b.ice_id() == "::Test::B"); + + test(ret !== null); + test(ret.sb == "B.sb (2)"); + test(ret.pb === null); + test(ret.ice_id() == "::Test::B"); + } + out.writeLine("ok"); + + out.write("param ptr slicing, instance marshaled in unknown derived as base... "); + { + const b1 = new Test.B(); + b1.sb = "B.sb(1)"; + b1.pb = b1; + + const d3 = new Test.D3(); + d3.sb = "D3.sb"; + d3.pb = d3; + d3.sd3 = "D3.sd3"; + d3.pd3 = b1; + + const b2 = new Test.B(); + b2.sb = "B.sb(2)"; + b2.pb = b1; + + const ret = await prx.returnTest3(d3, b2); + test(ret !== null); + test(ret.ice_id() == "::Test::B"); + test(ret.sb == "D3.sb"); + test(ret.pb === ret); + } + out.writeLine("ok"); + + out.write("param ptr slicing, instance marshaled in unknown derived as derived... "); + { + const d11 = new Test.D1(); + d11.sb = "D1.sb(1)"; + d11.pb = d11; + d11.sd1 = "D1.sd1(1)"; + + const d3 = new Test.D3(); + d3.sb = "D3.sb"; + d3.pb = d3; + d3.sd3 = "D3.sd3"; + d3.pd3 = d11; + + const d12 = new Test.D1(); + d12.sb = "D1.sb(2)"; + d12.pb = d12; + d12.sd1 = "D1.sd1(2)"; + d12.pd1 = d11; + + const ret = await prx.returnTest3(d3, d12); + test(ret !== null); + test(ret.ice_id() == "::Test::B"); + test(ret.sb == "D3.sb"); + test(ret.pb === ret); + } + out.writeLine("ok"); + + out.write("sequence slicing... "); + { + let ss1b = new Test.B(); + ss1b.sb = "B.sb"; + ss1b.pb = ss1b; + + let ss1d1 = new Test.D1(); + ss1d1.sb = "D1.sb"; + ss1d1.sd1 = "D1.sd1"; + ss1d1.pb = ss1b; + + let ss1d3 = new Test.D3(); + ss1d3.sb = "D3.sb"; + ss1d3.sd3 = "D3.sd3"; + ss1d3.pb = ss1b; + + let ss2b = new Test.B(); + ss2b.sb = "B.sb"; + ss2b.pb = ss1b; + + let ss2d1 = new Test.D1(); + ss2d1.sb = "D1.sb"; + ss2d1.sd1 = "D1.sd1"; + ss2d1.pb = ss2b; + + let ss2d3 = new Test.D3(); + ss2d3.sb = "D3.sb"; + ss2d3.sd3 = "D3.sd3"; + ss2d3.pb = ss2b; + + ss1d1.pd1 = ss2b; + ss1d3.pd3 = ss2d1; + + ss2d1.pd1 = ss1d3; + ss2d3.pd3 = ss1d1; + + const ss1 = new Test.SS1(); + ss1.s = []; + ss1.s[0] = ss1b; + ss1.s[1] = ss1d1; + ss1.s[2] = ss1d3; + + const ss2 = new Test.SS2(); + ss2.s = []; + ss2.s[0] = ss2b; + ss2.s[1] = ss2d1; + ss2.s[2] = ss2d3; + + const ss = await prx.sequenceTest(ss1, ss2); + + test(ss.c1 !== null); + const ss1b2 = ss.c1.s[0]; + const ss1d2 = ss.c1.s[1]; + test(ss.c2 !== null); + const ss1d4 = ss.c1.s[2]; + + test(ss.c2 !== null); + const ss2b2 = ss.c2.s[0]; + const ss2d2 = ss.c2.s[1]; + const ss2d4 = ss.c2.s[2]; + + test(ss1b2.pb == ss1b2); + test(ss1d2.pb == ss1b2); + test(ss1d4.pb == ss1b2); + + test(ss2b2.pb == ss1b2); + test(ss2d2.pb == ss2b2); + test(ss2d4.pb == ss2b2); + + test(ss1b2.ice_id() == "::Test::B"); + test(ss1d2.ice_id() == "::Test::D1"); + test(ss1d4.ice_id() == "::Test::B"); + + test(ss2b2.ice_id() == "::Test::B"); + test(ss2d2.ice_id() == "::Test::D1"); + test(ss2d4.ice_id() == "::Test::B"); + } + out.writeLine("ok"); + + out.write("dictionary slicing... "); + { + const bin = new Map(); + for(let i = 0; i < 10; ++i) + { + const s = `D1.${i}`; + const d1 = new Test.D1(); + d1.sb = s; + d1.pb = d1; + d1.sd1 = s; + bin.set(i, d1); + } + + const [ret, boutH] = await prx.dictionaryTest(bin); + test(boutH.size === 10); + for(let i = 0; i < 10; ++i) + { + const b = boutH.get(i * 10); + test(b !== null); + const s = `D1.${i}`; + test(b.sb == s); + test(b.pb !== null); + test(b.pb !== b); + test(b.pb.sb == s); + test(b.pb.pb == b.pb); + } + + test(ret.size === 10); + for(let i = 0; i < 10; ++i) + { + const b = ret.get(i * 20); + test(b !== null); + const s = "D1." + (i * 20); + test(b.sb == s); + test(b.pb === (i === 0 ? null : ret.get((i - 1) * 20))); + const d1 = b as Test.D1; + test(d1 != null); + test(d1.sd1 == s); + test(d1.pd1 === b); + } + } + out.writeLine("ok"); + + out.write("base exception thrown as base exception... "); + try + { + await prx.throwBaseAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.BaseException, ex); + test(ex.ice_id() == "::Test::BaseException"); + test(ex.sbe == "sbe"); + test(ex.pb !== null); + test(ex.pb.sb == "sb"); + test(ex.pb.pb == ex.pb); + } + out.writeLine("ok"); + + out.write("derived exception thrown as base exception... "); + try + { + await prx.throwDerivedAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.DerivedException, ex); + test(ex.ice_id() == "::Test::DerivedException"); + test(ex.sbe == "sbe"); + test(ex.pb !== null); + test(ex.pb.sb == "sb1"); + test(ex.pb.pb === ex.pb); + test(ex.sde == "sde1"); + test(ex.pd1 !== null); + test(ex.pd1.sb == "sb2"); + test(ex.pd1.pb === ex.pd1); + test(ex.pd1.sd1 == "sd2"); + test(ex.pd1.pd1 === ex.pd1); + } + out.writeLine("ok"); + + out.write("derived exception thrown as derived exception... "); + try + { + await prx.throwDerivedAsDerived(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.DerivedException, ex); + test(ex.ice_id() == "::Test::DerivedException"); + test(ex.sbe == "sbe"); + test(ex.pb !== null); + test(ex.pb.sb == "sb1"); + test(ex.pb.pb == ex.pb); + test(ex.sde == "sde1"); + test(ex.pd1 !== null); + test(ex.pd1.sb == "sb2"); + test(ex.pd1.pb === ex.pd1); + test(ex.pd1.sd1 == "sd2"); + test(ex.pd1.pd1 === ex.pd1); + } + out.writeLine("ok"); + + out.write("unknown derived exception thrown as base exception... "); + try + { + await prx.throwUnknownDerivedAsBase(); + test(false); + } + catch(ex) + { + test(ex instanceof Test.BaseException, ex); + test(ex.ice_id() == "::Test::BaseException"); + test(ex.sbe == "sbe"); + test(ex.pb !== null); + test(ex.pb.sb == "sb d2"); + test(ex.pb.pb == ex.pb); + } + out.writeLine("ok"); + + out.write("forward-declared class... "); + { + const f = await prx.useForward(); + test(f !== null); + } + out.writeLine("ok"); + + out.write("preserved classes... "); + // + // Register a factory in order to substitute our own subclass of Preserved. This provides + // an easy way to determine how many unmarshaled instances currently exist. + // + // TODO: We have to install this now (even though it's not necessary yet), because otherwise + // the Ice run time will install its own internal factory for Preserved upon receiving the + // first instance. + // + communicator.getValueFactoryManager().add(PreservedFactoryI, Test.Preserved.ice_staticId()); + { + // + // Server knows the most-derived class PDerived. + // + const pd = new Test.PDerived(); + pd.pi = 3; + pd.ps = "preserved"; + pd.pb = pd; + + const p2 = await prx.exchangePBase(pd) as Test.PDerived; + + test(p2.pi === 3); + test(p2.ps == "preserved"); + test(p2.pb === p2); + } + + { + // + // Server only knows the base (non-preserved) type, so the object is sliced. + // + const pu = new Test.PCUnknown(); + pu.pi = 3; + pu.pu = "preserved"; + + const r = await prx.exchangePBase(pu); + + test(!(r instanceof Test.PCUnknown)); + test(r.pi == 3); + } + + { + // + // Server only knows the intermediate type Preserved. The object will be sliced to + // Preserved for the 1.0 encoding; otherwise it should be returned intact. + // + const pcd = new Test.PCDerived(); + pcd.pi = 3; + pcd.pbs = [pcd]; + + const r = await prx.exchangePBase(pcd); + if(prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)) + { + test(!(r instanceof Test.PCDerived)); + test(r.pi === 3); + } + else + { + const p2 = r as Test.PCDerived; + test(p2.pi === 3); + test(p2.pbs[0] === r); + } + } + + { + // + // Server only knows the intermediate type Preserved. The object will be sliced to + // Preserved for the 1.0 encoding; otherwise it should be returned intact. + // + const pcd = new Test.CompactPCDerived(); + pcd.pi = 3; + pcd.pbs = [pcd]; + + const r = await prx.exchangePBase(pcd); + if(prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)) + { + test(!(r instanceof Test.CompactPCDerived)); + test(r.pi === 3); + } + else + { + const p2 = r as Test.PCDerived; + test(p2.pi === 3); + test(p2.pbs[0] === p2); + } + } + + { + // + // Send an object that will have multiple preserved slices in the server. + // The object will be sliced to Preserved for the 1.0 encoding. + // + const pcd = new Test.PCDerived3(); + pcd.pi = 3; + + // + // Sending more than 254 objects exercises the encoding for object ids. + // + pcd.pbs = new Array(300); + for(let i = 0; i < 300; ++i) + { + const p2 = new Test.PCDerived2(); + p2.pi = i; + p2.pbs = [null]; // Nil reference. This slice should not have an indirection table. + p2.pcd2 = i; + pcd.pbs[i] = p2; + } + pcd.pcd2 = pcd.pi; + pcd.pcd3 = pcd.pbs[10]; + + const r = await prx.exchangePBase(pcd); + if(prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)) + { + test(!(r instanceof Test.PCDerived3)); + test(r instanceof Test.Preserved); + test(r.pi === 3); + } + else + { + const p3 = r as Test.PCDerived3; + test(p3.pi === 3); + for(let i = 0; i < 300; ++i) + { + const p2 = p3.pbs[i] as Test.PCDerived2; + test(p2.pi === i); + test(p2.pbs.length === 1); + test(p2.pbs[0] === null); + test(p2.pcd2 === i); + } + test(p3.pcd2 === p3.pi); + test(p3.pcd3 === p3.pbs[10]); + } + } + + { + // + // Obtain an object with preserved slices and send it back to the server. + // The preserved slices should be excluded for the 1.0 encoding, otherwise + // they should be included. + // + const p = await prx.PBSUnknownAsPreserved(); + await prx.checkPBSUnknown(p); + + if(!prx.ice_getEncodingVersion().equals(Ice.Encoding_1_0)) + { + const slicedData = p.ice_getSlicedData(); + test(slicedData !== null); + test(slicedData.slices.length === 1); + test(slicedData.slices[0].typeId == "::Test::PSUnknown"); + await prx.ice_encodingVersion(Ice.Encoding_1_0).checkPBSUnknown(p); + } + else + { + test(p.ice_getSlicedData() === null); + } + } + out.writeLine("ok"); + await prx.shutdown(); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/slicing/objects/Test.ice b/js/test/ts/Ice/slicing/objects/Test.ice new file mode 100644 index 00000000000..031a0ef2034 --- /dev/null +++ b/js/test/ts/Ice/slicing/objects/Test.ice @@ -0,0 +1,214 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +// +// Duplicate types from Test.ice. We cannot use #include since +// that will use the types from the same prefix. +// + +class SBase +{ + string sb; +} + +class SBSKnownDerived extends SBase +{ + string sbskd; +} + +class B +{ + string sb; + B pb; +} + +class D1 extends B +{ + string sd1; + B pd1; +} + +sequence<B> BSeq; + +class SS1 +{ + BSeq s; +} + +class SS2 +{ + BSeq s; +} + +struct SS3 +{ + SS1 c1; + SS2 c2; +} + +dictionary<int, B> BDict; + +exception BaseException +{ + string sbe; + B pb; +} + +exception DerivedException extends BaseException +{ + string sde; + D1 pd1; +} + +class Forward; + +class PBase +{ + int pi; +} + +sequence<PBase> PBaseSeq; + +["preserve-slice"] +class Preserved extends PBase +{ + string ps; +} + +class PDerived extends Preserved +{ + PBase pb; +} + +class CompactPDerived(56) extends Preserved +{ + PBase pb; +} + +["preserve-slice"] +class PNode +{ + PNode next; +} + +["preserve-slice"] +exception PreservedException +{ +} + +["format:sliced"] +interface TestIntf +{ + Object SBaseAsObject(); + SBase SBaseAsSBase(); + SBase SBSKnownDerivedAsSBase(); + SBSKnownDerived SBSKnownDerivedAsSBSKnownDerived(); + + SBase SBSUnknownDerivedAsSBase(); + + ["format:compact"] SBase SBSUnknownDerivedAsSBaseCompact(); + + Object SUnknownAsObject(); + void checkSUnknown(Object o); + + B oneElementCycle(); + B twoElementCycle(); + B D1AsB(); + D1 D1AsD1(); + B D2AsB(); + + void paramTest1(out B p1, out B p2); + void paramTest2(out B p2, out B p1); + B paramTest3(out B p1, out B p2); + B paramTest4(out B p); + + B returnTest1(out B p1, out B p2); + B returnTest2(out B p2, out B p1); + B returnTest3(B p1, B p2); + + SS3 sequenceTest(SS1 p1, SS2 p2); + + BDict dictionaryTest(BDict bin, out BDict bout); + + PBase exchangePBase(PBase pb); + + Preserved PBSUnknownAsPreserved(); + void checkPBSUnknown(Preserved p); + + ["amd"] Preserved PBSUnknownAsPreservedWithGraph(); + void checkPBSUnknownWithGraph(Preserved p); + + ["amd"] Preserved PBSUnknown2AsPreservedWithGraph(); + void checkPBSUnknown2WithGraph(Preserved p); + + PNode exchangePNode(PNode pn); + + void throwBaseAsBase() throws BaseException; + void throwDerivedAsBase() throws BaseException; + void throwDerivedAsDerived() throws DerivedException; + void throwUnknownDerivedAsBase() throws BaseException; + ["amd"] void throwPreservedException() throws PreservedException; + + void useForward(out Forward f); /* Use of forward-declared class to verify that code is generated correctly. */ + + void shutdown(); +} + +// +// Types private to the client. +// + +class D3 extends B +{ + string sd3; + B pd3; +} + +["preserve-slice"] +class PCUnknown extends PBase +{ + string pu; +} + +class PCDerived extends PDerived +{ + PBaseSeq pbs; +} + +class PCDerived2 extends PCDerived +{ + int pcd2; +} + +class PCDerived3 extends PCDerived2 +{ + Object pcd3; +} + +class CompactPCDerived(57) extends CompactPDerived +{ + PBaseSeq pbs; +} + +class Hidden +{ + Forward f; +} + +class Forward +{ + Hidden h; +} + +} diff --git a/js/test/ts/Ice/stream/Client.ts b/js/test/ts/Ice/stream/Client.ts new file mode 100644 index 00000000000..130c13778da --- /dev/null +++ b/js/test/ts/Ice/stream/Client.ts @@ -0,0 +1,633 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + allTests() + { + const communicator = this.communicator(); + const out = this.getWriter(); + + class MyInterfaceI extends Ice.InterfaceByValue + { + constructor() + { + super(Test.MyInterface.ice_staticId()); + } + } + communicator.getValueFactoryManager().add(id => new MyInterfaceI(), Test.MyInterface.ice_staticId()); + + let inS:Ice.InputStream = null; + let outS:Ice.OutputStream = null; + + out.write("testing primitive types... "); + + { + const data = new Uint8Array(0); + inS = new Ice.InputStream(communicator, data); + } + + { + outS = new Ice.OutputStream(communicator); + outS.startEncapsulation(); + outS.writeBool(true); + outS.endEncapsulation(); + const data = outS.finished(); + + inS = new Ice.InputStream(communicator, data); + inS.startEncapsulation(); + test(inS.readBool()); + inS.endEncapsulation(); + + inS = new Ice.InputStream(communicator, data); + inS.startEncapsulation(); + test(inS.readBool()); + inS.endEncapsulation(); + } + + { + const data = new Uint8Array(0); + inS = new Ice.InputStream(communicator, data); + try + { + inS.readBool(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.UnmarshalOutOfBoundsException); + } + } + + { + outS = new Ice.OutputStream(communicator); + outS.writeBool(true); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + test(inS.readBool()); + } + + { + outS = new Ice.OutputStream(communicator); + outS.writeByte(1); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + test(inS.readByte() == 1); + } + + { + outS = new Ice.OutputStream(communicator); + outS.writeShort(2); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + test(inS.readShort() == 2); + } + + { + outS = new Ice.OutputStream(communicator); + outS.writeInt(3); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + test(inS.readInt() == 3); + } + + { + outS = new Ice.OutputStream(communicator); + outS.writeLong(new Ice.Long(4)); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + test(inS.readLong().toNumber() == 4); + } + + { + outS = new Ice.OutputStream(communicator); + outS.writeFloat(5.0); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + test(inS.readFloat() == 5.0); + } + + { + outS = new Ice.OutputStream(communicator); + outS.writeDouble(6.0); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + test(inS.readDouble() == 6.0); + } + + { + outS = new Ice.OutputStream(communicator); + outS.writeString("hello world"); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + test(inS.readString() == "hello world"); + } + + out.writeLine("ok"); + + out.write("testing constructed types... "); + + { + outS = new Ice.OutputStream(communicator); + outS.writeEnum(Test.MyEnum.enum3); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const e:Test.MyEnum = inS.readEnum(Test.MyEnum); + test(e == Test.MyEnum.enum3); + } + + { + outS = new Ice.OutputStream(communicator); + const s = new Test.SmallStruct(); + s.bo = true; + s.by = 1; + s.sh = 2; + s.i = 3; + s.l = new Ice.Long(4); + s.f = 5.0; + s.d = 6.0; + s.str = "7"; + s.e = Test.MyEnum.enum2; + s.p = Test.MyInterfacePrx.uncheckedCast(communicator.stringToProxy("test:default")); + Test.SmallStruct.write(outS, s); + const data = outS.finished(); + const s2 = Test.SmallStruct.read(new Ice.InputStream(communicator, data)); + test(s2.equals(s)); + } + + { + outS = new Ice.OutputStream(communicator); + const o = new Test.OptionalClass(); + o.bo = true; + o.by = 5; + o.sh = 4; + o.i = 3; + outS.writeValue(o); + outS.writePendingValues(); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + let o2:Test.OptionalClass; + inS.readValue((obj:Test.OptionalClass) => + { + o2 = obj; + }, + Test.OptionalClass); + inS.readPendingValues(); + + test(o2.bo == o.bo); + test(o2.by == o.by); + if(communicator.getProperties().getProperty("Ice.Default.EncodingVersion") == "1.0") + { + test(o2.sh === undefined); + test(o2.i === undefined); + } + else + { + test(o2.sh == o.sh); + test(o2.i == o.i); + } + } + + { + outS = new Ice.OutputStream(communicator, Ice.Encoding_1_0); + const o = new Test.OptionalClass(); + o.bo = true; + o.by = 5; + o.sh = 4; + o.i = 3; + outS.writeValue(o); + outS.writePendingValues(); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, Ice.Encoding_1_0, data); + let o2:Test.OptionalClass; + inS.readValue((obj:Test.OptionalClass) => + { + o2 = obj; + }, + Test.OptionalClass); + inS.readPendingValues(); + test(o2.bo == o.bo); + test(o2.by == o.by); + test(o2.sh === undefined); + test(o2.i === undefined); + } + + { + const arr = [true, false, true, false]; + outS = new Ice.OutputStream(communicator); + Ice.BoolSeqHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Ice.BoolSeqHelper.read(inS); + test(Ice.ArrayUtil.equals(arr, arr2)); + + const arrS = [arr, [], arr]; + outS = new Ice.OutputStream(communicator); + Test.BoolSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.BoolSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + { + const arr = new Uint8Array([0x01, 0x11, 0x12, 0x22]); + outS = new Ice.OutputStream(communicator); + Ice.ByteSeqHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Ice.ByteSeqHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2, arr)); + + const arrS:Uint8Array[] = [arr, new Uint8Array(0), arr]; + outS = new Ice.OutputStream(communicator); + Test.ByteSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.ByteSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + { + const arr = [0x01, 0x11, 0x12, 0x22]; + outS = new Ice.OutputStream(communicator); + Ice.ShortSeqHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Ice.ShortSeqHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2, arr)); + + const arrS = [arr, [], arr]; + outS = new Ice.OutputStream(communicator); + Test.ShortSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.ShortSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + { + const arr = [0x01, 0x11, 0x12, 0x22]; + outS = new Ice.OutputStream(communicator); + Ice.IntSeqHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Ice.IntSeqHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2, arr)); + + const arrS = [arr, [], arr]; + outS = new Ice.OutputStream(communicator); + Test.IntSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.IntSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + { + const arr = [new Ice.Long(0x01), new Ice.Long(0x11), new Ice.Long(0x12), new Ice.Long(0x22)]; + outS = new Ice.OutputStream(communicator); + Ice.LongSeqHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Ice.LongSeqHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2, arr)); + + const arrS = [arr, [], arr]; + outS = new Ice.OutputStream(communicator); + Test.LongSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.LongSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + { + const arr = [1, 2, 3, 4]; + outS = new Ice.OutputStream(communicator); + Ice.FloatSeqHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Ice.FloatSeqHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2, arr)); + + const arrS = [arr, [], arr]; + outS = new Ice.OutputStream(communicator); + Test.FloatSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.FloatSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + { + const arr = [1, 2, 3, 4]; + outS = new Ice.OutputStream(communicator); + Ice.DoubleSeqHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Ice.DoubleSeqHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2, arr)); + + const arrS = [arr, [], arr]; + outS = new Ice.OutputStream(communicator); + Test.DoubleSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.DoubleSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + { + const arr = ["string1", "string2", "string3", "string4"]; + outS = new Ice.OutputStream(communicator); + Ice.StringSeqHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Ice.StringSeqHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2, arr)); + + const arrS = [arr, [], arr]; + outS = new Ice.OutputStream(communicator); + Test.StringSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.StringSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + { + const arr = [Test.MyEnum.enum3, Test.MyEnum.enum2, Test.MyEnum.enum1, Test.MyEnum.enum2]; + outS = new Ice.OutputStream(communicator); + Test.MyEnumSHelper.write(outS, arr); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Test.MyEnumSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2, arr)); + + const arrS = [arr, [], arr]; + outS = new Ice.OutputStream(communicator); + Test.MyEnumSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.MyEnumSSHelper.read(inS); + test(Ice.ArrayUtil.equals(arr2S, arrS)); + } + + const smallStructArray = []; + for(let i = 0; i < 3; ++i) + { + const s = new Test.SmallStruct(); + s.bo = true; + s.by = 1; + s.sh = 2; + s.i = 3; + s.l = new Ice.Long(4); + s.f = 5.0; + s.d = 6.0; + s.str = "7"; + s.e = Test.MyEnum.enum2; + s.p = Test.MyInterfacePrx.uncheckedCast(communicator.stringToProxy("test:default")); + smallStructArray[i] = s; + } + + const myClassArray = []; + for(let i = 0; i < 4; ++i) + { + const c = new Test.MyClass(); + myClassArray[i] = c; + c.c = myClassArray[i]; + c.o = myClassArray[i]; + c.s = new Test.SmallStruct(); + c.s.e = Test.MyEnum.enum2; + c.seq1 = [true, false, true, false]; + c.seq2 = new Uint8Array([1, 2, 3, 4]); + c.seq3 = [1, 2, 3, 4]; + c.seq4 = [1, 2, 3, 4]; + c.seq5 = [new Ice.Long(1), new Ice.Long(2), new Ice.Long(3), new Ice.Long(4)]; + c.seq6 = [1, 2, 3, 4]; + c.seq7 = [1, 2, 3, 4]; + c.seq8 = ["string1", "string2", "string3", "string4"]; + c.seq9 = [Test.MyEnum.enum3, Test.MyEnum.enum2, Test.MyEnum.enum1]; + c.seq10 = [null, null, null, null]; // null elements. + c.d = new Test.StringMyClassD(); + c.d.set("hi", myClassArray[i]); + } + + const myInterfaceArray = []; + for(let i = 0; i < 4; ++i) + { + myInterfaceArray[i] = new Ice.InterfaceByValue("::Test::MyInterface"); + } + + { + outS = new Ice.OutputStream(communicator); + Test.MyClassSHelper.write(outS, myClassArray); + outS.writePendingValues(); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Test.MyClassSHelper.read(inS); + inS.readPendingValues(); + test(arr2.length == myClassArray.length); + for(let i = 0; i < arr2.length; ++i) + { + test(arr2[i] !== null); + test(arr2[i].c == arr2[i]); + test(arr2[i].o == arr2[i]); + test(arr2[i].s.e == Test.MyEnum.enum2); + test(Ice.ArrayUtil.equals(arr2[i].seq1, myClassArray[i].seq1)); + test(Ice.ArrayUtil.equals(arr2[i].seq2, myClassArray[i].seq2)); + test(Ice.ArrayUtil.equals(arr2[i].seq3, myClassArray[i].seq3)); + test(Ice.ArrayUtil.equals(arr2[i].seq4, myClassArray[i].seq4)); + test(Ice.ArrayUtil.equals(arr2[i].seq5, myClassArray[i].seq5)); + test(Ice.ArrayUtil.equals(arr2[i].seq6, myClassArray[i].seq6)); + test(Ice.ArrayUtil.equals(arr2[i].seq7, myClassArray[i].seq7)); + test(Ice.ArrayUtil.equals(arr2[i].seq8, myClassArray[i].seq8)); + test(Ice.ArrayUtil.equals(arr2[i].seq9, myClassArray[i].seq9)); + test(arr2[i].d.get("hi") == arr2[i]); + } + const arrS = [myClassArray, [], myClassArray]; + outS = new Ice.OutputStream(communicator); + Test.MyClassSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.MyClassSSHelper.read(inS); + test(arr2S.length == arrS.length); + test(arr2S[0].length == arrS[0].length); + test(arr2S[1].length == arrS[1].length); + test(arr2S[2].length == arrS[2].length); + } + + { + outS = new Ice.OutputStream(communicator); + Test.MyInterfaceSHelper.write(outS, myInterfaceArray); + outS.writePendingValues(); + let data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2 = Test.MyInterfaceSHelper.read(inS); + inS.readPendingValues(); + test(arr2.length == myInterfaceArray.length); + const arrS = [myInterfaceArray, [], myInterfaceArray]; + outS = new Ice.OutputStream(communicator); + Test.MyInterfaceSSHelper.write(outS, arrS); + data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const arr2S = Test.MyInterfaceSSHelper.read(inS); + test(arr2S.length == arrS.length); + test(arr2S[0].length == arrS[0].length); + test(arr2S[1].length == arrS[1].length); + test(arr2S[2].length == arrS[2].length); + } + + { + outS = new Ice.OutputStream(communicator); + const ex = new Test.MyException(); + + const c = new Test.MyClass(); + c.c = c; + c.o = c; + c.s = new Test.SmallStruct(); + c.s.e = Test.MyEnum.enum2; + c.seq1 = [true, false, true, false]; + c.seq2 = new Uint8Array([1, 2, 3, 4]); + c.seq3 = [1, 2, 3, 4]; + c.seq4 = [1, 2, 3, 4]; + c.seq5 = [new Ice.Long(1), new Ice.Long(2), new Ice.Long(3), new Ice.Long(4)]; + c.seq6 = [1, 2, 3, 4]; + c.seq7 = [1, 2, 3, 4]; + c.seq8 = ["string1", "string2", "string3", "string4"]; + c.seq9 = [Test.MyEnum.enum3, Test.MyEnum.enum2, Test.MyEnum.enum1]; + c.seq10 = [null, null, null, null]; // null elements. + c.d = new Test.StringMyClassD(); + c.d.set("hi", c); + + ex.c = c; + + outS.writeException(ex); + const data = outS.finished(); + + inS = new Ice.InputStream(communicator, data); + try + { + inS.throwException(); + test(false); + } + catch(ex1) + { + test(ex1 instanceof Test.MyException); + test(ex1.c.s.e == c.s.e); + test(Ice.ArrayUtil.equals(ex1.c.seq1, c.seq1)); + test(Ice.ArrayUtil.equals(ex1.c.seq2, c.seq2)); + test(Ice.ArrayUtil.equals(ex1.c.seq3, c.seq3)); + test(Ice.ArrayUtil.equals(ex1.c.seq4, c.seq4)); + test(Ice.ArrayUtil.equals(ex1.c.seq5, c.seq5)); + test(Ice.ArrayUtil.equals(ex1.c.seq6, c.seq6)); + test(Ice.ArrayUtil.equals(ex1.c.seq7, c.seq7)); + test(Ice.ArrayUtil.equals(ex1.c.seq8, c.seq8)); + test(Ice.ArrayUtil.equals(ex1.c.seq9, c.seq9)); + } + } + + { + const dict = new Test.ByteBoolD(); + dict.set(4, true); + dict.set(1, false); + outS = new Ice.OutputStream(communicator); + Test.ByteBoolDHelper.write(outS, dict); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const dict2 = Test.ByteBoolDHelper.read(inS); + test(Ice.MapUtil.equals(dict2, dict)); + } + + { + const dict = new Test.ShortIntD(); + dict.set(1, 9); + dict.set(4, 8); + outS = new Ice.OutputStream(communicator); + Test.ShortIntDHelper.write(outS, dict); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const dict2 = Test.ShortIntDHelper.read(inS); + test(Ice.MapUtil.equals(dict2, dict)); + } + + { + const dict = new Test.LongFloatD(); + dict.set(new Ice.Long(123809828), 0.5); + dict.set(new Ice.Long(123809829), 0.6); + outS = new Ice.OutputStream(communicator); + Test.LongFloatDHelper.write(outS, dict); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const dict2 = Test.LongFloatDHelper.read(inS); + test(dict2.size == 2); + test(dict2.get(new Ice.Long(123809828)) == 0.5); + test(Math.abs(dict2.get(new Ice.Long(123809829)) - 0.6) <= 0.001); + } + + { + const dict = new Test.StringStringD(); + dict.set("key1", "value1"); + dict.set("key2", "value2"); + outS = new Ice.OutputStream(communicator); + Test.StringStringDHelper.write(outS, dict); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const dict2 = Test.StringStringDHelper.read(inS); + test(Ice.MapUtil.equals(dict2, dict)); + } + + { + const dict = new Test.StringMyClassD(); + let c = new Test.MyClass(); + c.s = new Test.SmallStruct(); + c.s.e = Test.MyEnum.enum2; + dict.set("key1", c); + c = new Test.MyClass(); + c.s = new Test.SmallStruct(); + c.s.e = Test.MyEnum.enum3; + dict.set("key2", c); + outS = new Ice.OutputStream(communicator); + Test.StringMyClassDHelper.write(outS, dict); + outS.writePendingValues(); + const data = outS.finished(); + inS = new Ice.InputStream(communicator, data); + const dict2 = Test.StringMyClassDHelper.read(inS); + inS.readPendingValues(); + test(dict2.size == dict.size); + test(dict2.get("key1").s.e == Test.MyEnum.enum2); + test(dict2.get("key2").s.e == Test.MyEnum.enum3); + } + out.writeLine("ok"); + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + [communicator] = this.initialize(args); + this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/stream/Test.ice b/js/test/ts/Ice/stream/Test.ice new file mode 100644 index 00000000000..b7e11d87a36 --- /dev/null +++ b/js/test/ts/Ice/stream/Test.ice @@ -0,0 +1,103 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +// +// Suppress invalid metadata warnings +// +[["suppress-warning:invalid-metadata, deprecated"]] + +#include <Ice/BuiltinSequences.ice> + +module Test +{ + +enum MyEnum +{ + enum1, + enum2, + enum3 +} + +class MyClass; +interface MyInterface; + +struct SmallStruct +{ + bool bo; + byte by; + short sh; + int i; + long l; + float f; + double d; + string str; + MyEnum e; + MyInterface* p; +} + +class OptionalClass +{ + bool bo; + byte by; + optional(1) short sh; + optional(2) int i; +} + +sequence<MyEnum> MyEnumS; +sequence<MyClass> MyClassS; +sequence<MyInterface> MyInterfaceS; + +sequence<Ice::BoolSeq> BoolSS; +sequence<Ice::ByteSeq> ByteSS; +sequence<Ice::ShortSeq> ShortSS; +sequence<Ice::IntSeq> IntSS; +sequence<Ice::LongSeq> LongSS; +sequence<Ice::FloatSeq> FloatSS; +sequence<Ice::DoubleSeq> DoubleSS; +sequence<Ice::StringSeq> StringSS; +sequence<MyEnumS> MyEnumSS; +sequence<MyClassS> MyClassSS; +sequence<MyInterfaceS> MyInterfaceSS; + +dictionary<byte, bool> ByteBoolD; +dictionary<short, int> ShortIntD; +dictionary<long, float> LongFloatD; +dictionary<string, string> StringStringD; +dictionary<string, MyClass> StringMyClassD; + +class MyClass +{ + MyClass c; + Object o; + SmallStruct s; + Ice::BoolSeq seq1; + Ice::ByteSeq seq2; + Ice::ShortSeq seq3; + Ice::IntSeq seq4; + Ice::LongSeq seq5; + Ice::FloatSeq seq6; + Ice::DoubleSeq seq7; + Ice::StringSeq seq8; + MyEnumS seq9; + MyClassS seq10; + StringMyClassD d; +} + +exception MyException +{ + MyClass c; +} + +interface MyInterface +{ +} + +} diff --git a/js/test/ts/Ice/timeout/Client.ts b/js/test/ts/Ice/timeout/Client.ts new file mode 100644 index 00000000000..3a920293f9b --- /dev/null +++ b/js/test/ts/Ice/timeout/Client.ts @@ -0,0 +1,405 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + async allTests() + { + async function connect(prx:Test.TimeoutPrx) + { + let nRetry = 10; + while(--nRetry > 0) + { + try + { + await prx.ice_getConnection(); + break; + } + catch(ex) + { + // Can sporadically occur with slow machines + test(ex instanceof Ice.ConnectTimeoutException || + ex instanceof Ice.ConnectFailedException, ex); + } + await Ice.Promise.delay(100); + } + return prx.ice_getConnection(); + } + + const communicator = this.communicator(); + const out = this.getWriter(); + + const ref = "timeout:" + this.getTestEndpoint(); + const obj = communicator.stringToProxy(ref); + test(obj !== null); + + let mult = 1; + if(["ssl", "wss"].includes( + communicator.getProperties().getPropertyWithDefault("Ice.Default.Protocol", "tcp"))) + { + mult = 4; + } + + const timeout = await Test.TimeoutPrx.checkedCast(obj); + test(timeout !== null); + + const controller = Test.ControllerPrx.uncheckedCast( + communicator.stringToProxy("controller:" + this.getTestEndpoint(1))); + test(controller !== null); + + out.write("testing connect timeout... "); + { + const to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(100 * mult)); + await controller.holdAdapter(-1); + try + { + await to.op(); // Expect ConnectTimeoutException. + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ConnectTimeoutException, ex); + } + finally + { + await controller.resumeAdapter(); + } + await timeout.op(); // Ensure adapter is active. + } + + { + const to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(-1)); + await controller.holdAdapter(100 * mult); + await to.ice_getConnection(); + try + { + await to.op(); // Expect success. + } + catch(ex) + { + test(false, ex); + } + } + out.writeLine("ok"); + + const seq = new Uint8Array(10000000); + out.write("testing connection timeout... "); + { + const to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(250 * mult)); + await connect(to); + await controller.holdAdapter(-1); + try + { + await to.sendData(seq); // Expect TimeoutException + test(false); + } + catch(ex) + { + test(ex instanceof Ice.TimeoutException, ex); + } + finally + { + await controller.resumeAdapter(); + } + await timeout.op(); // Ensure adapter is active. + } + + { + // NOTE: 30s timeout is necessary for Firefox/IE on Windows + const to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(30000 * mult)); + await controller.holdAdapter(200 * mult); + try + { + await to.sendData(new Uint8Array(5 * 1024)); // Expect success. + } + catch(ex) + { + test(false, ex); + } + } + out.writeLine("ok"); + + out.write("testing invocation timeout... "); + { + const connection = await obj.ice_getConnection(); + let to = Test.TimeoutPrx.uncheckedCast(obj.ice_invocationTimeout(100)); + test(connection == await to.ice_getConnection()); + + try + { + await to.sleep(500); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.InvocationTimeoutException, ex); + } + await obj.ice_ping(); + to = await Test.TimeoutPrx.checkedCast(obj.ice_invocationTimeout(1000)); + test(connection === await obj.ice_getConnection()); + + try + { + await to.sleep(100); + } + catch(ex) + { + test(ex instanceof Ice.InvocationTimeoutException, ex); + } + } + out.writeLine("ok"); + + // Small delay is useful for IE which doesn't like too many connection failures in a row + await Ice.Promise.delay(500); + + out.write("testing close timeout... "); + { + const to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(500)); + const connection = await connect(to); + await controller.holdAdapter(-1); + await connection.close(Ice.ConnectionClose.GracefullyWithWait); + + try + { + connection.getInfo(); // getInfo() doesn't throw in the closing state + while(true) + { + try + { + connection.getInfo(); + await Ice.Promise.delay(10); + } + catch(ex) + { + test(ex instanceof Ice.ConnectionManuallyClosedException, ex); // Expected + test(ex.graceful); + break; + } + } + } + catch(ex) + { + test(false, ex); + } + finally + { + await controller.resumeAdapter(); + } + await timeout.op(); + } + out.writeLine("ok"); + + // Small delay is useful for IE which doesn't like too many connection failures in a row + await Ice.Promise.delay(500); + + out.write("testing timeout overrides... "); + { + // + // Test Ice.Override.Timeout. This property overrides all + // endpoint timeouts. + // + const initData = new Ice.InitializationData(); + initData.properties = communicator.getProperties().clone(); + if(mult === 1) + { + initData.properties.setProperty("Ice.Override.ConnectTimeout", "250"); + initData.properties.setProperty("Ice.Override.Timeout", "100"); + } + else + { + initData.properties.setProperty("Ice.Override.ConnectTimeout", "5000"); + initData.properties.setProperty("Ice.Override.Timeout", "2000"); + } + const comm = Ice.initialize(initData); + let to = Test.TimeoutPrx.uncheckedCast(comm.stringToProxy(ref)); + await connect(to); + await controller.holdAdapter(-1); + + try + { + await to.sendData(seq); // Expect TimeoutException. + test(false); + } + catch(ex) + { + test(ex instanceof Ice.TimeoutException, ex); + } + finally + { + await controller.resumeAdapter(); + } + await timeout.op(); + // + // Calling ice_timeout() should have no effect. + // + to = Test.TimeoutPrx.uncheckedCast(to.ice_timeout(1000 * mult)); + await connect(to); + await controller.holdAdapter(-1); + try + { + await to.sendData(seq); // Expect TimeoutException. + test(false); + } + catch(ex) + { + test(ex instanceof Ice.TimeoutException, ex); + } + finally + { + await controller.resumeAdapter(); + } + await timeout.op(); + await comm.destroy(); + } + + // Small delay is useful for IE which doesn't like too many connection failures in a row + await Ice.Promise.delay(500); + { + // + // Test Ice.Override.ConnectTimeout. + // + const initData = new Ice.InitializationData(); + initData.properties = communicator.getProperties().clone(); + if(mult === 1) + { + initData.properties.setProperty("Ice.Override.ConnectTimeout", "250"); + } + else + { + initData.properties.setProperty("Ice.Override.ConnectTimeout", "1000"); + } + const comm = Ice.initialize(initData); + let to = Test.TimeoutPrx.uncheckedCast(comm.stringToProxy(ref)); + await controller.holdAdapter(-1); + + try + { + await to.op(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ConnectTimeoutException, ex); + } + finally + { + await controller.resumeAdapter(); + } + await timeout.op(); + await controller.holdAdapter(-1); + + // + // Calling ice_timeout() should have no effect on the connect timeout. + // + to = Test.TimeoutPrx.uncheckedCast(to.ice_timeout(1000 * mult)); + + try + { + await to.op(); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.ConnectTimeoutException, ex); + } + finally + { + await controller.resumeAdapter(); + } + await timeout.op(); // Ensure adapter is active + + // + // Verify that timeout set via ice_timeout() is still used for requests. + // + to = Test.TimeoutPrx.uncheckedCast(to.ice_timeout(100 * mult)); + await connect(to); // Force connection. + await controller.holdAdapter(-1); + + try + { + await to.sendData(seq); + test(false); + } + catch(ex) + { + test(ex instanceof Ice.TimeoutException, ex); + } + finally + { + await controller.resumeAdapter(); + } + await timeout.op(); + await comm.destroy(); + } + + // Small delay is useful for IE which doesn't like too many connection failures in a row + await Ice.Promise.delay(500); + { + // + // Test Ice.Override.CloseTimeout. + // + const initData = new Ice.InitializationData(); + initData.properties = communicator.getProperties().clone(); + initData.properties.setProperty("Ice.Override.CloseTimeout", "100"); + const comm = Ice.initialize(initData); + await comm.stringToProxy(ref).ice_getConnection(); + + await controller.holdAdapter(-1); + + const start = Date.now(); + await comm.destroy(); + const end = Date.now(); + try + { + test(end - start < mult * 2000); + } + finally + { + await controller.resumeAdapter(); + } + out.writeLine("ok"); + await controller.shutdown(); + } + } + + async run(args:string[]) + { + let communicator:Ice.Communicator; + try + { + const [properties] = this.createTestProperties(args); + // + // For this test, we want to disable retries. + // + properties.setProperty("Ice.RetryIntervals", "-1"); + + // + // We don't want connection warnings because of the timeout + // + properties.setProperty("Ice.Warn.Connections", "0"); + properties.setProperty("Ice.PrintStackTraces", "1"); + + [communicator] = this.initialize(properties); + await this.allTests(); + } + finally + { + if(communicator) + { + await communicator.destroy(); + } + } + } +} diff --git a/js/test/ts/Ice/timeout/Test.ice b/js/test/ts/Ice/timeout/Test.ice new file mode 100644 index 00000000000..87655462f50 --- /dev/null +++ b/js/test/ts/Ice/timeout/Test.ice @@ -0,0 +1,31 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +sequence<byte> ByteSeq; + +interface Timeout +{ + void op(); + void sendData(ByteSeq seq); + void sleep(int to); +} + +interface Controller +{ + void holdAdapter(int to); + void resumeAdapter(); + void shutdown(); +} + +} diff --git a/js/test/ts/Slice/macros/Client.ts b/js/test/ts/Slice/macros/Client.ts new file mode 100644 index 00000000000..f50de29f293 --- /dev/null +++ b/js/test/ts/Slice/macros/Client.ts @@ -0,0 +1,42 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +import {Ice} from "ice"; +import {Test} from "./Test"; +import {TestHelper} from "../../../Common/TestHelper"; + +const test = TestHelper.test; + +export class Client extends TestHelper +{ + allTests() + { + const out = this.getWriter(); + out.write("testing Slice predefined macros... "); + + const d = new Test._Default(); + test(d.x == 10); + test(d.y == 10); + + const nd = new Test.NoDefault(); + test(nd.x != 10); + test(nd.y != 10); + + const c = new Test.JsOnly(); + test(c.lang == "js"); + test(c.version == Ice.intVersion()); + + out.writeLine("ok"); + } + + run(args:string[]) + { + this.allTests(); + } +} diff --git a/js/test/ts/Slice/macros/Test.ice b/js/test/ts/Slice/macros/Test.ice new file mode 100644 index 00000000000..d3ebc7f181d --- /dev/null +++ b/js/test/ts/Slice/macros/Test.ice @@ -0,0 +1,54 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +// +// This macro sets the default value only when compiling with slice2js. +// +#ifdef __SLICE2JS__ +# define DEFAULT(X) = X +#else +# define DEFAULT(X) /**/ +#endif + +// +// This macro sets the default value only when not compiling with slice2js. +// +#ifndef __SLICE2JS__ +# define NODEFAULT(X) = X +#else +# define NODEFAULT(X) /**/ +#endif + +module Test +{ + +class Default +{ + int x DEFAULT(10); + int y DEFAULT(10); +} + +class NoDefault +{ + int x NODEFAULT(10); + int y NODEFAULT(10); +} + +// +// This class is only defined when compiling with slice2js. +// +#ifdef __SLICE2JS__ +class JsOnly +{ + string lang DEFAULT("js"); + int version DEFAULT(ICE_VERSION); +} +#endif + +} diff --git a/scripts/Component.py b/scripts/Component.py index 4144c75b8a6..6e339e4d59e 100644 --- a/scripts/Component.py +++ b/scripts/Component.py @@ -119,6 +119,9 @@ class Ice(Component): "Ice/plugin", "Ice/logger", "Ice/properties"]) + elif isinstance(mapping, JavaScriptMapping): + return ([], + ["ts/*"] + (["Slice/escape", "Ice/properties"] if config.typescript else [])) return ([], []) def canRun(self, testId, mapping, current): diff --git a/scripts/Util.py b/scripts/Util.py index 1abbd1e00ab..64eda187962 100644 --- a/scripts/Util.py +++ b/scripts/Util.py @@ -543,6 +543,7 @@ class Mapping(object): self.uwp = False self.openssl = False self.browser = False + self.typescript = False self.device = "" self.avd = "" self.androidemulator = False @@ -3647,7 +3648,7 @@ class JavaScriptMapping(Mapping): @classmethod def getSupportedArgs(self): - return ("", ["es5", "browser=", "worker"]) + return ("", ["es5", "browser=", "worker", "typescript"]) @classmethod def usage(self): @@ -3656,10 +3657,12 @@ class JavaScriptMapping(Mapping): print("--es5 Use JavaScript ES5 (Babel compiled code).") print("--browser=<name> Run with the given browser.") print("--worker Run with Web workers enabled.") + print("--typescript Run TypeScript tests.") def __init__(self, options=[]): Mapping.Config.__init__(self, options) self.es5 = False + self.typescript = False self.browser = "" self.worker = False parseOptions(self, options) @@ -3671,6 +3674,7 @@ class JavaScriptMapping(Mapping): self.es5 = True def loadTestSuites(self, tests, config, filters, rfilters): + #filters = filters + ["ts"] if filters else ["ts"] Mapping.loadTestSuites(self, tests, config, filters, rfilters) self.getServerMapping().loadTestSuites(list(self.testsuites.keys()) + ["Ice/echo"], config) @@ -3703,7 +3707,12 @@ class JavaScriptMapping(Mapping): if current.config.es5: commonPath = os.path.join(commonPath, "es5") commonPath = os.path.join(commonPath, "Common") - env["NODE_PATH"] = os.pathsep.join([commonPath, self.getTestCwd(process, current)]) + testDir = self.getTestCwd(process, current) + if current.config.typescript: + env["NODE_PATH"] = os.pathsep.join([commonPath, testDir.replace(os.path.join("js", "test"), + os.path.join("js", "test", "ts"))]) + else: + env["NODE_PATH"] = os.pathsep.join([commonPath, testDir]) return env def getSSLProps(self, process, current): diff --git a/slice/Glacier2/Metrics.ice b/slice/Glacier2/Metrics.ice index 798f0fad3e4..a20f462257f 100644 --- a/slice/Glacier2/Metrics.ice +++ b/slice/Glacier2/Metrics.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "js:ice-build", "python:pkgdir:Glacier2"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "python:pkgdir:Glacier2"]] [["cpp:include:Glacier2/Config.h"]] #include <Ice/Metrics.ice> @@ -18,7 +18,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEMX"] +["objc:prefix:ICEMX", "js:module:ice"] module IceMX { diff --git a/slice/Glacier2/PermissionsVerifier.ice b/slice/Glacier2/PermissionsVerifier.ice index 748562dd703..18521b620d1 100644 --- a/slice/Glacier2/PermissionsVerifier.ice +++ b/slice/Glacier2/PermissionsVerifier.ice @@ -9,7 +9,7 @@ #pragma once -[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "js:ice-build", "python:pkgdir:Glacier2"]] +[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "python:pkgdir:Glacier2"]] [["cpp:include:Glacier2/Config.h"]] #include <Glacier2/SSLInfo.ice> @@ -18,7 +18,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:GLACIER2"] +["objc:prefix:GLACIER2", "js:module:ice"] module Glacier2 { diff --git a/slice/Glacier2/PermissionsVerifierF.ice b/slice/Glacier2/PermissionsVerifierF.ice index 57c60717053..46695f5d937 100644 --- a/slice/Glacier2/PermissionsVerifierF.ice +++ b/slice/Glacier2/PermissionsVerifierF.ice @@ -9,13 +9,13 @@ #pragma once -[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "js:ice-build", "python:pkgdir:Glacier2"]] +[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "python:pkgdir:Glacier2"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:GLACIER2"] +["objc:prefix:GLACIER2", "js:module:ice"] module Glacier2 { diff --git a/slice/Glacier2/Router.ice b/slice/Glacier2/Router.ice index 2ef405d94f0..bd01298167b 100644 --- a/slice/Glacier2/Router.ice +++ b/slice/Glacier2/Router.ice @@ -9,7 +9,7 @@ #pragma once -[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "js:ice-build", "python:pkgdir:Glacier2"]] +[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "python:pkgdir:Glacier2"]] [["cpp:include:Glacier2/Config.h"]] #include <Ice/Router.ice> @@ -28,7 +28,7 @@ * security solution that is both non-intrusive and easy to configure. * **/ -["objc:prefix:GLACIER2"] +["objc:prefix:GLACIER2", "js:module:ice"] module Glacier2 { diff --git a/slice/Glacier2/RouterF.ice b/slice/Glacier2/RouterF.ice index a413c72b065..7e261550daa 100644 --- a/slice/Glacier2/RouterF.ice +++ b/slice/Glacier2/RouterF.ice @@ -9,13 +9,13 @@ #pragma once -[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "js:ice-build", "python:pkgdir:Glacier2"]] +[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "python:pkgdir:Glacier2"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:GLACIER2"] +["objc:prefix:GLACIER2", "js:module:ice"] module Glacier2 { diff --git a/slice/Glacier2/SSLInfo.ice b/slice/Glacier2/SSLInfo.ice index eada5952c3d..3a131c49ecd 100644 --- a/slice/Glacier2/SSLInfo.ice +++ b/slice/Glacier2/SSLInfo.ice @@ -9,7 +9,7 @@ #pragma once -[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "js:ice-build", "python:pkgdir:Glacier2"]] +[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "python:pkgdir:Glacier2"]] [["cpp:include:Glacier2/Config.h"]] #include <Ice/BuiltinSequences.ice> @@ -18,7 +18,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:GLACIER2"] +["objc:prefix:GLACIER2", "js:module:ice"] module Glacier2 { diff --git a/slice/Glacier2/Session.ice b/slice/Glacier2/Session.ice index da165af247a..708d7d7ba85 100644 --- a/slice/Glacier2/Session.ice +++ b/slice/Glacier2/Session.ice @@ -9,7 +9,7 @@ #pragma once -[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "js:ice-build", "python:pkgdir:Glacier2"]] +[["cpp:header-ext:h", "cpp:dll-export:GLACIER2_API", "cpp:doxygen:include:Glacier2/Glacier2.h", "objc:header-dir:objc", "objc:dll-export:GLACIER2_API", "python:pkgdir:Glacier2"]] [["cpp:include:Glacier2/Config.h"]] #include <Ice/BuiltinSequences.ice> @@ -20,7 +20,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:GLACIER2"] +["objc:prefix:GLACIER2", "js:module:ice"] module Glacier2 { diff --git a/slice/Ice/BuiltinSequences.ice b/slice/Ice/BuiltinSequences.ice index b55d72e0af6..8beb033540d 100644 --- a/slice/Ice/BuiltinSequences.ice +++ b/slice/Ice/BuiltinSequences.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Communicator.ice b/slice/Ice/Communicator.ice index 978968e09e2..da6d33abecb 100644 --- a/slice/Ice/Communicator.ice +++ b/slice/Ice/Communicator.ice @@ -38,7 +38,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { @@ -83,7 +83,7 @@ local interface Communicator * @see ObjectAdapter#destroy * **/ - ["cpp:noexcept"] void destroy(); + ["cpp:noexcept", "js:async"] void destroy(); /** * @@ -102,7 +102,7 @@ local interface Communicator * @see ObjectAdapter#deactivate * **/ - ["cpp:noexcept"] void shutdown(); + ["cpp:noexcept", "js:async"] void shutdown(); /** * @@ -123,7 +123,7 @@ local interface Communicator * @see ObjectAdapter#waitForDeactivate * **/ - ["cpp:noexcept"] void waitForShutdown(); + ["cpp:noexcept", "js:async"] void waitForShutdown(); /** * @@ -252,7 +252,7 @@ local interface Communicator * @see Properties * **/ - ObjectAdapter createObjectAdapter(string name); + ["js:async"] ObjectAdapter createObjectAdapter(string name); /** * @@ -275,7 +275,7 @@ local interface Communicator * @see Properties * **/ - ObjectAdapter createObjectAdapterWithEndpoints(string name, string endpoints); + ["js:async"] ObjectAdapter createObjectAdapterWithEndpoints(string name, string endpoints); /** * @@ -296,7 +296,7 @@ local interface Communicator * @see Properties * **/ - ObjectAdapter createObjectAdapterWithRouter(string name, ["objc:param:router"] Router* rtr); + ["js:async"] ObjectAdapter createObjectAdapterWithRouter(string name, ["objc:param:router"] Router* rtr); /** * @@ -400,6 +400,7 @@ local interface Communicator **/ ["cpp:const", "cpp:noexcept"] Logger getLogger(); +#ifndef __SLICE2JS__ /** * * Get the observer resolver object for this communicator. @@ -408,6 +409,7 @@ local interface Communicator * **/ ["cpp:const", "cpp:noexcept"] Instrumentation::CommunicatorObserver getObserver(); +#endif /** * @@ -473,6 +475,7 @@ local interface Communicator **/ void setDefaultLocator(Locator* loc); +#ifndef __SLICE2JS__ /** * * Get the plug-in manager for this communicator. @@ -483,6 +486,7 @@ local interface Communicator * **/ ["cpp:const"] PluginManager getPluginManager(); +#endif /** * @@ -508,6 +512,7 @@ local interface Communicator **/ ["async-oneway"] void flushBatchRequests(CompressBatch compress); +#ifndef __SLICE2JS__ /** * * Add the Admin object with all its facets to the provided object adapter. @@ -593,6 +598,7 @@ local interface Communicator * **/ FacetMap findAllAdminFacets(); +#endif } #endif diff --git a/slice/Ice/CommunicatorF.ice b/slice/Ice/CommunicatorF.ice index a446d95c786..c02a81ab534 100644 --- a/slice/Ice/CommunicatorF.ice +++ b/slice/Ice/CommunicatorF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Connection.ice b/slice/Ice/Connection.ice index 00873506d4c..e526446416c 100644 --- a/slice/Ice/Connection.ice +++ b/slice/Ice/Connection.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #include <Ice/ObjectAdapterF.ice> #include <Ice/Identity.ice> @@ -19,7 +19,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { @@ -221,7 +221,7 @@ local interface Connection * * @see ConnectionClose **/ - ["cpp:noexcept"] void close(ConnectionClose mode); + ["cpp:noexcept", "js:async"] void close(ConnectionClose mode); /** * diff --git a/slice/Ice/ConnectionF.ice b/slice/Ice/ConnectionF.ice index 409322dddb3..c9970429981 100644 --- a/slice/Ice/ConnectionF.ice +++ b/slice/Ice/ConnectionF.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Current.ice b/slice/Ice/Current.ice index 378a59c58e3..a4d91b0ec7f 100644 --- a/slice/Ice/Current.ice +++ b/slice/Ice/Current.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #include <Ice/ObjectAdapterF.ice> #include <Ice/ConnectionF.ice> @@ -20,7 +20,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Endpoint.ice b/slice/Ice/Endpoint.ice index 1e055ba9b70..05d0a57c45f 100644 --- a/slice/Ice/Endpoint.ice +++ b/slice/Ice/Endpoint.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #include <Ice/Version.ice> #include <Ice/BuiltinSequences.ice> @@ -19,7 +19,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { @@ -151,7 +151,7 @@ local class EndpointInfo * The user-level interface to an endpoint. * **/ -["cpp:comparable"] +["cpp:comparable", "js:comparable"] local interface Endpoint { /** diff --git a/slice/Ice/EndpointF.ice b/slice/Ice/EndpointF.ice index 20c8d75a1c5..1b87a257ffd 100644 --- a/slice/Ice/EndpointF.ice +++ b/slice/Ice/EndpointF.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/EndpointTypes.ice b/slice/Ice/EndpointTypes.ice index 54fbef0536f..20334af5f1c 100644 --- a/slice/Ice/EndpointTypes.ice +++ b/slice/Ice/EndpointTypes.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/FacetMap.ice b/slice/Ice/FacetMap.ice index ee6aa8caa4f..6280cae1723 100644 --- a/slice/Ice/FacetMap.ice +++ b/slice/Ice/FacetMap.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Identity.ice b/slice/Ice/Identity.ice index b1ece4eddbf..1723b9a545c 100644 --- a/slice/Ice/Identity.ice +++ b/slice/Ice/Identity.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/ImplicitContext.ice b/slice/Ice/ImplicitContext.ice index 5aa6cd39db3..81a904d9348 100644 --- a/slice/Ice/ImplicitContext.ice +++ b/slice/Ice/ImplicitContext.ice @@ -18,7 +18,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/ImplicitContextF.ice b/slice/Ice/ImplicitContextF.ice index 37da7b7dac4..5be5b367036 100644 --- a/slice/Ice/ImplicitContextF.ice +++ b/slice/Ice/ImplicitContextF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Instrumentation.ice b/slice/Ice/Instrumentation.ice index 4db97acc335..ac9533048f8 100644 --- a/slice/Ice/Instrumentation.ice +++ b/slice/Ice/Instrumentation.ice @@ -19,7 +19,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/InstrumentationF.ice b/slice/Ice/InstrumentationF.ice index d386d3c30e4..2c3596a10d0 100644 --- a/slice/Ice/InstrumentationF.ice +++ b/slice/Ice/InstrumentationF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/LocalException.ice b/slice/Ice/LocalException.ice index 6f2d1494045..8ec3d057306 100644 --- a/slice/Ice/LocalException.ice +++ b/slice/Ice/LocalException.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #include <Ice/Identity.ice> #include <Ice/Version.ice> @@ -19,7 +19,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Locator.ice b/slice/Ice/Locator.ice index 97d23e56af4..00cb45acf93 100644 --- a/slice/Ice/Locator.ice +++ b/slice/Ice/Locator.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #include <Ice/Identity.ice> #include <Ice/Process.ice> @@ -18,7 +18,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/LocatorF.ice b/slice/Ice/LocatorF.ice index a61e639fbbc..1d349f4dc85 100644 --- a/slice/Ice/LocatorF.ice +++ b/slice/Ice/LocatorF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Logger.ice b/slice/Ice/Logger.ice index 9850455c6f9..84e8021ddb1 100644 --- a/slice/Ice/Logger.ice +++ b/slice/Ice/Logger.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/LoggerF.ice b/slice/Ice/LoggerF.ice index ba7786e40bf..1ddbbb874ef 100644 --- a/slice/Ice/LoggerF.ice +++ b/slice/Ice/LoggerF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Metrics.ice b/slice/Ice/Metrics.ice index d21a37a67db..ae039219c3f 100644 --- a/slice/Ice/Metrics.ice +++ b/slice/Ice/Metrics.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #include <Ice/BuiltinSequences.ice> @@ -24,7 +24,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEMX"] +["objc:prefix:ICEMX", "js:module:ice"] module IceMX { @@ -352,8 +352,7 @@ class CollocatedMetrics extends ChildInvocationMetrics /** * * Provides information on invocations that are specifically sent over - * Ice connections. Remote metrics are embedded within {@link - * InvocationMetrics}. + * Ice connections. Remote metrics are embedded within {@link InvocationMetrics}. * **/ class RemoteMetrics extends ChildInvocationMetrics diff --git a/slice/Ice/ObjectAdapter.ice b/slice/Ice/ObjectAdapter.ice index 196ea3b1f42..e4426951cc1 100644 --- a/slice/Ice/ObjectAdapter.ice +++ b/slice/Ice/ObjectAdapter.ice @@ -22,7 +22,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { @@ -71,7 +71,7 @@ local interface ObjectAdapter * @see #deactivate * **/ - void activate(); + ["js:async"] void activate(); /** * @@ -101,7 +101,7 @@ local interface ObjectAdapter * @see Communicator#waitForShutdown * **/ - void waitForHold(); + ["js:async"] void waitForHold(); /** * @@ -128,7 +128,7 @@ local interface ObjectAdapter * @see Communicator#shutdown * **/ - ["cpp:noexcept"] void deactivate(); + ["cpp:noexcept", "js:async"] void deactivate(); /** * @@ -142,7 +142,7 @@ local interface ObjectAdapter * @see Communicator#waitForShutdown * **/ - ["cpp:noexcept"] void waitForDeactivate(); + ["cpp:noexcept", "js:async"] void waitForDeactivate(); /** * @@ -169,7 +169,7 @@ local interface ObjectAdapter * @see Communicator#destroy * **/ - ["cpp:noexcept"] void destroy(); + ["cpp:noexcept", "js:async"] void destroy(); /** * @@ -659,7 +659,7 @@ local interface ObjectAdapter * an object adapter if the network interfaces used by a host changes. * **/ - void refreshPublishedEndpoints(); + ["js:async"] void refreshPublishedEndpoints(); /** * diff --git a/slice/Ice/ObjectAdapterF.ice b/slice/Ice/ObjectAdapterF.ice index 3be96fedc94..41a6bf42ea7 100644 --- a/slice/Ice/ObjectAdapterF.ice +++ b/slice/Ice/ObjectAdapterF.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/ObjectFactory.ice b/slice/Ice/ObjectFactory.ice index 50a0bbcd1ca..e4bd4bda195 100644 --- a/slice/Ice/ObjectFactory.ice +++ b/slice/Ice/ObjectFactory.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Plugin.ice b/slice/Ice/Plugin.ice index 5d533342065..e9e84c66224 100644 --- a/slice/Ice/Plugin.ice +++ b/slice/Ice/Plugin.ice @@ -19,7 +19,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/PluginF.ice b/slice/Ice/PluginF.ice index 310734773b2..65f27ad3d90 100644 --- a/slice/Ice/PluginF.ice +++ b/slice/Ice/PluginF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Process.ice b/slice/Ice/Process.ice index fd97d49cd83..bcb87364610 100644 --- a/slice/Ice/Process.ice +++ b/slice/Ice/Process.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/ProcessF.ice b/slice/Ice/ProcessF.ice index 79e84cf0807..395340da35a 100644 --- a/slice/Ice/ProcessF.ice +++ b/slice/Ice/ProcessF.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Properties.ice b/slice/Ice/Properties.ice index 0a610e58362..ef248a858ab 100644 --- a/slice/Ice/Properties.ice +++ b/slice/Ice/Properties.ice @@ -17,7 +17,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { @@ -211,6 +211,7 @@ local interface Properties **/ StringSeq parseIceCommandLineOptions(StringSeq options); +#ifndef __SLICE2JS__ /** * * Load properties from a file. @@ -219,6 +220,7 @@ local interface Properties * **/ void load(string file); +#endif /** * diff --git a/slice/Ice/PropertiesAdmin.ice b/slice/Ice/PropertiesAdmin.ice index 03abfaf7467..4153a3693d8 100644 --- a/slice/Ice/PropertiesAdmin.ice +++ b/slice/Ice/PropertiesAdmin.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #include <Ice/BuiltinSequences.ice> @@ -17,7 +17,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/PropertiesF.ice b/slice/Ice/PropertiesF.ice index a426ca2c42b..edbb2051cda 100644 --- a/slice/Ice/PropertiesF.ice +++ b/slice/Ice/PropertiesF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/RemoteLogger.ice b/slice/Ice/RemoteLogger.ice index 76b73f24278..1f2c9a6b497 100644 --- a/slice/Ice/RemoteLogger.ice +++ b/slice/Ice/RemoteLogger.ice @@ -11,14 +11,14 @@ #include <Ice/BuiltinSequences.ice> -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] [["cpp:include:list"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Router.ice b/slice/Ice/Router.ice index 038be2640dc..3d9799a4ea2 100644 --- a/slice/Ice/Router.ice +++ b/slice/Ice/Router.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #include <Ice/BuiltinSequences.ice> @@ -17,7 +17,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/RouterF.ice b/slice/Ice/RouterF.ice index 1713106d385..3801ab05ad7 100644 --- a/slice/Ice/RouterF.ice +++ b/slice/Ice/RouterF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/ServantLocator.ice b/slice/Ice/ServantLocator.ice index 9404da20f9f..5f8abfb553a 100644 --- a/slice/Ice/ServantLocator.ice +++ b/slice/Ice/ServantLocator.ice @@ -18,7 +18,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/ServantLocatorF.ice b/slice/Ice/ServantLocatorF.ice index 832eeab51fb..342a00d6159 100644 --- a/slice/Ice/ServantLocatorF.ice +++ b/slice/Ice/ServantLocatorF.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/SliceChecksumDict.ice b/slice/Ice/SliceChecksumDict.ice index 8748f5e0c3b..365cfa16dbc 100644 --- a/slice/Ice/SliceChecksumDict.ice +++ b/slice/Ice/SliceChecksumDict.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/ValueFactory.ice b/slice/Ice/ValueFactory.ice index be32bd98401..b9f162379aa 100644 --- a/slice/Ice/ValueFactory.ice +++ b/slice/Ice/ValueFactory.ice @@ -15,7 +15,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/Ice/Version.ice b/slice/Ice/Version.ice index 558ba3d0119..2f012161536 100644 --- a/slice/Ice/Version.ice +++ b/slice/Ice/Version.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "js:ice-build", "python:pkgdir:Ice"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICE_API", "cpp:doxygen:include:Ice/Ice.h", "objc:header-dir:objc", "objc:dll-export:ICE_API", "python:pkgdir:Ice"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICE"] +["objc:prefix:ICE", "js:module:ice"] module Ice { diff --git a/slice/IceBT/EndpointInfo.ice b/slice/IceBT/EndpointInfo.ice index 4d528d2efb4..d59bde1aada 100644 --- a/slice/IceBT/EndpointInfo.ice +++ b/slice/IceBT/EndpointInfo.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEBT_API", "cpp:doxygen:include:IceBT/IceBT.h", "objc:header-dir:objc", "js:ice-build", "python:pkgdir:IceBT"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEBT_API", "cpp:doxygen:include:IceBT/IceBT.h", "objc:header-dir:objc", "python:pkgdir:IceBT"]] #include <Ice/Endpoint.ice> diff --git a/slice/IceGrid/Admin.ice b/slice/IceGrid/Admin.ice index d023418fd48..47f40293d6d 100644 --- a/slice/IceGrid/Admin.ice +++ b/slice/IceGrid/Admin.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "js:ice-build", "python:pkgdir:IceGrid"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "python:pkgdir:IceGrid"]] [["cpp:include:IceGrid/Config.h"]] #include <Ice/Identity.ice> @@ -24,7 +24,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEGRID"] +["objc:prefix:ICEGRID", "js:module:ice"] module IceGrid { diff --git a/slice/IceGrid/Descriptor.ice b/slice/IceGrid/Descriptor.ice index ce39f0bdd7c..a8878bba345 100644 --- a/slice/IceGrid/Descriptor.ice +++ b/slice/IceGrid/Descriptor.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "js:ice-build", "python:pkgdir:IceGrid"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "python:pkgdir:IceGrid"]] #ifndef ICE_BUILDING_ICEGRIDDB [["cpp:dll-export:ICEGRID_API", "objc:dll-export:ICEGRID_API"]] @@ -24,7 +24,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEGRID"] +["objc:prefix:ICEGRID", "js:module:ice"] module IceGrid { diff --git a/slice/IceGrid/Exception.ice b/slice/IceGrid/Exception.ice index c56e62d6b8a..696da6fcd78 100644 --- a/slice/IceGrid/Exception.ice +++ b/slice/IceGrid/Exception.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "js:ice-build", "python:pkgdir:IceGrid"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "python:pkgdir:IceGrid"]] #ifndef ICE_BUILDING_ICEGRIDDB [["cpp:dll-export:ICEGRID_API", "objc:dll-export:ICEGRID_API"]] @@ -24,7 +24,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEGRID"] +["objc:prefix:ICEGRID", "js:module:ice"] module IceGrid { diff --git a/slice/IceGrid/FileParser.ice b/slice/IceGrid/FileParser.ice index 9a8c3e3d3fb..2d3d930f3b8 100644 --- a/slice/IceGrid/FileParser.ice +++ b/slice/IceGrid/FileParser.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "js:ice-build", "python:pkgdir:IceGrid"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "python:pkgdir:IceGrid"]] [["cpp:include:IceGrid/Config.h"]] #include <IceGrid/Admin.ice> @@ -18,7 +18,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEGRID"] +["objc:prefix:ICEGRID", "js:module:ice"] module IceGrid { diff --git a/slice/IceGrid/PluginFacade.ice b/slice/IceGrid/PluginFacade.ice index 1c1fc3c612f..51917db5872 100644 --- a/slice/IceGrid/PluginFacade.ice +++ b/slice/IceGrid/PluginFacade.ice @@ -21,7 +21,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEGRID"] +["objc:prefix:ICEGRID", "js:module:ice"] module IceGrid { diff --git a/slice/IceGrid/Registry.ice b/slice/IceGrid/Registry.ice index 4f99025ee23..dae186d65a4 100644 --- a/slice/IceGrid/Registry.ice +++ b/slice/IceGrid/Registry.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "js:ice-build", "python:pkgdir:IceGrid"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "python:pkgdir:IceGrid"]] [["cpp:include:IceGrid/Config.h"]] #include <IceGrid/Exception.ice> @@ -21,7 +21,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEGRID"] +["objc:prefix:ICEGRID", "js:module:ice"] module IceGrid { diff --git a/slice/IceGrid/Session.ice b/slice/IceGrid/Session.ice index b595fa19b8c..65d5147289d 100644 --- a/slice/IceGrid/Session.ice +++ b/slice/IceGrid/Session.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "js:ice-build", "python:pkgdir:IceGrid"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "python:pkgdir:IceGrid"]] [["cpp:include:IceGrid/Config.h"]] #include <Glacier2/Session.ice> @@ -19,7 +19,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEGRID"] +["objc:prefix:ICEGRID", "js:module:ice"] module IceGrid { diff --git a/slice/IceGrid/UserAccountMapper.ice b/slice/IceGrid/UserAccountMapper.ice index 1fd619b8202..439162ef871 100644 --- a/slice/IceGrid/UserAccountMapper.ice +++ b/slice/IceGrid/UserAccountMapper.ice @@ -9,14 +9,14 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "js:ice-build", "python:pkgdir:IceGrid"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICEGRID_API", "cpp:doxygen:include:IceGrid/IceGrid.h", "objc:header-dir:objc", "objc:dll-export:ICEGRID_API", "python:pkgdir:IceGrid"]] [["cpp:include:IceGrid/Config.h"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEGRID"] +["objc:prefix:ICEGRID", "js:module:ice"] module IceGrid { diff --git a/slice/IceSSL/ConnectionInfo.ice b/slice/IceSSL/ConnectionInfo.ice index c0ba59eb936..12a335217d0 100644 --- a/slice/IceSSL/ConnectionInfo.ice +++ b/slice/IceSSL/ConnectionInfo.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESSL_API", "cpp:doxygen:include:IceSSL/IceSSL.h", "objc:header-dir:objc", "objc:dll-export:ICESSL_API", "js:ice-build", "python:pkgdir:IceSSL"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESSL_API", "cpp:doxygen:include:IceSSL/IceSSL.h", "objc:header-dir:objc", "objc:dll-export:ICESSL_API", "python:pkgdir:IceSSL"]] [["cpp:include:IceSSL/Plugin.h"]] @@ -19,7 +19,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICESSL"] +["objc:prefix:ICESSL", "js:module:ice"] module IceSSL { diff --git a/slice/IceSSL/ConnectionInfoF.ice b/slice/IceSSL/ConnectionInfoF.ice index 8540fc63f78..dddd4d5d17c 100644 --- a/slice/IceSSL/ConnectionInfoF.ice +++ b/slice/IceSSL/ConnectionInfoF.ice @@ -9,13 +9,13 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESSL_API", "cpp:doxygen:include:IceSSL/IceSSL.h", "objc:header-dir:objc", "objc:dll-export:ICESSL_API", "js:ice-build", "python:pkgdir:IceSSL"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESSL_API", "cpp:doxygen:include:IceSSL/IceSSL.h", "objc:header-dir:objc", "objc:dll-export:ICESSL_API", "python:pkgdir:IceSSL"]] #ifndef __SLICE2JAVA_COMPAT__ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICESSL"] +["objc:prefix:ICESSL", "js:module:ice"] module IceSSL { diff --git a/slice/IceSSL/EndpointInfo.ice b/slice/IceSSL/EndpointInfo.ice index a54ff31c4f9..426ee808848 100644 --- a/slice/IceSSL/EndpointInfo.ice +++ b/slice/IceSSL/EndpointInfo.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESSL_API", "cpp:doxygen:include:IceSSL/IceSSL.h", "objc:header-dir:objc", "objc:dll-export:ICESSL_API", "js:ice-build", "python:pkgdir:IceSSL"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESSL_API", "cpp:doxygen:include:IceSSL/IceSSL.h", "objc:header-dir:objc", "objc:dll-export:ICESSL_API", "python:pkgdir:IceSSL"]] #include <Ice/Endpoint.ice> @@ -22,7 +22,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICESSL"] +["objc:prefix:ICESSL", "js:module:ice"] module IceSSL { diff --git a/slice/IceStorm/IceStorm.ice b/slice/IceStorm/IceStorm.ice index 492fde2bbe4..32b2b546638 100644 --- a/slice/IceStorm/IceStorm.ice +++ b/slice/IceStorm/IceStorm.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESTORM_API", "cpp:doxygen:include:IceStorm/IceStorm.h", "objc:header-dir:objc", "objc:dll-export:ICESTORM_API", "js:ice-build", "python:pkgdir:IceStorm"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESTORM_API", "cpp:doxygen:include:IceStorm/IceStorm.h", "objc:header-dir:objc", "objc:dll-export:ICESTORM_API", "python:pkgdir:IceStorm"]] [["cpp:include:IceStorm/Config.h"]] #include <Ice/Identity.ice> @@ -29,7 +29,7 @@ * easy as invoking a method on an interface. * **/ -["objc:prefix:ICESTORM"] +["objc:prefix:ICESTORM", "js:module:ice"] module IceStorm { diff --git a/slice/IceStorm/Metrics.ice b/slice/IceStorm/Metrics.ice index 2d9a2404fbd..fec7d3545b2 100644 --- a/slice/IceStorm/Metrics.ice +++ b/slice/IceStorm/Metrics.ice @@ -9,7 +9,7 @@ #pragma once -[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESTORM_API", "cpp:doxygen:include:IceStorm/IceStorm.h", "objc:header-dir:objc", "objc:dll-export:ICESTORM_API", "js:ice-build", "python:pkgdir:IceStorm"]] +[["ice-prefix", "cpp:header-ext:h", "cpp:dll-export:ICESTORM_API", "cpp:doxygen:include:IceStorm/IceStorm.h", "objc:header-dir:objc", "objc:dll-export:ICESTORM_API", "python:pkgdir:IceStorm"]] [["cpp:include:IceStorm/Config.h"]] #include <Ice/Metrics.ice> @@ -18,7 +18,7 @@ [["java:package:com.zeroc"]] #endif -["objc:prefix:ICEMX"] +["objc:prefix:ICEMX", "js:module:ice"] module IceMX { |