@typetron/framework 0.5.3 → 0.5.4

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.
Files changed (195) hide show
  1. package/.eslintrc-old.js +208 -0
  2. package/Cache/Cache.ts +13 -0
  3. package/Cache/Stores/DatabaseStore.ts +120 -0
  4. package/Cache/Stores/FileStore.ts +69 -0
  5. package/Cache/Stores/MemoryStore.ts +71 -0
  6. package/Cache/index.ts +5 -0
  7. package/Cache/types.ts +4 -0
  8. package/Container/ClassResolver.ts +106 -0
  9. package/Container/Container.ts +144 -0
  10. package/Container/Contracts.ts +3 -0
  11. package/Container/Decorators.ts +20 -0
  12. package/Container/Metadata.ts +16 -0
  13. package/Container/Resolver.ts +27 -0
  14. package/Container/index.ts +5 -0
  15. package/Database/Clauses/Where.ts +0 -0
  16. package/Database/Connection.ts +52 -0
  17. package/Database/Decorators.ts +142 -0
  18. package/Database/Drivers/DatabaseDriver.ts +37 -0
  19. package/Database/Drivers/MySQL/Alter/index.ts +55 -0
  20. package/Database/Drivers/MySQL/ColumnDefinition.ts +16 -0
  21. package/Database/Drivers/MySQL/Create.ts +47 -0
  22. package/Database/Drivers/MySQL/MysqlDriver.ts +123 -0
  23. package/Database/Drivers/MySQL/Schema.ts +82 -0
  24. package/Database/Drivers/MySQL/index.ts +13 -0
  25. package/Database/Drivers/SQL/Schema.ts +73 -0
  26. package/Database/Drivers/SQL/Statements/Alter.ts +22 -0
  27. package/Database/Drivers/SQL/Statements/BaseStatement.ts +55 -0
  28. package/Database/Drivers/SQL/Statements/Delete.ts +20 -0
  29. package/Database/Drivers/SQL/Statements/Insert.ts +24 -0
  30. package/Database/Drivers/SQL/Statements/Select.ts +55 -0
  31. package/Database/Drivers/SQL/Statements/Update.ts +33 -0
  32. package/Database/Drivers/SQL/index.ts +8 -0
  33. package/Database/Drivers/SQLite/Create.ts +45 -0
  34. package/Database/Drivers/SQLite/Schema.ts +54 -0
  35. package/Database/Drivers/SQLite/SqliteDriver.ts +144 -0
  36. package/Database/Drivers/SQLite/index.ts +15 -0
  37. package/Database/Drivers/SchemaContract.ts +11 -0
  38. package/Database/Drivers/Statement.ts +16 -0
  39. package/Database/Drivers/index.ts +4 -0
  40. package/Database/Entity.ts +377 -0
  41. package/Database/EntityNotFoundError.ts +5 -0
  42. package/Database/EntityProxyHandler.ts +43 -0
  43. package/Database/EntityQuery.ts +197 -0
  44. package/Database/Expression.ts +3 -0
  45. package/Database/Fields.ts +816 -0
  46. package/Database/Helpers.ts +12 -0
  47. package/Database/List.ts +71 -0
  48. package/Database/Migrations/Migration.ts +10 -0
  49. package/Database/Migrations/MigrationHistory.ts +20 -0
  50. package/Database/Migrations/Migrator.ts +122 -0
  51. package/Database/Migrations/index.ts +3 -0
  52. package/Database/ORM/BaseRelationship.ts +10 -0
  53. package/Database/Query.ts +374 -0
  54. package/Database/Seeders/Seeder.ts +3 -0
  55. package/Database/Seeders/SeederManager.ts +27 -0
  56. package/Database/Seeders/index.ts +2 -0
  57. package/Database/StringExpression.ts +9 -0
  58. package/Database/Types.ts +165 -0
  59. package/Database/index.ts +23 -0
  60. package/Encryption/index.ts +51 -0
  61. package/Forms/Decorators.ts +29 -0
  62. package/Forms/Form.ts +70 -0
  63. package/Forms/FormFields.ts +36 -0
  64. package/Forms/index.ts +3 -0
  65. package/Framework/App.ts +10 -0
  66. package/Framework/Application.ts +118 -0
  67. package/Framework/Auth/Auth.ts +122 -0
  68. package/Framework/Auth/Authenticatable.ts +9 -0
  69. package/Framework/Auth/User.ts +27 -0
  70. package/Framework/Auth/index.ts +29 -0
  71. package/Framework/Config/AppConfig.ts +25 -0
  72. package/Framework/Config/AuthConfig.ts +9 -0
  73. package/Framework/Config/BaseConfig.ts +9 -0
  74. package/Framework/Config/CacheConfig.ts +38 -0
  75. package/Framework/Config/DatabaseConfig.ts +21 -0
  76. package/Framework/Config/MailConfig.ts +30 -0
  77. package/Framework/Config/index.ts +6 -0
  78. package/Framework/Middleware/AuthMiddleware.ts +31 -0
  79. package/Framework/Middleware/CorsMiddleware.ts +32 -0
  80. package/Framework/Middleware/StaticAssetsMiddleware.ts +76 -0
  81. package/Framework/Middleware/index.ts +2 -0
  82. package/Framework/Provider.ts +9 -0
  83. package/Framework/Providers/CacheProvider.ts +28 -0
  84. package/Framework/Providers/DatabaseProvider.ts +36 -0
  85. package/Framework/Providers/MailProvider.ts +31 -0
  86. package/Framework/Providers/WebsocketsProvider.ts +120 -0
  87. package/Framework/Resolvers/AuthResolver.ts +23 -0
  88. package/Framework/Resolvers/EntityResolver.ts +41 -0
  89. package/Framework/Resolvers/FormResolver.ts +37 -0
  90. package/Framework/RootDir.ts +1 -0
  91. package/Framework/index.ts +8 -0
  92. package/Frontend/Angular/index.ts +24 -0
  93. package/Frontend/Websockets/index.ts +86 -0
  94. package/Mail/MailAddress.ts +4 -0
  95. package/Mail/MailTransport.ts +6 -0
  96. package/Mail/Mailable.ts +16 -0
  97. package/Mail/Mailer.ts +27 -0
  98. package/Mail/PendingMail.ts +68 -0
  99. package/Mail/SentMessage.ts +20 -0
  100. package/Mail/Transports/MemoryTransport.ts +13 -0
  101. package/Mail/Transports/SendGridTransport.ts +95 -0
  102. package/Mail/index.ts +3 -0
  103. package/Models/Model.ts +41 -0
  104. package/Models/index.ts +54 -0
  105. package/Router/BaseController.ts +7 -0
  106. package/Router/Decorators.ts +224 -0
  107. package/Router/Guard.ts +10 -0
  108. package/Router/Http/Contracts.ts +4 -0
  109. package/Router/Http/ErrorHandler.ts +45 -0
  110. package/Router/Http/ErrorHandlerInterface.ts +6 -0
  111. package/Router/Http/Errors/HttpError.ts +15 -0
  112. package/Router/Http/Handler.ts +183 -0
  113. package/Router/Http/HttpRoute.ts +110 -0
  114. package/Router/Http/Middleware.ts +7 -0
  115. package/Router/Http/Request.ts +225 -0
  116. package/Router/Http/Response.ts +35 -0
  117. package/Router/Http/index.ts +85 -0
  118. package/Router/Metadata.ts +34 -0
  119. package/Router/Middleware.ts +16 -0
  120. package/Router/Request.ts +65 -0
  121. package/Router/Route.ts +16 -0
  122. package/Router/RouteNotFoundError.ts +5 -0
  123. package/Router/Router.ts +35 -0
  124. package/Router/Servers/index.ts +6 -0
  125. package/Router/Servers/node.ts +49 -0
  126. package/Router/Servers/uNetworking.ts +151 -0
  127. package/Router/Websockets/Handler.ts +82 -0
  128. package/Router/Websockets/Middleware.ts +7 -0
  129. package/Router/Websockets/Request.ts +3 -0
  130. package/Router/Websockets/WebsocketRoute.ts +61 -0
  131. package/Router/Websockets/index.ts +57 -0
  132. package/Router/Websockets/types.ts +23 -0
  133. package/Router/index.ts +6 -0
  134. package/Storage/File.ts +30 -0
  135. package/Storage/Image.ts +19 -0
  136. package/Storage/InvalidImage.ts +3 -0
  137. package/Storage/Storage.ts +98 -0
  138. package/Storage/index.ts +4 -0
  139. package/Storage/utils.ts +18 -0
  140. package/Support/Array.ts +184 -0
  141. package/Support/Math.ts +12 -0
  142. package/Support/Metadata.ts +31 -0
  143. package/Support/String.ts +38 -0
  144. package/Support/index.ts +19 -0
  145. package/Support/utils.ts +7 -0
  146. package/Testing/TestCase.ts +193 -0
  147. package/Validation/Rule.ts +9 -0
  148. package/Validation/RuleInterface.ts +10 -0
  149. package/Validation/Rules/Email.ts +20 -0
  150. package/Validation/Rules/FileExtension.ts +21 -0
  151. package/Validation/Rules/MaxLength.ts +17 -0
  152. package/Validation/Rules/MinLength.ts +18 -0
  153. package/Validation/Rules/Optional.ts +18 -0
  154. package/Validation/Rules/Required.ts +29 -0
  155. package/Validation/Validator.ts +7 -0
  156. package/Validation/index.ts +12 -0
  157. package/benchmark-index.js +20 -0
  158. package/benchmark.ts +47 -0
  159. package/package.json +7 -3
  160. package/tests/Cache/DatabaseStoreTest.ts +110 -0
  161. package/tests/Cache/FileStoreTest.ts +93 -0
  162. package/tests/Cache/MemoryStoreTest.ts +92 -0
  163. package/tests/Container/ContainerTest.ts +336 -0
  164. package/tests/Database/Drivers/MySQL/AlterTest.ts +100 -0
  165. package/tests/Database/Drivers/MySQL/CreateTest.ts +39 -0
  166. package/tests/Database/Drivers/MysqlDriverTest.ts +140 -0
  167. package/tests/Database/Drivers/SqliteDriverTest.ts +126 -0
  168. package/tests/Database/Entities/Article.ts +21 -0
  169. package/tests/Database/Entities/Profile.ts +21 -0
  170. package/tests/Database/Entities/Role.ts +15 -0
  171. package/tests/Database/Entities/User.ts +35 -0
  172. package/tests/Database/EntityRelationshipsTest.ts +475 -0
  173. package/tests/Database/EntityTest.ts +202 -0
  174. package/tests/Database/Migrations/RunnerTest.ts +96 -0
  175. package/tests/Database/Migrations/migrations/1.createUserTable.ts +12 -0
  176. package/tests/Database/Migrations/migrations/2.createArticlesTable.ts +12 -0
  177. package/tests/Database/QueryTest.ts +573 -0
  178. package/tests/Database/SchemaTest.ts +32 -0
  179. package/tests/Database/Seeders/RunnerTest.ts +30 -0
  180. package/tests/Database/Seeders/seeders/RandomSeeder.ts +10 -0
  181. package/tests/Database/utils.ts +16 -0
  182. package/tests/Forms/FormsTest.ts +59 -0
  183. package/tests/Framework/Middleware/StaticAssetsMiddlewareTest.ts +129 -0
  184. package/tests/Framework/Resolvers/EntityResolverTest.ts +48 -0
  185. package/tests/Framework/Router/RouterTest.ts +33 -0
  186. package/tests/Mail/MailerTest.ts +76 -0
  187. package/tests/Model/ModelTest.ts +183 -0
  188. package/tests/Router/HttpHandlerTest.ts +72 -0
  189. package/tests/Router/RequestTest.ts +77 -0
  190. package/tests/Router/WebSocketsHandlerTest.ts +51 -0
  191. package/tests/Storage/StorageTest.ts +97 -0
  192. package/tests/Support/ArrayTest.ts +167 -0
  193. package/tests/Support/StringTest.ts +18 -0
  194. package/tests/Validation/RulesTest.ts +54 -0
  195. 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
+ }