@typetron/framework 0.5.3 → 0.5.5
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/.eslintrc-old.js +208 -0
- package/Cache/Cache.ts +13 -0
- package/Cache/Stores/DatabaseStore.ts +120 -0
- package/Cache/Stores/FileStore.ts +69 -0
- package/Cache/Stores/MemoryStore.ts +71 -0
- package/Cache/index.ts +5 -0
- package/Cache/types.ts +4 -0
- package/Container/ClassResolver.ts +106 -0
- package/Container/Container.ts +144 -0
- package/Container/Contracts.ts +3 -0
- package/Container/Decorators.ts +20 -0
- package/Container/Metadata.ts +16 -0
- package/Container/Resolver.ts +27 -0
- package/Container/index.ts +5 -0
- package/Database/Clauses/Where.ts +0 -0
- package/Database/Connection.ts +52 -0
- package/Database/Decorators.ts +142 -0
- package/Database/Drivers/DatabaseDriver.ts +37 -0
- package/Database/Drivers/MySQL/Alter/index.ts +55 -0
- package/Database/Drivers/MySQL/ColumnDefinition.ts +16 -0
- package/Database/Drivers/MySQL/Create.ts +47 -0
- package/Database/Drivers/MySQL/MysqlDriver.ts +123 -0
- package/Database/Drivers/MySQL/Schema.ts +82 -0
- package/Database/Drivers/MySQL/index.ts +13 -0
- package/Database/Drivers/SQL/Schema.ts +73 -0
- package/Database/Drivers/SQL/Statements/Alter.ts +22 -0
- package/Database/Drivers/SQL/Statements/BaseStatement.ts +55 -0
- package/Database/Drivers/SQL/Statements/Delete.ts +20 -0
- package/Database/Drivers/SQL/Statements/Insert.ts +24 -0
- package/Database/Drivers/SQL/Statements/Select.ts +55 -0
- package/Database/Drivers/SQL/Statements/Update.ts +33 -0
- package/Database/Drivers/SQL/index.ts +8 -0
- package/Database/Drivers/SQLite/Create.ts +45 -0
- package/Database/Drivers/SQLite/Schema.ts +54 -0
- package/Database/Drivers/SQLite/SqliteDriver.ts +144 -0
- package/Database/Drivers/SQLite/index.ts +15 -0
- package/Database/Drivers/SchemaContract.ts +11 -0
- package/Database/Drivers/Statement.ts +16 -0
- package/Database/Drivers/index.ts +4 -0
- package/Database/Entity.ts +377 -0
- package/Database/EntityNotFoundError.ts +5 -0
- package/Database/EntityProxyHandler.ts +43 -0
- package/Database/EntityQuery.ts +197 -0
- package/Database/Expression.ts +3 -0
- package/Database/Fields.ts +816 -0
- package/Database/Helpers.ts +12 -0
- package/Database/List.ts +71 -0
- package/Database/Migrations/Migration.ts +10 -0
- package/Database/Migrations/MigrationHistory.ts +20 -0
- package/Database/Migrations/Migrator.ts +122 -0
- package/Database/Migrations/index.ts +3 -0
- package/Database/ORM/BaseRelationship.ts +10 -0
- package/Database/Query.ts +374 -0
- package/Database/Seeders/Seeder.ts +3 -0
- package/Database/Seeders/SeederManager.ts +27 -0
- package/Database/Seeders/index.ts +2 -0
- package/Database/StringExpression.ts +9 -0
- package/Database/Types.ts +165 -0
- package/Database/index.ts +23 -0
- package/Encryption/index.ts +51 -0
- package/Forms/Decorators.ts +29 -0
- package/Forms/Form.ts +70 -0
- package/Forms/FormFields.ts +36 -0
- package/Forms/index.ts +3 -0
- package/Framework/App.ts +10 -0
- package/Framework/Application.ts +118 -0
- package/Framework/Auth/Auth.ts +122 -0
- package/Framework/Auth/Authenticatable.ts +9 -0
- package/Framework/Auth/User.ts +27 -0
- package/Framework/Auth/index.ts +29 -0
- package/Framework/Config/AppConfig.ts +25 -0
- package/Framework/Config/AuthConfig.ts +9 -0
- package/Framework/Config/BaseConfig.ts +9 -0
- package/Framework/Config/CacheConfig.ts +38 -0
- package/Framework/Config/DatabaseConfig.ts +21 -0
- package/Framework/Config/MailConfig.ts +30 -0
- package/Framework/Config/index.ts +6 -0
- package/Framework/Middleware/AuthMiddleware.ts +31 -0
- package/Framework/Middleware/CorsMiddleware.ts +32 -0
- package/Framework/Middleware/StaticAssetsMiddleware.ts +76 -0
- package/Framework/Middleware/index.ts +2 -0
- package/Framework/Provider.ts +9 -0
- package/Framework/Providers/CacheProvider.ts +28 -0
- package/Framework/Providers/DatabaseProvider.ts +36 -0
- package/Framework/Providers/MailProvider.ts +31 -0
- package/Framework/Providers/WebsocketsProvider.ts +120 -0
- package/Framework/Resolvers/AuthResolver.ts +23 -0
- package/Framework/Resolvers/EntityResolver.ts +41 -0
- package/Framework/Resolvers/FormResolver.ts +37 -0
- package/Framework/RootDir.ts +1 -0
- package/Framework/index.ts +8 -0
- package/Frontend/Angular/index.ts +24 -0
- package/Frontend/Websockets/index.ts +86 -0
- package/Mail/MailAddress.ts +4 -0
- package/Mail/MailTransport.ts +6 -0
- package/Mail/Mailable.ts +16 -0
- package/Mail/Mailer.ts +27 -0
- package/Mail/PendingMail.ts +68 -0
- package/Mail/SentMessage.ts +20 -0
- package/Mail/Transports/MemoryTransport.ts +13 -0
- package/Mail/Transports/SendGridTransport.ts +95 -0
- package/Mail/index.ts +3 -0
- package/Models/Model.ts +41 -0
- package/Models/index.ts +54 -0
- package/Router/BaseController.ts +7 -0
- package/Router/Decorators.ts +224 -0
- package/Router/Guard.ts +10 -0
- package/Router/Http/Contracts.ts +4 -0
- package/Router/Http/ErrorHandler.ts +45 -0
- package/Router/Http/ErrorHandlerInterface.ts +6 -0
- package/Router/Http/Errors/HttpError.ts +15 -0
- package/Router/Http/Handler.ts +183 -0
- package/Router/Http/HttpRoute.ts +110 -0
- package/Router/Http/Middleware.ts +7 -0
- package/Router/Http/Request.ts +225 -0
- package/Router/Http/Response.ts +35 -0
- package/Router/Http/index.ts +85 -0
- package/Router/Metadata.ts +34 -0
- package/Router/Middleware.ts +16 -0
- package/Router/Request.ts +65 -0
- package/Router/Route.ts +16 -0
- package/Router/RouteNotFoundError.ts +5 -0
- package/Router/Router.ts +35 -0
- package/Router/Servers/index.ts +6 -0
- package/Router/Servers/node.ts +49 -0
- package/Router/Servers/uNetworking.ts +151 -0
- package/Router/Websockets/Handler.ts +82 -0
- package/Router/Websockets/Middleware.ts +7 -0
- package/Router/Websockets/Request.ts +3 -0
- package/Router/Websockets/WebsocketRoute.ts +61 -0
- package/Router/Websockets/index.ts +57 -0
- package/Router/Websockets/types.ts +23 -0
- package/Router/index.ts +6 -0
- package/Storage/File.ts +30 -0
- package/Storage/Image.ts +19 -0
- package/Storage/InvalidImage.ts +3 -0
- package/Storage/Storage.ts +98 -0
- package/Storage/index.ts +4 -0
- package/Storage/utils.ts +18 -0
- package/Support/Array.ts +184 -0
- package/Support/Math.ts +12 -0
- package/Support/Metadata.ts +31 -0
- package/Support/String.ts +38 -0
- package/Support/index.ts +19 -0
- package/Support/utils.ts +7 -0
- package/Testing/TestCase.ts +193 -0
- package/Validation/Rule.ts +9 -0
- package/Validation/RuleInterface.ts +10 -0
- package/Validation/Rules/Email.ts +20 -0
- package/Validation/Rules/FileExtension.ts +21 -0
- package/Validation/Rules/MaxLength.ts +17 -0
- package/Validation/Rules/MinLength.ts +18 -0
- package/Validation/Rules/Optional.ts +18 -0
- package/Validation/Rules/Required.ts +29 -0
- package/Validation/Validator.ts +7 -0
- package/Validation/index.ts +12 -0
- package/benchmark-index.js +20 -0
- package/benchmark.ts +47 -0
- package/package.json +7 -3
- package/tests/Cache/DatabaseStoreTest.ts +110 -0
- package/tests/Cache/FileStoreTest.ts +93 -0
- package/tests/Cache/MemoryStoreTest.ts +92 -0
- package/tests/Container/ContainerTest.ts +336 -0
- package/tests/Database/Drivers/MySQL/AlterTest.ts +100 -0
- package/tests/Database/Drivers/MySQL/CreateTest.ts +39 -0
- package/tests/Database/Drivers/MysqlDriverTest.ts +140 -0
- package/tests/Database/Drivers/SqliteDriverTest.ts +126 -0
- package/tests/Database/Entities/Article.ts +21 -0
- package/tests/Database/Entities/Profile.ts +21 -0
- package/tests/Database/Entities/Role.ts +15 -0
- package/tests/Database/Entities/User.ts +35 -0
- package/tests/Database/EntityRelationshipsTest.ts +475 -0
- package/tests/Database/EntityTest.ts +202 -0
- package/tests/Database/Migrations/RunnerTest.ts +96 -0
- package/tests/Database/Migrations/migrations/1.createUserTable.ts +12 -0
- package/tests/Database/Migrations/migrations/2.createArticlesTable.ts +12 -0
- package/tests/Database/QueryTest.ts +573 -0
- package/tests/Database/SchemaTest.ts +32 -0
- package/tests/Database/Seeders/RunnerTest.ts +30 -0
- package/tests/Database/Seeders/seeders/RandomSeeder.ts +10 -0
- package/tests/Database/utils.ts +16 -0
- package/tests/Forms/FormsTest.ts +59 -0
- package/tests/Framework/Middleware/StaticAssetsMiddlewareTest.ts +129 -0
- package/tests/Framework/Resolvers/EntityResolverTest.ts +48 -0
- package/tests/Framework/Router/RouterTest.ts +33 -0
- package/tests/Mail/MailerTest.ts +76 -0
- package/tests/Model/ModelTest.ts +183 -0
- package/tests/Router/HttpHandlerTest.ts +72 -0
- package/tests/Router/RequestTest.ts +77 -0
- package/tests/Router/WebSocketsHandlerTest.ts +51 -0
- package/tests/Storage/StorageTest.ts +97 -0
- package/tests/Support/ArrayTest.ts +167 -0
- package/tests/Support/StringTest.ts +18 -0
- package/tests/Validation/RulesTest.ts +54 -0
- package/types.d.ts +8 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { expect } from 'chai'
|
|
2
|
+
import { suite, test } from '@testdeck/mocha'
|
|
3
|
+
import { BaseResolver, Container, Inject, Injectable, Scope } from '../../Container'
|
|
4
|
+
import { ServiceIdentifier } from '../../Container/Contracts'
|
|
5
|
+
|
|
6
|
+
@suite
|
|
7
|
+
class ContainerTest {
|
|
8
|
+
@test
|
|
9
|
+
givesSingletonContainer() {
|
|
10
|
+
const container = Container.getInstance()
|
|
11
|
+
expect(container).instanceOf(Container)
|
|
12
|
+
expect(Container.getInstance()).to.be.equal(container)
|
|
13
|
+
expect(Container.getInstance()).instanceOf(Container)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@test
|
|
17
|
+
overwritesSingletonContainer() {
|
|
18
|
+
const container = Container.setInstance(new Container)
|
|
19
|
+
expect(container).equal(Container.getInstance())
|
|
20
|
+
const container2 = new Container
|
|
21
|
+
Container.setInstance(container2)
|
|
22
|
+
expect(container).not.equal(Container.getInstance())
|
|
23
|
+
expect(container2).equal(Container.getInstance())
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@test
|
|
27
|
+
createsInstance() {
|
|
28
|
+
const container = new Container()
|
|
29
|
+
|
|
30
|
+
@Injectable()
|
|
31
|
+
class Request {}
|
|
32
|
+
|
|
33
|
+
expect(container.get(Request)).instanceOf(Request)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// @test
|
|
37
|
+
// bindsCallbacks() {
|
|
38
|
+
// class Dependency {}
|
|
39
|
+
//
|
|
40
|
+
// const container = new Container;
|
|
41
|
+
//
|
|
42
|
+
// @Injectable() // not possible right now
|
|
43
|
+
// function myFunction(dependency: Dependency) {
|
|
44
|
+
// return dependency;
|
|
45
|
+
// };
|
|
46
|
+
// expect(container.call(myFunction())).to.be.instanceOf(Dependency);
|
|
47
|
+
// }
|
|
48
|
+
|
|
49
|
+
@test
|
|
50
|
+
singletonScope() {
|
|
51
|
+
class Request {}
|
|
52
|
+
|
|
53
|
+
const container = new Container()
|
|
54
|
+
const request = container.get(Request)
|
|
55
|
+
expect(request).to.be.equal(container.get(Request))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@test
|
|
59
|
+
transientScope() {
|
|
60
|
+
@Injectable(Scope.TRANSIENT)
|
|
61
|
+
class Request {}
|
|
62
|
+
|
|
63
|
+
const container = new Container()
|
|
64
|
+
const request1 = container.get(Request)
|
|
65
|
+
const request2 = container.get(Request)
|
|
66
|
+
expect(request1).not.to.be.equal(request2)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@test
|
|
70
|
+
requestScope() {
|
|
71
|
+
@Injectable(Scope.REQUEST)
|
|
72
|
+
class Request {}
|
|
73
|
+
|
|
74
|
+
const container = new Container()
|
|
75
|
+
const childContainer = container.createChildContainer()
|
|
76
|
+
const request = childContainer.get(Request)
|
|
77
|
+
expect(container.getInstances().size).to.be.equal(0)
|
|
78
|
+
expect(childContainer.getInstances().size).to.be.equal(2)
|
|
79
|
+
expect(request).to.be.instanceof(Request)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// @test
|
|
83
|
+
// requestScopeWithSingletonDependencyFromParenContainer() {
|
|
84
|
+
// @Injectable(Scope.REQUEST)
|
|
85
|
+
// class Request {}
|
|
86
|
+
//
|
|
87
|
+
// class Controller {
|
|
88
|
+
// @Inject()
|
|
89
|
+
// request: Request;
|
|
90
|
+
// }
|
|
91
|
+
//
|
|
92
|
+
// const container = new Container();
|
|
93
|
+
// const childContainer = container.createChildContainer();
|
|
94
|
+
// const controller = childContainer.get(Controller);
|
|
95
|
+
// expect(Object.values(container.getInstances())).to.have.length(0);
|
|
96
|
+
// expect(Object.values(childContainer.getInstances())).to.have.length(1);
|
|
97
|
+
// expect(Object.values(childContainer.getInstances())[0]).to.be.instanceof(Request);
|
|
98
|
+
// }
|
|
99
|
+
|
|
100
|
+
@test
|
|
101
|
+
bindsStringToImplementation() {
|
|
102
|
+
@Injectable(Scope.TRANSIENT)
|
|
103
|
+
class Request {}
|
|
104
|
+
|
|
105
|
+
const container = new Container()
|
|
106
|
+
const request = container.get(Request)
|
|
107
|
+
container.set('request', request)
|
|
108
|
+
|
|
109
|
+
expect(request).to.be.equal(container.get('request'))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@test
|
|
113
|
+
bindsImplementationsWithTheSameName() {
|
|
114
|
+
const namespaceA = {
|
|
115
|
+
Request: class Request {}
|
|
116
|
+
}
|
|
117
|
+
const namespaceB = {
|
|
118
|
+
Request: class Request {}
|
|
119
|
+
}
|
|
120
|
+
const namespaceC = {
|
|
121
|
+
Request: class Request {}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const container = new Container()
|
|
125
|
+
const requestA = container.get(namespaceA.Request)
|
|
126
|
+
const requestB = container.get(namespaceB.Request)
|
|
127
|
+
const requestC = container.get(namespaceC.Request)
|
|
128
|
+
expect(requestA).to.be.instanceOf(namespaceA.Request)
|
|
129
|
+
expect(requestB).to.be.instanceOf(namespaceB.Request)
|
|
130
|
+
expect(requestC).to.be.instanceOf(namespaceC.Request)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@test
|
|
134
|
+
bindsClassToInterface() {
|
|
135
|
+
abstract class StorageInterface {}
|
|
136
|
+
|
|
137
|
+
class DiskStorage implements StorageInterface {}
|
|
138
|
+
|
|
139
|
+
class CloudStorage implements StorageInterface {}
|
|
140
|
+
|
|
141
|
+
const container = new Container()
|
|
142
|
+
container.set(StorageInterface, new DiskStorage)
|
|
143
|
+
expect(container.get(StorageInterface)).to.be.instanceOf(DiskStorage)
|
|
144
|
+
container.set(StorageInterface, new CloudStorage())
|
|
145
|
+
expect(container.get(StorageInterface)).to.be.instanceOf(CloudStorage)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@test
|
|
149
|
+
throwsExceptionIfCannotResolve() {
|
|
150
|
+
const container = new Container
|
|
151
|
+
expect(() => container.get('DoesNotExist')).to.throw(`No instance found for 'DoesNotExist'`)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@test
|
|
155
|
+
throwsExceptionIfCannotFindAnAbstractName() {
|
|
156
|
+
const container = new Container
|
|
157
|
+
const x = {} as typeof Container
|
|
158
|
+
expect(() => container.get(x)).to.throw(`Cannot get abstract name for ${x}`)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@test
|
|
162
|
+
resolvesDependenciesFromClassProperties() {
|
|
163
|
+
const container = new Container()
|
|
164
|
+
|
|
165
|
+
@Injectable()
|
|
166
|
+
class UserRepository {
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@Injectable()
|
|
170
|
+
class AuthService {
|
|
171
|
+
@Inject()
|
|
172
|
+
userRepository: UserRepository
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@Injectable()
|
|
176
|
+
class UserController {
|
|
177
|
+
@Inject()
|
|
178
|
+
authService: AuthService
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const userController = container.get(UserController)
|
|
182
|
+
expect(userController).instanceOf(UserController)
|
|
183
|
+
expect(userController.authService).instanceOf(AuthService)
|
|
184
|
+
expect(userController.authService.userRepository).instanceOf(UserRepository)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@test
|
|
188
|
+
resolvesDependenciesFromConstructorParameters() {
|
|
189
|
+
const container = new Container
|
|
190
|
+
|
|
191
|
+
@Injectable()
|
|
192
|
+
class UserRepository {
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@Injectable()
|
|
196
|
+
class AuthService {
|
|
197
|
+
constructor(public userRepository: UserRepository) {
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@Injectable()
|
|
202
|
+
class UserController {
|
|
203
|
+
constructor(public authService: AuthService) {
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const userController = container.get(UserController)
|
|
208
|
+
expect(userController).instanceOf(UserController)
|
|
209
|
+
expect(userController.authService).instanceOf(AuthService)
|
|
210
|
+
expect(userController.authService.userRepository).instanceOf(UserRepository)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// @test
|
|
214
|
+
// async throwsExceptionIfDependencyCannotBeResolved() {
|
|
215
|
+
// const container = new Container;
|
|
216
|
+
//
|
|
217
|
+
// @Injectable()
|
|
218
|
+
// class UserController {
|
|
219
|
+
// constructor(public userRepository: object) {
|
|
220
|
+
// }
|
|
221
|
+
// }
|
|
222
|
+
//
|
|
223
|
+
// await expect(() => container.get(UserController)).to.throw(`No binding found for parameter 0 in 'UserController'`);
|
|
224
|
+
// }
|
|
225
|
+
|
|
226
|
+
@test
|
|
227
|
+
createsChildContainer() {
|
|
228
|
+
const container = new Container()
|
|
229
|
+
const childContainer = container.createChildContainer()
|
|
230
|
+
expect(childContainer).to.be.instanceOf(Container)
|
|
231
|
+
expect(childContainer).not.to.equal(container)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@test
|
|
235
|
+
childContainerGetsObjectFromParentContainer() {
|
|
236
|
+
class Storage {}
|
|
237
|
+
|
|
238
|
+
const container = new Container()
|
|
239
|
+
const childContainer = container.createChildContainer()
|
|
240
|
+
|
|
241
|
+
const storage = container.get(Storage)
|
|
242
|
+
expect(childContainer.get(Storage)).to.equal(storage)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
@test
|
|
246
|
+
dependenciesHaveTheScopeSingleton() {
|
|
247
|
+
class Request {}
|
|
248
|
+
|
|
249
|
+
const container = new Container()
|
|
250
|
+
const childContainer = container.createChildContainer()
|
|
251
|
+
|
|
252
|
+
const request = childContainer.get(Request)
|
|
253
|
+
expect(childContainer.get(Request)).to.equal(request)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@test
|
|
257
|
+
async resolvesAsyncDependencies() {
|
|
258
|
+
class User {}
|
|
259
|
+
|
|
260
|
+
class Request {
|
|
261
|
+
@Inject()
|
|
262
|
+
user: User
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
class UserResolver extends BaseResolver {
|
|
266
|
+
canResolve<T>(abstract: ServiceIdentifier<T>): boolean {
|
|
267
|
+
return abstract === User
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async resolve<T>(abstract: ServiceIdentifier<T>, parameters: object[]): Promise<T> {
|
|
271
|
+
await new Promise(resolve => setTimeout(resolve, 1))
|
|
272
|
+
return new User as T
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const container = new Container()
|
|
277
|
+
container.resolvers.unshift(new UserResolver(container))
|
|
278
|
+
|
|
279
|
+
const request = container.get(Request)
|
|
280
|
+
expect(request).to.be.instanceof(Promise)
|
|
281
|
+
const resolvedRequest = await container.get(Request)
|
|
282
|
+
expect(resolvedRequest).to.be.instanceof(Request)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@test
|
|
286
|
+
async injectsDependencyUsingStringAlias() {
|
|
287
|
+
class SomeClass {
|
|
288
|
+
@Inject('theCode')
|
|
289
|
+
code: number
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const container = new Container()
|
|
293
|
+
container.set('theCode', 123)
|
|
294
|
+
|
|
295
|
+
const instance = container.get(SomeClass)
|
|
296
|
+
|
|
297
|
+
expect(instance.code).to.be.equal(123)
|
|
298
|
+
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// @test
|
|
302
|
+
// async customDecorators() {
|
|
303
|
+
// class Database {
|
|
304
|
+
// debug = false;
|
|
305
|
+
//
|
|
306
|
+
// async init() {
|
|
307
|
+
// this.debug = true;
|
|
308
|
+
// }
|
|
309
|
+
// }
|
|
310
|
+
//
|
|
311
|
+
// function CustomDecorator() {
|
|
312
|
+
// return function (target: Object, targetKey: string) {
|
|
313
|
+
// // @ts-ignore
|
|
314
|
+
// console.log('thi ->', this);
|
|
315
|
+
// const metadata = InjectableMetadata.get(target.constructor);
|
|
316
|
+
// metadata.dependencies[targetKey] = AuthUserIdentifier;
|
|
317
|
+
// metadata.scope = Scope.REQUEST;
|
|
318
|
+
// InjectableMetadata.set(metadata, target.constructor);
|
|
319
|
+
// };
|
|
320
|
+
// // return Container.createPropertyDecorator(container => {
|
|
321
|
+
// //
|
|
322
|
+
// // });
|
|
323
|
+
// }
|
|
324
|
+
//
|
|
325
|
+
// class Controller {
|
|
326
|
+
// @CustomDecorator()
|
|
327
|
+
// database: Database;
|
|
328
|
+
// }
|
|
329
|
+
//
|
|
330
|
+
// const container = new Container();
|
|
331
|
+
// const controller = await container.get(Controller);
|
|
332
|
+
//
|
|
333
|
+
// expect(controller.database).to.be.instanceof(Database);
|
|
334
|
+
// expect(controller.database.debug).to.equal(true);
|
|
335
|
+
// }
|
|
336
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { suite, test } from '@testdeck/mocha'
|
|
2
|
+
import { expectQuery } from '@Typetron/tests/Database/utils'
|
|
3
|
+
import { AddColumn, AddConstraint, Alter, Constraints, DropColumn, ModifyColumn } from '@Typetron/Database/Drivers/MySQL/Alter'
|
|
4
|
+
|
|
5
|
+
@suite
|
|
6
|
+
class AlterTest {
|
|
7
|
+
|
|
8
|
+
@test
|
|
9
|
+
async addColumn() {
|
|
10
|
+
const addAge = new AddColumn({
|
|
11
|
+
name: 'age',
|
|
12
|
+
type: 'integer',
|
|
13
|
+
})
|
|
14
|
+
const statement = new Alter('test', [addAge])
|
|
15
|
+
expectQuery(statement).toEqual('ALTER TABLE test ADD age integer')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@test
|
|
19
|
+
async addPrimaryKeyColumn() {
|
|
20
|
+
const addAge = new AddColumn({
|
|
21
|
+
name: 'age',
|
|
22
|
+
type: 'integer',
|
|
23
|
+
})
|
|
24
|
+
const statement = new Alter('test', [addAge])
|
|
25
|
+
expectQuery(statement).toEqual('ALTER TABLE test ADD age integer')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@test
|
|
29
|
+
async dropColumn() {
|
|
30
|
+
const age = new DropColumn('age')
|
|
31
|
+
const statement = new Alter('test', [age])
|
|
32
|
+
expectQuery(statement).toEqual('ALTER TABLE test DROP COLUMN age')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@test
|
|
36
|
+
async ModifyColumn() {
|
|
37
|
+
const age = new ModifyColumn({
|
|
38
|
+
name: 'age',
|
|
39
|
+
type: 'integer',
|
|
40
|
+
})
|
|
41
|
+
const statement = new Alter('test', [age])
|
|
42
|
+
expectQuery(statement).toEqual('ALTER TABLE test MODIFY age integer')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@test
|
|
46
|
+
async ModifyColumnWithAutoIncrement() {
|
|
47
|
+
const age = new ModifyColumn({
|
|
48
|
+
name: 'age',
|
|
49
|
+
type: 'integer',
|
|
50
|
+
autoIncrement: 1
|
|
51
|
+
})
|
|
52
|
+
const statement = new Alter('test', [age])
|
|
53
|
+
expectQuery(statement).toEqual('ALTER TABLE test MODIFY age integer AUTO_INCREMENT')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@test
|
|
57
|
+
async addPrimaryKeyConstraint() {
|
|
58
|
+
const age = new AddConstraint({
|
|
59
|
+
name: 'age',
|
|
60
|
+
type: 'integer',
|
|
61
|
+
}, Constraints.PrimaryKey)
|
|
62
|
+
const statement = new Alter('test', [age])
|
|
63
|
+
expectQuery(statement).toEqual('ALTER TABLE test ADD CONSTRAINT PRIMARY KEY (age)')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@test
|
|
67
|
+
async addForeignKeyConstraint() {
|
|
68
|
+
const age = new AddConstraint({
|
|
69
|
+
name: 'age',
|
|
70
|
+
type: 'integer',
|
|
71
|
+
}, Constraints.ForeignKey)
|
|
72
|
+
const statement = new Alter('test', [age])
|
|
73
|
+
expectQuery(statement).toEqual('ALTER TABLE test ADD CONSTRAINT FOREIGN KEY (age)')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@test
|
|
77
|
+
async altersMultipleColumns() {
|
|
78
|
+
const addAge = new AddColumn({
|
|
79
|
+
name: 'age',
|
|
80
|
+
type: 'integer',
|
|
81
|
+
})
|
|
82
|
+
const dropName = new DropColumn('age')
|
|
83
|
+
const dropTitle = new DropColumn('title')
|
|
84
|
+
|
|
85
|
+
const addAddress = new AddColumn({
|
|
86
|
+
name: 'address',
|
|
87
|
+
type: 'varchar(255)',
|
|
88
|
+
})
|
|
89
|
+
const statement = new Alter('test', [addAge, dropName, dropTitle, addAddress])
|
|
90
|
+
expectQuery(statement).toEqual(`
|
|
91
|
+
ALTER TABLE test
|
|
92
|
+
ADD age integer,
|
|
93
|
+
DROP
|
|
94
|
+
COLUMN age,
|
|
95
|
+
DROP
|
|
96
|
+
COLUMN title,
|
|
97
|
+
ADD address varchar(255)
|
|
98
|
+
`)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { suite, test } from '@testdeck/mocha'
|
|
2
|
+
import { Create } from '@Typetron/Database/Drivers/MySQL/Create'
|
|
3
|
+
import { expectQuery } from '@Typetron/tests/Database/utils'
|
|
4
|
+
|
|
5
|
+
@suite
|
|
6
|
+
class CreateTest {
|
|
7
|
+
|
|
8
|
+
@test
|
|
9
|
+
async createsEmptyTable() {
|
|
10
|
+
const statement = new Create('test')
|
|
11
|
+
expectQuery(statement).toEqual('CREATE TABLE test ( )')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@test
|
|
15
|
+
async createsTableWithIntegerColumn() {
|
|
16
|
+
const statement = new Create('test', [{
|
|
17
|
+
name: 'age',
|
|
18
|
+
type: 'integer',
|
|
19
|
+
}])
|
|
20
|
+
expectQuery(statement).toEqual('CREATE TABLE test ( age integer )')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@test
|
|
24
|
+
async createsTableWithPrimaryAutoIncrementColumn() {
|
|
25
|
+
const statement = new Create('test', [{
|
|
26
|
+
name: 'id',
|
|
27
|
+
type: 'integer',
|
|
28
|
+
primaryKey: true,
|
|
29
|
+
autoIncrement: 1
|
|
30
|
+
}])
|
|
31
|
+
expectQuery(statement).toEqual(`
|
|
32
|
+
CREATE TABLE test
|
|
33
|
+
(
|
|
34
|
+
id integer AUTO_INCREMENT,
|
|
35
|
+
PRIMARY KEY (id)
|
|
36
|
+
)
|
|
37
|
+
`)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { suite, test } from '@testdeck/mocha'
|
|
2
|
+
import { BelongsTo, Column, Entity, HasOne, ID, MysqlDriver, Options, PrimaryColumn, Relation } from '@Typetron/Database'
|
|
3
|
+
import { anyString, instance, mock, when } from 'ts-mockito'
|
|
4
|
+
import { Schema } from '@Typetron/Database/Drivers/MySQL/Schema'
|
|
5
|
+
import { expectQuery } from '../utils'
|
|
6
|
+
import { DatabaseDriver } from '@Typetron/Database/Drivers/DatabaseDriver'
|
|
7
|
+
|
|
8
|
+
@suite
|
|
9
|
+
class MysqlDriverTest {
|
|
10
|
+
|
|
11
|
+
driver: DatabaseDriver
|
|
12
|
+
schema: Schema
|
|
13
|
+
query: string
|
|
14
|
+
|
|
15
|
+
async before() {
|
|
16
|
+
this.driver = mock(MysqlDriver)
|
|
17
|
+
this.schema = new Schema(instance(this.driver))
|
|
18
|
+
when(this.driver.run(anyString())).thenCall((query: string) => this.query = query)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@test
|
|
22
|
+
async createsEmptyTable() {
|
|
23
|
+
@Options()
|
|
24
|
+
class Test extends Entity {}
|
|
25
|
+
|
|
26
|
+
await this.schema.synchronize([Test].pluck('metadata'))
|
|
27
|
+
expectQuery(this.query).toEqual('CREATE TABLE test ( )')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@test
|
|
31
|
+
async createsTableWithIntegerColumn() {
|
|
32
|
+
class Test extends Entity {
|
|
33
|
+
@Column()
|
|
34
|
+
age: number
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
await this.schema.synchronize([Test].pluck('metadata'))
|
|
38
|
+
expectQuery(this.query).toEqual('CREATE TABLE test ( age integer )')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@test
|
|
42
|
+
async createsTableWithPrimaryAutoIncrementColumn() {
|
|
43
|
+
class Test extends Entity {
|
|
44
|
+
@PrimaryColumn()
|
|
45
|
+
id: ID
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
await this.schema.synchronize([Test].pluck('metadata'))
|
|
49
|
+
expectQuery(this.query).toEqual(`
|
|
50
|
+
CREATE TABLE test
|
|
51
|
+
(
|
|
52
|
+
id integer AUTO_INCREMENT,
|
|
53
|
+
PRIMARY KEY (id)
|
|
54
|
+
)
|
|
55
|
+
`)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@test
|
|
59
|
+
async createsTableWithForeignColumn() {
|
|
60
|
+
class User extends Entity {
|
|
61
|
+
@Column()
|
|
62
|
+
@Relation(() => Image, 'user')
|
|
63
|
+
image: HasOne<Image>
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
class Image extends Entity {
|
|
67
|
+
@Column()
|
|
68
|
+
@Relation(() => User, 'image')
|
|
69
|
+
user: BelongsTo<User>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
await this.schema.synchronize([Image].pluck('metadata'))
|
|
73
|
+
expectQuery(this.query).toEqual(`
|
|
74
|
+
CREATE TABLE image
|
|
75
|
+
(
|
|
76
|
+
userId integer
|
|
77
|
+
)
|
|
78
|
+
`)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@test
|
|
82
|
+
async altersTable() {
|
|
83
|
+
when(this.driver.tableExists(anyString())).thenReturn(Promise.resolve(true))
|
|
84
|
+
when(this.driver.tableColumns(anyString())).thenReturn(Promise.resolve([
|
|
85
|
+
{
|
|
86
|
+
name: 'column2',
|
|
87
|
+
type: 'integer'
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'column3',
|
|
91
|
+
type: 'integer'
|
|
92
|
+
},
|
|
93
|
+
]))
|
|
94
|
+
|
|
95
|
+
class User extends Entity {
|
|
96
|
+
@Column()
|
|
97
|
+
column1: number
|
|
98
|
+
|
|
99
|
+
@Column()
|
|
100
|
+
column2: string
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
await this.schema.synchronize([User].pluck('metadata'))
|
|
104
|
+
|
|
105
|
+
expectQuery(this.query).toEqual(`
|
|
106
|
+
ALTER TABLE user
|
|
107
|
+
ADD column1 integer,
|
|
108
|
+
MODIFY column2 varchar(255),
|
|
109
|
+
DROP
|
|
110
|
+
COLUMN column3
|
|
111
|
+
`)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@test
|
|
115
|
+
async altersTableAddPrimaryKey() {
|
|
116
|
+
when(this.driver.tableExists(anyString())).thenReturn(Promise.resolve(true))
|
|
117
|
+
when(this.driver.tableColumns(anyString())).thenReturn(Promise.resolve([]))
|
|
118
|
+
|
|
119
|
+
class User extends Entity {
|
|
120
|
+
@PrimaryColumn()
|
|
121
|
+
id: ID
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const queries: string[] = []
|
|
125
|
+
when(this.driver.run(anyString())).thenCall((query: string) => queries.push(query))
|
|
126
|
+
|
|
127
|
+
await this.schema.synchronize([User].pluck('metadata'))
|
|
128
|
+
|
|
129
|
+
expectQuery(queries[0]).toEqual(`
|
|
130
|
+
ALTER TABLE user
|
|
131
|
+
ADD id integer
|
|
132
|
+
`)
|
|
133
|
+
|
|
134
|
+
expectQuery(queries[1]).toEqual(`
|
|
135
|
+
ALTER TABLE user
|
|
136
|
+
ADD CONSTRAINT PRIMARY KEY (id),
|
|
137
|
+
MODIFY id integer AUTO_INCREMENT
|
|
138
|
+
`)
|
|
139
|
+
}
|
|
140
|
+
}
|