@autometa/app 0.1.11 → 0.1.13
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/CHANGELOG.md +16 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.cts +83 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +12 -11
- package/.turbo/turbo-build.log +0 -21
- package/.turbo/turbo-clean.log +0 -4
- package/.turbo/turbo-coverage.log +0 -22
- package/.turbo/turbo-lint.log +0 -4
- package/.turbo/turbo-lint:fix.log +0 -4
- package/.turbo/turbo-test.log +0 -14
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/clover.xml +0 -18
- package/coverage/coverage-final.json +0 -2
- package/coverage/favicon.png +0 -0
- package/coverage/fixture.ts.html +0 -256
- package/coverage/index.html +0 -116
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @autometa/app
|
|
2
2
|
|
|
3
|
+
## 0.1.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 04ed85d: feat: added HTP client based on axios
|
|
8
|
+
- Updated dependencies [04ed85d]
|
|
9
|
+
- @autometa/asserters@0.1.4
|
|
10
|
+
- @autometa/phrases@0.1.8
|
|
11
|
+
- @autometa/errors@0.1.4
|
|
12
|
+
|
|
13
|
+
## 0.1.12
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 4ee4e99: Fixes strings like 'abc2bd' being parsed as NaN in `primitive` expression type. Not supports comma and decimal delimters (EU, US respectively
|
|
18
|
+
|
|
3
19
|
## 0.1.11
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/esm/index.js
CHANGED
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/autometa-app.ts","../../src/autometa-world.ts","../../src/get-app.ts","../../src/decorators/fixture.ts","../../src/decorators/app-type.ts"],"sourcesContent":["import { World } from \"./fixtures.typings\";\n\nexport abstract class AutometaApp {\n id: string;\n [key: string]: unknown;\n world: World\n}\n","import { PhraseParser, IFromPhrase } from \"@autometa/phrases\";\n\n@PhraseParser\nexport class AutometaWorld {\n [key: string]: unknown;\n\n fromPhrase: IFromPhrase;\n}\n","import { container } from \"tsyringe\";\nimport { AutometaApp } from \"./autometa-app\";\nimport { Class } from \"@autometa/types\";\nimport { AutomationError } from \"@autometa/errors\";\nimport { AutometaWorld } from \".\";\nimport { v4 } from \"uuid\";\n\nexport function getApp<T extends AutometaApp, K extends AutometaWorld>(\n appType: Class<T>,\n worldType: Class<K>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...instances: { token: any; instance?: any; cls?: Class<any> }[]\n) {\n if (!appType) {\n throw new AutomationError(`A reference to an 'app' and 'world' is required to run tests.\n\nConfigure the app by extending 'AutometaApp' and adding it to your\n'autometa.config.ts' file:\n\n@AppType(MyWorld)\nexport class MyAutometaApp extends AutometaApp {\n ...\n}\ndefineConfig({\n roots: {\n app: './src/
|
|
1
|
+
{"version":3,"sources":["../../src/autometa-app.ts","../../src/autometa-world.ts","../../src/get-app.ts","../../src/decorators/fixture.ts","../../src/decorators/app-type.ts"],"sourcesContent":["import { World } from \"./fixtures.typings\";\n\nexport abstract class AutometaApp {\n id: string;\n [key: string]: unknown;\n world: World\n}\n","import { PhraseParser, IFromPhrase } from \"@autometa/phrases\";\n\n@PhraseParser\nexport class AutometaWorld {\n [key: string]: unknown;\n\n fromPhrase: IFromPhrase;\n}\n","import { container } from \"tsyringe\";\nimport { AutometaApp } from \"./autometa-app\";\nimport { Class } from \"@autometa/types\";\nimport { AutomationError } from \"@autometa/errors\";\nimport { AutometaWorld } from \".\";\nimport { v4 } from \"uuid\";\n\nexport function getApp<T extends AutometaApp, K extends AutometaWorld>(\n appType: Class<T>,\n worldType: Class<K>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...instances: { token: any; instance?: any; cls?: Class<any> }[]\n) {\n if (!appType) {\n throw new AutomationError(`A reference to an 'app' and 'world' is required to run tests.\n\nConfigure the app by extending 'AutometaApp' and adding it to your\n'autometa.config.ts' file:\n\n@AppType(MyWorld)\nexport class MyAutometaApp extends AutometaApp {\n ...\n}\ndefineConfig({\n roots: {\n app: './src/app'\n }\n})`);\n }\n instances.forEach(({ token, instance, cls }) =>\n child.register(token, instance ?? cls)\n );\n\n const child = container.createChildContainer();\n const app = child.resolve(appType);\n app.world = child.resolve(worldType);\n app.id = v4();\n return app;\n}\n","import \"reflect-metadata\";\n\nimport { Class } from \"@autometa/types\";\nimport {\n scoped,\n inject,\n Lifecycle as LC,\n injectable,\n singleton\n} from \"tsyringe\";\n/**\n * Marks a class as an injectable fixture. Constructor parameters\n * which are also injectable will be automatically constructed\n * and passed to the constructor.\n *\n * Example fixtures are the `App` which acts as shared\n * entry point for all steps in a test, and the World,\n * which stores persistent data across tests.\n *\n * Fixtures are persistent by default, meaning each class\n * will exist as a singleton for the duration of the test\n * ```ts\n * @Fixture\n * export class World {\n * [key: string]: unknown;\n *\n * declare someExpectedData: MyDataType\n * }\n *\n * @Fixture\n * export class MyClient {\n * constructor(world: MyWorld){}\n *\n * login = async ()=>{\n * this.world.someExpectedData = await fetch(...)\n * }\n * }\n *\n * @Fixture\n * export class App {\n * constructor(\n * world: MyWorld,\n * client: MyClient\n * ){}\n * }\n * ```\n */\nexport function Fixture(target: Class<unknown>): void;\nexport function Fixture<T extends Class<unknown>>(\n scope?: Lifecycle\n): (target: T) => void;\nexport function Fixture(arg: Lifecycle | undefined | Class<unknown>) {\n if (arg !== undefined && typeof arg !== \"number\") {\n injectable()(arg);\n scoped(LC.ContainerScoped)(arg);\n return;\n }\n return (target: Class<unknown>) => {\n injectable()(target);\n if (arg === LIFE_CYCLE.Singleton) {\n singleton()(target);\n return;\n }\n scoped(arg ?? (LIFE_CYCLE.ContainerScoped as number))(target);\n };\n}\n\nexport const Inject = inject;\n\nexport const LIFE_CYCLE = {\n Transient: LC.Transient as 0,\n Singleton: LC.Singleton as 1,\n ResolutionScoped: LC.ResolutionScoped as 2,\n ContainerScoped: LC.ContainerScoped as 3\n} as const;\n\nexport type Lifecycle = (typeof LIFE_CYCLE)[keyof typeof LIFE_CYCLE];\n","import { Class } from \"@autometa/types\";\nimport { Lifecycle } from \"tsyringe\";\nimport { AutometaWorld } from \"..\";\nimport { Fixture } from \"./fixture\";\n\n\nexport function AppType(\n container: Record<string, { app: unknown; world: unknown; }>,\n world: Class<AutometaWorld>,\n environment = \"default\"\n) {\n const env = environment ?? \"default\";\n return (target: Class<unknown>) => {\n Fixture(Lifecycle.ContainerScoped)(target);\n container[env] = { app: target, world };\n };\n}\n"],"mappings":";;;;;;;;;;;;;AAEO,IAAe,cAAf,MAA2B;AAIlC;;;ACNA,SAAS,oBAAiC;AAGnC,IAAM,gBAAN,MAAoB;AAI3B;AAJa,gBAAN;AAAA,EADN;AAAA,GACY;;;ACHb,SAAS,iBAAiB;AAG1B,SAAS,uBAAuB;AAEhC,SAAS,UAAU;AAEZ,SAAS,OACd,SACA,cAEG,WACH;AACA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAa3B;AAAA,EACD;AACA,YAAU;AAAA,IAAQ,CAAC,EAAE,OAAO,UAAU,IAAI,MACxC,MAAM,SAAS,OAAO,YAAY,GAAG;AAAA,EACvC;AAEA,QAAM,QAAQ,UAAU,qBAAqB;AAC7C,QAAM,MAAM,MAAM,QAAQ,OAAO;AACjC,MAAI,QAAQ,MAAM,QAAQ,SAAS;AACnC,MAAI,KAAK,GAAG;AACZ,SAAO;AACT;;;ACtCA,OAAO;AAGP;AAAA,EACE;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,OACK;AA0CA,SAAS,QAAQ,KAA6C;AACnE,MAAI,QAAQ,UAAa,OAAO,QAAQ,UAAU;AAChD,eAAW,EAAE,GAAG;AAChB,WAAO,GAAG,eAAe,EAAE,GAAG;AAC9B;AAAA,EACF;AACA,SAAO,CAAC,WAA2B;AACjC,eAAW,EAAE,MAAM;AACnB,QAAI,QAAQ,WAAW,WAAW;AAChC,gBAAU,EAAE,MAAM;AAClB;AAAA,IACF;AACA,WAAO,OAAQ,WAAW,eAA0B,EAAE,MAAM;AAAA,EAC9D;AACF;AAEO,IAAM,SAAS;AAEf,IAAM,aAAa;AAAA,EACxB,WAAW,GAAG;AAAA,EACd,WAAW,GAAG;AAAA,EACd,kBAAkB,GAAG;AAAA,EACrB,iBAAiB,GAAG;AACtB;;;ACzEA,SAAS,iBAAiB;AAKnB,SAAS,QACdA,YACA,OACA,cAAc,WACd;AACA,QAAM,MAAM,eAAe;AAC3B,SAAO,CAAC,WAA2B;AACjC,YAAQ,UAAU,eAAe,EAAE,MAAM;AACzC,IAAAA,WAAU,GAAG,IAAI,EAAE,KAAK,QAAQ,MAAM;AAAA,EACxC;AACF;","names":["container"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -2,8 +2,91 @@ import { IFromPhrase } from '@autometa/phrases';
|
|
|
2
2
|
import { Class } from '@autometa/types';
|
|
3
3
|
import { inject } from 'tsyringe';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Basic Key Value store for managing state across Step Definitions. A unique copy of this object
|
|
7
|
+
* is shared between all steps and hooks in a given running Scenario, however it is not possible
|
|
8
|
+
* to interact with state outside of that Scenarios life cycle. That is to say, while the World
|
|
9
|
+
* is shared between steps, it is unique across tests.
|
|
10
|
+
*
|
|
11
|
+
* To extend the worlds vocabulary, you can declare properties on the World. These do not need
|
|
12
|
+
* to be defined at run time. Instead they will be filled in as they are produced by steps.
|
|
13
|
+
*
|
|
14
|
+
* To declare World properties, you can simply declare an uninitialized property. Depending
|
|
15
|
+
* on your `tsconfig.json` settings you can do so with one of the three following syntaxes:
|
|
16
|
+
*
|
|
17
|
+
* ```typescript
|
|
18
|
+
* @Fixture
|
|
19
|
+
* export class World {
|
|
20
|
+
* [key: string]: unknown;
|
|
21
|
+
*
|
|
22
|
+
* declare foo: number
|
|
23
|
+
*
|
|
24
|
+
* foo: number
|
|
25
|
+
*
|
|
26
|
+
* foo!: number
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* The World is automatically injected into the {@link App} object, and can be accessed via
|
|
30
|
+
* the last (or only) argument of a step definition callback.
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* Given('I have {int} cats', (cats: number, app: App) => {
|
|
34
|
+
* app.world.cats = cats
|
|
35
|
+
* })
|
|
36
|
+
*
|
|
37
|
+
* // using destructuring
|
|
38
|
+
* Given('I have {int} cats', ({world}: App) => {
|
|
39
|
+
* world.cats = cats
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
5
43
|
interface World {
|
|
44
|
+
[key: string]: unknown;
|
|
6
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* The App object is the primary interface for interacting with the running application. It is
|
|
48
|
+
* composed of `Fixtures` which are classes decorated with the `@Fixture` decorator. Fixtures
|
|
49
|
+
* are automatically instantiated and injected into the App object. The App object is then
|
|
50
|
+
* injected into the last (or only) argument of a step definition callback.
|
|
51
|
+
*
|
|
52
|
+
* i.e.
|
|
53
|
+
*
|
|
54
|
+
* ```ts
|
|
55
|
+
* // single argument
|
|
56
|
+
* Given('I have 5 cats', (app: App) => {})
|
|
57
|
+
* // Cucumber Expression
|
|
58
|
+
* Given('I have {int} cats', (cats: number, app: App) => {})
|
|
59
|
+
* // Data table
|
|
60
|
+
* Given('I have {int} cats', (cats: number, table: HTable app: App) => {}, HTable)
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* **Note**: The type annotations here are optional. Non-custom Cucumber Expression types
|
|
64
|
+
* will be automatically inferred by their expression template. Custom types will need to
|
|
65
|
+
* be added via declaration file (see docs)
|
|
66
|
+
*
|
|
67
|
+
* The App is unique across all tests, and is shared between all steps and hooks within a test.
|
|
68
|
+
* If you have any Fixture classes defined, you can add them as constructor parameters of the App
|
|
69
|
+
* to make them available to step Definitions (Fixtures can also be accessed as properties from other Fixtures if not defined here);
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* \@\Fixture
|
|
73
|
+
* export class World {}
|
|
74
|
+
*
|
|
75
|
+
*
|
|
76
|
+
* \@\Fixture
|
|
77
|
+
* export class Fixture1 {}
|
|
78
|
+
*
|
|
79
|
+
* \@\Fixture
|
|
80
|
+
* export class Fixture2 {
|
|
81
|
+
* constructor(readonly fixture1: Fixture1, readonly world: World) {}
|
|
82
|
+
* }
|
|
83
|
+
*
|
|
84
|
+
* \@\AppType(World)
|
|
85
|
+
* export class App {
|
|
86
|
+
* constructor(readonly fixture1: Fixture1, readonly fixture2: Fixture2) {}
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
7
90
|
interface App {
|
|
8
91
|
readonly id: string;
|
|
9
92
|
world: World;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,91 @@ import { IFromPhrase } from '@autometa/phrases';
|
|
|
2
2
|
import { Class } from '@autometa/types';
|
|
3
3
|
import { inject } from 'tsyringe';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Basic Key Value store for managing state across Step Definitions. A unique copy of this object
|
|
7
|
+
* is shared between all steps and hooks in a given running Scenario, however it is not possible
|
|
8
|
+
* to interact with state outside of that Scenarios life cycle. That is to say, while the World
|
|
9
|
+
* is shared between steps, it is unique across tests.
|
|
10
|
+
*
|
|
11
|
+
* To extend the worlds vocabulary, you can declare properties on the World. These do not need
|
|
12
|
+
* to be defined at run time. Instead they will be filled in as they are produced by steps.
|
|
13
|
+
*
|
|
14
|
+
* To declare World properties, you can simply declare an uninitialized property. Depending
|
|
15
|
+
* on your `tsconfig.json` settings you can do so with one of the three following syntaxes:
|
|
16
|
+
*
|
|
17
|
+
* ```typescript
|
|
18
|
+
* @Fixture
|
|
19
|
+
* export class World {
|
|
20
|
+
* [key: string]: unknown;
|
|
21
|
+
*
|
|
22
|
+
* declare foo: number
|
|
23
|
+
*
|
|
24
|
+
* foo: number
|
|
25
|
+
*
|
|
26
|
+
* foo!: number
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* The World is automatically injected into the {@link App} object, and can be accessed via
|
|
30
|
+
* the last (or only) argument of a step definition callback.
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* Given('I have {int} cats', (cats: number, app: App) => {
|
|
34
|
+
* app.world.cats = cats
|
|
35
|
+
* })
|
|
36
|
+
*
|
|
37
|
+
* // using destructuring
|
|
38
|
+
* Given('I have {int} cats', ({world}: App) => {
|
|
39
|
+
* world.cats = cats
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
5
43
|
interface World {
|
|
44
|
+
[key: string]: unknown;
|
|
6
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* The App object is the primary interface for interacting with the running application. It is
|
|
48
|
+
* composed of `Fixtures` which are classes decorated with the `@Fixture` decorator. Fixtures
|
|
49
|
+
* are automatically instantiated and injected into the App object. The App object is then
|
|
50
|
+
* injected into the last (or only) argument of a step definition callback.
|
|
51
|
+
*
|
|
52
|
+
* i.e.
|
|
53
|
+
*
|
|
54
|
+
* ```ts
|
|
55
|
+
* // single argument
|
|
56
|
+
* Given('I have 5 cats', (app: App) => {})
|
|
57
|
+
* // Cucumber Expression
|
|
58
|
+
* Given('I have {int} cats', (cats: number, app: App) => {})
|
|
59
|
+
* // Data table
|
|
60
|
+
* Given('I have {int} cats', (cats: number, table: HTable app: App) => {}, HTable)
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* **Note**: The type annotations here are optional. Non-custom Cucumber Expression types
|
|
64
|
+
* will be automatically inferred by their expression template. Custom types will need to
|
|
65
|
+
* be added via declaration file (see docs)
|
|
66
|
+
*
|
|
67
|
+
* The App is unique across all tests, and is shared between all steps and hooks within a test.
|
|
68
|
+
* If you have any Fixture classes defined, you can add them as constructor parameters of the App
|
|
69
|
+
* to make them available to step Definitions (Fixtures can also be accessed as properties from other Fixtures if not defined here);
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* \@\Fixture
|
|
73
|
+
* export class World {}
|
|
74
|
+
*
|
|
75
|
+
*
|
|
76
|
+
* \@\Fixture
|
|
77
|
+
* export class Fixture1 {}
|
|
78
|
+
*
|
|
79
|
+
* \@\Fixture
|
|
80
|
+
* export class Fixture2 {
|
|
81
|
+
* constructor(readonly fixture1: Fixture1, readonly world: World) {}
|
|
82
|
+
* }
|
|
83
|
+
*
|
|
84
|
+
* \@\AppType(World)
|
|
85
|
+
* export class App {
|
|
86
|
+
* constructor(readonly fixture1: Fixture1, readonly fixture2: Fixture2) {}
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
7
90
|
interface App {
|
|
8
91
|
readonly id: string;
|
|
9
92
|
world: World;
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/autometa-app.ts","../src/autometa-world.ts","../src/get-app.ts","../src/decorators/fixture.ts","../src/decorators/app-type.ts"],"sourcesContent":["export * from './autometa-app'\nexport * from './autometa-world'\nexport * from './get-app'\nexport * from './decorators'\nexport * from './fixtures.typings'","import { World } from \"./fixtures.typings\";\n\nexport abstract class AutometaApp {\n id: string;\n [key: string]: unknown;\n world: World\n}\n","import { PhraseParser, IFromPhrase } from \"@autometa/phrases\";\n\n@PhraseParser\nexport class AutometaWorld {\n [key: string]: unknown;\n\n fromPhrase: IFromPhrase;\n}\n","import { container } from \"tsyringe\";\nimport { AutometaApp } from \"./autometa-app\";\nimport { Class } from \"@autometa/types\";\nimport { AutomationError } from \"@autometa/errors\";\nimport { AutometaWorld } from \".\";\nimport { v4 } from \"uuid\";\n\nexport function getApp<T extends AutometaApp, K extends AutometaWorld>(\n appType: Class<T>,\n worldType: Class<K>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...instances: { token: any; instance?: any; cls?: Class<any> }[]\n) {\n if (!appType) {\n throw new AutomationError(`A reference to an 'app' and 'world' is required to run tests.\n\nConfigure the app by extending 'AutometaApp' and adding it to your\n'autometa.config.ts' file:\n\n@AppType(MyWorld)\nexport class MyAutometaApp extends AutometaApp {\n ...\n}\ndefineConfig({\n roots: {\n app: './src/
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/autometa-app.ts","../src/autometa-world.ts","../src/get-app.ts","../src/decorators/fixture.ts","../src/decorators/app-type.ts"],"sourcesContent":["export * from './autometa-app'\nexport * from './autometa-world'\nexport * from './get-app'\nexport * from './decorators'\nexport * from './fixtures.typings'","import { World } from \"./fixtures.typings\";\n\nexport abstract class AutometaApp {\n id: string;\n [key: string]: unknown;\n world: World\n}\n","import { PhraseParser, IFromPhrase } from \"@autometa/phrases\";\n\n@PhraseParser\nexport class AutometaWorld {\n [key: string]: unknown;\n\n fromPhrase: IFromPhrase;\n}\n","import { container } from \"tsyringe\";\nimport { AutometaApp } from \"./autometa-app\";\nimport { Class } from \"@autometa/types\";\nimport { AutomationError } from \"@autometa/errors\";\nimport { AutometaWorld } from \".\";\nimport { v4 } from \"uuid\";\n\nexport function getApp<T extends AutometaApp, K extends AutometaWorld>(\n appType: Class<T>,\n worldType: Class<K>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...instances: { token: any; instance?: any; cls?: Class<any> }[]\n) {\n if (!appType) {\n throw new AutomationError(`A reference to an 'app' and 'world' is required to run tests.\n\nConfigure the app by extending 'AutometaApp' and adding it to your\n'autometa.config.ts' file:\n\n@AppType(MyWorld)\nexport class MyAutometaApp extends AutometaApp {\n ...\n}\ndefineConfig({\n roots: {\n app: './src/app'\n }\n})`);\n }\n instances.forEach(({ token, instance, cls }) =>\n child.register(token, instance ?? cls)\n );\n\n const child = container.createChildContainer();\n const app = child.resolve(appType);\n app.world = child.resolve(worldType);\n app.id = v4();\n return app;\n}\n","import \"reflect-metadata\";\n\nimport { Class } from \"@autometa/types\";\nimport {\n scoped,\n inject,\n Lifecycle as LC,\n injectable,\n singleton\n} from \"tsyringe\";\n/**\n * Marks a class as an injectable fixture. Constructor parameters\n * which are also injectable will be automatically constructed\n * and passed to the constructor.\n *\n * Example fixtures are the `App` which acts as shared\n * entry point for all steps in a test, and the World,\n * which stores persistent data across tests.\n *\n * Fixtures are persistent by default, meaning each class\n * will exist as a singleton for the duration of the test\n * ```ts\n * @Fixture\n * export class World {\n * [key: string]: unknown;\n *\n * declare someExpectedData: MyDataType\n * }\n *\n * @Fixture\n * export class MyClient {\n * constructor(world: MyWorld){}\n *\n * login = async ()=>{\n * this.world.someExpectedData = await fetch(...)\n * }\n * }\n *\n * @Fixture\n * export class App {\n * constructor(\n * world: MyWorld,\n * client: MyClient\n * ){}\n * }\n * ```\n */\nexport function Fixture(target: Class<unknown>): void;\nexport function Fixture<T extends Class<unknown>>(\n scope?: Lifecycle\n): (target: T) => void;\nexport function Fixture(arg: Lifecycle | undefined | Class<unknown>) {\n if (arg !== undefined && typeof arg !== \"number\") {\n injectable()(arg);\n scoped(LC.ContainerScoped)(arg);\n return;\n }\n return (target: Class<unknown>) => {\n injectable()(target);\n if (arg === LIFE_CYCLE.Singleton) {\n singleton()(target);\n return;\n }\n scoped(arg ?? (LIFE_CYCLE.ContainerScoped as number))(target);\n };\n}\n\nexport const Inject = inject;\n\nexport const LIFE_CYCLE = {\n Transient: LC.Transient as 0,\n Singleton: LC.Singleton as 1,\n ResolutionScoped: LC.ResolutionScoped as 2,\n ContainerScoped: LC.ContainerScoped as 3\n} as const;\n\nexport type Lifecycle = (typeof LIFE_CYCLE)[keyof typeof LIFE_CYCLE];\n","import { Class } from \"@autometa/types\";\nimport { Lifecycle } from \"tsyringe\";\nimport { AutometaWorld } from \"..\";\nimport { Fixture } from \"./fixture\";\n\n\nexport function AppType(\n container: Record<string, { app: unknown; world: unknown; }>,\n world: Class<AutometaWorld>,\n environment = \"default\"\n) {\n const env = environment ?? \"default\";\n return (target: Class<unknown>) => {\n Fixture(Lifecycle.ContainerScoped)(target);\n container[env] = { app: target, world };\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAe,cAAf,MAA2B;AAIlC;;;ACNA,qBAA0C;AAGnC,IAAM,gBAAN,MAAoB;AAI3B;AAJa,gBAAN;AAAA,EADN;AAAA,GACY;;;ACHb,sBAA0B;AAG1B,oBAAgC;AAEhC,kBAAmB;AAEZ,SAAS,OACd,SACA,cAEG,WACH;AACA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,8BAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAa3B;AAAA,EACD;AACA,YAAU;AAAA,IAAQ,CAAC,EAAE,OAAO,UAAU,IAAI,MACxC,MAAM,SAAS,OAAO,YAAY,GAAG;AAAA,EACvC;AAEA,QAAM,QAAQ,0BAAU,qBAAqB;AAC7C,QAAM,MAAM,MAAM,QAAQ,OAAO;AACjC,MAAI,QAAQ,MAAM,QAAQ,SAAS;AACnC,MAAI,SAAK,gBAAG;AACZ,SAAO;AACT;;;ACtCA,8BAAO;AAGP,IAAAA,mBAMO;AA0CA,SAAS,QAAQ,KAA6C;AACnE,MAAI,QAAQ,UAAa,OAAO,QAAQ,UAAU;AAChD,qCAAW,EAAE,GAAG;AAChB,iCAAO,iBAAAC,UAAG,eAAe,EAAE,GAAG;AAC9B;AAAA,EACF;AACA,SAAO,CAAC,WAA2B;AACjC,qCAAW,EAAE,MAAM;AACnB,QAAI,QAAQ,WAAW,WAAW;AAChC,sCAAU,EAAE,MAAM;AAClB;AAAA,IACF;AACA,iCAAO,OAAQ,WAAW,eAA0B,EAAE,MAAM;AAAA,EAC9D;AACF;AAEO,IAAM,SAAS;AAEf,IAAM,aAAa;AAAA,EACxB,WAAW,iBAAAA,UAAG;AAAA,EACd,WAAW,iBAAAA,UAAG;AAAA,EACd,kBAAkB,iBAAAA,UAAG;AAAA,EACrB,iBAAiB,iBAAAA,UAAG;AACtB;;;ACzEA,IAAAC,mBAA0B;AAKnB,SAAS,QACdC,YACA,OACA,cAAc,WACd;AACA,QAAM,MAAM,eAAe;AAC3B,SAAO,CAAC,WAA2B;AACjC,YAAQ,2BAAU,eAAe,EAAE,MAAM;AACzC,IAAAA,WAAU,GAAG,IAAI,EAAE,KAAK,QAAQ,MAAM;AAAA,EACxC;AACF;","names":["import_tsyringe","LC","import_tsyringe","container"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autometa/app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "App and World container for Autometa",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
},
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"devDependencies": {
|
|
17
|
+
"@autometa/types": "^0.4.1",
|
|
17
18
|
"@types/node": "^18.11.18",
|
|
18
|
-
"@types/uuid": "^9.0.
|
|
19
|
+
"@types/uuid": "^9.0.5",
|
|
19
20
|
"@typescript-eslint/eslint-plugin": "^5.54.1",
|
|
20
21
|
"@typescript-eslint/parser": "^5.54.1",
|
|
21
22
|
"@vitest/coverage-istanbul": "^0.31.0",
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
"datetime": "link:packages/datetime",
|
|
28
29
|
"errors": "link:packages/errors",
|
|
29
30
|
"eslint": "^8.37.0",
|
|
31
|
+
"eslint-config-custom": "0.6.0",
|
|
30
32
|
"eslint-config-prettier": "^8.3.0",
|
|
31
33
|
"events": "link:packages/events",
|
|
32
34
|
"gherkin": "link:packages/gherkin",
|
|
@@ -39,20 +41,18 @@
|
|
|
39
41
|
"scopes": "link:packages/scopes",
|
|
40
42
|
"test-builder": "link:packages/test-builder",
|
|
41
43
|
"test-executor": "link:packages/test-executor",
|
|
44
|
+
"tsconfig": " *",
|
|
42
45
|
"tsup": "^7.2.0",
|
|
43
46
|
"types": "link:packages/types",
|
|
44
47
|
"typescript": "^4.9.5",
|
|
45
|
-
"vitest": "0.
|
|
46
|
-
"@autometa/types": "^0.4.1",
|
|
47
|
-
"eslint-config-custom": "0.6.0",
|
|
48
|
-
"tsconfig": "0.7.0"
|
|
48
|
+
"vitest": "0.34.6"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
+
"@autometa/asserters": "0.1.4",
|
|
52
|
+
"@autometa/errors": "0.1.4",
|
|
53
|
+
"@autometa/phrases": "0.1.8",
|
|
51
54
|
"tsyringe": "^4.8.0",
|
|
52
|
-
"uuid": "^9.0.
|
|
53
|
-
"@autometa/asserters": "0.1.3",
|
|
54
|
-
"@autometa/phrases": "0.1.7",
|
|
55
|
-
"@autometa/errors": "0.1.3"
|
|
55
|
+
"uuid": "^9.0.1"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"test": "vitest run",
|
|
@@ -63,5 +63,6 @@
|
|
|
63
63
|
"clean": "rimraf dist",
|
|
64
64
|
"build": "tsup",
|
|
65
65
|
"build:watch": "tsup --watch"
|
|
66
|
-
}
|
|
66
|
+
},
|
|
67
|
+
"readme": "# Introduction\n\nThere's nothing here yet"
|
|
67
68
|
}
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @autometa/app@0.0.0 build /Users/ben.aherne/Documents/GitHub/autometa/packages/app
|
|
3
|
-
> tsup
|
|
4
|
-
|
|
5
|
-
CLI Building entry: src/index.ts
|
|
6
|
-
CLI Using tsconfig: tsconfig.json
|
|
7
|
-
CLI tsup v6.7.0
|
|
8
|
-
CLI Using tsup config: /Users/ben.aherne/Documents/GitHub/autometa/packages/app/tsup.config.ts
|
|
9
|
-
CLI Target: es2020
|
|
10
|
-
CLI Cleaning output folder
|
|
11
|
-
CJS Build start
|
|
12
|
-
ESM Build start
|
|
13
|
-
CJS You have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin
|
|
14
|
-
ESM You have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin
|
|
15
|
-
ESM dist/esm/index.js 1.18 KB
|
|
16
|
-
ESM ⚡️ Build success in 9ms
|
|
17
|
-
CJS dist/index.js 2.43 KB
|
|
18
|
-
CJS ⚡️ Build success in 9ms
|
|
19
|
-
DTS Build start
|
|
20
|
-
DTS ⚡️ Build success in 599ms
|
|
21
|
-
DTS dist/index.d.ts 1.59 KB
|
package/.turbo/turbo-clean.log
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @autometa/app@0.1.1 coverage /Users/ben.aherne/Documents/GitHub/autometa/packages/app
|
|
3
|
-
> vitest run --coverage
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
RUN v0.33.0 /Users/ben.aherne/Documents/GitHub/autometa/packages/app
|
|
7
|
-
Coverage enabled with istanbul
|
|
8
|
-
|
|
9
|
-
✓ src/decorators/fixture.spec.ts (2 tests) 3ms
|
|
10
|
-
|
|
11
|
-
Test Files 1 passed (1)
|
|
12
|
-
Tests 2 passed (2)
|
|
13
|
-
Start at 16:39:00
|
|
14
|
-
Duration 1.78s (transform 295ms, setup 0ms, collect 423ms, tests 3ms, environment 0ms, prepare 511ms)
|
|
15
|
-
|
|
16
|
-
% Coverage report from istanbul
|
|
17
|
-
------------|---------|----------|---------|---------|-------------------
|
|
18
|
-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
|
|
19
|
-
------------|---------|----------|---------|---------|-------------------
|
|
20
|
-
All files | 66.66 | 75 | 50 | 66.66 |
|
|
21
|
-
fixture.ts | 66.66 | 75 | 50 | 66.66 | 50-52
|
|
22
|
-
------------|---------|----------|---------|---------|-------------------
|
package/.turbo/turbo-lint.log
DELETED
package/.turbo/turbo-test.log
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @autometa/app@0.1.9 test /Users/ben.aherne/Documents/GitHub/autometa/packages/app
|
|
3
|
-
> vitest run
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
RUN v0.33.0 /Users/ben.aherne/Documents/GitHub/autometa/packages/app
|
|
7
|
-
|
|
8
|
-
✓ src/decorators/fixture.spec.ts (2 tests) 2ms
|
|
9
|
-
|
|
10
|
-
Test Files 1 passed (1)
|
|
11
|
-
Tests 2 passed (2)
|
|
12
|
-
Start at 17:12:31
|
|
13
|
-
Duration 1.43s (transform 110ms, setup 0ms, collect 153ms, tests 2ms, environment 0ms, prepare 436ms)
|
|
14
|
-
|
package/coverage/base.css
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
body, html {
|
|
2
|
-
margin:0; padding: 0;
|
|
3
|
-
height: 100%;
|
|
4
|
-
}
|
|
5
|
-
body {
|
|
6
|
-
font-family: Helvetica Neue, Helvetica, Arial;
|
|
7
|
-
font-size: 14px;
|
|
8
|
-
color:#333;
|
|
9
|
-
}
|
|
10
|
-
.small { font-size: 12px; }
|
|
11
|
-
*, *:after, *:before {
|
|
12
|
-
-webkit-box-sizing:border-box;
|
|
13
|
-
-moz-box-sizing:border-box;
|
|
14
|
-
box-sizing:border-box;
|
|
15
|
-
}
|
|
16
|
-
h1 { font-size: 20px; margin: 0;}
|
|
17
|
-
h2 { font-size: 14px; }
|
|
18
|
-
pre {
|
|
19
|
-
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
20
|
-
margin: 0;
|
|
21
|
-
padding: 0;
|
|
22
|
-
-moz-tab-size: 2;
|
|
23
|
-
-o-tab-size: 2;
|
|
24
|
-
tab-size: 2;
|
|
25
|
-
}
|
|
26
|
-
a { color:#0074D9; text-decoration:none; }
|
|
27
|
-
a:hover { text-decoration:underline; }
|
|
28
|
-
.strong { font-weight: bold; }
|
|
29
|
-
.space-top1 { padding: 10px 0 0 0; }
|
|
30
|
-
.pad2y { padding: 20px 0; }
|
|
31
|
-
.pad1y { padding: 10px 0; }
|
|
32
|
-
.pad2x { padding: 0 20px; }
|
|
33
|
-
.pad2 { padding: 20px; }
|
|
34
|
-
.pad1 { padding: 10px; }
|
|
35
|
-
.space-left2 { padding-left:55px; }
|
|
36
|
-
.space-right2 { padding-right:20px; }
|
|
37
|
-
.center { text-align:center; }
|
|
38
|
-
.clearfix { display:block; }
|
|
39
|
-
.clearfix:after {
|
|
40
|
-
content:'';
|
|
41
|
-
display:block;
|
|
42
|
-
height:0;
|
|
43
|
-
clear:both;
|
|
44
|
-
visibility:hidden;
|
|
45
|
-
}
|
|
46
|
-
.fl { float: left; }
|
|
47
|
-
@media only screen and (max-width:640px) {
|
|
48
|
-
.col3 { width:100%; max-width:100%; }
|
|
49
|
-
.hide-mobile { display:none!important; }
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.quiet {
|
|
53
|
-
color: #7f7f7f;
|
|
54
|
-
color: rgba(0,0,0,0.5);
|
|
55
|
-
}
|
|
56
|
-
.quiet a { opacity: 0.7; }
|
|
57
|
-
|
|
58
|
-
.fraction {
|
|
59
|
-
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
|
60
|
-
font-size: 10px;
|
|
61
|
-
color: #555;
|
|
62
|
-
background: #E8E8E8;
|
|
63
|
-
padding: 4px 5px;
|
|
64
|
-
border-radius: 3px;
|
|
65
|
-
vertical-align: middle;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
div.path a:link, div.path a:visited { color: #333; }
|
|
69
|
-
table.coverage {
|
|
70
|
-
border-collapse: collapse;
|
|
71
|
-
margin: 10px 0 0 0;
|
|
72
|
-
padding: 0;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
table.coverage td {
|
|
76
|
-
margin: 0;
|
|
77
|
-
padding: 0;
|
|
78
|
-
vertical-align: top;
|
|
79
|
-
}
|
|
80
|
-
table.coverage td.line-count {
|
|
81
|
-
text-align: right;
|
|
82
|
-
padding: 0 5px 0 20px;
|
|
83
|
-
}
|
|
84
|
-
table.coverage td.line-coverage {
|
|
85
|
-
text-align: right;
|
|
86
|
-
padding-right: 10px;
|
|
87
|
-
min-width:20px;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
table.coverage td span.cline-any {
|
|
91
|
-
display: inline-block;
|
|
92
|
-
padding: 0 5px;
|
|
93
|
-
width: 100%;
|
|
94
|
-
}
|
|
95
|
-
.missing-if-branch {
|
|
96
|
-
display: inline-block;
|
|
97
|
-
margin-right: 5px;
|
|
98
|
-
border-radius: 3px;
|
|
99
|
-
position: relative;
|
|
100
|
-
padding: 0 4px;
|
|
101
|
-
background: #333;
|
|
102
|
-
color: yellow;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.skip-if-branch {
|
|
106
|
-
display: none;
|
|
107
|
-
margin-right: 10px;
|
|
108
|
-
position: relative;
|
|
109
|
-
padding: 0 4px;
|
|
110
|
-
background: #ccc;
|
|
111
|
-
color: white;
|
|
112
|
-
}
|
|
113
|
-
.missing-if-branch .typ, .skip-if-branch .typ {
|
|
114
|
-
color: inherit !important;
|
|
115
|
-
}
|
|
116
|
-
.coverage-summary {
|
|
117
|
-
border-collapse: collapse;
|
|
118
|
-
width: 100%;
|
|
119
|
-
}
|
|
120
|
-
.coverage-summary tr { border-bottom: 1px solid #bbb; }
|
|
121
|
-
.keyline-all { border: 1px solid #ddd; }
|
|
122
|
-
.coverage-summary td, .coverage-summary th { padding: 10px; }
|
|
123
|
-
.coverage-summary tbody { border: 1px solid #bbb; }
|
|
124
|
-
.coverage-summary td { border-right: 1px solid #bbb; }
|
|
125
|
-
.coverage-summary td:last-child { border-right: none; }
|
|
126
|
-
.coverage-summary th {
|
|
127
|
-
text-align: left;
|
|
128
|
-
font-weight: normal;
|
|
129
|
-
white-space: nowrap;
|
|
130
|
-
}
|
|
131
|
-
.coverage-summary th.file { border-right: none !important; }
|
|
132
|
-
.coverage-summary th.pct { }
|
|
133
|
-
.coverage-summary th.pic,
|
|
134
|
-
.coverage-summary th.abs,
|
|
135
|
-
.coverage-summary td.pct,
|
|
136
|
-
.coverage-summary td.abs { text-align: right; }
|
|
137
|
-
.coverage-summary td.file { white-space: nowrap; }
|
|
138
|
-
.coverage-summary td.pic { min-width: 120px !important; }
|
|
139
|
-
.coverage-summary tfoot td { }
|
|
140
|
-
|
|
141
|
-
.coverage-summary .sorter {
|
|
142
|
-
height: 10px;
|
|
143
|
-
width: 7px;
|
|
144
|
-
display: inline-block;
|
|
145
|
-
margin-left: 0.5em;
|
|
146
|
-
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
|
|
147
|
-
}
|
|
148
|
-
.coverage-summary .sorted .sorter {
|
|
149
|
-
background-position: 0 -20px;
|
|
150
|
-
}
|
|
151
|
-
.coverage-summary .sorted-desc .sorter {
|
|
152
|
-
background-position: 0 -10px;
|
|
153
|
-
}
|
|
154
|
-
.status-line { height: 10px; }
|
|
155
|
-
/* yellow */
|
|
156
|
-
.cbranch-no { background: yellow !important; color: #111; }
|
|
157
|
-
/* dark red */
|
|
158
|
-
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
|
|
159
|
-
.low .chart { border:1px solid #C21F39 }
|
|
160
|
-
.highlighted,
|
|
161
|
-
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
|
|
162
|
-
background: #C21F39 !important;
|
|
163
|
-
}
|
|
164
|
-
/* medium red */
|
|
165
|
-
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
|
|
166
|
-
/* light red */
|
|
167
|
-
.low, .cline-no { background:#FCE1E5 }
|
|
168
|
-
/* light green */
|
|
169
|
-
.high, .cline-yes { background:rgb(230,245,208) }
|
|
170
|
-
/* medium green */
|
|
171
|
-
.cstat-yes { background:rgb(161,215,106) }
|
|
172
|
-
/* dark green */
|
|
173
|
-
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
|
|
174
|
-
.high .chart { border:1px solid rgb(77,146,33) }
|
|
175
|
-
/* dark yellow (gold) */
|
|
176
|
-
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
|
|
177
|
-
.medium .chart { border:1px solid #f9cd0b; }
|
|
178
|
-
/* light yellow */
|
|
179
|
-
.medium { background: #fff4c2; }
|
|
180
|
-
|
|
181
|
-
.cstat-skip { background: #ddd; color: #111; }
|
|
182
|
-
.fstat-skip { background: #ddd; color: #111 !important; }
|
|
183
|
-
.cbranch-skip { background: #ddd !important; color: #111; }
|
|
184
|
-
|
|
185
|
-
span.cline-neutral { background: #eaeaea; }
|
|
186
|
-
|
|
187
|
-
.coverage-summary td.empty {
|
|
188
|
-
opacity: .5;
|
|
189
|
-
padding-top: 4px;
|
|
190
|
-
padding-bottom: 4px;
|
|
191
|
-
line-height: 1;
|
|
192
|
-
color: #888;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.cover-fill, .cover-empty {
|
|
196
|
-
display:inline-block;
|
|
197
|
-
height: 12px;
|
|
198
|
-
}
|
|
199
|
-
.chart {
|
|
200
|
-
line-height: 0;
|
|
201
|
-
}
|
|
202
|
-
.cover-empty {
|
|
203
|
-
background: white;
|
|
204
|
-
}
|
|
205
|
-
.cover-full {
|
|
206
|
-
border-right: none !important;
|
|
207
|
-
}
|
|
208
|
-
pre.prettyprint {
|
|
209
|
-
border: none !important;
|
|
210
|
-
padding: 0 !important;
|
|
211
|
-
margin: 0 !important;
|
|
212
|
-
}
|
|
213
|
-
.com { color: #999 !important; }
|
|
214
|
-
.ignore-none { color: #999; font-weight: normal; }
|
|
215
|
-
|
|
216
|
-
.wrapper {
|
|
217
|
-
min-height: 100%;
|
|
218
|
-
height: auto !important;
|
|
219
|
-
height: 100%;
|
|
220
|
-
margin: 0 auto -48px;
|
|
221
|
-
}
|
|
222
|
-
.footer, .push {
|
|
223
|
-
height: 48px;
|
|
224
|
-
}
|