specmatic 0.8.2__py3-none-any.whl → 0.9.1__py3-none-any.whl

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.

Potentially problematic release.


This version of specmatic might be problematic. Click here for more details.

@@ -5,25 +5,38 @@ from specmatic.core.specmatic_test import SpecmaticTest
5
5
  from specmatic.generators.pytest_generator import PyTestGenerator
6
6
  from specmatic.generators.unittest_generator import UnitTestGenerator
7
7
  from specmatic.servers.app_server import AppServer
8
+ from specmatic.servers.asgi_app_server import ASGIAppServer
9
+ from specmatic.servers.wsgi_app_server import WSGIAppServer
8
10
  from specmatic.utils import get_junit_report_file_path
9
11
 
10
12
 
11
13
  class Specmatic:
12
14
  def __init__(self):
13
- self.test_args = None
15
+ self.app = None
16
+ self.app_module = ''
17
+ self.app_host = '127.0.0.1'
18
+ self.app_port = 0
19
+ self.reset_app_config_func = None
20
+ self.set_app_config_func = None
21
+ self.app_server = None
22
+
23
+ self.stub_host = None
24
+ self.stub_port = None
25
+ self.expectations = None
14
26
  self.stub_args = None
27
+ self.stub = None
28
+
15
29
  self.test_class = None
16
- self.test_port = None
17
30
  self.test_host = None
18
- self.app_server = None
19
- self.expectations = None
20
- self.stub_port = None
21
- self.stub_host = None
31
+ self.test_port = None
32
+ self.test_args = None
33
+
34
+ self.project_root = ''
35
+ self.specmatic_json_file_path = ''
36
+
22
37
  self.run_stub = False
23
38
  self.run_app = False
24
39
  self.run_tests = False
25
- self.project_root = ''
26
- self.specmatic_json_file_path = ''
27
40
 
28
41
  def with_project_root(self, project_root):
29
42
  self.project_root = project_root
@@ -33,7 +46,7 @@ class Specmatic:
33
46
  self.specmatic_json_file_path = specmatic_json_file_path
34
47
  return self
35
48
 
36
- def stub(self, stub_host: str = '127.0.0.1', stub_port: int = 0, expectations=None, args=None):
49
+ def with_stub(self, stub_host: str = '127.0.0.1', stub_port: int = 0, expectations=None, args=None):
37
50
  self.stub_host = stub_host
38
51
  self.stub_port = stub_port
39
52
  self.run_stub = True
@@ -46,6 +59,26 @@ class Specmatic:
46
59
  self.run_app = True
47
60
  return self
48
61
 
62
+ def with_wsgi_app(self, app, host: str = '127.0.0.1', port: int = 0, set_app_config_func=None,
63
+ reset_app_config_func=None):
64
+ self.app = app
65
+ self.app_host = host
66
+ self.app_port = port
67
+ self.set_app_config_func = set_app_config_func
68
+ self.reset_app_config_func = reset_app_config_func
69
+ self.run_app = True
70
+ return self
71
+
72
+ def with_asgi_app(self, app_module: str, host: str = '127.0.0.1', port: int = 0, set_app_config_func=None,
73
+ reset_app_config_func=None):
74
+ self.app_module = app_module
75
+ self.app_host = host
76
+ self.app_port = port
77
+ self.set_app_config_func = set_app_config_func
78
+ self.reset_app_config_func = reset_app_config_func
79
+ self.run_app = True
80
+ return self
81
+
49
82
  def test(self, test_class, test_host: str = '127.0.0.1', test_port: int = 0, args=None):
50
83
  self.test_class = test_class
51
84
  self.test_host = test_host
@@ -54,26 +87,46 @@ class Specmatic:
54
87
  self.run_tests = True
55
88
  return self
56
89
 
