expo-modules-test-core 0.18.1 → 0.18.2-canary-20240927-ab8a962
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +6 -6
- package/android/src/main/java/expo/modules/test/core/legacy/ModuleMock.kt +2 -2
- package/build/getStructure.d.ts.map +1 -1
- package/build/getStructure.js +19 -16
- package/build/getStructure.js.map +1 -1
- package/build/mockgen.d.ts.map +1 -1
- package/build/mockgen.js +78 -17
- package/build/mockgen.js.map +1 -1
- package/build/types.d.ts +3 -2
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/expo-modules-test-core-0.18.2-canary-20240927-ab8a962.tgz +0 -0
- package/ios/ExpoModulesTestCore.podspec +3 -1
- package/package.json +2 -2
- package/src/getStructure.ts +32 -24
- package/src/mockgen.ts +148 -52
- package/src/types.ts +4 -2
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
|
|
3
3
|
group = 'org.unimodules'
|
|
4
|
-
version = '0.18.
|
|
4
|
+
version = '0.18.0'
|
|
5
5
|
|
|
6
6
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
7
|
apply from: expoModulesCorePlugin
|
|
@@ -14,7 +14,7 @@ android {
|
|
|
14
14
|
namespace "org.unimodules.test.core"
|
|
15
15
|
defaultConfig {
|
|
16
16
|
versionCode 3
|
|
17
|
-
versionName '0.18.
|
|
17
|
+
versionName '0.18.0'
|
|
18
18
|
}
|
|
19
19
|
packagingOptions {
|
|
20
20
|
resources {
|
|
@@ -27,7 +27,7 @@ android {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
dependencies {
|
|
30
|
-
api 'androidx.test:core:1.
|
|
30
|
+
api 'androidx.test:core:1.6.1'
|
|
31
31
|
api 'junit:junit:4.13.2'
|
|
32
32
|
api('io.mockk:mockk:1.13.5') {
|
|
33
33
|
// jupiter is junit 5 which we don't use
|
|
@@ -47,9 +47,9 @@ dependencies {
|
|
|
47
47
|
implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion()}"
|
|
48
48
|
|
|
49
49
|
// instrumented testing dependencies
|
|
50
|
-
api 'androidx.test.ext:junit:1.1
|
|
51
|
-
api 'androidx.test:runner:1.
|
|
52
|
-
api 'androidx.test:rules:1.
|
|
50
|
+
api 'androidx.test.ext:junit:1.2.1'
|
|
51
|
+
api 'androidx.test:runner:1.6.2'
|
|
52
|
+
api 'androidx.test:rules:1.6.1'
|
|
53
53
|
api "com.google.truth:truth:1.1.2"
|
|
54
54
|
api "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
|
|
55
55
|
}
|
|
@@ -3,7 +3,7 @@ package expo.modules.test.core.legacy
|
|
|
3
3
|
import android.content.Context
|
|
4
4
|
import android.os.Bundle
|
|
5
5
|
import androidx.test.core.app.ApplicationProvider
|
|
6
|
-
import com.facebook.react.bridge.
|
|
6
|
+
import com.facebook.react.bridge.BridgeReactContext
|
|
7
7
|
import expo.modules.core.interfaces.services.EventEmitter
|
|
8
8
|
import expo.modules.kotlin.AppContext
|
|
9
9
|
import expo.modules.kotlin.ModuleHolder
|
|
@@ -119,7 +119,7 @@ data class ModuleMock<TestInterfaceType : Any, ModuleType : Module>(
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
private fun prepareMockAppContext(customAppContext: AppContext?): AppContext {
|
|
122
|
-
val reactContext =
|
|
122
|
+
val reactContext = BridgeReactContext(ApplicationProvider.getApplicationContext<Context>())
|
|
123
123
|
val appContext = customAppContext ?: AppContext(
|
|
124
124
|
modulesProvider = mockk(relaxed = true),
|
|
125
125
|
legacyModuleRegistry = mockk(relaxed = true),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getStructure.d.ts","sourceRoot":"","sources":["../src/getStructure.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,sBAAsB,
|
|
1
|
+
{"version":3,"file":"getStructure.d.ts","sourceRoot":"","sources":["../src/getStructure.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAuQjB,wBAAgB,mCAAmC,6BAGlD"}
|
package/build/getStructure.js
CHANGED
|
@@ -166,27 +166,29 @@ function findGroupedDefinitionsOfType(type, moduleDefinition, file) {
|
|
|
166
166
|
return definitionParams.map((d) => ({ name: getIdentifierFromOffsetObject(d, file) }));
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
169
|
+
function findAndParseNestedClassesOfType(moduleDefinition, file, type) {
|
|
170
|
+
// we support reading definitions from closure only
|
|
171
|
+
const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);
|
|
172
|
+
return definitionsOfType
|
|
173
|
+
.map((df) => {
|
|
174
|
+
const nestedModuleDefinition = df['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.['key.substructure'];
|
|
175
|
+
if (!nestedModuleDefinition) {
|
|
176
|
+
console.warn('Could not parse definition');
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
const name = getIdentifierFromOffsetObject(df['key.substructure']?.[0], file).replace('.self', '');
|
|
180
|
+
// let's drop nested view field and classes (are null anyways)
|
|
181
|
+
const { views: _, classes: _2, ...definition } = parseModuleDefinition(nestedModuleDefinition, file);
|
|
182
|
+
return { ...definition, name };
|
|
183
|
+
})
|
|
184
|
+
.flatMap((f) => (f ? [f] : []));
|
|
183
185
|
}
|
|
184
186
|
function omitParamsFromClosureArguments(definitions, paramsToOmit) {
|
|
185
187
|
return definitions.map((d) => ({
|
|
186
188
|
...d,
|
|
187
189
|
types: {
|
|
188
190
|
...d.types,
|
|
189
|
-
parameters: d.types?.parameters?.filter((t, idx) =>
|
|
191
|
+
parameters: d.types?.parameters?.filter((t, idx) => !paramsToOmit.includes(t.name)) ?? [],
|
|
190
192
|
},
|
|
191
193
|
}));
|
|
192
194
|
}
|
|
@@ -206,7 +208,8 @@ function parseModuleDefinition(moduleDefinition, file) {
|
|
|
206
208
|
events: findGroupedDefinitionsOfType('Events', preparedModuleDefinition, file),
|
|
207
209
|
properties: findNamedDefinitionsOfType('Property', preparedModuleDefinition, file),
|
|
208
210
|
props: omitParamsFromClosureArguments(findNamedDefinitionsOfType('Prop', preparedModuleDefinition, file), ['view']),
|
|
209
|
-
|
|
211
|
+
views: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'View'),
|
|
212
|
+
classes: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'Class'),
|
|
210
213
|
};
|
|
211
214
|
return parsedDefinition;
|
|
212
215
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getStructure.js","sourceRoot":"","sources":["../src/getStructure.ts"],"names":[],"mappings":"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","sourcesContent":["// convert requires above to imports\nimport { execSync } from 'child_process';\nimport fsNode from 'fs';\nimport { globSync } from 'glob';\nimport XML from 'xml-js';\nimport YAML from 'yaml';\n\nimport {\n Closure,\n CursorInfoOutput,\n FileType,\n FullyAnnotatedDecl,\n OutputModuleDefinition,\n OutputViewDefinition,\n Structure,\n} from './types';\n\nconst rootDir = process.cwd();\nconst pattern = `${rootDir}/**/*.swift`;\n\nfunction getStructureFromFile(file: FileType) {\n const command = 'sourcekitten structure --file ' + file.path;\n\n try {\n const output = execSync(command);\n return JSON.parse(output.toString());\n } catch (error) {\n console.error('An error occurred while executing the command:', error);\n }\n}\n// find an object with \"key.typename\" : \"ModuleDefinition\" somewhere in the structure and return it\nfunction findModuleDefinitionInStructure(structure: Structure): Structure[] | null {\n if (!structure) {\n return null;\n }\n if (structure?.['key.typename'] === 'ModuleDefinition') {\n const root = structure?.['key.substructure'];\n if (!root) {\n console.warn('Found ModuleDefinition but it is malformed');\n }\n return root;\n }\n const substructure = structure['key.substructure'];\n if (Array.isArray(substructure) && substructure.length > 0) {\n for (const child of substructure) {\n let result = null;\n result = findModuleDefinitionInStructure(child);\n if (result) {\n return result;\n }\n }\n }\n return null;\n}\n\n// Read string straight from file – needed since we can't get cursorinfo for modulename\nfunction getIdentifierFromOffsetObject(offsetObject: Structure, file: FileType) {\n // adding 1 and removing 1 to get rid of quotes\n return file.content\n .substring(offsetObject['key.offset'], offsetObject['key.offset'] + offsetObject['key.length'])\n .replaceAll('\"', '');\n}\n\nfunction maybeUnwrapXMLStructs(type: string | Partial<{ _text: string; 'ref.struct': string }>) {\n if (!type) {\n return type;\n }\n if (typeof type === 'string') {\n return type;\n }\n if (type['_text']) {\n return type['_text'];\n }\n if (type['ref.struct']) {\n return maybeUnwrapXMLStructs(type['ref.struct']);\n }\n return type;\n}\n\nfunction maybeWrapArray<T>(itemOrItems: T[] | T | null) {\n if (!itemOrItems) {\n return null;\n }\n if (Array.isArray(itemOrItems)) {\n return itemOrItems;\n } else {\n return [itemOrItems];\n }\n}\n\nfunction parseXMLAnnotatedDeclarations(cursorInfoOutput: CursorInfoOutput) {\n const xml = cursorInfoOutput['key.fully_annotated_decl'];\n if (!xml) {\n return null;\n }\n const parsed = XML.xml2js(xml, { compact: true }) as FullyAnnotatedDecl;\n\n const parameters =\n maybeWrapArray(parsed?.['decl.function.free']?.['decl.var.parameter'])?.map((p) => ({\n name: maybeUnwrapXMLStructs(p['decl.var.parameter.argument_label']),\n typename: maybeUnwrapXMLStructs(p['decl.var.parameter.type']),\n })) ?? [];\n const returnType = maybeUnwrapXMLStructs(\n parsed?.['decl.function.free']?.['decl.function.returntype']\n );\n return { parameters, returnType };\n}\n\nlet cachedSDKPath: string | null = null;\nfunction getSDKPath() {\n if (cachedSDKPath) {\n return cachedSDKPath;\n }\n const sdkPath = execSync('xcrun --sdk iphoneos --show-sdk-path').toString().trim();\n cachedSDKPath = sdkPath;\n return cachedSDKPath;\n}\n\n// Read type description with sourcekitten, works only for variables\nfunction getTypeFromOffsetObject(offsetObject: Structure, file: FileType) {\n if (!offsetObject) {\n return null;\n }\n const request = {\n 'key.request': 'source.request.cursorinfo',\n 'key.sourcefile': file.path,\n 'key.offset': offsetObject['key.offset'],\n 'key.compilerargs': [file.path, '-target', 'arm64-apple-ios', '-sdk', getSDKPath()],\n };\n const yamlRequest = YAML.stringify(request, {\n defaultStringType: 'QUOTE_DOUBLE',\n lineWidth: 0,\n defaultKeyType: 'PLAIN',\n // needed since behaviour of sourcekitten is not consistent\n } as any).replace('\"source.request.cursorinfo\"', 'source.request.cursorinfo');\n\n const command = 'sourcekitten request --yaml \"' + yamlRequest.replaceAll('\"', '\\\\\"') + '\"';\n try {\n const output = execSync(command, { stdio: 'pipe' });\n return parseXMLAnnotatedDeclarations(JSON.parse(output.toString()));\n } catch (error) {\n console.error('An error occurred while executing the command:', error);\n }\n return null;\n}\n\nfunction hasSubstructure(structureObject: Structure) {\n return structureObject?.['key.substructure'] && structureObject['key.substructure'].length > 0;\n}\n\nfunction parseClosureTypes(structureObject: Structure) {\n const closure = structureObject['key.substructure']?.find(\n (s) => s['key.kind'] === 'source.lang.swift.expr.closure'\n );\n if (!closure) {\n return null;\n }\n const parameters = closure['key.substructure']\n ?.filter((s) => s['key.kind'] === 'source.lang.swift.decl.var.parameter')\n .map((p) => ({ name: p['key.name'], typename: p['key.typename'] }));\n\n const returnType = closure?.['key.typename'] ?? 'unknown';\n return { parameters, returnType };\n}\n\n// Used for functions,async functions, all of shape Identifier(name, closure or function)\nfunction findNamedDefinitionsOfType(type: string, moduleDefinition: Structure[], file: FileType) {\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType.map((d) => {\n const definitionParams = d['key.substructure'];\n const name = getIdentifierFromOffsetObject(definitionParams[0], file);\n let types = null;\n if (hasSubstructure(definitionParams[1])) {\n types = parseClosureTypes(definitionParams[1]);\n } else {\n types = getTypeFromOffsetObject(definitionParams[1], file);\n }\n return { name, types };\n });\n}\n\n// Used for events\nfunction findGroupedDefinitionsOfType(type: string, moduleDefinition: Structure[], file: FileType) {\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType.flatMap((d) => {\n const definitionParams = d['key.substructure'];\n return definitionParams.map((d) => ({ name: getIdentifierFromOffsetObject(d, file) }));\n });\n}\n\nfunction findAndParseView(\n moduleDefinition: Structure[],\n file: FileType\n): null | OutputViewDefinition {\n const viewDefinition = moduleDefinition.find((md) => md['key.name'] === 'View');\n if (!viewDefinition) {\n return null;\n }\n // we support reading view definitions from closure only\n const viewModuleDefinition =\n viewDefinition['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.[\n 'key.substructure'\n ];\n if (!viewModuleDefinition) {\n console.warn('Could not parse view definition');\n return null;\n }\n // let's drop nested view field (is null anyways)\n const { view: _, ...definition } = parseModuleDefinition(viewModuleDefinition, file);\n return definition;\n}\n\nfunction omitParamsFromClosureArguments<T extends Closure>(\n definitions: T[],\n paramsToOmit: string[]\n) {\n return definitions.map((d) => ({\n ...d,\n types: {\n ...d.types,\n parameters:\n d.types?.parameters?.filter((t, idx) => idx !== 0 && !paramsToOmit.includes(t.name)) ?? [],\n },\n }));\n}\n\n// Some blocks have additional modifiers like runOnQueue – we may need to do additional traversing to get to the function definition\nfunction parseBlockModifiers(structureObject: Structure) {\n if (structureObject['key.name']?.includes('runOnQueue')) {\n return structureObject['key.substructure'][0];\n }\n return structureObject;\n}\n\nfunction parseModuleDefinition(\n moduleDefinition: Structure[],\n file: FileType\n): OutputModuleDefinition {\n const preparedModuleDefinition = moduleDefinition.map(parseBlockModifiers);\n const parsedDefinition = {\n name: findNamedDefinitionsOfType('Name', preparedModuleDefinition, file)?.[0]?.name,\n functions: findNamedDefinitionsOfType('Function', preparedModuleDefinition, file),\n asyncFunctions: omitParamsFromClosureArguments(\n findNamedDefinitionsOfType('AsyncFunction', preparedModuleDefinition, file),\n ['promise']\n ),\n events: findGroupedDefinitionsOfType('Events', preparedModuleDefinition, file),\n properties: findNamedDefinitionsOfType('Property', preparedModuleDefinition, file),\n props: omitParamsFromClosureArguments(\n findNamedDefinitionsOfType('Prop', preparedModuleDefinition, file),\n ['view']\n ),\n view: findAndParseView(preparedModuleDefinition, file),\n };\n return parsedDefinition;\n}\n\nfunction findModuleDefinitionsInFiles(files: string[]) {\n const modules = [];\n for (const path of files) {\n const file = { path, content: fsNode.readFileSync(path, 'utf8') };\n const definition = findModuleDefinitionInStructure(getStructureFromFile(file));\n if (definition) {\n modules.push(parseModuleDefinition(definition, file));\n }\n }\n return modules;\n}\n\nexport function getAllExpoModulesInWorkingDirectory() {\n const files = globSync(pattern);\n return findModuleDefinitionsInFiles(files);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"getStructure.js","sourceRoot":"","sources":["../src/getStructure.ts"],"names":[],"mappings":"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","sourcesContent":["// convert requires above to imports\nimport { execSync } from 'child_process';\nimport fsNode from 'fs';\nimport { globSync } from 'glob';\nimport XML from 'xml-js';\nimport YAML from 'yaml';\n\nimport {\n Closure,\n CursorInfoOutput,\n FileType,\n FullyAnnotatedDecl,\n OutputModuleDefinition,\n Structure,\n} from './types';\n\nconst rootDir = process.cwd();\nconst pattern = `${rootDir}/**/*.swift`;\n\nfunction getStructureFromFile(file: FileType) {\n const command = 'sourcekitten structure --file ' + file.path;\n\n try {\n const output = execSync(command);\n return JSON.parse(output.toString());\n } catch (error) {\n console.error('An error occurred while executing the command:', error);\n }\n}\n// find an object with \"key.typename\" : \"ModuleDefinition\" somewhere in the structure and return it\nfunction findModuleDefinitionInStructure(structure: Structure): Structure[] | null {\n if (!structure) {\n return null;\n }\n if (structure?.['key.typename'] === 'ModuleDefinition') {\n const root = structure?.['key.substructure'];\n if (!root) {\n console.warn('Found ModuleDefinition but it is malformed');\n }\n return root;\n }\n const substructure = structure['key.substructure'];\n if (Array.isArray(substructure) && substructure.length > 0) {\n for (const child of substructure) {\n let result = null;\n result = findModuleDefinitionInStructure(child);\n if (result) {\n return result;\n }\n }\n }\n return null;\n}\n\n// Read string straight from file – needed since we can't get cursorinfo for modulename\nfunction getIdentifierFromOffsetObject(offsetObject: Structure, file: FileType) {\n // adding 1 and removing 1 to get rid of quotes\n return file.content\n .substring(offsetObject['key.offset'], offsetObject['key.offset'] + offsetObject['key.length'])\n .replaceAll('\"', '');\n}\n\nfunction maybeUnwrapXMLStructs(type: string | Partial<{ _text: string; 'ref.struct': string }>) {\n if (!type) {\n return type;\n }\n if (typeof type === 'string') {\n return type;\n }\n if (type['_text']) {\n return type['_text'];\n }\n if (type['ref.struct']) {\n return maybeUnwrapXMLStructs(type['ref.struct']);\n }\n return type;\n}\n\nfunction maybeWrapArray<T>(itemOrItems: T[] | T | null) {\n if (!itemOrItems) {\n return null;\n }\n if (Array.isArray(itemOrItems)) {\n return itemOrItems;\n } else {\n return [itemOrItems];\n }\n}\n\nfunction parseXMLAnnotatedDeclarations(cursorInfoOutput: CursorInfoOutput) {\n const xml = cursorInfoOutput['key.fully_annotated_decl'];\n if (!xml) {\n return null;\n }\n const parsed = XML.xml2js(xml, { compact: true }) as FullyAnnotatedDecl;\n\n const parameters =\n maybeWrapArray(parsed?.['decl.function.free']?.['decl.var.parameter'])?.map((p) => ({\n name: maybeUnwrapXMLStructs(p['decl.var.parameter.argument_label']),\n typename: maybeUnwrapXMLStructs(p['decl.var.parameter.type']),\n })) ?? [];\n const returnType = maybeUnwrapXMLStructs(\n parsed?.['decl.function.free']?.['decl.function.returntype']\n );\n return { parameters, returnType };\n}\n\nlet cachedSDKPath: string | null = null;\nfunction getSDKPath() {\n if (cachedSDKPath) {\n return cachedSDKPath;\n }\n const sdkPath = execSync('xcrun --sdk iphoneos --show-sdk-path').toString().trim();\n cachedSDKPath = sdkPath;\n return cachedSDKPath;\n}\n\n// Read type description with sourcekitten, works only for variables\nfunction getTypeFromOffsetObject(offsetObject: Structure, file: FileType) {\n if (!offsetObject) {\n return null;\n }\n const request = {\n 'key.request': 'source.request.cursorinfo',\n 'key.sourcefile': file.path,\n 'key.offset': offsetObject['key.offset'],\n 'key.compilerargs': [file.path, '-target', 'arm64-apple-ios', '-sdk', getSDKPath()],\n };\n const yamlRequest = YAML.stringify(request, {\n defaultStringType: 'QUOTE_DOUBLE',\n lineWidth: 0,\n defaultKeyType: 'PLAIN',\n // needed since behaviour of sourcekitten is not consistent\n } as any).replace('\"source.request.cursorinfo\"', 'source.request.cursorinfo');\n\n const command = 'sourcekitten request --yaml \"' + yamlRequest.replaceAll('\"', '\\\\\"') + '\"';\n try {\n const output = execSync(command, { stdio: 'pipe' });\n return parseXMLAnnotatedDeclarations(JSON.parse(output.toString()));\n } catch (error) {\n console.error('An error occurred while executing the command:', error);\n }\n return null;\n}\n\nfunction hasSubstructure(structureObject: Structure) {\n return structureObject?.['key.substructure'] && structureObject['key.substructure'].length > 0;\n}\n\nfunction parseClosureTypes(structureObject: Structure) {\n const closure = structureObject['key.substructure']?.find(\n (s) => s['key.kind'] === 'source.lang.swift.expr.closure'\n );\n if (!closure) {\n return null;\n }\n const parameters = closure['key.substructure']\n ?.filter((s) => s['key.kind'] === 'source.lang.swift.decl.var.parameter')\n .map((p) => ({ name: p['key.name'], typename: p['key.typename'] }));\n\n const returnType = closure?.['key.typename'] ?? 'unknown';\n return { parameters, returnType };\n}\n\n// Used for functions,async functions, all of shape Identifier(name, closure or function)\nfunction findNamedDefinitionsOfType(type: string, moduleDefinition: Structure[], file: FileType) {\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType.map((d) => {\n const definitionParams = d['key.substructure'];\n const name = getIdentifierFromOffsetObject(definitionParams[0], file);\n let types = null;\n if (hasSubstructure(definitionParams[1])) {\n types = parseClosureTypes(definitionParams[1]);\n } else {\n types = getTypeFromOffsetObject(definitionParams[1], file);\n }\n return { name, types };\n });\n}\n\n// Used for events\nfunction findGroupedDefinitionsOfType(type: string, moduleDefinition: Structure[], file: FileType) {\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType.flatMap((d) => {\n const definitionParams = d['key.substructure'];\n return definitionParams.map((d) => ({ name: getIdentifierFromOffsetObject(d, file) }));\n });\n}\nfunction findAndParseNestedClassesOfType(\n moduleDefinition: Structure[],\n file: FileType,\n type: string\n) {\n // we support reading definitions from closure only\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType\n .map((df) => {\n const nestedModuleDefinition =\n df['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.[\n 'key.substructure'\n ];\n if (!nestedModuleDefinition) {\n console.warn('Could not parse definition');\n return null;\n }\n const name = getIdentifierFromOffsetObject(df['key.substructure']?.[0], file).replace(\n '.self',\n ''\n );\n // let's drop nested view field and classes (are null anyways)\n const {\n views: _,\n classes: _2,\n ...definition\n } = parseModuleDefinition(nestedModuleDefinition, file);\n return { ...definition, name };\n })\n .flatMap((f) => (f ? [f] : []));\n}\n\nfunction omitParamsFromClosureArguments<T extends Closure>(\n definitions: T[],\n paramsToOmit: string[]\n) {\n return definitions.map((d) => ({\n ...d,\n types: {\n ...d.types,\n parameters: d.types?.parameters?.filter((t, idx) => !paramsToOmit.includes(t.name)) ?? [],\n },\n }));\n}\n\n// Some blocks have additional modifiers like runOnQueue – we may need to do additional traversing to get to the function definition\nfunction parseBlockModifiers(structureObject: Structure) {\n if (structureObject['key.name']?.includes('runOnQueue')) {\n return structureObject['key.substructure'][0];\n }\n return structureObject;\n}\n\nfunction parseModuleDefinition(\n moduleDefinition: Structure[],\n file: FileType\n): OutputModuleDefinition {\n const preparedModuleDefinition = moduleDefinition.map(parseBlockModifiers);\n const parsedDefinition = {\n name: findNamedDefinitionsOfType('Name', preparedModuleDefinition, file)?.[0]?.name,\n functions: findNamedDefinitionsOfType('Function', preparedModuleDefinition, file),\n asyncFunctions: omitParamsFromClosureArguments(\n findNamedDefinitionsOfType('AsyncFunction', preparedModuleDefinition, file),\n ['promise']\n ),\n events: findGroupedDefinitionsOfType('Events', preparedModuleDefinition, file),\n properties: findNamedDefinitionsOfType('Property', preparedModuleDefinition, file),\n props: omitParamsFromClosureArguments(\n findNamedDefinitionsOfType('Prop', preparedModuleDefinition, file),\n ['view']\n ),\n views: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'View'),\n classes: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'Class'),\n };\n return parsedDefinition;\n}\n\nfunction findModuleDefinitionsInFiles(files: string[]) {\n const modules = [];\n for (const path of files) {\n const file = { path, content: fsNode.readFileSync(path, 'utf8') };\n const definition = findModuleDefinitionInStructure(getStructureFromFile(file));\n if (definition) {\n modules.push(parseModuleDefinition(definition, file));\n }\n }\n return modules;\n}\n\nexport function getAllExpoModulesInWorkingDirectory() {\n const files = globSync(pattern);\n return findModuleDefinitionsInFiles(files);\n}\n"]}
|
package/build/mockgen.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockgen.d.ts","sourceRoot":"","sources":["../src/mockgen.ts"],"names":[],"mappings":";AAQA,OAAO,
|
|
1
|
+
{"version":3,"file":"mockgen.d.ts","sourceRoot":"","sources":["../src/mockgen.ts"],"names":[],"mappings":";AAQA,OAAO,EAGL,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AA2bjB,wBAAsB,aAAa,CACjC,OAAO,EAAE,sBAAsB,EAAE,EACjC,cAAc,GAAE,YAAY,GAAG,YAA2B,iBAqC3D"}
|
package/build/mockgen.js
CHANGED
|
@@ -67,6 +67,17 @@ function isSwiftDictionary(type) {
|
|
|
67
67
|
type.endsWith(']') &&
|
|
68
68
|
findRootColonInDictionary(type.substring(1, type.length - 1)) >= 0);
|
|
69
69
|
}
|
|
70
|
+
function isEither(type) {
|
|
71
|
+
return type.startsWith('Either<');
|
|
72
|
+
}
|
|
73
|
+
// "Either<TypeOne, TypeTwo>" -> ["TypeOne", "TypeTwo"]
|
|
74
|
+
function maybeUnwrapEither(type) {
|
|
75
|
+
if (!isEither(type)) {
|
|
76
|
+
return [type];
|
|
77
|
+
}
|
|
78
|
+
const innerType = type.substring(7, type.length - 1);
|
|
79
|
+
return innerType.split(',').map((t) => t.trim());
|
|
80
|
+
}
|
|
70
81
|
/*
|
|
71
82
|
The Swift object type can have nested objects as the type of it's values (or maybe even keys).
|
|
72
83
|
[String: [String: Any]]
|
|
@@ -123,6 +134,10 @@ function mapSwiftTypeToTsType(type) {
|
|
|
123
134
|
if (isSwiftArray(type)) {
|
|
124
135
|
return typescript_1.default.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));
|
|
125
136
|
}
|
|
137
|
+
// Custom handling for the Either convertible
|
|
138
|
+
if (isEither(type)) {
|
|
139
|
+
return typescript_1.default.factory.createUnionTypeNode(maybeUnwrapEither(type).map((t) => mapSwiftTypeToTsType(t)));
|
|
140
|
+
}
|
|
126
141
|
switch (type) {
|
|
127
142
|
// Our custom representation for types that we have no type hints for. Not necessairly Swift any.
|
|
128
143
|
case 'unknown':
|
|
@@ -165,9 +180,6 @@ function getMockLiterals(tsReturnType) {
|
|
|
165
180
|
case typescript_1.default.SyntaxKind.TypeLiteral:
|
|
166
181
|
// handles a dictionary, could be improved by creating an object fitting the schema instead of an empty one
|
|
167
182
|
return typescript_1.default.factory.createObjectLiteralExpression([], false);
|
|
168
|
-
case typescript_1.default.SyntaxKind.TypeReference:
|
|
169
|
-
// A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.
|
|
170
|
-
return typescript_1.default.addSyntheticTrailingComment(typescript_1.default.factory.createNull(), typescript_1.default.SyntaxKind.SingleLineCommentTrivia, ` TODO: Replace with mock for value of type ${tsReturnType?.typeName?.escapedText ?? ''}.`);
|
|
171
183
|
}
|
|
172
184
|
return undefined;
|
|
173
185
|
}
|
|
@@ -178,19 +190,30 @@ function maybeWrapWithReturnStatement(tsType) {
|
|
|
178
190
|
if (tsType.kind === typescript_1.default.SyntaxKind.AnyKeyword || tsType.kind === typescript_1.default.SyntaxKind.VoidKeyword) {
|
|
179
191
|
return [];
|
|
180
192
|
}
|
|
193
|
+
if (tsType.kind === typescript_1.default.SyntaxKind.TypeReference) {
|
|
194
|
+
// A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.
|
|
195
|
+
return [
|
|
196
|
+
typescript_1.default.addSyntheticTrailingComment(typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createNull()), typescript_1.default.SyntaxKind.SingleLineCommentTrivia, ` TODO: Replace with mock for value of type ${tsType?.typeName?.escapedText ?? ''}.`),
|
|
197
|
+
];
|
|
198
|
+
}
|
|
181
199
|
return [typescript_1.default.factory.createReturnStatement(getMockLiterals(tsType))];
|
|
182
200
|
}
|
|
183
201
|
/*
|
|
184
202
|
We iterate over a list of functions and we create TS AST for each of them.
|
|
185
203
|
*/
|
|
186
|
-
function getMockedFunctions(functions, async = false) {
|
|
204
|
+
function getMockedFunctions(functions, { async = false, classMethod = false } = {}) {
|
|
187
205
|
return functions.map((fnStructure) => {
|
|
188
206
|
const name = typescript_1.default.factory.createIdentifier(fnStructure.name);
|
|
189
207
|
const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);
|
|
208
|
+
const parameters = fnStructure?.types?.parameters.map((p) => typescript_1.default.factory.createParameterDeclaration(undefined, undefined, p.name ?? '_', undefined, mapSwiftTypeToTsType(p.typename), undefined)) ?? [];
|
|
209
|
+
const returnBlock = typescript_1.default.factory.createBlock(maybeWrapWithReturnStatement(returnType), true);
|
|
210
|
+
if (classMethod) {
|
|
211
|
+
return typescript_1.default.factory.createMethodDeclaration([async ? typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.AsyncKeyword) : undefined].flatMap((f) => f ? [f] : []), undefined, name, undefined, undefined, parameters, async ? wrapWithAsync(returnType) : returnType, returnBlock);
|
|
212
|
+
}
|
|
190
213
|
const func = typescript_1.default.factory.createFunctionDeclaration([
|
|
191
214
|
typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword),
|
|
192
215
|
async ? typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.AsyncKeyword) : undefined,
|
|
193
|
-
].
|
|
216
|
+
].flatMap((f) => (f ? [f] : [])), undefined, name, undefined, parameters, async ? wrapWithAsync(returnType) : returnType, returnBlock);
|
|
194
217
|
return func;
|
|
195
218
|
});
|
|
196
219
|
}
|
|
@@ -238,14 +261,8 @@ and works out of the box with the expo jest preset.
|
|
|
238
261
|
function getPrefix() {
|
|
239
262
|
return [typescript_1.default.factory.createJSDocComment(prefix)];
|
|
240
263
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
*/
|
|
244
|
-
function getMockedView(definition) {
|
|
245
|
-
if (!definition) {
|
|
246
|
-
return [];
|
|
247
|
-
}
|
|
248
|
-
const propsType = typescript_1.default.factory.createTypeAliasDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], 'ViewProps', undefined, typescript_1.default.factory.createTypeLiteralNode([
|
|
264
|
+
function generatePropTypesForDefinition(definition) {
|
|
265
|
+
return typescript_1.default.factory.createTypeAliasDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], 'ViewProps', undefined, typescript_1.default.factory.createTypeLiteralNode([
|
|
249
266
|
...definition.props.map((p) => {
|
|
250
267
|
const propType = mapSwiftTypeToTsType(p.types.parameters[0].typename);
|
|
251
268
|
return typescript_1.default.factory.createPropertySignature(undefined, p.name, undefined, propType);
|
|
@@ -257,17 +274,61 @@ function getMockedView(definition) {
|
|
|
257
274
|
return typescript_1.default.factory.createPropertySignature(undefined, e.name, undefined, eventType);
|
|
258
275
|
}),
|
|
259
276
|
]));
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
277
|
+
}
|
|
278
|
+
/*
|
|
279
|
+
Generate a mock for view props and functions.
|
|
280
|
+
*/
|
|
281
|
+
function getMockedViews(viewDefinitions) {
|
|
282
|
+
return viewDefinitions.flatMap((definition) => {
|
|
283
|
+
if (!definition) {
|
|
284
|
+
return [];
|
|
285
|
+
}
|
|
286
|
+
const propsType = generatePropTypesForDefinition(definition);
|
|
287
|
+
const props = typescript_1.default.factory.createParameterDeclaration(undefined, undefined, 'props', undefined, typescript_1.default.factory.createTypeReferenceNode('ViewProps', undefined), undefined);
|
|
288
|
+
const viewFunction = typescript_1.default.factory.createFunctionDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], undefined,
|
|
289
|
+
// TODO: Handle this better once requireNativeViewManager accepts view name or a different solution for multiple views is built.
|
|
290
|
+
viewDefinitions.length === 1 ? 'View' : definition.name, undefined, [props], undefined, typescript_1.default.factory.createBlock([]));
|
|
291
|
+
return [propsType, viewFunction];
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
function getMockedClass(def) {
|
|
295
|
+
const classDecl = typescript_1.default.factory.createClassDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], typescript_1.default.factory.createIdentifier(def.name), undefined, undefined, [
|
|
296
|
+
...getMockedFunctions(def.functions, { classMethod: true }),
|
|
297
|
+
...getMockedFunctions(def.asyncFunctions, { async: true, classMethod: true }),
|
|
298
|
+
]);
|
|
299
|
+
return classDecl;
|
|
300
|
+
}
|
|
301
|
+
function getMockedClasses(def) {
|
|
302
|
+
return def.map((d) => getMockedClass(d));
|
|
263
303
|
}
|
|
264
304
|
const newlineIdentifier = typescript_1.default.factory.createIdentifier('\n\n');
|
|
265
305
|
function separateWithNewlines(arr) {
|
|
266
306
|
return [arr, newlineIdentifier];
|
|
267
307
|
}
|
|
308
|
+
function omitFromSet(set, toOmit) {
|
|
309
|
+
const newSet = new Set(set);
|
|
310
|
+
toOmit.forEach((item) => {
|
|
311
|
+
if (item) {
|
|
312
|
+
newSet.delete(item);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
return newSet;
|
|
316
|
+
}
|
|
268
317
|
function getMockForModule(module, includeTypes) {
|
|
269
318
|
return []
|
|
270
|
-
.concat(getPrefix(), newlineIdentifier, includeTypes
|
|
319
|
+
.concat(getPrefix(), newlineIdentifier, includeTypes
|
|
320
|
+
? getMockedTypes(omitFromSet(new Set([
|
|
321
|
+
...getTypesToMock(module),
|
|
322
|
+
...new Set(...module.views.map((v) => getTypesToMock(v))),
|
|
323
|
+
...new Set(...module.classes.map((c) => getTypesToMock(c))),
|
|
324
|
+
]),
|
|
325
|
+
// Ignore all types that are actually native classes
|
|
326
|
+
[
|
|
327
|
+
module.name,
|
|
328
|
+
...module.views.map((c) => c.name),
|
|
329
|
+
...module.classes.map((c) => c.name),
|
|
330
|
+
]))
|
|
331
|
+
: [], newlineIdentifier, getMockedFunctions(module.functions), getMockedFunctions(module.asyncFunctions, { async: true }), newlineIdentifier, getMockedViews(module.views), getMockedClasses(module.classes))
|
|
271
332
|
.flatMap(separateWithNewlines);
|
|
272
333
|
}
|
|
273
334
|
async function prettifyCode(text, parser = 'babel') {
|
package/build/mockgen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockgen.js","sourceRoot":"","sources":["../src/mockgen.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n'use strict';\n\nimport fs from 'fs';\nimport path from 'path';\nimport * as prettier from 'prettier';\nimport ts from 'typescript';\n\nimport { Closure, ClosureTypes, OutputModuleDefinition, OutputViewDefinition } from './types';\n\nconst directoryPath = process.cwd();\n\n/*\nWe receive types from SourceKitten and `getStructure` like so (examples):\n[AcceptedTypes]?, UIColor?, [String: Any]\n\nWe need to parse them first to TS nodes in `mapSwiftTypeToTsType` with the following helper functions.\n*/\n\nfunction isSwiftArray(type: string) {\n // This can also be an object, but we check that first, so if it's not an object and is wrapped with [] it's an array.\n return type.startsWith('[') && type.endsWith(']');\n}\nfunction maybeUnwrapSwiftArray(type: string) {\n const isArray = isSwiftArray(type);\n if (!isArray) {\n return type;\n }\n const innerType = type.substring(1, type.length - 1);\n return innerType;\n}\n\nfunction isSwiftOptional(type: string) {\n return type.endsWith('?');\n}\nfunction maybeUnwrapSwiftOptional(type: string) {\n const isOptional = isSwiftOptional(type);\n if (!isOptional) {\n return type;\n }\n const innerType = type.substring(0, type.length - 1);\n return innerType;\n}\n\nfunction isSwiftDictionary(type: string) {\n return (\n type.startsWith('[') &&\n type.endsWith(']') &&\n findRootColonInDictionary(type.substring(1, type.length - 1)) >= 0\n );\n}\n\n/*\nThe Swift object type can have nested objects as the type of it's values (or maybe even keys).\n[String: [String: Any]]\n\nWe can't use regex to find the root colon, so this is the safest way – by counting brackets.\n*/\nfunction findRootColonInDictionary(type: string) {\n let colonIndex = -1;\n let openBracketsCount = 0;\n for (let i = 0; i < type.length; i++) {\n if (type[i] === '[') {\n openBracketsCount++;\n } else if (type[i] === ']') {\n openBracketsCount--;\n } else if (type[i] === ':' && openBracketsCount === 0) {\n colonIndex = i;\n break;\n }\n }\n return colonIndex;\n}\nfunction unwrapSwiftDictionary(type: string) {\n const innerType = type.substring(1, type.length - 1);\n const colonPosition = findRootColonInDictionary(innerType);\n return {\n key: innerType.slice(0, colonPosition).trim(),\n value: innerType.slice(colonPosition + 1).trim(),\n };\n}\n\ntype TSNode =\n | ts.UnionTypeNode\n | ts.KeywordTypeNode\n | ts.TypeReferenceNode\n | ts.ArrayTypeNode\n | ts.OptionalTypeNode\n | ts.TypeLiteralNode;\n\n/*\nMain function that converts a string representation of a Swift type to a TypeScript compiler API node AST.\nWe can pass those types straight to a TypeScript printer (a function that converts AST to text).\n*/\nfunction mapSwiftTypeToTsType(type: string): TSNode {\n if (!type) {\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);\n }\n if (isSwiftOptional(type)) {\n return ts.factory.createUnionTypeNode([\n mapSwiftTypeToTsType(maybeUnwrapSwiftOptional(type)),\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),\n ]);\n }\n if (isSwiftDictionary(type)) {\n const { key, value } = unwrapSwiftDictionary(type);\n const keyType = mapSwiftTypeToTsType(key);\n const valueType = mapSwiftTypeToTsType(value);\n\n const indexSignature = ts.factory.createIndexSignature(\n undefined,\n [ts.factory.createParameterDeclaration(undefined, undefined, 'key', undefined, keyType)],\n valueType\n );\n\n const typeLiteralNode = ts.factory.createTypeLiteralNode([indexSignature]);\n return typeLiteralNode;\n }\n if (isSwiftArray(type)) {\n return ts.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));\n }\n switch (type) {\n // Our custom representation for types that we have no type hints for. Not necessairly Swift any.\n case 'unknown':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n case 'String':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);\n case 'Bool':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);\n case 'Int':\n case 'Float':\n case 'Double':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);\n case 'Any': // Swift Any type\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n default: // Custom Swift type (record) – for now mapped to a custom TS type exported at the top of the file by `getMockedTypes`.\n return ts.factory.createTypeReferenceNode(type);\n }\n}\n\n// Mocks require sample return values, so we generate them based on TS AST.\nfunction getMockLiterals(tsReturnType: TSNode) {\n if (!tsReturnType) {\n return undefined;\n }\n switch (tsReturnType.kind) {\n case ts.SyntaxKind.AnyKeyword:\n case ts.SyntaxKind.VoidKeyword:\n return undefined;\n case ts.SyntaxKind.UnionType:\n // we take the first element of our union for the mock – we know the cast is correct since we create the type ourselves\n // the second is `undefined` for optionals.\n return getMockLiterals(tsReturnType.types[0] as TSNode);\n case ts.SyntaxKind.StringKeyword:\n return ts.factory.createStringLiteral('');\n case ts.SyntaxKind.BooleanKeyword:\n return ts.factory.createFalse();\n case ts.SyntaxKind.NumberKeyword:\n return ts.factory.createNumericLiteral('0');\n case ts.SyntaxKind.ArrayType:\n return ts.factory.createArrayLiteralExpression();\n case ts.SyntaxKind.TypeLiteral:\n // handles a dictionary, could be improved by creating an object fitting the schema instead of an empty one\n return ts.factory.createObjectLiteralExpression([], false);\n case ts.SyntaxKind.TypeReference:\n // A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.\n return ts.addSyntheticTrailingComment(\n ts.factory.createNull(),\n ts.SyntaxKind.SingleLineCommentTrivia,\n ` TODO: Replace with mock for value of type ${\n ((tsReturnType as any)?.typeName as any)?.escapedText ?? ''\n }.`\n );\n }\n return undefined;\n}\n\nfunction wrapWithAsync(tsType: ts.TypeNode) {\n return ts.factory.createTypeReferenceNode('Promise', [tsType]);\n}\n\nfunction maybeWrapWithReturnStatement(tsType: TSNode) {\n if (tsType.kind === ts.SyntaxKind.AnyKeyword || tsType.kind === ts.SyntaxKind.VoidKeyword) {\n return [];\n }\n return [ts.factory.createReturnStatement(getMockLiterals(tsType))];\n}\n\n/*\nWe iterate over a list of functions and we create TS AST for each of them.\n*/\nfunction getMockedFunctions(functions: Closure[], async = false) {\n return functions.map((fnStructure) => {\n const name = ts.factory.createIdentifier(fnStructure.name);\n const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);\n const func = ts.factory.createFunctionDeclaration(\n [\n ts.factory.createToken(ts.SyntaxKind.ExportKeyword),\n async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined,\n ].filter((f) => !!f) as ts.ModifierToken<any>[],\n undefined,\n name,\n undefined,\n fnStructure?.types?.parameters.map((p) =>\n ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n p.name,\n undefined,\n mapSwiftTypeToTsType(p.typename),\n undefined\n )\n ) ?? [],\n async ? wrapWithAsync(returnType) : returnType,\n ts.factory.createBlock(maybeWrapWithReturnStatement(returnType), true)\n );\n return func;\n });\n}\n\n/**\n * Collect all type references used in any of the AST types to generate type aliases\n * e.g. type `[URL: string]?` will generate `type URL = any;`\n */\nfunction getAllTypeReferences(node: ts.Node, accumulator: string[]) {\n if (ts.isTypeReferenceNode(node)) {\n accumulator.push((node.typeName as any)?.escapedText);\n }\n node.forEachChild((n) => getAllTypeReferences(n, accumulator));\n}\n\n/**\n * Iterates over types to collect the aliases.\n */\nfunction getTypesToMock(module: OutputModuleDefinition | OutputViewDefinition) {\n const foundTypes: string[] = [];\n\n Object.values(module)\n .flatMap((t) => (Array.isArray(t) ? t?.map((t2) => (t2 as Closure)?.types) : [] ?? []))\n .forEach((types: ClosureTypes | null) => {\n types?.parameters.forEach(({ typename }) => {\n getAllTypeReferences(mapSwiftTypeToTsType(typename), foundTypes);\n });\n types?.returnType &&\n getAllTypeReferences(mapSwiftTypeToTsType(types?.returnType), foundTypes);\n });\n return new Set(foundTypes);\n}\n\n/**\n * Gets a mock for a custom type.\n */\nfunction getMockedTypes(types: Set<string>) {\n return Array.from(types).map((type) => {\n const name = ts.factory.createIdentifier(type);\n const typeAlias = ts.factory.createTypeAliasDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n name,\n undefined,\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)\n );\n return typeAlias;\n });\n}\n\nconst prefix = `Automatically generated by expo-modules-test-core.\n\nThis autogenerated file provides a mock for native Expo module,\nand works out of the box with the expo jest preset.\n`;\nfunction getPrefix() {\n return [ts.factory.createJSDocComment(prefix)];\n}\n\n/*\nGenerate a mock for view props and functions.\n*/\nfunction getMockedView(definition: OutputViewDefinition | null) {\n if (!definition) {\n return [];\n }\n const propsType = ts.factory.createTypeAliasDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n 'ViewProps',\n undefined,\n ts.factory.createTypeLiteralNode([\n ...definition.props.map((p) => {\n const propType = mapSwiftTypeToTsType(p.types.parameters[0].typename);\n return ts.factory.createPropertySignature(undefined, p.name, undefined, propType);\n }),\n ...definition.events.map((e) => {\n const eventType = ts.factory.createFunctionTypeNode(\n undefined,\n [\n ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n 'event',\n undefined,\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)\n ),\n ],\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)\n );\n return ts.factory.createPropertySignature(undefined, e.name, undefined, eventType);\n }),\n ])\n );\n const props = ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n 'props',\n undefined,\n ts.factory.createTypeReferenceNode('ViewProps', undefined),\n undefined\n );\n const viewFunction = ts.factory.createFunctionDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n undefined,\n 'View',\n undefined,\n [props],\n undefined,\n ts.factory.createBlock([])\n );\n return [propsType, viewFunction];\n}\n\nconst newlineIdentifier = ts.factory.createIdentifier('\\n\\n') as any;\nfunction separateWithNewlines<T>(arr: T) {\n return [arr, newlineIdentifier];\n}\n\nfunction getMockForModule(module: OutputModuleDefinition, includeTypes: boolean) {\n return ([] as (ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.JSDoc)[])\n .concat(\n getPrefix(),\n newlineIdentifier,\n includeTypes ? getMockedTypes(getTypesToMock(module)) : [],\n newlineIdentifier,\n getMockedFunctions(module.functions).flatMap((mf) => [mf, newlineIdentifier]),\n getMockedFunctions(module.asyncFunctions, true),\n newlineIdentifier,\n includeTypes && module.view ? getMockedTypes(getTypesToMock(module.view)) : [],\n newlineIdentifier,\n getMockedView(module.view)\n )\n .flatMap(separateWithNewlines);\n}\n\nasync function prettifyCode(text: string, parser: 'babel' | 'typescript' = 'babel') {\n return await prettier.format(text, {\n parser,\n tabWidth: 2,\n printWidth: 100,\n trailingComma: 'none',\n singleQuote: true,\n });\n}\n\nexport async function generateMocks(\n modules: OutputModuleDefinition[],\n outputLanguage: 'javascript' | 'typescript' = 'javascript'\n) {\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n\n for (const m of modules) {\n const filename = m.name + (outputLanguage === 'javascript' ? '.js' : '.ts');\n const resultFile = ts.createSourceFile(\n filename,\n '',\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TSX\n );\n fs.mkdirSync(path.join(directoryPath, 'mocks'), { recursive: true });\n const filePath = path.join(directoryPath, 'mocks', filename);\n // get ts nodearray from getMockForModule(m) array\n const mock = ts.factory.createNodeArray(getMockForModule(m, outputLanguage === 'typescript'));\n const printedTs = printer.printList(\n ts.ListFormat.MultiLine + ts.ListFormat.PreserveLines,\n mock,\n resultFile\n );\n\n if (outputLanguage === 'javascript') {\n const compiledJs = ts.transpileModule(printedTs, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ESNext,\n },\n }).outputText;\n const prettifiedJs = await prettifyCode(compiledJs);\n fs.writeFileSync(filePath, prettifiedJs);\n } else {\n const prettifiedTs = await prettifyCode(printedTs, 'typescript');\n fs.writeFileSync(filePath, prettifiedTs);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mockgen.js","sourceRoot":"","sources":["../src/mockgen.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n'use strict';\n\nimport fs from 'fs';\nimport path from 'path';\nimport * as prettier from 'prettier';\nimport ts from 'typescript';\n\nimport {\n Closure,\n ClosureTypes,\n OutputModuleDefinition,\n OutputNestedClassDefinition,\n} from './types';\n\nconst directoryPath = process.cwd();\n\n/*\nWe receive types from SourceKitten and `getStructure` like so (examples):\n[AcceptedTypes]?, UIColor?, [String: Any]\n\nWe need to parse them first to TS nodes in `mapSwiftTypeToTsType` with the following helper functions.\n*/\n\nfunction isSwiftArray(type: string) {\n // This can also be an object, but we check that first, so if it's not an object and is wrapped with [] it's an array.\n return type.startsWith('[') && type.endsWith(']');\n}\nfunction maybeUnwrapSwiftArray(type: string) {\n const isArray = isSwiftArray(type);\n if (!isArray) {\n return type;\n }\n const innerType = type.substring(1, type.length - 1);\n return innerType;\n}\n\nfunction isSwiftOptional(type: string) {\n return type.endsWith('?');\n}\nfunction maybeUnwrapSwiftOptional(type: string) {\n const isOptional = isSwiftOptional(type);\n if (!isOptional) {\n return type;\n }\n const innerType = type.substring(0, type.length - 1);\n return innerType;\n}\n\nfunction isSwiftDictionary(type: string) {\n return (\n type.startsWith('[') &&\n type.endsWith(']') &&\n findRootColonInDictionary(type.substring(1, type.length - 1)) >= 0\n );\n}\n\nfunction isEither(type: string) {\n return type.startsWith('Either<');\n}\n// \"Either<TypeOne, TypeTwo>\" -> [\"TypeOne\", \"TypeTwo\"]\nfunction maybeUnwrapEither(type: string): string[] {\n if (!isEither(type)) {\n return [type];\n }\n const innerType = type.substring(7, type.length - 1);\n return innerType.split(',').map((t) => t.trim());\n}\n\n/*\nThe Swift object type can have nested objects as the type of it's values (or maybe even keys).\n[String: [String: Any]]\n\nWe can't use regex to find the root colon, so this is the safest way – by counting brackets.\n*/\nfunction findRootColonInDictionary(type: string) {\n let colonIndex = -1;\n let openBracketsCount = 0;\n for (let i = 0; i < type.length; i++) {\n if (type[i] === '[') {\n openBracketsCount++;\n } else if (type[i] === ']') {\n openBracketsCount--;\n } else if (type[i] === ':' && openBracketsCount === 0) {\n colonIndex = i;\n break;\n }\n }\n return colonIndex;\n}\nfunction unwrapSwiftDictionary(type: string) {\n const innerType = type.substring(1, type.length - 1);\n const colonPosition = findRootColonInDictionary(innerType);\n return {\n key: innerType.slice(0, colonPosition).trim(),\n value: innerType.slice(colonPosition + 1).trim(),\n };\n}\n\ntype TSNode =\n | ts.UnionTypeNode\n | ts.KeywordTypeNode\n | ts.TypeReferenceNode\n | ts.ArrayTypeNode\n | ts.OptionalTypeNode\n | ts.TypeLiteralNode;\n\n/*\nMain function that converts a string representation of a Swift type to a TypeScript compiler API node AST.\nWe can pass those types straight to a TypeScript printer (a function that converts AST to text).\n*/\nfunction mapSwiftTypeToTsType(type: string): TSNode {\n if (!type) {\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);\n }\n if (isSwiftOptional(type)) {\n return ts.factory.createUnionTypeNode([\n mapSwiftTypeToTsType(maybeUnwrapSwiftOptional(type)),\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),\n ]);\n }\n if (isSwiftDictionary(type)) {\n const { key, value } = unwrapSwiftDictionary(type);\n const keyType = mapSwiftTypeToTsType(key);\n const valueType = mapSwiftTypeToTsType(value);\n\n const indexSignature = ts.factory.createIndexSignature(\n undefined,\n [ts.factory.createParameterDeclaration(undefined, undefined, 'key', undefined, keyType)],\n valueType\n );\n\n const typeLiteralNode = ts.factory.createTypeLiteralNode([indexSignature]);\n return typeLiteralNode;\n }\n if (isSwiftArray(type)) {\n return ts.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));\n }\n // Custom handling for the Either convertible\n if (isEither(type)) {\n return ts.factory.createUnionTypeNode(\n maybeUnwrapEither(type).map((t) => mapSwiftTypeToTsType(t))\n );\n }\n\n switch (type) {\n // Our custom representation for types that we have no type hints for. Not necessairly Swift any.\n case 'unknown':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n case 'String':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);\n case 'Bool':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);\n case 'Int':\n case 'Float':\n case 'Double':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);\n case 'Any': // Swift Any type\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n default: // Custom Swift type (record) – for now mapped to a custom TS type exported at the top of the file by `getMockedTypes`.\n return ts.factory.createTypeReferenceNode(type);\n }\n}\n\n// Mocks require sample return values, so we generate them based on TS AST.\nfunction getMockLiterals(tsReturnType: TSNode) {\n if (!tsReturnType) {\n return undefined;\n }\n switch (tsReturnType.kind) {\n case ts.SyntaxKind.AnyKeyword:\n case ts.SyntaxKind.VoidKeyword:\n return undefined;\n case ts.SyntaxKind.UnionType:\n // we take the first element of our union for the mock – we know the cast is correct since we create the type ourselves\n // the second is `undefined` for optionals.\n return getMockLiterals(tsReturnType.types[0] as TSNode);\n case ts.SyntaxKind.StringKeyword:\n return ts.factory.createStringLiteral('');\n case ts.SyntaxKind.BooleanKeyword:\n return ts.factory.createFalse();\n case ts.SyntaxKind.NumberKeyword:\n return ts.factory.createNumericLiteral('0');\n case ts.SyntaxKind.ArrayType:\n return ts.factory.createArrayLiteralExpression();\n case ts.SyntaxKind.TypeLiteral:\n // handles a dictionary, could be improved by creating an object fitting the schema instead of an empty one\n return ts.factory.createObjectLiteralExpression([], false);\n }\n return undefined;\n}\n\nfunction wrapWithAsync(tsType: ts.TypeNode) {\n return ts.factory.createTypeReferenceNode('Promise', [tsType]);\n}\n\nfunction maybeWrapWithReturnStatement(tsType: TSNode) {\n if (tsType.kind === ts.SyntaxKind.AnyKeyword || tsType.kind === ts.SyntaxKind.VoidKeyword) {\n return [];\n }\n if (tsType.kind === ts.SyntaxKind.TypeReference) {\n // A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.\n return [\n ts.addSyntheticTrailingComment(\n ts.factory.createReturnStatement(ts.factory.createNull()),\n ts.SyntaxKind.SingleLineCommentTrivia,\n ` TODO: Replace with mock for value of type ${\n ((tsType as any)?.typeName as any)?.escapedText ?? ''\n }.`\n ),\n ];\n }\n return [ts.factory.createReturnStatement(getMockLiterals(tsType))];\n}\n\n/*\nWe iterate over a list of functions and we create TS AST for each of them.\n*/\nfunction getMockedFunctions(functions: Closure[], { async = false, classMethod = false } = {}) {\n return functions.map((fnStructure) => {\n const name = ts.factory.createIdentifier(fnStructure.name);\n const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);\n const parameters =\n fnStructure?.types?.parameters.map((p) =>\n ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n p.name ?? '_',\n undefined,\n mapSwiftTypeToTsType(p.typename),\n undefined\n )\n ) ?? [];\n const returnBlock = ts.factory.createBlock(maybeWrapWithReturnStatement(returnType), true);\n\n if (classMethod) {\n return ts.factory.createMethodDeclaration(\n [async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined].flatMap((f) =>\n f ? [f] : []\n ),\n undefined,\n name,\n undefined,\n undefined,\n parameters,\n async ? wrapWithAsync(returnType) : returnType,\n returnBlock\n );\n }\n const func = ts.factory.createFunctionDeclaration(\n [\n ts.factory.createToken(ts.SyntaxKind.ExportKeyword),\n async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined,\n ].flatMap((f) => (f ? [f] : [])),\n undefined,\n name,\n undefined,\n parameters,\n async ? wrapWithAsync(returnType) : returnType,\n returnBlock\n );\n return func;\n });\n}\n\n/**\n * Collect all type references used in any of the AST types to generate type aliases\n * e.g. type `[URL: string]?` will generate `type URL = any;`\n */\nfunction getAllTypeReferences(node: ts.Node, accumulator: string[]) {\n if (ts.isTypeReferenceNode(node)) {\n accumulator.push((node.typeName as any)?.escapedText);\n }\n node.forEachChild((n) => getAllTypeReferences(n, accumulator));\n}\n\n/**\n * Iterates over types to collect the aliases.\n */\nfunction getTypesToMock(module: OutputModuleDefinition | OutputNestedClassDefinition) {\n const foundTypes: string[] = [];\n\n Object.values(module)\n .flatMap((t) => (Array.isArray(t) ? t?.map((t2) => (t2 as Closure)?.types) : [] ?? []))\n .forEach((types: ClosureTypes | null) => {\n types?.parameters.forEach(({ typename }) => {\n getAllTypeReferences(mapSwiftTypeToTsType(typename), foundTypes);\n });\n types?.returnType &&\n getAllTypeReferences(mapSwiftTypeToTsType(types?.returnType), foundTypes);\n });\n return new Set(foundTypes);\n}\n\n/**\n * Gets a mock for a custom type.\n */\nfunction getMockedTypes(types: Set<string>) {\n return Array.from(types).map((type) => {\n const name = ts.factory.createIdentifier(type);\n const typeAlias = ts.factory.createTypeAliasDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n name,\n undefined,\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)\n );\n return typeAlias;\n });\n}\n\nconst prefix = `Automatically generated by expo-modules-test-core.\n\nThis autogenerated file provides a mock for native Expo module,\nand works out of the box with the expo jest preset.\n`;\nfunction getPrefix() {\n return [ts.factory.createJSDocComment(prefix)];\n}\n\nfunction generatePropTypesForDefinition(definition: OutputNestedClassDefinition) {\n return ts.factory.createTypeAliasDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n 'ViewProps',\n undefined,\n ts.factory.createTypeLiteralNode([\n ...definition.props.map((p) => {\n const propType = mapSwiftTypeToTsType(p.types.parameters[0].typename);\n return ts.factory.createPropertySignature(undefined, p.name, undefined, propType);\n }),\n ...definition.events.map((e) => {\n const eventType = ts.factory.createFunctionTypeNode(\n undefined,\n [\n ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n 'event',\n undefined,\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)\n ),\n ],\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)\n );\n return ts.factory.createPropertySignature(undefined, e.name, undefined, eventType);\n }),\n ])\n );\n}\n/*\nGenerate a mock for view props and functions.\n*/\nfunction getMockedViews(viewDefinitions: OutputNestedClassDefinition[]) {\n return viewDefinitions.flatMap((definition) => {\n if (!definition) {\n return [];\n }\n const propsType = generatePropTypesForDefinition(definition);\n const props = ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n 'props',\n undefined,\n ts.factory.createTypeReferenceNode('ViewProps', undefined),\n undefined\n );\n const viewFunction = ts.factory.createFunctionDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n undefined,\n // TODO: Handle this better once requireNativeViewManager accepts view name or a different solution for multiple views is built.\n viewDefinitions.length === 1 ? 'View' : definition.name,\n undefined,\n [props],\n undefined,\n ts.factory.createBlock([])\n );\n return [propsType, viewFunction];\n });\n}\n\nfunction getMockedClass(def: OutputNestedClassDefinition) {\n const classDecl = ts.factory.createClassDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n ts.factory.createIdentifier(def.name),\n undefined,\n undefined,\n [\n ...getMockedFunctions(def.functions, { classMethod: true }),\n ...getMockedFunctions(def.asyncFunctions, { async: true, classMethod: true }),\n ] as ts.MethodDeclaration[]\n );\n return classDecl;\n}\n\nfunction getMockedClasses(def: OutputNestedClassDefinition[]) {\n return def.map((d) => getMockedClass(d));\n}\n\nconst newlineIdentifier = ts.factory.createIdentifier('\\n\\n') as any;\nfunction separateWithNewlines<T>(arr: T) {\n return [arr, newlineIdentifier];\n}\n\nfunction omitFromSet(set: Set<string>, toOmit: (string | undefined)[]) {\n const newSet = new Set(set);\n toOmit.forEach((item) => {\n if (item) {\n newSet.delete(item);\n }\n });\n return newSet;\n}\n\nfunction getMockForModule(module: OutputModuleDefinition, includeTypes: boolean) {\n return (\n [] as (ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.JSDoc | ts.ClassDeclaration)[]\n )\n .concat(\n getPrefix(),\n newlineIdentifier,\n includeTypes\n ? getMockedTypes(\n omitFromSet(\n new Set([\n ...getTypesToMock(module),\n ...new Set(...module.views.map((v) => getTypesToMock(v))),\n ...new Set(...module.classes.map((c) => getTypesToMock(c))),\n ]),\n // Ignore all types that are actually native classes\n [\n module.name,\n ...module.views.map((c) => c.name),\n ...module.classes.map((c) => c.name),\n ]\n )\n )\n : [],\n newlineIdentifier,\n getMockedFunctions(module.functions) as ts.FunctionDeclaration[],\n getMockedFunctions(module.asyncFunctions, { async: true }) as ts.FunctionDeclaration[],\n newlineIdentifier,\n getMockedViews(module.views),\n getMockedClasses(module.classes)\n )\n .flatMap(separateWithNewlines);\n}\n\nasync function prettifyCode(text: string, parser: 'babel' | 'typescript' = 'babel') {\n return await prettier.format(text, {\n parser,\n tabWidth: 2,\n printWidth: 100,\n trailingComma: 'none',\n singleQuote: true,\n });\n}\n\nexport async function generateMocks(\n modules: OutputModuleDefinition[],\n outputLanguage: 'javascript' | 'typescript' = 'javascript'\n) {\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n\n for (const m of modules) {\n const filename = m.name + (outputLanguage === 'javascript' ? '.js' : '.ts');\n const resultFile = ts.createSourceFile(\n filename,\n '',\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TSX\n );\n fs.mkdirSync(path.join(directoryPath, 'mocks'), { recursive: true });\n const filePath = path.join(directoryPath, 'mocks', filename);\n // get ts nodearray from getMockForModule(m) array\n const mock = ts.factory.createNodeArray(getMockForModule(m, outputLanguage === 'typescript'));\n const printedTs = printer.printList(\n ts.ListFormat.MultiLine + ts.ListFormat.PreserveLines,\n mock,\n resultFile\n );\n\n if (outputLanguage === 'javascript') {\n const compiledJs = ts.transpileModule(printedTs, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ESNext,\n },\n }).outputText;\n const prettifiedJs = await prettifyCode(compiledJs);\n fs.writeFileSync(filePath, prettifiedJs);\n } else {\n const prettifiedTs = await prettifyCode(printedTs, 'typescript');\n fs.writeFileSync(filePath, prettifiedTs);\n }\n }\n}\n"]}
|
package/build/types.d.ts
CHANGED
|
@@ -40,10 +40,11 @@ export type Prop = {
|
|
|
40
40
|
};
|
|
41
41
|
export type OutputModuleDefinition = {
|
|
42
42
|
name: string;
|
|
43
|
-
|
|
43
|
+
views: OutputNestedClassDefinition[];
|
|
44
|
+
classes: OutputNestedClassDefinition[];
|
|
44
45
|
events: {
|
|
45
46
|
name: string;
|
|
46
47
|
}[];
|
|
47
48
|
} & Record<'asyncFunctions' | 'functions' | 'properties', Closure[]> & Record<'props', Prop[]>;
|
|
48
|
-
export type
|
|
49
|
+
export type OutputNestedClassDefinition = Omit<OutputModuleDefinition, 'views' | 'classes'>;
|
|
49
50
|
//# sourceMappingURL=types.d.ts.map
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,kBAAkB,EAAE,SAAS,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0BAA0B,EAAE,MAAM,CAAC;IACnC,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,oBAAoB,EAAE;QACpB,oBAAoB,EAAE;YACpB,mCAAmC,EAAE,MAAM,CAAC;YAC5C,yBAAyB,EAAE,MAAM,CAAC;SACnC,EAAE,CAAC;QACJ,0BAA0B,EAAE,MAAM,CAAC;KACpC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,GAAG,CAAC;QACV,QAAQ,EAAE,GAAG,CAAC;KACf,EAAE,CAAC;IACJ,UAAU,EAAE,GAAG,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,kBAAkB,EAAE,SAAS,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0BAA0B,EAAE,MAAM,CAAC;IACnC,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,oBAAoB,EAAE;QACpB,oBAAoB,EAAE;YACpB,mCAAmC,EAAE,MAAM,CAAC;YAC5C,yBAAyB,EAAE,MAAM,CAAC;SACnC,EAAE,CAAC;QACJ,0BAA0B,EAAE,MAAM,CAAC;KACpC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,GAAG,CAAC;QACV,QAAQ,EAAE,GAAG,CAAC;KACf,EAAE,CAAC;IACJ,UAAU,EAAE,GAAG,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,2BAA2B,EAAE,CAAC;IACrC,OAAO,EAAE,2BAA2B,EAAE,CAAC;IACvC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,EAAE,CAAC;CACL,GAAG,MAAM,CAAC,gBAAgB,GAAG,WAAW,GAAG,YAAY,EAAE,OAAO,EAAE,CAAC,GAClE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAG1B,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC"}
|
package/build/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export type FileType = {\n path: string;\n content: string;\n};\n\nexport type Structure = {\n 'key.substructure': Structure[];\n 'key.typename': string;\n 'key.name': string;\n 'key.kind': string;\n 'key.offset': number;\n 'key.length': number;\n};\n\nexport type CursorInfoOutput = {\n 'key.fully_annotated_decl': string;\n 'key.annotated_decl': string;\n};\n\nexport type FullyAnnotatedDecl = {\n 'decl.function.free': {\n 'decl.var.parameter': {\n 'decl.var.parameter.argument_label': string;\n 'decl.var.parameter.type': string;\n }[];\n 'decl.function.returntype': string;\n };\n};\n\nexport type ClosureTypes = {\n parameters: {\n name: any;\n typename: any;\n }[];\n returnType: any;\n};\n\nexport type Closure = {\n name: string;\n types: ClosureTypes | null;\n};\n\nexport type Prop = {\n name: string;\n types: Omit<ClosureTypes, 'returnType'>;\n};\n\nexport type OutputModuleDefinition = {\n name: string;\n
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export type FileType = {\n path: string;\n content: string;\n};\n\nexport type Structure = {\n 'key.substructure': Structure[];\n 'key.typename': string;\n 'key.name': string;\n 'key.kind': string;\n 'key.offset': number;\n 'key.length': number;\n};\n\nexport type CursorInfoOutput = {\n 'key.fully_annotated_decl': string;\n 'key.annotated_decl': string;\n};\n\nexport type FullyAnnotatedDecl = {\n 'decl.function.free': {\n 'decl.var.parameter': {\n 'decl.var.parameter.argument_label': string;\n 'decl.var.parameter.type': string;\n }[];\n 'decl.function.returntype': string;\n };\n};\n\nexport type ClosureTypes = {\n parameters: {\n name: any;\n typename: any;\n }[];\n returnType: any;\n};\n\nexport type Closure = {\n name: string;\n types: ClosureTypes | null;\n};\n\nexport type Prop = {\n name: string;\n types: Omit<ClosureTypes, 'returnType'>;\n};\n\nexport type OutputModuleDefinition = {\n name: string;\n views: OutputNestedClassDefinition[];\n classes: OutputNestedClassDefinition[];\n events: {\n name: string;\n }[];\n} & Record<'asyncFunctions' | 'functions' | 'properties', Closure[]> &\n Record<'props', Prop[]>;\n\n// views and classes are a very similar structure, same as module but without more nesting levels\nexport type OutputNestedClassDefinition = Omit<OutputModuleDefinition, 'views' | 'classes'>;\n"]}
|
|
Binary file
|
|
@@ -10,7 +10,9 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.license = package['license']
|
|
11
11
|
s.author = package['author']
|
|
12
12
|
s.homepage = package['homepage']
|
|
13
|
-
s.
|
|
13
|
+
s.platforms = {
|
|
14
|
+
:ios => '15.1'
|
|
15
|
+
}
|
|
14
16
|
s.swift_version = '5.4'
|
|
15
17
|
s.source = { git: 'https://github.com/expo/expo.git' }
|
|
16
18
|
s.static_framework = true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-test-core",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.2-canary-20240927-ab8a962",
|
|
4
4
|
"main": "./app.plugin.js",
|
|
5
5
|
"description": "Module providing native testing utilities for testing Expo modules",
|
|
6
6
|
"keywords": [
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"xml-js": "^1.6.11",
|
|
35
35
|
"yaml": "^2.3.2"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "ab8a962d2c3dddbda124a6bd88d24475831dae00"
|
|
38
38
|
}
|
package/src/getStructure.ts
CHANGED
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
FileType,
|
|
12
12
|
FullyAnnotatedDecl,
|
|
13
13
|
OutputModuleDefinition,
|
|
14
|
-
OutputViewDefinition,
|
|
15
14
|
Structure,
|
|
16
15
|
} from './types';
|
|
17
16
|
|
|
@@ -187,27 +186,36 @@ function findGroupedDefinitionsOfType(type: string, moduleDefinition: Structure[
|
|
|
187
186
|
return definitionParams.map((d) => ({ name: getIdentifierFromOffsetObject(d, file) }));
|
|
188
187
|
});
|
|
189
188
|
}
|
|
190
|
-
|
|
191
|
-
function findAndParseView(
|
|
189
|
+
function findAndParseNestedClassesOfType(
|
|
192
190
|
moduleDefinition: Structure[],
|
|
193
|
-
file: FileType
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
191
|
+
file: FileType,
|
|
192
|
+
type: string
|
|
193
|
+
) {
|
|
194
|
+
// we support reading definitions from closure only
|
|
195
|
+
const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);
|
|
196
|
+
return definitionsOfType
|
|
197
|
+
.map((df) => {
|
|
198
|
+
const nestedModuleDefinition =
|
|
199
|
+
df['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.[
|
|
200
|
+
'key.substructure'
|
|
201
|
+
];
|
|
202
|
+
if (!nestedModuleDefinition) {
|
|
203
|
+
console.warn('Could not parse definition');
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
const name = getIdentifierFromOffsetObject(df['key.substructure']?.[0], file).replace(
|
|
207
|
+
'.self',
|
|
208
|
+
''
|
|
209
|
+
);
|
|
210
|
+
// let's drop nested view field and classes (are null anyways)
|
|
211
|
+
const {
|
|
212
|
+
views: _,
|
|
213
|
+
classes: _2,
|
|
214
|
+
...definition
|
|
215
|
+
} = parseModuleDefinition(nestedModuleDefinition, file);
|
|
216
|
+
return { ...definition, name };
|
|
217
|
+
})
|
|
218
|
+
.flatMap((f) => (f ? [f] : []));
|
|
211
219
|
}
|
|
212
220
|
|
|
213
221
|
function omitParamsFromClosureArguments<T extends Closure>(
|
|
@@ -218,8 +226,7 @@ function omitParamsFromClosureArguments<T extends Closure>(
|
|
|
218
226
|
...d,
|
|
219
227
|
types: {
|
|
220
228
|
...d.types,
|
|
221
|
-
parameters:
|
|
222
|
-
d.types?.parameters?.filter((t, idx) => idx !== 0 && !paramsToOmit.includes(t.name)) ?? [],
|
|
229
|
+
parameters: d.types?.parameters?.filter((t, idx) => !paramsToOmit.includes(t.name)) ?? [],
|
|
223
230
|
},
|
|
224
231
|
}));
|
|
225
232
|
}
|
|
@@ -250,7 +257,8 @@ function parseModuleDefinition(
|
|
|
250
257
|
findNamedDefinitionsOfType('Prop', preparedModuleDefinition, file),
|
|
251
258
|
['view']
|
|
252
259
|
),
|
|
253
|
-
|
|
260
|
+
views: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'View'),
|
|
261
|
+
classes: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'Class'),
|
|
254
262
|
};
|
|
255
263
|
return parsedDefinition;
|
|
256
264
|
}
|
package/src/mockgen.ts
CHANGED
|
@@ -6,7 +6,12 @@ import path from 'path';
|
|
|
6
6
|
import * as prettier from 'prettier';
|
|
7
7
|
import ts from 'typescript';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
Closure,
|
|
11
|
+
ClosureTypes,
|
|
12
|
+
OutputModuleDefinition,
|
|
13
|
+
OutputNestedClassDefinition,
|
|
14
|
+
} from './types';
|
|
10
15
|
|
|
11
16
|
const directoryPath = process.cwd();
|
|
12
17
|
|
|
@@ -50,6 +55,18 @@ function isSwiftDictionary(type: string) {
|
|
|
50
55
|
);
|
|
51
56
|
}
|
|
52
57
|
|
|
58
|
+
function isEither(type: string) {
|
|
59
|
+
return type.startsWith('Either<');
|
|
60
|
+
}
|
|
61
|
+
// "Either<TypeOne, TypeTwo>" -> ["TypeOne", "TypeTwo"]
|
|
62
|
+
function maybeUnwrapEither(type: string): string[] {
|
|
63
|
+
if (!isEither(type)) {
|
|
64
|
+
return [type];
|
|
65
|
+
}
|
|
66
|
+
const innerType = type.substring(7, type.length - 1);
|
|
67
|
+
return innerType.split(',').map((t) => t.trim());
|
|
68
|
+
}
|
|
69
|
+
|
|
53
70
|
/*
|
|
54
71
|
The Swift object type can have nested objects as the type of it's values (or maybe even keys).
|
|
55
72
|
[String: [String: Any]]
|
|
@@ -119,6 +136,13 @@ function mapSwiftTypeToTsType(type: string): TSNode {
|
|
|
119
136
|
if (isSwiftArray(type)) {
|
|
120
137
|
return ts.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));
|
|
121
138
|
}
|
|
139
|
+
// Custom handling for the Either convertible
|
|
140
|
+
if (isEither(type)) {
|
|
141
|
+
return ts.factory.createUnionTypeNode(
|
|
142
|
+
maybeUnwrapEither(type).map((t) => mapSwiftTypeToTsType(t))
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
122
146
|
switch (type) {
|
|
123
147
|
// Our custom representation for types that we have no type hints for. Not necessairly Swift any.
|
|
124
148
|
case 'unknown':
|
|
@@ -162,15 +186,6 @@ function getMockLiterals(tsReturnType: TSNode) {
|
|
|
162
186
|
case ts.SyntaxKind.TypeLiteral:
|
|
163
187
|
// handles a dictionary, could be improved by creating an object fitting the schema instead of an empty one
|
|
164
188
|
return ts.factory.createObjectLiteralExpression([], false);
|
|
165
|
-
case ts.SyntaxKind.TypeReference:
|
|
166
|
-
// A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.
|
|
167
|
-
return ts.addSyntheticTrailingComment(
|
|
168
|
-
ts.factory.createNull(),
|
|
169
|
-
ts.SyntaxKind.SingleLineCommentTrivia,
|
|
170
|
-
` TODO: Replace with mock for value of type ${
|
|
171
|
-
((tsReturnType as any)?.typeName as any)?.escapedText ?? ''
|
|
172
|
-
}.`
|
|
173
|
-
);
|
|
174
189
|
}
|
|
175
190
|
return undefined;
|
|
176
191
|
}
|
|
@@ -183,36 +198,66 @@ function maybeWrapWithReturnStatement(tsType: TSNode) {
|
|
|
183
198
|
if (tsType.kind === ts.SyntaxKind.AnyKeyword || tsType.kind === ts.SyntaxKind.VoidKeyword) {
|
|
184
199
|
return [];
|
|
185
200
|
}
|
|
201
|
+
if (tsType.kind === ts.SyntaxKind.TypeReference) {
|
|
202
|
+
// A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.
|
|
203
|
+
return [
|
|
204
|
+
ts.addSyntheticTrailingComment(
|
|
205
|
+
ts.factory.createReturnStatement(ts.factory.createNull()),
|
|
206
|
+
ts.SyntaxKind.SingleLineCommentTrivia,
|
|
207
|
+
` TODO: Replace with mock for value of type ${
|
|
208
|
+
((tsType as any)?.typeName as any)?.escapedText ?? ''
|
|
209
|
+
}.`
|
|
210
|
+
),
|
|
211
|
+
];
|
|
212
|
+
}
|
|
186
213
|
return [ts.factory.createReturnStatement(getMockLiterals(tsType))];
|
|
187
214
|
}
|
|
188
215
|
|
|
189
216
|
/*
|
|
190
217
|
We iterate over a list of functions and we create TS AST for each of them.
|
|
191
218
|
*/
|
|
192
|
-
function getMockedFunctions(functions: Closure[], async = false) {
|
|
219
|
+
function getMockedFunctions(functions: Closure[], { async = false, classMethod = false } = {}) {
|
|
193
220
|
return functions.map((fnStructure) => {
|
|
194
221
|
const name = ts.factory.createIdentifier(fnStructure.name);
|
|
195
222
|
const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);
|
|
196
|
-
const
|
|
197
|
-
[
|
|
198
|
-
ts.factory.createToken(ts.SyntaxKind.ExportKeyword),
|
|
199
|
-
async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined,
|
|
200
|
-
].filter((f) => !!f) as ts.ModifierToken<any>[],
|
|
201
|
-
undefined,
|
|
202
|
-
name,
|
|
203
|
-
undefined,
|
|
223
|
+
const parameters =
|
|
204
224
|
fnStructure?.types?.parameters.map((p) =>
|
|
205
225
|
ts.factory.createParameterDeclaration(
|
|
206
226
|
undefined,
|
|
207
227
|
undefined,
|
|
208
|
-
p.name,
|
|
228
|
+
p.name ?? '_',
|
|
209
229
|
undefined,
|
|
210
230
|
mapSwiftTypeToTsType(p.typename),
|
|
211
231
|
undefined
|
|
212
232
|
)
|
|
213
|
-
) ?? []
|
|
233
|
+
) ?? [];
|
|
234
|
+
const returnBlock = ts.factory.createBlock(maybeWrapWithReturnStatement(returnType), true);
|
|
235
|
+
|
|
236
|
+
if (classMethod) {
|
|
237
|
+
return ts.factory.createMethodDeclaration(
|
|
238
|
+
[async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined].flatMap((f) =>
|
|
239
|
+
f ? [f] : []
|
|
240
|
+
),
|
|
241
|
+
undefined,
|
|
242
|
+
name,
|
|
243
|
+
undefined,
|
|
244
|
+
undefined,
|
|
245
|
+
parameters,
|
|
246
|
+
async ? wrapWithAsync(returnType) : returnType,
|
|
247
|
+
returnBlock
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
const func = ts.factory.createFunctionDeclaration(
|
|
251
|
+
[
|
|
252
|
+
ts.factory.createToken(ts.SyntaxKind.ExportKeyword),
|
|
253
|
+
async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined,
|
|
254
|
+
].flatMap((f) => (f ? [f] : [])),
|
|
255
|
+
undefined,
|
|
256
|
+
name,
|
|
257
|
+
undefined,
|
|
258
|
+
parameters,
|
|
214
259
|
async ? wrapWithAsync(returnType) : returnType,
|
|
215
|
-
|
|
260
|
+
returnBlock
|
|
216
261
|
);
|
|
217
262
|
return func;
|
|
218
263
|
});
|
|
@@ -232,7 +277,7 @@ function getAllTypeReferences(node: ts.Node, accumulator: string[]) {
|
|
|
232
277
|
/**
|
|
233
278
|
* Iterates over types to collect the aliases.
|
|
234
279
|
*/
|
|
235
|
-
function getTypesToMock(module: OutputModuleDefinition |
|
|
280
|
+
function getTypesToMock(module: OutputModuleDefinition | OutputNestedClassDefinition) {
|
|
236
281
|
const foundTypes: string[] = [];
|
|
237
282
|
|
|
238
283
|
Object.values(module)
|
|
@@ -272,14 +317,8 @@ function getPrefix() {
|
|
|
272
317
|
return [ts.factory.createJSDocComment(prefix)];
|
|
273
318
|
}
|
|
274
319
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
*/
|
|
278
|
-
function getMockedView(definition: OutputViewDefinition | null) {
|
|
279
|
-
if (!definition) {
|
|
280
|
-
return [];
|
|
281
|
-
}
|
|
282
|
-
const propsType = ts.factory.createTypeAliasDeclaration(
|
|
320
|
+
function generatePropTypesForDefinition(definition: OutputNestedClassDefinition) {
|
|
321
|
+
return ts.factory.createTypeAliasDeclaration(
|
|
283
322
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
284
323
|
'ViewProps',
|
|
285
324
|
undefined,
|
|
@@ -306,24 +345,54 @@ function getMockedView(definition: OutputViewDefinition | null) {
|
|
|
306
345
|
}),
|
|
307
346
|
])
|
|
308
347
|
);
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
348
|
+
}
|
|
349
|
+
/*
|
|
350
|
+
Generate a mock for view props and functions.
|
|
351
|
+
*/
|
|
352
|
+
function getMockedViews(viewDefinitions: OutputNestedClassDefinition[]) {
|
|
353
|
+
return viewDefinitions.flatMap((definition) => {
|
|
354
|
+
if (!definition) {
|
|
355
|
+
return [];
|
|
356
|
+
}
|
|
357
|
+
const propsType = generatePropTypesForDefinition(definition);
|
|
358
|
+
const props = ts.factory.createParameterDeclaration(
|
|
359
|
+
undefined,
|
|
360
|
+
undefined,
|
|
361
|
+
'props',
|
|
362
|
+
undefined,
|
|
363
|
+
ts.factory.createTypeReferenceNode('ViewProps', undefined),
|
|
364
|
+
undefined
|
|
365
|
+
);
|
|
366
|
+
const viewFunction = ts.factory.createFunctionDeclaration(
|
|
367
|
+
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
368
|
+
undefined,
|
|
369
|
+
// TODO: Handle this better once requireNativeViewManager accepts view name or a different solution for multiple views is built.
|
|
370
|
+
viewDefinitions.length === 1 ? 'View' : definition.name,
|
|
371
|
+
undefined,
|
|
372
|
+
[props],
|
|
373
|
+
undefined,
|
|
374
|
+
ts.factory.createBlock([])
|
|
375
|
+
);
|
|
376
|
+
return [propsType, viewFunction];
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function getMockedClass(def: OutputNestedClassDefinition) {
|
|
381
|
+
const classDecl = ts.factory.createClassDeclaration(
|
|
318
382
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
383
|
+
ts.factory.createIdentifier(def.name),
|
|
319
384
|
undefined,
|
|
320
|
-
'View',
|
|
321
|
-
undefined,
|
|
322
|
-
[props],
|
|
323
385
|
undefined,
|
|
324
|
-
|
|
386
|
+
[
|
|
387
|
+
...getMockedFunctions(def.functions, { classMethod: true }),
|
|
388
|
+
...getMockedFunctions(def.asyncFunctions, { async: true, classMethod: true }),
|
|
389
|
+
] as ts.MethodDeclaration[]
|
|
325
390
|
);
|
|
326
|
-
return
|
|
391
|
+
return classDecl;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function getMockedClasses(def: OutputNestedClassDefinition[]) {
|
|
395
|
+
return def.map((d) => getMockedClass(d));
|
|
327
396
|
}
|
|
328
397
|
|
|
329
398
|
const newlineIdentifier = ts.factory.createIdentifier('\n\n') as any;
|
|
@@ -331,19 +400,46 @@ function separateWithNewlines<T>(arr: T) {
|
|
|
331
400
|
return [arr, newlineIdentifier];
|
|
332
401
|
}
|
|
333
402
|
|
|
403
|
+
function omitFromSet(set: Set<string>, toOmit: (string | undefined)[]) {
|
|
404
|
+
const newSet = new Set(set);
|
|
405
|
+
toOmit.forEach((item) => {
|
|
406
|
+
if (item) {
|
|
407
|
+
newSet.delete(item);
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
return newSet;
|
|
411
|
+
}
|
|
412
|
+
|
|
334
413
|
function getMockForModule(module: OutputModuleDefinition, includeTypes: boolean) {
|
|
335
|
-
return (
|
|
414
|
+
return (
|
|
415
|
+
[] as (ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.JSDoc | ts.ClassDeclaration)[]
|
|
416
|
+
)
|
|
336
417
|
.concat(
|
|
337
418
|
getPrefix(),
|
|
338
419
|
newlineIdentifier,
|
|
339
|
-
includeTypes
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
420
|
+
includeTypes
|
|
421
|
+
? getMockedTypes(
|
|
422
|
+
omitFromSet(
|
|
423
|
+
new Set([
|
|
424
|
+
...getTypesToMock(module),
|
|
425
|
+
...new Set(...module.views.map((v) => getTypesToMock(v))),
|
|
426
|
+
...new Set(...module.classes.map((c) => getTypesToMock(c))),
|
|
427
|
+
]),
|
|
428
|
+
// Ignore all types that are actually native classes
|
|
429
|
+
[
|
|
430
|
+
module.name,
|
|
431
|
+
...module.views.map((c) => c.name),
|
|
432
|
+
...module.classes.map((c) => c.name),
|
|
433
|
+
]
|
|
434
|
+
)
|
|
435
|
+
)
|
|
436
|
+
: [],
|
|
343
437
|
newlineIdentifier,
|
|
344
|
-
|
|
438
|
+
getMockedFunctions(module.functions) as ts.FunctionDeclaration[],
|
|
439
|
+
getMockedFunctions(module.asyncFunctions, { async: true }) as ts.FunctionDeclaration[],
|
|
345
440
|
newlineIdentifier,
|
|
346
|
-
|
|
441
|
+
getMockedViews(module.views),
|
|
442
|
+
getMockedClasses(module.classes)
|
|
347
443
|
)
|
|
348
444
|
.flatMap(separateWithNewlines);
|
|
349
445
|
}
|
package/src/types.ts
CHANGED
|
@@ -47,11 +47,13 @@ export type Prop = {
|
|
|
47
47
|
|
|
48
48
|
export type OutputModuleDefinition = {
|
|
49
49
|
name: string;
|
|
50
|
-
|
|
50
|
+
views: OutputNestedClassDefinition[];
|
|
51
|
+
classes: OutputNestedClassDefinition[];
|
|
51
52
|
events: {
|
|
52
53
|
name: string;
|
|
53
54
|
}[];
|
|
54
55
|
} & Record<'asyncFunctions' | 'functions' | 'properties', Closure[]> &
|
|
55
56
|
Record<'props', Prop[]>;
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
// views and classes are a very similar structure, same as module but without more nesting levels
|
|
59
|
+
export type OutputNestedClassDefinition = Omit<OutputModuleDefinition, 'views' | 'classes'>;
|