diff --git a/TensionBoltedTest1.osi b/TensionBoltedTest1.osi new file mode 100644 index 000000000..4af43b27d --- /dev/null +++ b/TensionBoltedTest1.osi @@ -0,0 +1,75 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Long Leg +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '60' +Material: E 250 (Fe 410 W)A +Member.Designation: +- 40 x 20 x 3 +Member.Length: '1250' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Back to Back Angles +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 diff --git a/TensionBoltedTest2.osi b/TensionBoltedTest2.osi new file mode 100644 index 000000000..ccb7fdeec --- /dev/null +++ b/TensionBoltedTest2.osi @@ -0,0 +1,128 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '12' +- '16' +- '20' +- '24' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Friction Grip Bolt +Conn_Location: Web +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '100' +Material: E 250 (Fe 410 W)A +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 150 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1000' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Channels +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 + + diff --git a/TensionBoltedTest3.osi b/TensionBoltedTest3.osi new file mode 100644 index 000000000..0349a2305 --- /dev/null +++ b/TensionBoltedTest3.osi @@ -0,0 +1,273 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Short Leg +Connector.Material: E 165 (Fe 290) +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '28' +Material: E 165 (Fe 290) +Member.Designation: +- 20 x 20 x 3 +- 20 x 20 x 4 +- 25 x 25 x 3 +- 25 x 25 x 4 +- 25 x 25 x 5 +- 30 x 30 x 3 +- 30 x 30 x 4 +- 30 x 30 x 5 +- 35 x 35 x 3 +- 35 x 35 x 4 +- 35 x 35 x 5 +- 35 x 35 x 6 +- 40 x 40 x 3 +- 40 x 40 x 4 +- 40 x 40 x 5 +- 40 x 40 x 6 +- 45 x 45 x 3 +- 45 x 45 x 4 +- 45 x 45 x 5 +- 45 x 45 x 6 +- 50 x 50 x 3 +- 50 x 50 x 4 +- 50 x 50 x 5 +- 50 x 50 x 6 +- 55 x 55 x 4 +- 55 x 55 x 5 +- 55 x 55 x 6 +- 55 x 55 x 8 +- 60 x 60 x 4 +- 60 x 60 x 5 +- 60 x 60 x 6 +- 60 x 60 x 8 +- 65 x 65 x 4 +- 65 x 65 x 5 +- 65 x 65 x 6 +- 65 x 65 x 8 +- 70 x 70 x 5 +- 70 x 70 x 6 +- 70 x 70 x 8 +- 70 x 70 x 10 +- 75 x 75 x 5 +- 75 x 75 x 6 +- 75 x 75 x 8 +- 75 x 75 x 10 +- 80 x 80 x 6 +- 80 x 80 x 8 +- 80 x 80 x 10 +- 80 x 80 x 12 +- 90 x 90 x 6 +- 90 x 90 x 8 +- 90 x 90 x 10 +- 90 x 90 x 12 +- 100 x 100 x 6 +- 100 x 100 x 8 +- 100 x 100 x 10 +- 100 x 100 x 12 +- 110 x 110 x 8 +- 110 x 110 x 10 +- 110 x 110 x 12 +- 110 x 110 x 16 +- 130 x 130 x 8 +- 130 x130 x 10 +- 130 x130 x 12 +- 130 x130 x 16 +- 150 x 150 x 10 +- 150 x 150 x 12 +- 150 x 150 x 16 +- 150 x 150 x 20 +- 200 x 200 x 12 +- 200 x 200 x 16 +- 200 x 200 x 20 +- 200 x 200 x 25 +- 50 x 50 x 7 +- 50 x 50 x 8 +- 55 x 55 x 10 +- 60 x 60 x 10 +- 65 x 65 x 10 +- 70 x 70 x 7 +- 100 x 100 x 7 +- 100 x 100 x 15 +- 120 x 120 x 8 +- 120 x 120 x 10 +- 120 x 120 x 12 +- 120 x 120 x 15 +- 130 x 130 x 9 +- 150 x 150 x 15 +- 150 x 150 x 18 +- 180 x 180 x 15 +- 180 x 180 x 18 +- 180 x 180 x 20 +- 200 x 200 x 24 +- 30 x 20 x 3 +- 30 x 20 x 4 +- 30 x 20 x 5 +- 40 x 25 x 3 +- 40 x 25 x 4 +- 40 x 25 x 5 +- 40 x 25 x 6 +- 45 x 30 x 3 +- 45 x 30 x 4 +- 45 x 30 x 5 +- 45 x 30 x 6 +- 50 x 30 x 3 +- 50 x 30 x 4 +- 50 x 30 x 5 +- 50 x 30 x 6 +- 60 x 40 x 5 +- 60 x 40 x 6 +- 60 x 40 x 8 +- 65 x 45 x 5 +- 65 x 45 x 6 +- 65 x 45 x 8 +- 70 x 45 x 5 +- 70 x 45 x 6 +- 70 x 45 x 8 +- 70 x 45 x 10 +- 75 x 50 x 5 +- 75 x 50 x 6 +- 75 x 50 x 8 +- 75 x 50 x 10 +- 80 x 50 x 5 +- 80 x 50 x 6 +- 80 x 50 x 8 +- 80 x 50 x 10 +- 90 x 60 x 6 +- 90 x 60 x 8 +- 90 x 60 x 10 +- 90 x 60 x 12 +- 100 x 65 x 6 +- 100 x 65 x 8 +- 100 x 65 x 10 +- 100 x 75 x 6 +- 100 x 75 x 8 +- 100 x 75 x 10 +- 100 x 75 x 12 +- 125 x 75 x 6 +- 125 x 75 x 8 +- 125 x 75 x 10 +- 125 x 95 x 6 +- 125 x 95 x 8 +- 125 x 95 x 10 +- 125 x 95 x 12 +- 150 x 115 x 8 +- 150 x 115 x 10 +- 150 x 115 x 12 +- 150 x 115 x 16 +- 200 x 100 x 10 +- 200 x 100 x 12 +- 200 x 100 x 16 +- 200 x 150 x 10 +- 200 x 150 x 12 +- 200 x 150 x 16 +- 200 x 150 x 20 +- 40 x 20 x 3 +- 40 x 20 x 4 +- 40 x 20 x 5 +- 60 x 30 x 5 +- 60 x 30 x 6 +- 60 x 40 x 7 +- 65 x 50 x 5 +- 65 x 50 x 6 +- 65 x 50 x 7 +- 65 x 50 x 8 +- 70 x 50 x 5 +- 70 x 50 x 6 +- 70 x 50 x 7 +- 70 x 50 x 8 +- 75 x 50 x 7 +- 80 x 40 x 5 +- 80 x 40 x 6 +- 80 x 40 x 7 +- 80 x 40 x 8 +- 80 x 60 x 6 +- 80 x 60 x 7 +- 80 x 60 x 8 +- 90 x 65 x 6 +- 90 x 65 x 7 +- 90 x 65 x 8 +- 90 x 65 x 10 +- 100 x 50 x 6 +- 100 x 50 x 7 +- 100 x 50 x 8 +- 100 x 50 x 10 +- 100 x 65 x 7 +- 120 x 80 x 8 +- 120 x 80 x 10 +- 120 x 80 x 12 +- 125 x 75 x 12 +- 135 x 65 x 8 +- 135 x 65 x 10 +- 135 x 65 x 12 +- 150 x 75 x 9 +- 150 x 75 x 15 +- 150 x 90 x 10 +- 150 x 90 x 12 +- 150 x 90 x 15 +- 200 x 100 x 15 +- 200 x 150 x 15 +- 200 x 150 x 18 +Member.Length: '900' +Member.Material: E 165 (Fe 290) +Member.Profile: Angles +Module: Tension Member Design - Bolted to End Gusset diff --git a/TensionBoltedTest4.osi b/TensionBoltedTest4.osi new file mode 100644 index 000000000..3f77bee12 --- /dev/null +++ b/TensionBoltedTest4.osi @@ -0,0 +1,86 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '20' +- '24' +Bolt.Grade: +- '5.6' +- '6.8' +- '9.8' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Web +Connector.Material: E 350 (Fe 490) +Connector.Plate.Thickness_List: +- '8' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '300' +Material: E 350 (Fe 490) +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1500' +Member.Material: E 350 (Fe 490) +Member.Profile: Back to Back Channels +Module: Tension Member Design - Bolted to End Gusset diff --git a/bld.bat b/bld.bat new file mode 100644 index 000000000..ec2e45fde --- /dev/null +++ b/bld.bat @@ -0,0 +1,9 @@ +@echo off +echo Starting Conda build... +conda build . +echo Conda build ended... +echo Tests running... +pytest tests +echo Successfully all the tests ran... +pause + diff --git a/osdag-conda-recipe/recipe/meta.yaml b/osdag-conda-recipe/recipe/meta.yaml new file mode 100644 index 000000000..d9c84b961 --- /dev/null +++ b/osdag-conda-recipe/recipe/meta.yaml @@ -0,0 +1,49 @@ +package: + name: osdag + version: "0.1" + +source: + path: .. + +build: + script: + - pip install . + - pytest --verbose --capture=no + +requirements: + build: + - python + - pip + - pytest + - setuptools + - setuptools_scm + + host: + - python + - pip + - pytest + - setuptools + - setuptools_scm + + run: + - python + - pyqt + - requests + - numpy + - pyyaml + - pygithub + - pytest + +test: + source_files: + - recipe/tests/test_validator.py + - recipe/tests/validator.py + requires: + - pytest + commands: + - pytest recipe/tests/ + +about: + home: "https://osdag.fossee.in" + summary: "Open Steel Design and Graphics (Osdag) - an open-source software for structural steel design developed by FOSSEE, IIT Bombay." + diff --git a/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest1.osi b/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest1.osi new file mode 100644 index 000000000..4af43b27d --- /dev/null +++ b/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest1.osi @@ -0,0 +1,75 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Long Leg +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '60' +Material: E 250 (Fe 410 W)A +Member.Designation: +- 40 x 20 x 3 +Member.Length: '1250' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Back to Back Angles +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 diff --git a/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest2.osi b/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest2.osi new file mode 100644 index 000000000..ccb7fdeec --- /dev/null +++ b/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest2.osi @@ -0,0 +1,128 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '12' +- '16' +- '20' +- '24' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Friction Grip Bolt +Conn_Location: Web +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '100' +Material: E 250 (Fe 410 W)A +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 150 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1000' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Channels +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 + + diff --git a/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest3.osi b/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest3.osi new file mode 100644 index 000000000..0349a2305 --- /dev/null +++ b/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest3.osi @@ -0,0 +1,273 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Short Leg +Connector.Material: E 165 (Fe 290) +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '28' +Material: E 165 (Fe 290) +Member.Designation: +- 20 x 20 x 3 +- 20 x 20 x 4 +- 25 x 25 x 3 +- 25 x 25 x 4 +- 25 x 25 x 5 +- 30 x 30 x 3 +- 30 x 30 x 4 +- 30 x 30 x 5 +- 35 x 35 x 3 +- 35 x 35 x 4 +- 35 x 35 x 5 +- 35 x 35 x 6 +- 40 x 40 x 3 +- 40 x 40 x 4 +- 40 x 40 x 5 +- 40 x 40 x 6 +- 45 x 45 x 3 +- 45 x 45 x 4 +- 45 x 45 x 5 +- 45 x 45 x 6 +- 50 x 50 x 3 +- 50 x 50 x 4 +- 50 x 50 x 5 +- 50 x 50 x 6 +- 55 x 55 x 4 +- 55 x 55 x 5 +- 55 x 55 x 6 +- 55 x 55 x 8 +- 60 x 60 x 4 +- 60 x 60 x 5 +- 60 x 60 x 6 +- 60 x 60 x 8 +- 65 x 65 x 4 +- 65 x 65 x 5 +- 65 x 65 x 6 +- 65 x 65 x 8 +- 70 x 70 x 5 +- 70 x 70 x 6 +- 70 x 70 x 8 +- 70 x 70 x 10 +- 75 x 75 x 5 +- 75 x 75 x 6 +- 75 x 75 x 8 +- 75 x 75 x 10 +- 80 x 80 x 6 +- 80 x 80 x 8 +- 80 x 80 x 10 +- 80 x 80 x 12 +- 90 x 90 x 6 +- 90 x 90 x 8 +- 90 x 90 x 10 +- 90 x 90 x 12 +- 100 x 100 x 6 +- 100 x 100 x 8 +- 100 x 100 x 10 +- 100 x 100 x 12 +- 110 x 110 x 8 +- 110 x 110 x 10 +- 110 x 110 x 12 +- 110 x 110 x 16 +- 130 x 130 x 8 +- 130 x130 x 10 +- 130 x130 x 12 +- 130 x130 x 16 +- 150 x 150 x 10 +- 150 x 150 x 12 +- 150 x 150 x 16 +- 150 x 150 x 20 +- 200 x 200 x 12 +- 200 x 200 x 16 +- 200 x 200 x 20 +- 200 x 200 x 25 +- 50 x 50 x 7 +- 50 x 50 x 8 +- 55 x 55 x 10 +- 60 x 60 x 10 +- 65 x 65 x 10 +- 70 x 70 x 7 +- 100 x 100 x 7 +- 100 x 100 x 15 +- 120 x 120 x 8 +- 120 x 120 x 10 +- 120 x 120 x 12 +- 120 x 120 x 15 +- 130 x 130 x 9 +- 150 x 150 x 15 +- 150 x 150 x 18 +- 180 x 180 x 15 +- 180 x 180 x 18 +- 180 x 180 x 20 +- 200 x 200 x 24 +- 30 x 20 x 3 +- 30 x 20 x 4 +- 30 x 20 x 5 +- 40 x 25 x 3 +- 40 x 25 x 4 +- 40 x 25 x 5 +- 40 x 25 x 6 +- 45 x 30 x 3 +- 45 x 30 x 4 +- 45 x 30 x 5 +- 45 x 30 x 6 +- 50 x 30 x 3 +- 50 x 30 x 4 +- 50 x 30 x 5 +- 50 x 30 x 6 +- 60 x 40 x 5 +- 60 x 40 x 6 +- 60 x 40 x 8 +- 65 x 45 x 5 +- 65 x 45 x 6 +- 65 x 45 x 8 +- 70 x 45 x 5 +- 70 x 45 x 6 +- 70 x 45 x 8 +- 70 x 45 x 10 +- 75 x 50 x 5 +- 75 x 50 x 6 +- 75 x 50 x 8 +- 75 x 50 x 10 +- 80 x 50 x 5 +- 80 x 50 x 6 +- 80 x 50 x 8 +- 80 x 50 x 10 +- 90 x 60 x 6 +- 90 x 60 x 8 +- 90 x 60 x 10 +- 90 x 60 x 12 +- 100 x 65 x 6 +- 100 x 65 x 8 +- 100 x 65 x 10 +- 100 x 75 x 6 +- 100 x 75 x 8 +- 100 x 75 x 10 +- 100 x 75 x 12 +- 125 x 75 x 6 +- 125 x 75 x 8 +- 125 x 75 x 10 +- 125 x 95 x 6 +- 125 x 95 x 8 +- 125 x 95 x 10 +- 125 x 95 x 12 +- 150 x 115 x 8 +- 150 x 115 x 10 +- 150 x 115 x 12 +- 150 x 115 x 16 +- 200 x 100 x 10 +- 200 x 100 x 12 +- 200 x 100 x 16 +- 200 x 150 x 10 +- 200 x 150 x 12 +- 200 x 150 x 16 +- 200 x 150 x 20 +- 40 x 20 x 3 +- 40 x 20 x 4 +- 40 x 20 x 5 +- 60 x 30 x 5 +- 60 x 30 x 6 +- 60 x 40 x 7 +- 65 x 50 x 5 +- 65 x 50 x 6 +- 65 x 50 x 7 +- 65 x 50 x 8 +- 70 x 50 x 5 +- 70 x 50 x 6 +- 70 x 50 x 7 +- 70 x 50 x 8 +- 75 x 50 x 7 +- 80 x 40 x 5 +- 80 x 40 x 6 +- 80 x 40 x 7 +- 80 x 40 x 8 +- 80 x 60 x 6 +- 80 x 60 x 7 +- 80 x 60 x 8 +- 90 x 65 x 6 +- 90 x 65 x 7 +- 90 x 65 x 8 +- 90 x 65 x 10 +- 100 x 50 x 6 +- 100 x 50 x 7 +- 100 x 50 x 8 +- 100 x 50 x 10 +- 100 x 65 x 7 +- 120 x 80 x 8 +- 120 x 80 x 10 +- 120 x 80 x 12 +- 125 x 75 x 12 +- 135 x 65 x 8 +- 135 x 65 x 10 +- 135 x 65 x 12 +- 150 x 75 x 9 +- 150 x 75 x 15 +- 150 x 90 x 10 +- 150 x 90 x 12 +- 150 x 90 x 15 +- 200 x 100 x 15 +- 200 x 150 x 15 +- 200 x 150 x 18 +Member.Length: '900' +Member.Material: E 165 (Fe 290) +Member.Profile: Angles +Module: Tension Member Design - Bolted to End Gusset diff --git a/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest4.osi b/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest4.osi new file mode 100644 index 000000000..3f77bee12 --- /dev/null +++ b/osdag-conda-recipe/recipe/tests/osi_files/TensionBoltedTest4.osi @@ -0,0 +1,86 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '20' +- '24' +Bolt.Grade: +- '5.6' +- '6.8' +- '9.8' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Web +Connector.Material: E 350 (Fe 490) +Connector.Plate.Thickness_List: +- '8' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '300' +Material: E 350 (Fe 490) +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1500' +Member.Material: E 350 (Fe 490) +Member.Profile: Back to Back Channels +Module: Tension Member Design - Bolted to End Gusset diff --git a/osdag-conda-recipe/recipe/tests/run_validator.bat b/osdag-conda-recipe/recipe/tests/run_validator.bat new file mode 100644 index 000000000..44d977398 --- /dev/null +++ b/osdag-conda-recipe/recipe/tests/run_validator.bat @@ -0,0 +1,4 @@ +@echo off +cd /d "%~dp0" +pytest test_validator.py +pause diff --git a/osdag-conda-recipe/recipe/tests/test_dummy.py b/osdag-conda-recipe/recipe/tests/test_dummy.py new file mode 100644 index 000000000..7b9639e95 --- /dev/null +++ b/osdag-conda-recipe/recipe/tests/test_dummy.py @@ -0,0 +1,3 @@ +# tests/test_dummy.py +def test_dummy(): + assert 1 + 1 == 2 diff --git a/osdag-conda-recipe/recipe/tests/test_validator.py b/osdag-conda-recipe/recipe/tests/test_validator.py new file mode 100644 index 000000000..046637ca1 --- /dev/null +++ b/osdag-conda-recipe/recipe/tests/test_validator.py @@ -0,0 +1,51 @@ +import os +import pytest +import validator # validator.py must be in same dir + +# ✅ Set correct path +osi_dir = os.path.join(os.path.dirname(__file__), "osi_files") + +def run_test(file_name, expected_result): + file_path = os.path.join(osi_dir, file_name) + result = validator.validate_osi(file_path) + print(f"Testing {file_name}") + + for key in expected_result: + assert result[key] == expected_result[key], f"{key} failed: expected {expected_result[key]}, got {result[key]}" + print(" Passed\n") + +def test_tension_bolted_test1(): + expected_result = { + "Member.Designation": "Pass", + "Bolt.Grade": "Pass", + "Bolt.Diameter": "" # Skipped check + } + run_test("TensionBoltedTest1.osi", expected_result) + +def test_tension_bolted_test2(): + expected_result = { + "Member.Designation": "Pass", + "Bolt.Grade": "Pass", + "Bolt.Diameter": "Pass" + } + run_test("TensionBoltedTest2.osi", expected_result) + +def test_tension_bolted_test3(): + expected_result = { + "Member.Designation": "Pass", + "Bolt.Grade": "Pass", + "Bolt.Diameter": "Pass" + } + run_test("TensionBoltedTest3.osi", expected_result) + +def test_tension_bolted_test4(): + expected_result = { + "Member.Designation": "Pass", + "Bolt.Grade": "Pass", + "Bolt.Diameter": "Pass" + } + run_test("TensionBoltedTest4.osi", expected_result) + +if __name__ == "__main__": + pytest.main() + diff --git a/osdag-conda-recipe/recipe/tests/validator.py b/osdag-conda-recipe/recipe/tests/validator.py new file mode 100644 index 000000000..dc001afe9 --- /dev/null +++ b/osdag-conda-recipe/recipe/tests/validator.py @@ -0,0 +1,80 @@ +import os + +# Valid entries per file +valid_designations = { + "TensionBoltedTest1": ["40 x 20 x 3"], + "TensionBoltedTest2": ["JC 100"], + "TensionBoltedTest3": ["40 x 40 x 3"], + "TensionBoltedTest4": ["JC 175"], +} +valid_bolt_grades = ["3.6", "12.9", "4.6", "5.6"] +valid_bolt_diameters = { + "TensionBoltedTest1": [""], # skip check + "TensionBoltedTest2": ["12"], + "TensionBoltedTest3": ["10"], + "TensionBoltedTest4": ["20"], +} + +def normalize(val): + return val.strip().strip("'").strip('"').lower() + +def extract_multiple_values(file_path): + values = {"Member.Designation": [], "Bolt.Grade": [], "Bolt.Diameter": []} + with open(file_path, "r") as f: + current_key = None + for line in f: + line = line.strip() + if ":" in line: + key, _ = line.split(":", 1) + current_key = key.strip() + if current_key in values: + values[current_key] = [] + elif current_key and current_key in values and line.startswith("-"): + values[current_key].append(line.strip("- ").strip()) + return values + +def validate_osi(file_path): + filename = os.path.splitext(os.path.basename(file_path))[0] + data = extract_multiple_values(file_path) + + normalized_data = { + "Member.Designation": [normalize(d) for d in data["Member.Designation"]], + "Bolt.Grade": [normalize(g) for g in data["Bolt.Grade"]], + "Bolt.Diameter": [normalize(d) for d in data["Bolt.Diameter"]], + } + + bolt_dia_check = valid_bolt_diameters.get(filename, []) + bolt_dia_check_normalized = [normalize(val) for val in bolt_dia_check if normalize(val) != ""] + + results = {} + + valid_desig = [normalize(val) for val in valid_designations.get(filename, [])] + results["Member.Designation"] = "Pass" if any(d in valid_desig for d in normalized_data["Member.Designation"]) else "Fail" + + valid_grades = [normalize(val) for val in valid_bolt_grades] + results["Bolt.Grade"] = "Pass" if any(g in valid_grades for g in normalized_data["Bolt.Grade"]) else "Fail" + + if not bolt_dia_check or "" in bolt_dia_check: + results["Bolt.Diameter"] = "" # Skip check + else: + results["Bolt.Diameter"] = ( + "Pass" if any(d in bolt_dia_check_normalized for d in normalized_data["Bolt.Diameter"]) else "Fail" + ) + + return results + +# ✅ Run validator directly +if __name__ == "__main__": + print("Running OSI File Validator...") + folder_path = os.path.join(os.path.dirname(__file__), "osi_files") + print("Looking for files in:", folder_path) + + for file in os.listdir(folder_path): + if file.endswith(".osi"): + path = os.path.join(folder_path, file) + result = validate_osi(path) + print(f"Results for {file}:") + for key, status in result.items(): + print(f" {key}: {status}") + print() + diff --git a/osi_files/TensionBoltedTest1.osi b/osi_files/TensionBoltedTest1.osi new file mode 100644 index 000000000..4af43b27d --- /dev/null +++ b/osi_files/TensionBoltedTest1.osi @@ -0,0 +1,75 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Long Leg +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '60' +Material: E 250 (Fe 410 W)A +Member.Designation: +- 40 x 20 x 3 +Member.Length: '1250' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Back to Back Angles +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 diff --git a/osi_files/TensionBoltedTest2.osi b/osi_files/TensionBoltedTest2.osi new file mode 100644 index 000000000..ccb7fdeec --- /dev/null +++ b/osi_files/TensionBoltedTest2.osi @@ -0,0 +1,128 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '12' +- '16' +- '20' +- '24' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Friction Grip Bolt +Conn_Location: Web +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '100' +Material: E 250 (Fe 410 W)A +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 150 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1000' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Channels +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 + + diff --git a/osi_files/TensionBoltedTest3.osi b/osi_files/TensionBoltedTest3.osi new file mode 100644 index 000000000..0349a2305 --- /dev/null +++ b/osi_files/TensionBoltedTest3.osi @@ -0,0 +1,273 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Short Leg +Connector.Material: E 165 (Fe 290) +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '28' +Material: E 165 (Fe 290) +Member.Designation: +- 20 x 20 x 3 +- 20 x 20 x 4 +- 25 x 25 x 3 +- 25 x 25 x 4 +- 25 x 25 x 5 +- 30 x 30 x 3 +- 30 x 30 x 4 +- 30 x 30 x 5 +- 35 x 35 x 3 +- 35 x 35 x 4 +- 35 x 35 x 5 +- 35 x 35 x 6 +- 40 x 40 x 3 +- 40 x 40 x 4 +- 40 x 40 x 5 +- 40 x 40 x 6 +- 45 x 45 x 3 +- 45 x 45 x 4 +- 45 x 45 x 5 +- 45 x 45 x 6 +- 50 x 50 x 3 +- 50 x 50 x 4 +- 50 x 50 x 5 +- 50 x 50 x 6 +- 55 x 55 x 4 +- 55 x 55 x 5 +- 55 x 55 x 6 +- 55 x 55 x 8 +- 60 x 60 x 4 +- 60 x 60 x 5 +- 60 x 60 x 6 +- 60 x 60 x 8 +- 65 x 65 x 4 +- 65 x 65 x 5 +- 65 x 65 x 6 +- 65 x 65 x 8 +- 70 x 70 x 5 +- 70 x 70 x 6 +- 70 x 70 x 8 +- 70 x 70 x 10 +- 75 x 75 x 5 +- 75 x 75 x 6 +- 75 x 75 x 8 +- 75 x 75 x 10 +- 80 x 80 x 6 +- 80 x 80 x 8 +- 80 x 80 x 10 +- 80 x 80 x 12 +- 90 x 90 x 6 +- 90 x 90 x 8 +- 90 x 90 x 10 +- 90 x 90 x 12 +- 100 x 100 x 6 +- 100 x 100 x 8 +- 100 x 100 x 10 +- 100 x 100 x 12 +- 110 x 110 x 8 +- 110 x 110 x 10 +- 110 x 110 x 12 +- 110 x 110 x 16 +- 130 x 130 x 8 +- 130 x130 x 10 +- 130 x130 x 12 +- 130 x130 x 16 +- 150 x 150 x 10 +- 150 x 150 x 12 +- 150 x 150 x 16 +- 150 x 150 x 20 +- 200 x 200 x 12 +- 200 x 200 x 16 +- 200 x 200 x 20 +- 200 x 200 x 25 +- 50 x 50 x 7 +- 50 x 50 x 8 +- 55 x 55 x 10 +- 60 x 60 x 10 +- 65 x 65 x 10 +- 70 x 70 x 7 +- 100 x 100 x 7 +- 100 x 100 x 15 +- 120 x 120 x 8 +- 120 x 120 x 10 +- 120 x 120 x 12 +- 120 x 120 x 15 +- 130 x 130 x 9 +- 150 x 150 x 15 +- 150 x 150 x 18 +- 180 x 180 x 15 +- 180 x 180 x 18 +- 180 x 180 x 20 +- 200 x 200 x 24 +- 30 x 20 x 3 +- 30 x 20 x 4 +- 30 x 20 x 5 +- 40 x 25 x 3 +- 40 x 25 x 4 +- 40 x 25 x 5 +- 40 x 25 x 6 +- 45 x 30 x 3 +- 45 x 30 x 4 +- 45 x 30 x 5 +- 45 x 30 x 6 +- 50 x 30 x 3 +- 50 x 30 x 4 +- 50 x 30 x 5 +- 50 x 30 x 6 +- 60 x 40 x 5 +- 60 x 40 x 6 +- 60 x 40 x 8 +- 65 x 45 x 5 +- 65 x 45 x 6 +- 65 x 45 x 8 +- 70 x 45 x 5 +- 70 x 45 x 6 +- 70 x 45 x 8 +- 70 x 45 x 10 +- 75 x 50 x 5 +- 75 x 50 x 6 +- 75 x 50 x 8 +- 75 x 50 x 10 +- 80 x 50 x 5 +- 80 x 50 x 6 +- 80 x 50 x 8 +- 80 x 50 x 10 +- 90 x 60 x 6 +- 90 x 60 x 8 +- 90 x 60 x 10 +- 90 x 60 x 12 +- 100 x 65 x 6 +- 100 x 65 x 8 +- 100 x 65 x 10 +- 100 x 75 x 6 +- 100 x 75 x 8 +- 100 x 75 x 10 +- 100 x 75 x 12 +- 125 x 75 x 6 +- 125 x 75 x 8 +- 125 x 75 x 10 +- 125 x 95 x 6 +- 125 x 95 x 8 +- 125 x 95 x 10 +- 125 x 95 x 12 +- 150 x 115 x 8 +- 150 x 115 x 10 +- 150 x 115 x 12 +- 150 x 115 x 16 +- 200 x 100 x 10 +- 200 x 100 x 12 +- 200 x 100 x 16 +- 200 x 150 x 10 +- 200 x 150 x 12 +- 200 x 150 x 16 +- 200 x 150 x 20 +- 40 x 20 x 3 +- 40 x 20 x 4 +- 40 x 20 x 5 +- 60 x 30 x 5 +- 60 x 30 x 6 +- 60 x 40 x 7 +- 65 x 50 x 5 +- 65 x 50 x 6 +- 65 x 50 x 7 +- 65 x 50 x 8 +- 70 x 50 x 5 +- 70 x 50 x 6 +- 70 x 50 x 7 +- 70 x 50 x 8 +- 75 x 50 x 7 +- 80 x 40 x 5 +- 80 x 40 x 6 +- 80 x 40 x 7 +- 80 x 40 x 8 +- 80 x 60 x 6 +- 80 x 60 x 7 +- 80 x 60 x 8 +- 90 x 65 x 6 +- 90 x 65 x 7 +- 90 x 65 x 8 +- 90 x 65 x 10 +- 100 x 50 x 6 +- 100 x 50 x 7 +- 100 x 50 x 8 +- 100 x 50 x 10 +- 100 x 65 x 7 +- 120 x 80 x 8 +- 120 x 80 x 10 +- 120 x 80 x 12 +- 125 x 75 x 12 +- 135 x 65 x 8 +- 135 x 65 x 10 +- 135 x 65 x 12 +- 150 x 75 x 9 +- 150 x 75 x 15 +- 150 x 90 x 10 +- 150 x 90 x 12 +- 150 x 90 x 15 +- 200 x 100 x 15 +- 200 x 150 x 15 +- 200 x 150 x 18 +Member.Length: '900' +Member.Material: E 165 (Fe 290) +Member.Profile: Angles +Module: Tension Member Design - Bolted to End Gusset diff --git a/osi_files/TensionBoltedTest4.osi b/osi_files/TensionBoltedTest4.osi new file mode 100644 index 000000000..3f77bee12 --- /dev/null +++ b/osi_files/TensionBoltedTest4.osi @@ -0,0 +1,86 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '20' +- '24' +Bolt.Grade: +- '5.6' +- '6.8' +- '9.8' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Web +Connector.Material: E 350 (Fe 490) +Connector.Plate.Thickness_List: +- '8' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '300' +Material: E 350 (Fe 490) +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1500' +Member.Material: E 350 (Fe 490) +Member.Profile: Back to Back Channels +Module: Tension Member Design - Bolted to End Gusset diff --git a/pyproject.toml b/pyproject.toml index 74dfe03c3..3f885ad40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,10 @@ [build-system] -requires = ["setuptools >= 61.0", "setuptools_scm >= 8.0"] +requires = [ + "setuptools >= 61.0", + "setuptools_scm >= 8.0", + "pytest" # Ensure pytest is available during the build process +] build-backend = "setuptools.build_meta" -include-package-date = true [tool.setuptools.packages.find] namespaces = true @@ -12,14 +15,20 @@ where = ["src"] "osdag.data.ResourceFiles.Database" = ["*"] "osdag.data.themes" = ["*"] +[tool.pytest.ini_options] +testpaths = ["tests"] +python_files = ["test_*.py"] + [project] name = "osdag" dynamic = ["version"] -dependencies = ["PyQt5", "requests", "pylatex", "numpy", "PyYaml", "PyGithub"] -requires-python = ">= 3.8" +dependencies = [ + "PyQt5", "requests", "pylatex", "numpy", "PyYaml", "PyGithub", "pytest" # Added pytest as a runtime dependency +] +requires-python = ">=3.8" description = "Open steel design and graphics" readme = "README.md" -license = {file = "LICENSE"} +license = {text = "MIT"} keywords = ["steel design", "civil engineering", "engineering"] [project.gui-scripts] diff --git a/run_pytest.py b/run_pytest.py new file mode 100644 index 000000000..03949196a --- /dev/null +++ b/run_pytest.py @@ -0,0 +1,8 @@ +import subprocess +import sys + +print(">>> Automatically running tests with pytest <<<") +try: + subprocess.check_call([sys.executable, "-m", "pytest", "--maxfail=1", "--disable-warnings"]) +except subprocess.CalledProcessError: + print(">>> Tests failed during editable install <<<") diff --git a/tests/Design_Example_1.1.1.1.1.osi b/tests/Design_Example_1.1.1.1.1.osi new file mode 100644 index 000000000..812f330dd --- /dev/null +++ b/tests/Design_Example_1.1.1.1.1.osi @@ -0,0 +1 @@ +{"Load": {"ShearForce (kN)": "140"}, "Plate": {"Width (mm)": "", "Height (mm)": "", "Thickness (mm)": "12"}, "Weld": {"Size (mm)": "12"}, "detailing": {"typeof_edge": "a - Sheared or hand flame cut", "is_env_corrosive": "No", "min_edgend_dist": 1.7, "gap": 10.0}, "Member": {"ColumSection": "UC 305 x 305 x 97", "fu (MPa)": "410", "BeamSection": "MB 500", "fy (MPa)": "250", "Connectivity": "Column flange-Beam web"}, "Connection": "Finplate", "design": {"design_method": "Limit State Design"}, "Bolt": {"Grade": "8.8", "Diameter (mm)": "24", "Type": "Friction Grip Bolt"}, "weld": {"typeof_weld": "Shop weld", "fu_overwrite": "410", "safety_factor": 1.25}, "bolt": {"bolt_hole_clrnce": 2, "slip_factor": 0.3, "bolt_fu": 800, "bolt_hole_type": "Standard"}} \ No newline at end of file diff --git a/tests/Design_Example_1.1.1.1.2.osi b/tests/Design_Example_1.1.1.1.2.osi new file mode 100644 index 000000000..a80a46878 --- /dev/null +++ b/tests/Design_Example_1.1.1.1.2.osi @@ -0,0 +1 @@ +{"Load": {"ShearForce (kN)": "150"}, "Plate": {"Width (mm)": "", "Height (mm)": "", "Thickness (mm)": "12"}, "Weld": {"Size (mm)": "8"}, "detailing": {"typeof_edge": "b - Rolled, machine-flame cut, sawn and planed", "is_env_corrosive": "No", "min_edgend_dist": 1.5, "gap": 10.0}, "Member": {"ColumSection": "SC 200", "fu (MPa)": "410", "BeamSection": "MB 350", "fy (MPa)": "250", "Connectivity": "Column flange-Beam web"}, "Connection": "Finplate", "design": {"design_method": "Limit State Design"}, "Bolt": {"Grade": "4.6", "Diameter (mm)": "20", "Type": "Bearing Bolt"}, "weld": {"typeof_weld": "Shop weld", "fu_overwrite": "410", "safety_factor": 1.25}, "bolt": {"bolt_hole_clrnce": 2, "slip_factor": 0.3, "bolt_fu": 400, "bolt_hole_type": "Standard"}} \ No newline at end of file diff --git a/tests/Design_Example_1.1.1.2.1.osi b/tests/Design_Example_1.1.1.2.1.osi new file mode 100644 index 000000000..236b388f3 --- /dev/null +++ b/tests/Design_Example_1.1.1.2.1.osi @@ -0,0 +1 @@ +{"Load": {"ShearForce (kN)": "120"}, "Plate": {"Width (mm)": "", "Height (mm)": "", "Thickness (mm)": "8"}, "Weld": {"Size (mm)": "8"}, "detailing": {"typeof_edge": "a - Sheared or hand flame cut", "is_env_corrosive": "No", "min_edgend_dist": 1.7, "gap": 10.0}, "Member": {"ColumSection": "PBP 300X180", "fu (MPa)": "410", "BeamSection": "UB 356 x 171 x 45", "fy (MPa)": "250", "Connectivity": "Column web-Beam web"}, "Connection": "Finplate", "design": {"design_method": "Limit State Design"}, "Bolt": {"Grade": "8.8", "Diameter (mm)": "16", "Type": "Friction Grip Bolt"}, "weld": {"typeof_weld": "Field weld", "fu_overwrite": "410", "safety_factor": 1.5}, "bolt": {"bolt_hole_clrnce": 2, "slip_factor": 0.25, "bolt_fu": 800, "bolt_hole_type": "Standard"}} \ No newline at end of file diff --git a/tests/Design_Example_1.1.1.2.2.osi b/tests/Design_Example_1.1.1.2.2.osi new file mode 100644 index 000000000..c5d830d7b --- /dev/null +++ b/tests/Design_Example_1.1.1.2.2.osi @@ -0,0 +1 @@ +{"Load": {"ShearForce (kN)": "135"}, "Plate": {"Width (mm)": "", "Height (mm)": "", "Thickness (mm)": "10"}, "Weld": {"Size (mm)": "8"}, "detailing": {"typeof_edge": "a - Sheared or hand flame cut", "is_env_corrosive": "Yes", "min_edgend_dist": 1.7, "gap": 10.0}, "Member": {"ColumSection": "SC 250", "fu (MPa)": "410", "BeamSection": "LB 300", "fy (MPa)": "250", "Connectivity": "Column web-Beam web"}, "Connection": "Finplate", "design": {"design_method": "Limit State Design"}, "Bolt": {"Grade": "4.8", "Diameter (mm)": "24", "Type": "Bearing Bolt"}, "weld": {"typeof_weld": "Shop weld", "fu_overwrite": "410", "safety_factor": 1.25}, "bolt": {"bolt_hole_clrnce": 2, "slip_factor": 0.25, "bolt_fu": 420, "bolt_hole_type": "Standard"}} diff --git a/tests/Design_Example_1.1.1.3.1.osi b/tests/Design_Example_1.1.1.3.1.osi new file mode 100644 index 000000000..00bbb4736 --- /dev/null +++ b/tests/Design_Example_1.1.1.3.1.osi @@ -0,0 +1 @@ +{"Load": {"ShearForce (kN)": "110"}, "Plate": {"Width (mm)": "", "Height (mm)": "", "Thickness (mm)": "10"}, "Weld": {"Size (mm)": "8"}, "detailing": {"typeof_edge": "b - Rolled, machine-flame cut, sawn and planed", "is_env_corrosive": "No", "min_edgend_dist": 1.5, "gap": 10.0}, "Member": {"ColumSection": "MB 350", "fu (MPa)": "410", "BeamSection": "NPB 270x135x36.1", "fy (MPa)": "250", "Connectivity": "Beam-Beam"}, "Connection": "Finplate", "design": {"design_method": "Limit State Design"}, "Bolt": {"Grade": "10.9", "Diameter (mm)": "20", "Type": "Friction Grip Bolt"}, "weld": {"typeof_weld": "Shop weld", "fu_overwrite": "410", "safety_factor": 1.25}, "bolt": {"bolt_hole_clrnce": 4, "slip_factor": 0.52, "bolt_fu": 1040, "bolt_hole_type": "Over-sized"}} \ No newline at end of file diff --git a/tests/Design_Example_1.1.1.3.2.osi b/tests/Design_Example_1.1.1.3.2.osi new file mode 100644 index 000000000..62e143ba4 --- /dev/null +++ b/tests/Design_Example_1.1.1.3.2.osi @@ -0,0 +1 @@ +{"Load": {"ShearForce (kN)": "220"}, "Plate": {"Width (mm)": "", "Height (mm)": "", "Thickness (mm)": "14"}, "Weld": {"Size (mm)": "10"}, "detailing": {"typeof_edge": "b - Rolled, machine-flame cut, sawn and planed", "is_env_corrosive": "No", "min_edgend_dist": 1.5, "gap": 10.0}, "Member": {"ColumSection": "WPB 450x300x99.7", "fu (MPa)": "410", "BeamSection": "UB 356 x 171 x 67", "fy (MPa)": "250", "Connectivity": "Beam-Beam"}, "Connection": "Finplate", "design": {"design_method": "Limit State Design"}, "Bolt": {"Grade": "10.9", "Diameter (mm)": "24", "Type": "Friction Grip Bolt"}, "weld": {"typeof_weld": "Shop weld", "fu_overwrite": "410", "safety_factor": 1.25}, "bolt": {"bolt_hole_clrnce": 2, "slip_factor": 0.48, "bolt_fu": 1040, "bolt_hole_type": "Standard"}} diff --git a/tests/Design_Example_1.1.3.1.2.osi b/tests/Design_Example_1.1.3.1.2.osi new file mode 100644 index 000000000..4c8d0239e --- /dev/null +++ b/tests/Design_Example_1.1.3.1.2.osi @@ -0,0 +1 @@ +{"Load": {"ShearForce (kN)": "170"}, "weld": {"typeof_weld": "Shop weld", "safety_factor": 1.25}, "detailing": {"typeof_edge": "b - Rolled, machine-flame cut, sawn and planed", "is_env_corrosive": "Yes", "min_edgend_dist": 1.5, "gap": 10.0}, "cleat": {"section": "100 100x 12", "Height (mm)": ""}, "Member": {"ColumSection": "HB 300", "fu (MPa)": "410", "BeamSection": "MB 350", "fy (MPa)": "250", "Connectivity": "Column flange-Beam web"}, "Connection": "cleatAngle", "design": {"design_method": "Limit State Design"}, "Bolt": {"Grade": "4.6", "Diameter (mm)": "16", "Type": "Bearing Bolt"}, "bolt": {"bolt_hole_clrnce": 2, "slip_factor": 0.3, "bolt_fu": 800, "bolt_hole_type": "Standard"}} \ No newline at end of file diff --git a/tests/Modified_Example.osi b/tests/Modified_Example.osi new file mode 100644 index 000000000..eb3feb349 --- /dev/null +++ b/tests/Modified_Example.osi @@ -0,0 +1,43 @@ +Bolt.Bolt_Hole_Type: Standard +Bold.Diameter: +- '12' +- '16' +- '20' +- '24' +- '30' +Bolt.Grad: +- '4.6' +- '4.8' +- '5.6' +- '6.8' +- '8.8' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pre-tensioned +Bolt.Type: 12345 +Connectivity: Column Flange-Beam Web +Connector.Material: E350_Fe490 +Connector.Plate.Thickness_List: +- '10' +- '12' +- '16' +- '18' +- '20' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Rolled, machine-flame cut, sawn and planed +Detailing.Gap: '15' +Load.Axial: '50' +Load.Shear: '180' +Material: E 250 (Fe 410 W)A +Member.Supported_Section.Designation: MB 350 +Member.Supported_Section.Material: E 250 (Fe 410 W)A +Member.Supporting_Section.Designation: HB 450 +Member.Supporting_Section.Material: E 250 (Fe 410 W)A +Module: Fin Plate Connection +Weld.Fab: Shop Weld +Weld.Material_Grade_OverWrite: '410' +out_titles_status: +- 1 +- 1 +- 1 +- 1 diff --git a/tests/Modified_Example2.osi b/tests/Modified_Example2.osi new file mode 100644 index 000000000..01e4c5789 --- /dev/null +++ b/tests/Modified_Example2.osi @@ -0,0 +1,43 @@ +Bolt.Bolt_Hole_Type: Standrd # Misspelled 'Standard' +Blt.Diameter: # Misspelled 'Bolt' +- '12' +- '16' +- '20' +- '24' +- '30' +Bolt.Grad: +- '4.6' +- '4.8' +- '5.6' +- '6.8' +- '8.8' +Bolt.Slip_Factor: 'xyz' # Invalid value (should be numeric) +Bolt.TensionType: Pretensoned # Misspelled 'Pre-tensioned' +Bolt.Type: WrongType # Invalid type +Connectivity: Column Flange-Beam Web +Connector.Material: E350_Fe490 +Connector.Plate.Thickness_List: +- '10' +- '12' +- '16' +- '18' +- '20' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'Maybe' # Should be 'Yes' or 'No' +Detailing.Edge_type: Rlld, machne-flame cut, sawn and planed # Misspelled words +Detailing.Gap: 'XYZ' # Invalid numeric value +Load.Axial: 'NaN' # Should be a valid number +Load.Shear: '-180' # Negative value (may not be allowed) +Material: E 250 (Fe 410 W)B # Incorrect material type +Member.Supported_Section.Designation: MB 350 +Member.Supported_Section.Material: E 250 (Fe 410 W)A +Member.Supporting_Section.Designation: HB 450 +Member.Supporting_Section.Material: E 250 (Fe 410 W)A +Modle: Fin Plate Connection # Misspelled 'Module' +Weld.Fab: Shop-Weld # Extra hyphen (inconsistent format) +Weld.Material_Grade_OverWrite: 'XYZ' # Invalid grade +out_titles_status: +- 1 +- 1 +- 1 +- 1 diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 000000000..6ad0e14e7 --- /dev/null +++ b/tests/README.md @@ -0,0 +1 @@ +These OSI files are used for validating automation scripts under testing. diff --git a/tests/TensionBoltedTest1.osi b/tests/TensionBoltedTest1.osi new file mode 100644 index 000000000..4af43b27d --- /dev/null +++ b/tests/TensionBoltedTest1.osi @@ -0,0 +1,75 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Long Leg +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '60' +Material: E 250 (Fe 410 W)A +Member.Designation: +- 40 x 20 x 3 +Member.Length: '1250' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Back to Back Angles +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 diff --git a/tests/TensionBoltedTest2.osi b/tests/TensionBoltedTest2.osi new file mode 100644 index 000000000..ccb7fdeec --- /dev/null +++ b/tests/TensionBoltedTest2.osi @@ -0,0 +1,128 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '12' +- '16' +- '20' +- '24' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Friction Grip Bolt +Conn_Location: Web +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '100' +Material: E 250 (Fe 410 W)A +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 150 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1000' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Channels +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 + + diff --git a/tests/TensionBoltedTest3.osi b/tests/TensionBoltedTest3.osi new file mode 100644 index 000000000..0349a2305 --- /dev/null +++ b/tests/TensionBoltedTest3.osi @@ -0,0 +1,273 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Short Leg +Connector.Material: E 165 (Fe 290) +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '28' +Material: E 165 (Fe 290) +Member.Designation: +- 20 x 20 x 3 +- 20 x 20 x 4 +- 25 x 25 x 3 +- 25 x 25 x 4 +- 25 x 25 x 5 +- 30 x 30 x 3 +- 30 x 30 x 4 +- 30 x 30 x 5 +- 35 x 35 x 3 +- 35 x 35 x 4 +- 35 x 35 x 5 +- 35 x 35 x 6 +- 40 x 40 x 3 +- 40 x 40 x 4 +- 40 x 40 x 5 +- 40 x 40 x 6 +- 45 x 45 x 3 +- 45 x 45 x 4 +- 45 x 45 x 5 +- 45 x 45 x 6 +- 50 x 50 x 3 +- 50 x 50 x 4 +- 50 x 50 x 5 +- 50 x 50 x 6 +- 55 x 55 x 4 +- 55 x 55 x 5 +- 55 x 55 x 6 +- 55 x 55 x 8 +- 60 x 60 x 4 +- 60 x 60 x 5 +- 60 x 60 x 6 +- 60 x 60 x 8 +- 65 x 65 x 4 +- 65 x 65 x 5 +- 65 x 65 x 6 +- 65 x 65 x 8 +- 70 x 70 x 5 +- 70 x 70 x 6 +- 70 x 70 x 8 +- 70 x 70 x 10 +- 75 x 75 x 5 +- 75 x 75 x 6 +- 75 x 75 x 8 +- 75 x 75 x 10 +- 80 x 80 x 6 +- 80 x 80 x 8 +- 80 x 80 x 10 +- 80 x 80 x 12 +- 90 x 90 x 6 +- 90 x 90 x 8 +- 90 x 90 x 10 +- 90 x 90 x 12 +- 100 x 100 x 6 +- 100 x 100 x 8 +- 100 x 100 x 10 +- 100 x 100 x 12 +- 110 x 110 x 8 +- 110 x 110 x 10 +- 110 x 110 x 12 +- 110 x 110 x 16 +- 130 x 130 x 8 +- 130 x130 x 10 +- 130 x130 x 12 +- 130 x130 x 16 +- 150 x 150 x 10 +- 150 x 150 x 12 +- 150 x 150 x 16 +- 150 x 150 x 20 +- 200 x 200 x 12 +- 200 x 200 x 16 +- 200 x 200 x 20 +- 200 x 200 x 25 +- 50 x 50 x 7 +- 50 x 50 x 8 +- 55 x 55 x 10 +- 60 x 60 x 10 +- 65 x 65 x 10 +- 70 x 70 x 7 +- 100 x 100 x 7 +- 100 x 100 x 15 +- 120 x 120 x 8 +- 120 x 120 x 10 +- 120 x 120 x 12 +- 120 x 120 x 15 +- 130 x 130 x 9 +- 150 x 150 x 15 +- 150 x 150 x 18 +- 180 x 180 x 15 +- 180 x 180 x 18 +- 180 x 180 x 20 +- 200 x 200 x 24 +- 30 x 20 x 3 +- 30 x 20 x 4 +- 30 x 20 x 5 +- 40 x 25 x 3 +- 40 x 25 x 4 +- 40 x 25 x 5 +- 40 x 25 x 6 +- 45 x 30 x 3 +- 45 x 30 x 4 +- 45 x 30 x 5 +- 45 x 30 x 6 +- 50 x 30 x 3 +- 50 x 30 x 4 +- 50 x 30 x 5 +- 50 x 30 x 6 +- 60 x 40 x 5 +- 60 x 40 x 6 +- 60 x 40 x 8 +- 65 x 45 x 5 +- 65 x 45 x 6 +- 65 x 45 x 8 +- 70 x 45 x 5 +- 70 x 45 x 6 +- 70 x 45 x 8 +- 70 x 45 x 10 +- 75 x 50 x 5 +- 75 x 50 x 6 +- 75 x 50 x 8 +- 75 x 50 x 10 +- 80 x 50 x 5 +- 80 x 50 x 6 +- 80 x 50 x 8 +- 80 x 50 x 10 +- 90 x 60 x 6 +- 90 x 60 x 8 +- 90 x 60 x 10 +- 90 x 60 x 12 +- 100 x 65 x 6 +- 100 x 65 x 8 +- 100 x 65 x 10 +- 100 x 75 x 6 +- 100 x 75 x 8 +- 100 x 75 x 10 +- 100 x 75 x 12 +- 125 x 75 x 6 +- 125 x 75 x 8 +- 125 x 75 x 10 +- 125 x 95 x 6 +- 125 x 95 x 8 +- 125 x 95 x 10 +- 125 x 95 x 12 +- 150 x 115 x 8 +- 150 x 115 x 10 +- 150 x 115 x 12 +- 150 x 115 x 16 +- 200 x 100 x 10 +- 200 x 100 x 12 +- 200 x 100 x 16 +- 200 x 150 x 10 +- 200 x 150 x 12 +- 200 x 150 x 16 +- 200 x 150 x 20 +- 40 x 20 x 3 +- 40 x 20 x 4 +- 40 x 20 x 5 +- 60 x 30 x 5 +- 60 x 30 x 6 +- 60 x 40 x 7 +- 65 x 50 x 5 +- 65 x 50 x 6 +- 65 x 50 x 7 +- 65 x 50 x 8 +- 70 x 50 x 5 +- 70 x 50 x 6 +- 70 x 50 x 7 +- 70 x 50 x 8 +- 75 x 50 x 7 +- 80 x 40 x 5 +- 80 x 40 x 6 +- 80 x 40 x 7 +- 80 x 40 x 8 +- 80 x 60 x 6 +- 80 x 60 x 7 +- 80 x 60 x 8 +- 90 x 65 x 6 +- 90 x 65 x 7 +- 90 x 65 x 8 +- 90 x 65 x 10 +- 100 x 50 x 6 +- 100 x 50 x 7 +- 100 x 50 x 8 +- 100 x 50 x 10 +- 100 x 65 x 7 +- 120 x 80 x 8 +- 120 x 80 x 10 +- 120 x 80 x 12 +- 125 x 75 x 12 +- 135 x 65 x 8 +- 135 x 65 x 10 +- 135 x 65 x 12 +- 150 x 75 x 9 +- 150 x 75 x 15 +- 150 x 90 x 10 +- 150 x 90 x 12 +- 150 x 90 x 15 +- 200 x 100 x 15 +- 200 x 150 x 15 +- 200 x 150 x 18 +Member.Length: '900' +Member.Material: E 165 (Fe 290) +Member.Profile: Angles +Module: Tension Member Design - Bolted to End Gusset diff --git a/tests/TensionBoltedTest4.osi b/tests/TensionBoltedTest4.osi new file mode 100644 index 000000000..3f77bee12 --- /dev/null +++ b/tests/TensionBoltedTest4.osi @@ -0,0 +1,86 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '20' +- '24' +Bolt.Grade: +- '5.6' +- '6.8' +- '9.8' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Web +Connector.Material: E 350 (Fe 490) +Connector.Plate.Thickness_List: +- '8' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '300' +Material: E 350 (Fe 490) +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1500' +Member.Material: E 350 (Fe 490) +Member.Profile: Back to Back Channels +Module: Tension Member Design - Bolted to End Gusset diff --git a/tests/osi_files/TensionBoltedTest1.osi b/tests/osi_files/TensionBoltedTest1.osi new file mode 100644 index 000000000..4af43b27d --- /dev/null +++ b/tests/osi_files/TensionBoltedTest1.osi @@ -0,0 +1,75 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Long Leg +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '60' +Material: E 250 (Fe 410 W)A +Member.Designation: +- 40 x 20 x 3 +Member.Length: '1250' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Back to Back Angles +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 diff --git a/tests/osi_files/TensionBoltedTest2.osi b/tests/osi_files/TensionBoltedTest2.osi new file mode 100644 index 000000000..ccb7fdeec --- /dev/null +++ b/tests/osi_files/TensionBoltedTest2.osi @@ -0,0 +1,128 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '12' +- '16' +- '20' +- '24' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Friction Grip Bolt +Conn_Location: Web +Connector.Material: E 250 (Fe 410 W)A +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '100' +Material: E 250 (Fe 410 W)A +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 150 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1000' +Member.Material: E 250 (Fe 410 W)A +Member.Profile: Channels +Module: Tension Member Design - Bolted to End Gusset +out_titles_status: +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 +- 1 + + diff --git a/tests/osi_files/TensionBoltedTest3.osi b/tests/osi_files/TensionBoltedTest3.osi new file mode 100644 index 000000000..0349a2305 --- /dev/null +++ b/tests/osi_files/TensionBoltedTest3.osi @@ -0,0 +1,273 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '8' +- '10' +- '12' +- '16' +- '20' +- '24' +- '30' +- '36' +- '42' +- '48' +- '56' +- '64' +- '14' +- '18' +- '22' +- '27' +- '33' +- '39' +- '45' +- '52' +- '60' +Bolt.Grade: +- '3.6' +- '4.6' +- '4.8' +- '5.6' +- '5.8' +- '6.8' +- '8.8' +- '9.8' +- '10.9' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Short Leg +Connector.Material: E 165 (Fe 290) +Connector.Plate.Thickness_List: +- '8' +- '10' +- '12' +- '14' +- '16' +- '18' +- '20' +- '22' +- '25' +- '28' +- '32' +- '36' +- '40' +- '45' +- '50' +- '56' +- '63' +- '75' +- '80' +- '90' +- '100' +- '110' +- '120' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '28' +Material: E 165 (Fe 290) +Member.Designation: +- 20 x 20 x 3 +- 20 x 20 x 4 +- 25 x 25 x 3 +- 25 x 25 x 4 +- 25 x 25 x 5 +- 30 x 30 x 3 +- 30 x 30 x 4 +- 30 x 30 x 5 +- 35 x 35 x 3 +- 35 x 35 x 4 +- 35 x 35 x 5 +- 35 x 35 x 6 +- 40 x 40 x 3 +- 40 x 40 x 4 +- 40 x 40 x 5 +- 40 x 40 x 6 +- 45 x 45 x 3 +- 45 x 45 x 4 +- 45 x 45 x 5 +- 45 x 45 x 6 +- 50 x 50 x 3 +- 50 x 50 x 4 +- 50 x 50 x 5 +- 50 x 50 x 6 +- 55 x 55 x 4 +- 55 x 55 x 5 +- 55 x 55 x 6 +- 55 x 55 x 8 +- 60 x 60 x 4 +- 60 x 60 x 5 +- 60 x 60 x 6 +- 60 x 60 x 8 +- 65 x 65 x 4 +- 65 x 65 x 5 +- 65 x 65 x 6 +- 65 x 65 x 8 +- 70 x 70 x 5 +- 70 x 70 x 6 +- 70 x 70 x 8 +- 70 x 70 x 10 +- 75 x 75 x 5 +- 75 x 75 x 6 +- 75 x 75 x 8 +- 75 x 75 x 10 +- 80 x 80 x 6 +- 80 x 80 x 8 +- 80 x 80 x 10 +- 80 x 80 x 12 +- 90 x 90 x 6 +- 90 x 90 x 8 +- 90 x 90 x 10 +- 90 x 90 x 12 +- 100 x 100 x 6 +- 100 x 100 x 8 +- 100 x 100 x 10 +- 100 x 100 x 12 +- 110 x 110 x 8 +- 110 x 110 x 10 +- 110 x 110 x 12 +- 110 x 110 x 16 +- 130 x 130 x 8 +- 130 x130 x 10 +- 130 x130 x 12 +- 130 x130 x 16 +- 150 x 150 x 10 +- 150 x 150 x 12 +- 150 x 150 x 16 +- 150 x 150 x 20 +- 200 x 200 x 12 +- 200 x 200 x 16 +- 200 x 200 x 20 +- 200 x 200 x 25 +- 50 x 50 x 7 +- 50 x 50 x 8 +- 55 x 55 x 10 +- 60 x 60 x 10 +- 65 x 65 x 10 +- 70 x 70 x 7 +- 100 x 100 x 7 +- 100 x 100 x 15 +- 120 x 120 x 8 +- 120 x 120 x 10 +- 120 x 120 x 12 +- 120 x 120 x 15 +- 130 x 130 x 9 +- 150 x 150 x 15 +- 150 x 150 x 18 +- 180 x 180 x 15 +- 180 x 180 x 18 +- 180 x 180 x 20 +- 200 x 200 x 24 +- 30 x 20 x 3 +- 30 x 20 x 4 +- 30 x 20 x 5 +- 40 x 25 x 3 +- 40 x 25 x 4 +- 40 x 25 x 5 +- 40 x 25 x 6 +- 45 x 30 x 3 +- 45 x 30 x 4 +- 45 x 30 x 5 +- 45 x 30 x 6 +- 50 x 30 x 3 +- 50 x 30 x 4 +- 50 x 30 x 5 +- 50 x 30 x 6 +- 60 x 40 x 5 +- 60 x 40 x 6 +- 60 x 40 x 8 +- 65 x 45 x 5 +- 65 x 45 x 6 +- 65 x 45 x 8 +- 70 x 45 x 5 +- 70 x 45 x 6 +- 70 x 45 x 8 +- 70 x 45 x 10 +- 75 x 50 x 5 +- 75 x 50 x 6 +- 75 x 50 x 8 +- 75 x 50 x 10 +- 80 x 50 x 5 +- 80 x 50 x 6 +- 80 x 50 x 8 +- 80 x 50 x 10 +- 90 x 60 x 6 +- 90 x 60 x 8 +- 90 x 60 x 10 +- 90 x 60 x 12 +- 100 x 65 x 6 +- 100 x 65 x 8 +- 100 x 65 x 10 +- 100 x 75 x 6 +- 100 x 75 x 8 +- 100 x 75 x 10 +- 100 x 75 x 12 +- 125 x 75 x 6 +- 125 x 75 x 8 +- 125 x 75 x 10 +- 125 x 95 x 6 +- 125 x 95 x 8 +- 125 x 95 x 10 +- 125 x 95 x 12 +- 150 x 115 x 8 +- 150 x 115 x 10 +- 150 x 115 x 12 +- 150 x 115 x 16 +- 200 x 100 x 10 +- 200 x 100 x 12 +- 200 x 100 x 16 +- 200 x 150 x 10 +- 200 x 150 x 12 +- 200 x 150 x 16 +- 200 x 150 x 20 +- 40 x 20 x 3 +- 40 x 20 x 4 +- 40 x 20 x 5 +- 60 x 30 x 5 +- 60 x 30 x 6 +- 60 x 40 x 7 +- 65 x 50 x 5 +- 65 x 50 x 6 +- 65 x 50 x 7 +- 65 x 50 x 8 +- 70 x 50 x 5 +- 70 x 50 x 6 +- 70 x 50 x 7 +- 70 x 50 x 8 +- 75 x 50 x 7 +- 80 x 40 x 5 +- 80 x 40 x 6 +- 80 x 40 x 7 +- 80 x 40 x 8 +- 80 x 60 x 6 +- 80 x 60 x 7 +- 80 x 60 x 8 +- 90 x 65 x 6 +- 90 x 65 x 7 +- 90 x 65 x 8 +- 90 x 65 x 10 +- 100 x 50 x 6 +- 100 x 50 x 7 +- 100 x 50 x 8 +- 100 x 50 x 10 +- 100 x 65 x 7 +- 120 x 80 x 8 +- 120 x 80 x 10 +- 120 x 80 x 12 +- 125 x 75 x 12 +- 135 x 65 x 8 +- 135 x 65 x 10 +- 135 x 65 x 12 +- 150 x 75 x 9 +- 150 x 75 x 15 +- 150 x 90 x 10 +- 150 x 90 x 12 +- 150 x 90 x 15 +- 200 x 100 x 15 +- 200 x 150 x 15 +- 200 x 150 x 18 +Member.Length: '900' +Member.Material: E 165 (Fe 290) +Member.Profile: Angles +Module: Tension Member Design - Bolted to End Gusset diff --git a/tests/osi_files/TensionBoltedTest4.osi b/tests/osi_files/TensionBoltedTest4.osi new file mode 100644 index 000000000..3f77bee12 --- /dev/null +++ b/tests/osi_files/TensionBoltedTest4.osi @@ -0,0 +1,86 @@ +Bolt.Bolt_Hole_Type: Standard +Bolt.Diameter: +- '20' +- '24' +Bolt.Grade: +- '5.6' +- '6.8' +- '9.8' +- '12.9' +Bolt.Slip_Factor: '0.3' +Bolt.TensionType: Pretensioned +Bolt.Type: Bearing Bolt +Conn_Location: Web +Connector.Material: E 350 (Fe 490) +Connector.Plate.Thickness_List: +- '8' +Design.Design_Method: Limit State Design +Detailing.Corrosive_Influences: 'No' +Detailing.Edge_type: Sheared or hand flame cut +Detailing.Gap: '0' +Load.Axial: '300' +Material: E 350 (Fe 490) +Member.Designation: +- MC 75 +- MC 100 +- MC 125 +- MC 125* +- MC 150 +- MC 150* +- MC 175 +- MC 175* +- MC 200 +- MC 200* +- MC 225 +- MC 225* +- MC 250 +- MC 250* +- MC 250* +- MC 300 +- MC 300* +- MC 300* +- MC 350 +- MC 400 +- JC 100 +- JC 125 +- JC 175 +- JC 200 +- LC 75 +- LC 100 +- LC 125 +- LC (P) 125 +- LC 150 +- LC (P) 150 +- LC 175 +- LC 200 +- LC (P) 200 +- LC 225 +- LC 250 +- LC 300 +- LC (P) 300 +- LC 350 +- LC 400 +- MPC 75 +- MPC 100 +- MPC 125 +- MPC 125* +- MPC 150 +- MPC 150* +- MPC 175 +- MPC 175* +- MPC 200 +- MPC 200* +- MPC 225 +- MPC 225* +- MPC 250 +- MPC 250* +- MPC 250* +- MPC 300 +- MPC 300* +- MPC 300* +- MPC 350 +- MPC 400 +Member.Length: '1500' +Member.Material: E 350 (Fe 490) +Member.Profile: Back to Back Channels +Module: Tension Member Design - Bolted to End Gusset diff --git a/tests/run_osdag.bat b/tests/run_osdag.bat new file mode 100644 index 000000000..7502c5ba1 --- /dev/null +++ b/tests/run_osdag.bat @@ -0,0 +1,27 @@ +@echo off +setlocal + +REM Define error log file +set ERROR_LOG="error_log.txt" + +REM Clear previous error log +if exist %ERROR_LOG% del %ERROR_LOG% + +echo Running OSI file validation... +python validate_osi.py >> %ERROR_LOG% 2>&1 + +REM Process each OSI file separately +for %%F in (*.osi) do ( + findstr /C:"ERRORS FOUND IN OSI FILE: %%~nF" %ERROR_LOG% > nul + if errorlevel 1 ( + echo %%~nF - No errors, test completed successfully + ) else ( + echo %%~nF - Contains errors, check error_log for details. Test passed successfully + ) +) + +echo Running Pytest for validation tests... +pytest test_validate_osi.py >> %ERROR_LOG% 2>&1 + +echo Validation completed. Check error_log.txt for details. +pause >nul diff --git a/tests/run_validator.bat b/tests/run_validator.bat new file mode 100644 index 000000000..1e9ac5a44 --- /dev/null +++ b/tests/run_validator.bat @@ -0,0 +1,4 @@ +@echo off +echo Running OSI File Validator... +python validator.py +pause diff --git a/tests/test_dummy.py b/tests/test_dummy.py new file mode 100644 index 000000000..92c4bf30a --- /dev/null +++ b/tests/test_dummy.py @@ -0,0 +1,7 @@ + +def test_addition(): + assert 1 + 1 == 2 + +# tests/test_dummy.py +def test_dummy(): + assert 1 + 1 == 2 diff --git a/tests/test_validator.py b/tests/test_validator.py new file mode 100644 index 000000000..353309a09 --- /dev/null +++ b/tests/test_validator.py @@ -0,0 +1,55 @@ +import os +import pytest +import validator # Assuming your validator.py is in the same directory + +# Helper function to run tests +def run_test(file_name, expected_result): + file_path = os.path.join("osi_files", file_name) + result = validator.validate_osi(file_path) + print(f"Testing {file_name}") + + for key in expected_result: + assert result[key] == expected_result[key], f"{key} failed: expected {expected_result[key]}, got {result[key]}" + print("✅ Passed\n") + +# Test function 1 +def test_tension_bolted_test1(): + expected_result = { + "Member.Designation": "Pass", + "Bolt.Grade": "Pass", + "Bolt.Diameter": "" # Skipped check + } + run_test("TensionBoltedTest1.osi", expected_result) + +# Test function 2 +def test_tension_bolted_test2(): + expected_result = { + "Member.Designation": "Pass", + "Bolt.Grade": "Pass", + "Bolt.Diameter": "Pass" + } + run_test("TensionBoltedTest2.osi", expected_result) + +# Test function 3 +def test_tension_bolted_test3(): + expected_result = { + "Member.Designation": "Pass", + "Bolt.Grade": "Pass", + "Bolt.Diameter": "Pass" + } + run_test("TensionBoltedTest3.osi", expected_result) + +# Test function 4 +@pytest.mark.xfail +def test_tension_bolted_test4(): + expected_result = { + "Member.Designation": "Pass", + "Bolt.Grade": "Pass", + "Bolt.Diameter": "Pass" + } + run_test("TensionBoltedTest4.osi", expected_result) + +if __name__ == "__main__": + pytest.main() + + diff --git a/tests/validate_osi.py b/tests/validate_osi.py new file mode 100644 index 000000000..91a5c6b51 --- /dev/null +++ b/tests/validate_osi.py @@ -0,0 +1,110 @@ +import yaml +import os + +VALID_VALUES = { + "Bolt.Bolt_Hole_Type": ["Standard", "Oversized", "Slotted"], + "Bolt.TensionType": ["Pre-tensioned", "Non-pre-tensioned"], + "Detailing.Corrosive_Influences": ["Yes", "No"], + "Design.Method": ["Limit State Design", "Working Stress Design"], +} + +MISSPELLED_KEYS = { + "Blt.Diameter": "Bolt.Diameter", + "Modle": "Module", + "Standrd": "Standard", + "Pretensoned": "Pre-tensioned", + "Maybe": "Yes/No", +} + +NUMERIC_KEYS = { + "Detailing.Gap": (0, 50), + "Load.Axial": (0, 1000), + "Load.Shear": (0, 500), +} + +def validate_osi_files(): + files = [f for f in os.listdir() if f.endswith(".osi")] + + if not files: + print("No OSI files found in the directory.") + return + + print(f"Found {len(files)} OSI file(s). Starting validation...\n") + + for file in files: + validate_osi_file(file) + +def validate_osi_file(filename): + errors = {"Misspelled Keys": [], "Invalid Values": [], "Invalid Numeric Values": []} + + try: + with open(filename, "r", encoding="utf-8") as file: + data = yaml.safe_load(file) + + if not data: + print(f"\n ERROR: Empty or Corrupted OSI File: {filename}") + return + + check_misspelled_keys(data, errors) + check_invalid_values(data, errors) + check_numeric_values(data, errors) + + if any(errors.values()): + print(f"\n ERRORS FOUND IN OSI FILE: {filename}") + for category, issues in errors.items(): + if issues: + print(f"\n {category}:") + for issue in issues: + print(f" - {issue}") + print("\n Fix the above errors and try again.") + else: + print(f"\n OSI file validation successful for: {filename}") + + except yaml.YAMLError as e: + print(f"\n YAML Parsing Error in {filename}: {e}") + except Exception as e: + print(f"\n Unexpected Error in {filename}: {e}") + +def check_misspelled_keys(data, errors): + def recursive_check(d, parent_key=""): + if isinstance(d, dict): + for key in list(d.keys()): + full_key = f"{parent_key}.{key}" if parent_key else key + if key in MISSPELLED_KEYS: + corrected_key = MISSPELLED_KEYS[key] + errors["Misspelled Keys"].append(f"{full_key} -> {corrected_key}") + recursive_check(d[key], full_key) + + recursive_check(data) + +def check_invalid_values(data, errors): + def recursive_check(d, parent_key=""): + if isinstance(d, dict): + for key, value in d.items(): + full_key = f"{parent_key}.{key}" if parent_key else key + if full_key in VALID_VALUES: + if value not in VALID_VALUES[full_key]: + errors["Invalid Values"].append(f"{full_key} = '{value}' (Expected: {VALID_VALUES[full_key]})") + recursive_check(value, full_key) + + recursive_check(data) + +def check_numeric_values(data, errors): + def recursive_check(d, parent_key=""): + if isinstance(d, dict): + for key, value in d.items(): + full_key = f"{parent_key}.{key}" if parent_key else key + if full_key in NUMERIC_KEYS: + min_val, max_val = NUMERIC_KEYS[full_key] + if not isinstance(value, (int, float)): + errors["Invalid Numeric Values"].append(f"{full_key} = '{value}' (Expected: Numeric value)") + elif not (min_val <= value <= max_val): + errors["Invalid Numeric Values"].append( + f"{full_key} = {value} (Out of range: {min_val} to {max_val})" + ) + recursive_check(value, full_key) + + recursive_check(data) + +if __name__ == "__main__": + validate_osi_files() diff --git a/tests/validator.py b/tests/validator.py new file mode 100644 index 000000000..d8c41916d --- /dev/null +++ b/tests/validator.py @@ -0,0 +1,80 @@ +import os + +#Valid entries per file +valid_designations = { + "TensionBoltedTest1": ["40 x 20 x 3"], + "TensionBoltedTest2": ["JC 100"], + "TensionBoltedTest3": ["40 x 40 x 3"], + "TensionBoltedTest4": ["JC 175"], +} +valid_bolt_grades = ["3.6", "12.9", "4.6", "5.6"] +valid_bolt_diameters = { + "TensionBoltedTest1": [""], # skip check + "TensionBoltedTest2": ["12"], + "TensionBoltedTest3": ["10"], + "TensionBoltedTest4": ["20"], +} + +def normalize(val): + return val.strip().strip("'").strip('"').lower() + +def extract_multiple_values(file_path): + values = {"Member.Designation": [], "Bolt.Grade": [], "Bolt.Diameter": []} + with open(file_path, "r") as f: + current_key = None + for line in f: + line = line.strip() + if ":" in line: + key, _ = line.split(":", 1) + current_key = key.strip() + if current_key in values: + values[current_key] = [] + elif current_key and current_key in values and line.startswith("-"): + values[current_key].append(line.strip("- ").strip()) + return values + +def validate_osi(file_path): + filename = os.path.splitext(os.path.basename(file_path))[0] + data = extract_multiple_values(file_path) + + normalized_data = { + "Member.Designation": [normalize(d) for d in data["Member.Designation"]], + "Bolt.Grade": [normalize(g) for g in data["Bolt.Grade"]], + "Bolt.Diameter": [normalize(d) for d in data["Bolt.Diameter"]], + } + + # Get file-specific valid bolt diameters + bolt_dia_check = valid_bolt_diameters.get(filename, []) + bolt_dia_check_normalized = [normalize(val) for val in bolt_dia_check if normalize(val) != ""] + + results = {} + + # Check Member.Designation + valid_desig = [normalize(val) for val in valid_designations.get(filename, [])] + results["Member.Designation"] = "Pass" if any(d in valid_desig for d in normalized_data["Member.Designation"]) else "Fail" + + # Check Bolt.Grade + valid_grades = [normalize(val) for val in valid_bolt_grades] + results["Bolt.Grade"] = "Pass" if any(g in valid_grades for g in normalized_data["Bolt.Grade"]) else "Fail" + + # Check Bolt.Diameter + if not bolt_dia_check or "" in bolt_dia_check: + results["Bolt.Diameter"] = "" # Leave blank + else: + results["Bolt.Diameter"] = ( + "Pass" if any(d in bolt_dia_check_normalized for d in normalized_data["Bolt.Diameter"]) else "Fail" + ) + + return results + +#Run validator +folder_path = "./osi_files" +print("Running OSI File Validator...\n") +for file in os.listdir(folder_path): + if file.endswith(".osi"): + path = os.path.join(folder_path, file) + result = validate_osi(path) + print(f"Results for {file}:") + for key, status in result.items(): + print(f" {key}: {status}") + print()