57
- def run(self):
58
- stub = None
59
- try:
60
- if self.run_stub:
61
- stub = SpecmaticStub(self.stub_host, self.stub_port, self.project_root, self.specmatic_json_file_path, self.stub_args)
62
- stub.set_expectations(self.expectations)
63
- self.app_server.set_app_config(stub.host, stub.port)
64
- if self.run_app:
90
+ def __init_app_server(self):
91
+ if self.run_app:
92
+ if self.app is None and self.app_module == '':
93
+ raise Exception('Please specify either an app or an app_module.')
94
+ if self.app is not None and self.app_module != '':
95
+ raise Exception('Please specify only one of app or app_module, and not both.')
96
+ if self.app is not None:
97
+ self.app_server = WSGIAppServer(self.app, self.app_host, self.app_port, self.set_app_config_func,
98
+ self.reset_app_config_func)
99
+ else:
100
+ self.app_server = ASGIAppServer(self.app_module, self.app_host, self.app_port, self.set_app_config_func,
101
+ self.reset_app_config_func)
102
+
103
+ def __start_stub(self):
104
+ if self.run_stub:
105
+ self.stub = SpecmaticStub(self.stub_host, self.stub_port, self.project_root, self.specmatic_json_file_path,
106
+ self.stub_args)
107
+ self.stub.set_expectations(self.expectations)
108
+ self.app_server.set_app_config(self.stub.host, self.stub.port)
109
+
110
+ def __execute_tests(self):
111
+ if self.run_tests:
112
+ if self.app_server is not None:
65
113
  self.app_server.start()
66
114
  self.test_host = self.app_server.host
67
115
  self.test_port = self.app_server.port
68
- if self.run_tests:
69
- SpecmaticTest(self.test_host, self.test_port, self.project_root,
70
- self.specmatic_json_file_path, self.test_args).run()
71
- if issubclass(self.test_class, unittest.TestCase):
72
- print("Injecting unittest methods")
73
- UnitTestGenerator(self.test_class, get_junit_report_file_path()).generate()
74
- else:
75
- print("Injecting pytest methods")
76
- PyTestGenerator(self.test_class, get_junit_report_file_path()).generate()
116
+ SpecmaticTest(self.test_host, self.test_port, self.project_root,
117
+ self.specmatic_json_file_path, self.test_args).run()
118
+ if issubclass(self.test_class, unittest.TestCase):
119
+ print("Injecting unittest methods")
120
+ UnitTestGenerator(self.test_class, get_junit_report_file_path()).generate()
121
+ else:
122
+ print("Injecting pytest methods")
123
+ PyTestGenerator(self.test_class, get_junit_report_file_path()).generate()
124
+
125
+ def run(self):
126
+ try:
127
+ self.__init_app_server()
128
+ self.__start_stub()
129
+ self.__execute_tests()
77
130
  except Exception as e:
78
131
  print(f"Error: {e}")
79
132
  raise e
@@ -81,5 +134,5 @@ class Specmatic:
81
134
  if self.app_server is not None:
82
135
  self.app_server.stop()
83
136
  self.app_server.reset_app_config()
84
- if stub is not None:
85
- stub.stop()
137
+ if self.stub is not None:
138
+ self.stub.stop()
@@ -43,6 +43,9 @@ class ASGIAppServer(AppServer):
43
43
  def __read_process_output(self):
44
44
  try:
45
45
  for line in iter(self.__process.stdout.readline, ''):
46
+ if self.__process.poll() is not None:
47
+ line = line.decode()
48
+ raise Exception('App process terminated due to an error ' + line)
46
49
  if line:
47
50
  line = line.decode().rstrip()
48
51
  print(line)
specmatic/version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = '0.8.2'
1
+ __version__ = '0.9.1'
2
2
  __specmatic_version__ = '0.68.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: specmatic
3
- Version: 0.8.2
3
+ Version: 0.9.1
4
4
  Summary: A Python module for using the Specmatic Library.
5
5
  Home-page: https://github.com/znsio/specmatic-python-extensions
6
6
  Author: Specmatic Builders
@@ -45,28 +45,24 @@ The open api specification can be present either locally or in a [Central Contra
45
45
  ## WSGI Apps
46
46
 
47
47
  #### To run contract tests with a stub for a wsgi app (like Flask):
48
- - Create an instance of a ``````WSGIAppServer`````` by passing it your app object, host, port:
49
- ``````app_server = WSGIAppServer(app, app_host, app_port)``````
50
- - Note:
51
- - The host and port are optional. If they are not specified, the app will be started on a random available port on 127.0.0.1.
52
- - You would need a [specmatic.json](https://specmatic.in/documentation/specmatic_json.html) file to be present in the root directory of your project.
53
- - To run tests using a stub for your dependencies:
48
+
54
49
  ``````
55
50
  class TestContract:
56
51
  pass
57
52
 
58
53
 
59
- app_server = WSGIAppServer(app, app_host, app_port)
60
54
  Specmatic() \
61
55
  .with_project_root(PROJECT_ROOT) \
62
- .stub(stub_host, stub_port, [expectation_json_file]) \
63
- .app(app_server) \
56
+ .with_stub(stub_host, stub_port, [expectation_json_file]) \
57
+ .with_wsgi_app(app, app_host, app_port) \
64
58
  .test(TestContract) \
65
59
  .run()
66
60
  ``````
67
61
 
68
62
  - In this, we are passing:
69
- - an instance of the WSGIAppServer class.
63
+ - an instance of your asgi app like flask
64
+ - app_host and app_port. If they are not specified, the app will be started on a random available port on 127.0.0.1.
65
+ - You would need a [specmatic.json](https://specmatic.in/documentation/specmatic_json.html) file to be present in the root directory of your project.
70
66
  - an empty test class.
71
67
  - stub_host, stub_port, optional list of json files to set expectations on the stub.
72
68
  The stub_host, stub_port will be used to run the specmatic stub server.
@@ -83,11 +79,9 @@ Specmatic() \
83
79
  class TestContract:
84
80
  pass
85
81
 
86
-
87
- app_server = WSGIAppServer(app, app_host, app_port)
88
82
  Specmatic() \
89
83
  .with_project_root(PROJECT_ROOT) \
90
- .app(app_server) \
84
+ .with_wsgi_app(app, app_host, app_port) \
91
85
  .test(TestContract) \
92
86
  .run()
93
87
  ``````
@@ -95,20 +89,16 @@ Specmatic() \
95
89
  ## ASGI Apps
96
90
 
97
91
  #### To run contract tests with a stub for an asgi app (like sanic):
98
- - Create an instance of a ``````ASGIAppServer`````` by passing it a string in the 'module:app' format for your asgi app, host, port:
99
- ``````app_server = ASGIAppServer('main:app', app_host, app_port)``````
100
- If host and port are not specified, the app will be started on a random available port on 127.0.0.1.
101
- - You can now use the ``````ASGIAppServer`````` object to run tests just like we do it for WSGI apps:
92
+ - If you are using an asgi app like sanic, fastapi, use the ``````with_asgi_app`````` function and pass it a string in the 'module:app' format.
102
93
  ``````
103
94
  class TestContract:
104
95
  pass
105
96
 
106
97
 
107
- app_server = ASGIAppServer('main:app', app_host, app_port)
108
98
  Specmatic() \
109
99
  .with_project_root(PROJECT_ROOT) \
110
- .stub(stub_host, stub_port, [expectation_json_file]) \
111
- .app(app_server) \
100
+ .with_stub(stub_host, stub_port, [expectation_json_file]) \
101
+ .with_asgi_app('main:app', app_host, app_port) \
112
102
  .test(TestContract) \
113
103
  .run()
114
104
  ``````
@@ -120,18 +110,17 @@ class TestContract:
120
110
  pass
121
111
 
122
112
 
123
- app_server = WSGIAppServer(app, app_host, app_port)
124
113
  Specmatic() \
125
114
  .with_project_root(PROJECT_ROOT) \
126
- .stub(stub_host, stub_port, [expectation_json_file], ['--strict']) \
127
- .app(app_server) \
115
+ .with_stub(stub_host, stub_port, [expectation_json_file], ['--strict']) \
116
+ .with_wsgi_app(app, port=app_port) \
128
117
  .test(TestContract, args=['--testBaseURL=http://localhost:5000']) \
129
118
  .run()
130
119
  ``````
131
120
 
132
121
  ## Common Issues
133
122
  - **'Error loading ASGI app'**
134
- This error occurs due to incorrect module being specified in the app module parameter 'module:app' string.
123
+ This error occurs when an incorrect app module string is passed to the ``````with_asgi_app`````` function.
135
124
 
136
125
  #### Solutions:
137
126
  - Try to identify the correct module in which your app variable is instantiated/imported.
@@ -1,10 +1,10 @@
1
1
  specmatic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  specmatic/utils.py,sha256=6JDPqpO51ykl0MWCOa32jkUOXZ-0RZ6N5Ng9_7r7XaU,519
3
- specmatic/version.py,sha256=ChaMG-i3_0ofrsjpKetrtiqQMlu3bPKNyhRsLcx4C74,55
3
+ specmatic/version.py,sha256=MpN_PFJMmvrp-2TOtwaw16FhamYEEkOXXdUWtIOP4YM,55
4
4
  specmatic/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  specmatic/core/decorators.py,sha256=_TWZMbUyH4WFyYHzW0oBcuef-c6ktukJ9Av3iYrDkTY,2879
6
6
  specmatic/core/specmatic.jar,sha256=LIHTAPFuGtfZ6zvcrwfVJ7luLAuSvMvDoalInN3pqUQ,87155557
7
- specmatic/core/specmatic.py,sha256=yldAkTDXeBaKyh_PoVh8fJevB5B0UHbMBwp2XZbqLM8,3221
7
+ specmatic/core/specmatic.py,sha256=avagtEtRnfxUFqwHR3q-vIB0YdypJTsWEmQVA6DPXQQ,5361
8
8
  specmatic/core/specmatic_base.py,sha256=sueXRmjXXLV8YC_3rsxGng2bPt2qWIsTWEO2A9MXMP0,1497
9
9
  specmatic/core/specmatic_stub.py,sha256=_I6jc8oI7me6Q64gtPchRRqA-c8GGO5YTCIpw1nrwEo,4563
10
10
  specmatic/core/specmatic_test.py,sha256=rZXCeTlH-3wkShJECL7VDN2hlkJgmuiKQYzVRwnLNok,994
@@ -14,10 +14,10 @@ specmatic/generators/test_generator_base.py,sha256=bCdJD9MOUX6FINPF2r06y9NQ5k10q
14
14
  specmatic/generators/unittest_generator.py,sha256=Vkm8BP-_rZ-tFbLwUTNc90OgQCMJ4OHd8w5mShhcFyU,713
15
15
  specmatic/servers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  specmatic/servers/app_server.py,sha256=kOZviJA7-F4kmMTLGiBln2oO5uYX28wKJM2xQJTOVQY,456
17
- specmatic/servers/asgi_app_server.py,sha256=mQ885snLeUUtb0mrDjLiT9CS-6MGVdFsCYEz9dAL51A,2743
17
+ specmatic/servers/asgi_app_server.py,sha256=yn3tpWoF-nP8labOJdn49UB85vKiqIELVXk-gAugcUc,2924
18
18
  specmatic/servers/wsgi_app_server.py,sha256=3aU-o6Hh8FrnZlbjCLLpGY92HvJoU_rcqsZIb9TKVr8,1342
19
19
  specmatic/servers/wsgi_server_thread.py,sha256=XUEYW7-FP1a-5EkQVGc3FI_jkDQBocArxHLiCn3JJvc,691
20
- specmatic-0.8.2.dist-info/METADATA,sha256=QNuMVSTfdOp0By2vb8r447iMwx64CmIx2a4rXhUaSqw,6322
21
- specmatic-0.8.2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
22
- specmatic-0.8.2.dist-info/top_level.txt,sha256=E7kQ78YacKBoKKeKWR_N83exlG8r5J0wlzlGqFmvIfo,10
23
- specmatic-0.8.2.dist-info/RECORD,,
20
+ specmatic-0.9.1.dist-info/METADATA,sha256=OwazAuFZ4kT_CqWPPI914IixxOgtBreA9Ivspedn4d0,5717
21
+ specmatic-0.9.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
22
+ specmatic-0.9.1.dist-info/top_level.txt,sha256=E7kQ78YacKBoKKeKWR_N83exlG8r5J0wlzlGqFmvIfo,10
23
+ specmatic-0.9.1.dist-info/RECORD,,