├── .gitignore ├── .rspec ├── .rubocop.yml ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Rakefile ├── lib ├── xcresult.rb └── xcresult │ ├── models.rb │ ├── parser.rb │ └── version.rb ├── spec ├── fixtures │ ├── .DS_Store │ └── Test.xcresult │ │ ├── Data │ │ ├── data.0~-fWjWEWCzcI3kbEATPLi73ZRjzFaPceON-c-2yw7WSTUxsm5VWOP9PFcNhFE5DnNOKTg2fpL9tdqdZDsEG4ObA== │ │ ├── data.0~2LVFAe2LWJ7FCnOsKan5UgGk7WChVJYuZlxPILKyxdpmfjsMrwjBJ2wUhaJQJ36Per_GRUfTI1cKeO2QiGvB8Q== │ │ ├── data.0~2fEViB_AHXXtEV42Omd60EKOGf74t700IKvBhXCZpWL3ndppdyTcXPsE54O3l9tNul8fGatXPWv6I-8v9l978A== │ │ ├── data.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== │ │ ├── data.0~7gHa7zyvbiYnQIuODyLD1ukApdh2A0EwOBjrYL1tEcPIhZSAlzLelm23NnBNHwCx5oVGu0IqpIEgA3etA18T6A== │ │ ├── data.0~9M0Qj-xDamLky3tGXmCgU_wx5rjhR1r8tYtaK3c-yB-i4SA-CvV3ItI5_cCQ2tK0EA3PMJjaBwbEFWX_JRxbXQ== │ │ ├── data.0~BrBB-2dagXo2_PtM2FTu-_HIiATuzrVO87XD0QPytFcnVrccCCkAfZgrkY8tSo6YsOD532s8xL201SpFKp_T7Q== │ │ ├── data.0~C1-P2gA8JuyI122raUqhJy68V5bzoHcEvA_youn2viwJ_pROYvVcN9wIswiUzJrINKVPfib6lHEjfFh6jGQBbg== │ │ ├── data.0~CdulzYX7TAIgZKzYi6GAT_wOECoumVWoJhKrUPnBu3EUDWHxYWmnuPptnrykWZfHOb5nhaN_J4ZSH7lDOzsFFg== │ │ ├── data.0~D-Jl7yn8lDlPMEfhM58Omu6yT3Kc2RhOF5Ftz4-Z-6ttHukpVjPI7_yu2J9VbCmX3XcdgfeXzgo8Y97QP42wOA== │ │ ├── data.0~J1CqCYY6tVPP1hyR1Y5QPDCxM2e8qGoXgPJ6yjB64pSb8sagiCpZ0lZBG56CivllcXpHlV9UYrZEVYveSkFihQ== │ │ ├── data.0~LUdKF1UnPtfSu3zwPp58lZBAB3ff_IepvEY6xIJrn21CmFBfSTyJk0gXqq9X5jJyKoZG0kzjJinRz8_zzMbteQ== │ │ ├── data.0~MOLiLjVAm7XOBW-XO5XIaCRjXsEfoFBHd636kaoqJRDZd0MAkKfhT9pJI1NEZL_F7rU1bdXjvNV3vdRi_KPrTQ== │ │ ├── data.0~Mv3qbi23MXIDzPEPgJ9KsTi7ro2YUP8bDbdP3vH1W4EalY5rZerLPEmxf7jQiM2XYZKuBm0-8bQfyAYYNXSVGQ== │ │ ├── data.0~Ns-bzKQx8G36fLzi7rojTuwSmp8ll6sTNBKWHoIGsFwtx78P-7o8OXBT6h-BdyUWppLQ8y2XWq9xANOdcLxM6w== │ │ ├── data.0~OYl0nlXqB-ZHe4aHqwi4KqKpmjPsT1uG9iTB85qRck0MdoX_PuVHoJpsjmRzbENZQKlpIlWWjNLlZK8N8ouRQg== │ │ ├── data.0~Q8sTyAcSG_vQ7QvWvQLAXn6XGWh9PM_OIMsDBFAv0wx1Eqv8jeNCM6LN2jM5ARGnlLugCrMbBsoDR6Jc6EGTrw== │ │ ├── data.0~TE2FhTmJYZ2fpDbV9KOH_GYVYzM8w7I1kG31UQfZSg2zOsFVQ_ILMkKXfD2tGug3gqncLudmXhqVa7agzDoWtw== │ │ ├── data.0~Tb67rfKaWyD6tF7TA9Eig401NC9Txmq2o32ySXFDX5XkQ_UaMsBea6lYolT1EKt1wyeW2Sw04mno5Tj5TAqqWw== │ │ ├── data.0~VY8CqbDqQGlciToyYBfYzPYKuVkzTPQgQIRpSWAdlnlEN1xhUI91vxf8n9bZ4KNrJv-DuV-BK914NGUZGE1vgg== │ │ ├── data.0~WBxsxjslHvapVgvmKeyHG8WwjVBLV8I6q_2RoBB269DBLoDJejrjkNqu2Bt9uud1VMpwo0m6Vp3IEt4i4qI34A== │ │ ├── data.0~XFCwqVKYQEhKveeH-nDRknBOg9_cT9XM8VRSpI9Bqxj1nqnpXX2fX3Pqx-_LUZLFgT4XKDUfCGe1QsSzRYPZ-w== │ │ ├── data.0~Y-LxNPpMhhlXlJMGILjd_s1DuOFlYoWFLz59WGxlMhUSvYAiMhdtZ18iERc8I3TlEmBgRJthjAi40wa-c2YxHw== │ │ ├── data.0~YhpPJjwAaYK49y6xtCTPhXjRd5h67H-_UIC03bX0X9r8duD2jFu93rGZ88WU1Jh4zApifUxA1odQkx2TQeBEow== │ │ ├── data.0~Z1eUZtKuKH4U6Z5CcijzzaTBvbS8_btB4hat3B6VGpFb2M7z22GNRBMaRrnODcI3kcwavyLRPOs_Q-3oSGczRA== │ │ ├── data.0~an-MjwYPv5jGpBO4LOh5e6MfvCwh1oiicTdOxfKguEnBB5RCmqE-bWjWX2hq8WlXv4tWh6NREHXJRzJLv87cSw== │ │ ├── data.0~ca2Nyd-DQTvSubqeVe3fuPpYe2Zhc1sJ38Cn5zWbzecmaSkQHFmscQOlERucFvLJ6iF5JwG9IgIAkwNpfz4g4w== │ │ ├── data.0~cig9aU8wbVYC1FRjSNPQteGAH75x-AzwDjui6xIo0tNAzLCA5Ixi_clkgR4gsbn9b0D0z5iQ2VJ7sZ8XJAqENQ== │ │ ├── data.0~fKDNQVWmg4-bXvTNVQyY9rCWHRMvAzkIP7iFGfkkQcOqINkYsctuvEIqYWi55L7z5AORwoHt3t3WNuo13iSTnQ== │ │ ├── data.0~gci9xFlEq0G4qP789bnD7Gp_YXpUGLSc7bYUjihQJk6fus1sIO1ZAQlwaxlwXkx2_TBEeWA1WegjrWHn-rUN0w== │ │ ├── data.0~jbHx1Hn8RN5tZGPJ9dVIovExaTAeOcS1nJFfioYZTwBQtNoZKp0Kuho1AmV4hNcGRbzFTkrZ2acfx0jgMRA_LQ== │ │ ├── data.0~lD1FMB_PbaosCwmDMM0SltEeOWJl4T4KouTBmxuJC38u1kTi19u4xmkmcUpliaKqo0xhMwTgYQZrgT3J7qBhPA== │ │ ├── data.0~lumBJu_i3Jb05RQxPDi9paJmQhq64l-r1p7LsBLKAUZBaOgeBlB1fuMvLE28kBpa4THoPvGmfj1cc3QfYTYcvg== │ │ ├── data.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA== │ │ ├── data.0~rTfC2vU6ZXnhBsRZZliZJVFQpvn-w7HPCQE_gNlEdiAf5wCkvvSlIIMlyOk73iGjSstM5RNUNSEtNVAPQwR0Yg== │ │ ├── data.0~s_ij9vBr3bcJMMjqQuE5efqmOwB_ncnzJix9goq3iderASwacda-Q24RCgdWsEq4L7dVEPC_UuMJxOu8KAYXqw== │ │ ├── data.0~wp21HLmd5m-UM-XZ_zFAoky6NJEPevfr_pbRfBxddabQ34Tk7HjchlwxyBz7t-JwKAxsXI67jYaPWgX_iV9C5w== │ │ ├── data.0~x887GlUHa8RnHzB4uvJReg0Mb9X2BgP1dNB0uq8vkpSe6Vjq3DtNDTaWHg5i2WNR8AQDsuh8ZBKFB0HS1yCz-w== │ │ ├── refs.0~-fWjWEWCzcI3kbEATPLi73ZRjzFaPceON-c-2yw7WSTUxsm5VWOP9PFcNhFE5DnNOKTg2fpL9tdqdZDsEG4ObA== │ │ ├── refs.0~2LVFAe2LWJ7FCnOsKan5UgGk7WChVJYuZlxPILKyxdpmfjsMrwjBJ2wUhaJQJ36Per_GRUfTI1cKeO2QiGvB8Q== │ │ ├── refs.0~2fEViB_AHXXtEV42Omd60EKOGf74t700IKvBhXCZpWL3ndppdyTcXPsE54O3l9tNul8fGatXPWv6I-8v9l978A== │ │ ├── refs.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== │ │ ├── refs.0~7gHa7zyvbiYnQIuODyLD1ukApdh2A0EwOBjrYL1tEcPIhZSAlzLelm23NnBNHwCx5oVGu0IqpIEgA3etA18T6A== │ │ ├── refs.0~9M0Qj-xDamLky3tGXmCgU_wx5rjhR1r8tYtaK3c-yB-i4SA-CvV3ItI5_cCQ2tK0EA3PMJjaBwbEFWX_JRxbXQ== │ │ ├── refs.0~BrBB-2dagXo2_PtM2FTu-_HIiATuzrVO87XD0QPytFcnVrccCCkAfZgrkY8tSo6YsOD532s8xL201SpFKp_T7Q== │ │ ├── refs.0~C1-P2gA8JuyI122raUqhJy68V5bzoHcEvA_youn2viwJ_pROYvVcN9wIswiUzJrINKVPfib6lHEjfFh6jGQBbg== │ │ ├── refs.0~CdulzYX7TAIgZKzYi6GAT_wOECoumVWoJhKrUPnBu3EUDWHxYWmnuPptnrykWZfHOb5nhaN_J4ZSH7lDOzsFFg== │ │ ├── refs.0~D-Jl7yn8lDlPMEfhM58Omu6yT3Kc2RhOF5Ftz4-Z-6ttHukpVjPI7_yu2J9VbCmX3XcdgfeXzgo8Y97QP42wOA== │ │ ├── refs.0~J1CqCYY6tVPP1hyR1Y5QPDCxM2e8qGoXgPJ6yjB64pSb8sagiCpZ0lZBG56CivllcXpHlV9UYrZEVYveSkFihQ== │ │ ├── refs.0~LUdKF1UnPtfSu3zwPp58lZBAB3ff_IepvEY6xIJrn21CmFBfSTyJk0gXqq9X5jJyKoZG0kzjJinRz8_zzMbteQ== │ │ ├── refs.0~MOLiLjVAm7XOBW-XO5XIaCRjXsEfoFBHd636kaoqJRDZd0MAkKfhT9pJI1NEZL_F7rU1bdXjvNV3vdRi_KPrTQ== │ │ ├── refs.0~Mv3qbi23MXIDzPEPgJ9KsTi7ro2YUP8bDbdP3vH1W4EalY5rZerLPEmxf7jQiM2XYZKuBm0-8bQfyAYYNXSVGQ== │ │ ├── refs.0~Ns-bzKQx8G36fLzi7rojTuwSmp8ll6sTNBKWHoIGsFwtx78P-7o8OXBT6h-BdyUWppLQ8y2XWq9xANOdcLxM6w== │ │ ├── refs.0~OYl0nlXqB-ZHe4aHqwi4KqKpmjPsT1uG9iTB85qRck0MdoX_PuVHoJpsjmRzbENZQKlpIlWWjNLlZK8N8ouRQg== │ │ ├── refs.0~Q8sTyAcSG_vQ7QvWvQLAXn6XGWh9PM_OIMsDBFAv0wx1Eqv8jeNCM6LN2jM5ARGnlLugCrMbBsoDR6Jc6EGTrw== │ │ ├── refs.0~TE2FhTmJYZ2fpDbV9KOH_GYVYzM8w7I1kG31UQfZSg2zOsFVQ_ILMkKXfD2tGug3gqncLudmXhqVa7agzDoWtw== │ │ ├── refs.0~Tb67rfKaWyD6tF7TA9Eig401NC9Txmq2o32ySXFDX5XkQ_UaMsBea6lYolT1EKt1wyeW2Sw04mno5Tj5TAqqWw== │ │ ├── refs.0~VY8CqbDqQGlciToyYBfYzPYKuVkzTPQgQIRpSWAdlnlEN1xhUI91vxf8n9bZ4KNrJv-DuV-BK914NGUZGE1vgg== │ │ ├── refs.0~WBxsxjslHvapVgvmKeyHG8WwjVBLV8I6q_2RoBB269DBLoDJejrjkNqu2Bt9uud1VMpwo0m6Vp3IEt4i4qI34A== │ │ ├── refs.0~XFCwqVKYQEhKveeH-nDRknBOg9_cT9XM8VRSpI9Bqxj1nqnpXX2fX3Pqx-_LUZLFgT4XKDUfCGe1QsSzRYPZ-w== │ │ ├── refs.0~Y-LxNPpMhhlXlJMGILjd_s1DuOFlYoWFLz59WGxlMhUSvYAiMhdtZ18iERc8I3TlEmBgRJthjAi40wa-c2YxHw== │ │ ├── refs.0~YhpPJjwAaYK49y6xtCTPhXjRd5h67H-_UIC03bX0X9r8duD2jFu93rGZ88WU1Jh4zApifUxA1odQkx2TQeBEow== │ │ ├── refs.0~Z1eUZtKuKH4U6Z5CcijzzaTBvbS8_btB4hat3B6VGpFb2M7z22GNRBMaRrnODcI3kcwavyLRPOs_Q-3oSGczRA== │ │ ├── refs.0~an-MjwYPv5jGpBO4LOh5e6MfvCwh1oiicTdOxfKguEnBB5RCmqE-bWjWX2hq8WlXv4tWh6NREHXJRzJLv87cSw== │ │ ├── refs.0~ca2Nyd-DQTvSubqeVe3fuPpYe2Zhc1sJ38Cn5zWbzecmaSkQHFmscQOlERucFvLJ6iF5JwG9IgIAkwNpfz4g4w== │ │ ├── refs.0~cig9aU8wbVYC1FRjSNPQteGAH75x-AzwDjui6xIo0tNAzLCA5Ixi_clkgR4gsbn9b0D0z5iQ2VJ7sZ8XJAqENQ== │ │ ├── refs.0~fKDNQVWmg4-bXvTNVQyY9rCWHRMvAzkIP7iFGfkkQcOqINkYsctuvEIqYWi55L7z5AORwoHt3t3WNuo13iSTnQ== │ │ ├── refs.0~gci9xFlEq0G4qP789bnD7Gp_YXpUGLSc7bYUjihQJk6fus1sIO1ZAQlwaxlwXkx2_TBEeWA1WegjrWHn-rUN0w== │ │ ├── refs.0~jbHx1Hn8RN5tZGPJ9dVIovExaTAeOcS1nJFfioYZTwBQtNoZKp0Kuho1AmV4hNcGRbzFTkrZ2acfx0jgMRA_LQ== │ │ ├── refs.0~lD1FMB_PbaosCwmDMM0SltEeOWJl4T4KouTBmxuJC38u1kTi19u4xmkmcUpliaKqo0xhMwTgYQZrgT3J7qBhPA== │ │ ├── refs.0~lumBJu_i3Jb05RQxPDi9paJmQhq64l-r1p7LsBLKAUZBaOgeBlB1fuMvLE28kBpa4THoPvGmfj1cc3QfYTYcvg== │ │ ├── refs.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA== │ │ ├── refs.0~rTfC2vU6ZXnhBsRZZliZJVFQpvn-w7HPCQE_gNlEdiAf5wCkvvSlIIMlyOk73iGjSstM5RNUNSEtNVAPQwR0Yg== │ │ ├── refs.0~s_ij9vBr3bcJMMjqQuE5efqmOwB_ncnzJix9goq3iderASwacda-Q24RCgdWsEq4L7dVEPC_UuMJxOu8KAYXqw== │ │ ├── refs.0~wp21HLmd5m-UM-XZ_zFAoky6NJEPevfr_pbRfBxddabQ34Tk7HjchlwxyBz7t-JwKAxsXI67jYaPWgX_iV9C5w== │ │ └── refs.0~x887GlUHa8RnHzB4uvJReg0Mb9X2BgP1dNB0uq8vkpSe6Vjq3DtNDTaWHg5i2WNR8AQDsuh8ZBKFB0HS1yCz-w== │ │ └── Info.plist ├── spec_helper.rb └── xcresult_spec.rb └── xcresult.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | 10 | # rspec failure tracking 11 | .rspec_status 12 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | Metrics/LineLength: 2 | Enabled: false 3 | 4 | Metrics/MethodLength: 5 | Enabled: false 6 | 7 | Metrics/AbcSize: 8 | Enabled: false 9 | 10 | Style/Documentation: 11 | Enabled: false 12 | 13 | Style/GuardClause: 14 | Enabled: false 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: false 3 | language: ruby 4 | cache: bundler 5 | rvm: 6 | - 2.3.7 7 | before_install: gem install bundler -v 1.17.3 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | gemspec 6 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | xcresult (0.2.2) 5 | 6 | GEM 7 | remote: https://rubygems.org/ 8 | specs: 9 | ast (2.4.2) 10 | diff-lcs (1.3) 11 | json (2.7.2) 12 | language_server-protocol (3.17.0.3) 13 | parallel (1.25.1) 14 | parser (3.3.4.0) 15 | ast (~> 2.4.1) 16 | racc 17 | racc (1.8.1) 18 | rainbow (3.1.1) 19 | rake (13.0.1) 20 | regexp_parser (2.9.2) 21 | rexml (3.3.4) 22 | strscan 23 | rspec (3.8.0) 24 | rspec-core (~> 3.8.0) 25 | rspec-expectations (~> 3.8.0) 26 | rspec-mocks (~> 3.8.0) 27 | rspec-core (3.8.2) 28 | rspec-support (~> 3.8.0) 29 | rspec-expectations (3.8.4) 30 | diff-lcs (>= 1.2.0, < 2.0) 31 | rspec-support (~> 3.8.0) 32 | rspec-mocks (3.8.1) 33 | diff-lcs (>= 1.2.0, < 2.0) 34 | rspec-support (~> 3.8.0) 35 | rspec-support (3.8.2) 36 | rubocop (1.65.1) 37 | json (~> 2.3) 38 | language_server-protocol (>= 3.17.0) 39 | parallel (~> 1.10) 40 | parser (>= 3.3.0.2) 41 | rainbow (>= 2.2.2, < 4.0) 42 | regexp_parser (>= 2.4, < 3.0) 43 | rexml (>= 3.2.5, < 4.0) 44 | rubocop-ast (>= 1.31.1, < 2.0) 45 | ruby-progressbar (~> 1.7) 46 | unicode-display_width (>= 2.4.0, < 3.0) 47 | rubocop-ast (1.32.0) 48 | parser (>= 3.3.1.0) 49 | ruby-progressbar (1.13.0) 50 | strscan (3.1.0) 51 | unicode-display_width (2.5.0) 52 | 53 | PLATFORMS 54 | ruby 55 | 56 | DEPENDENCIES 57 | bundler (~> 2.0) 58 | rake (~> 13.0) 59 | rspec (~> 3.0) 60 | rubocop (~> 1.65) 61 | xcresult! 62 | 63 | BUNDLED WITH 64 | 2.5.10 65 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Josh Holtz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XCResult 2 | 3 | [![Twitter: @joshdholtz](https://img.shields.io/badge/contact-@joshdholtz-blue.svg?style=flat)](https://twitter.com/KrauseFx) 4 | [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/KrauseFx/trainer/blob/master/LICENSE) 5 | [![Gem](https://img.shields.io/gem/v/xcresult.svg?style=flat)](http://rubygems.org/gems/trainer) 6 | 7 | Ruby interface for inspecting data and exporting data from Xcode 11 `.xcresult` files 8 | 9 | ## Installation 10 | 11 | Add this line to your application's Gemfile: 12 | 13 | ```ruby 14 | gem 'xcresult' 15 | ``` 16 | 17 | And then execute: 18 | 19 | $ bundle 20 | 21 | Or install it yourself as: 22 | 23 | $ gem install xcresult 24 | 25 | ## Roadmap 26 | 27 | - [x] Allow for easy querying of test plan summaires 28 | - [x] Allow for easy exporting of `.xccovreport` files 29 | - [ ] Allow for exporting of screenshots 30 | - [ ] Add full documentation on all classes and methods 31 | - [ ] Add more and better explain examples 32 | - [ ] Add tests and improved code coverage 33 | 34 | ## Usage 35 | 36 | ### Export .xccovreport files from .xcresult 37 | 38 | ```rb 39 | parser = XCResult::Parser.new(path: 'YourProject.xcresult') 40 | export_xccovreport_paths = parser.export_xccovreports(destination: './outputs') 41 | ``` 42 | 43 | ### Get test plan summaries from .xcresult 44 | 45 | ```rb 46 | parser = XCResult::Parser.new(path: 'YourProject.xcresult') 47 | summaries = parser.action_test_plan_summaries 48 | ``` 49 | 50 | ## Development 51 | 52 | After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. 53 | 54 | To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). 55 | 56 | ## Contributing 57 | 58 | Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/xcresult. 59 | 60 | ## License 61 | 62 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 63 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/gem_tasks' 4 | require 'rspec/core/rake_task' 5 | 6 | RSpec::Core::RakeTask.new(:spec) 7 | 8 | task default: :spec 9 | -------------------------------------------------------------------------------- /lib/xcresult.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'xcresult/version.rb' 4 | require_relative 'xcresult/models.rb' 5 | require_relative 'xcresult/parser.rb' 6 | -------------------------------------------------------------------------------- /lib/xcresult/models.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'xcresult/version' 4 | require 'time' 5 | module XCResult 6 | # Model attributes and relationships taken from running the following command: 7 | # xcrun xcresulttool formatDescription 8 | 9 | class AbstractObject 10 | attr_accessor :type 11 | def initialize(data) 12 | self.type = data['_type']['_name'] 13 | end 14 | 15 | def fetch_value(data, key) 16 | (data[key] || {})['_value'] 17 | end 18 | 19 | def fetch_values(data, key) 20 | return [] if data.nil? 21 | 22 | (data[key] || {})['_values'] || [] 23 | end 24 | end 25 | 26 | # - ActionTestPlanRunSummaries 27 | # * Kind: object 28 | # * Properties: 29 | # + summaries: [ActionTestPlanRunSummary] 30 | class ActionTestPlanRunSummaries < AbstractObject 31 | attr_accessor :summaries 32 | def initialize(data) 33 | self.summaries = fetch_values(data, 'summaries').map do |summary_data| 34 | ActionTestPlanRunSummary.new(summary_data) 35 | end 36 | super 37 | end 38 | end 39 | 40 | # - ActionAbstractTestSummary 41 | # * Kind: object 42 | # * Properties: 43 | # + name: String? 44 | class ActionAbstractTestSummary < AbstractObject 45 | attr_accessor :name 46 | def initialize(data) 47 | self.name = fetch_value(data, 'name') 48 | super 49 | end 50 | end 51 | 52 | # - ActionTestPlanRunSummary 53 | # * Supertype: ActionAbstractTestSummary 54 | # * Kind: object 55 | # * Properties: 56 | # + testableSummaries: [ActionTestableSummary] 57 | class ActionTestPlanRunSummary < ActionAbstractTestSummary 58 | attr_accessor :testable_summaries 59 | def initialize(data) 60 | self.testable_summaries = fetch_values(data, 'testableSummaries').map do |summary_data| 61 | ActionTestableSummary.new(summary_data) 62 | end 63 | super 64 | end 65 | end 66 | 67 | # - ActionTestableSummary 68 | # * Supertype: ActionAbstractTestSummary 69 | # * Kind: object 70 | # * Properties: 71 | # + projectRelativePath: String? 72 | # + targetName: String? 73 | # + testKind: String? 74 | # + tests: [ActionTestSummaryIdentifiableObject] 75 | # + diagnosticsDirectoryName: String? 76 | # + failureSummaries: [ActionTestFailureSummary] 77 | # + testLanguage: String? 78 | # + testRegion: String? 79 | class ActionTestableSummary < ActionAbstractTestSummary 80 | attr_accessor :project_relative_path 81 | attr_accessor :target_name 82 | attr_accessor :test_kind 83 | attr_accessor :tests 84 | def initialize(data) 85 | self.project_relative_path = fetch_value(data, 'projectRelativePath') 86 | self.target_name = fetch_value(data, 'targetName') 87 | self.test_kind = fetch_value(data, 'testKind') 88 | self.tests = fetch_values(data, 'tests').map do |tests_data| 89 | ActionTestSummaryIdentifiableObject.create(tests_data, self) 90 | end 91 | super 92 | end 93 | 94 | def all_tests 95 | tests.map(&:all_subtests).flatten 96 | end 97 | end 98 | 99 | # - ActionTestSummaryIdentifiableObject 100 | # * Supertype: ActionAbstractTestSummary 101 | # * Kind: object 102 | # * Properties: 103 | # + identifier: String? 104 | class ActionTestSummaryIdentifiableObject < ActionAbstractTestSummary 105 | attr_accessor :identifier 106 | attr_accessor :parent 107 | def initialize(data, parent) 108 | self.identifier = fetch_value(data, 'identifier') 109 | self.parent = parent 110 | super(data) 111 | end 112 | 113 | def all_subtests 114 | raise 'Not overridden' 115 | end 116 | 117 | def self.create(data, parent) 118 | type = data['_type']['_name'] 119 | if type == 'ActionTestSummaryGroup' 120 | return ActionTestSummaryGroup.new(data, parent) 121 | elsif type == 'ActionTestSummary' 122 | return ActionTestSummary.new(data, parent) 123 | elsif type == 'ActionTestMetadata' 124 | return ActionTestMetadata.new(data, parent) 125 | else 126 | raise "Unsupported type: #{type}" 127 | end 128 | end 129 | end 130 | 131 | # - ActionTestSummaryGroup 132 | # * Supertype: ActionTestSummaryIdentifiableObject 133 | # * Kind: object 134 | # * Properties: 135 | # + duration: Double 136 | # + subtests: [ActionTestSummaryIdentifiableObject] 137 | class ActionTestSummaryGroup < ActionTestSummaryIdentifiableObject 138 | attr_accessor :duration 139 | attr_accessor :subtests 140 | def initialize(data, parent) 141 | self.duration = fetch_value(data, 'duration').to_f 142 | self.subtests = fetch_values(data, 'subtests').map do |subtests_data| 143 | ActionTestSummaryIdentifiableObject.create(subtests_data, self) 144 | end 145 | super(data, parent) 146 | end 147 | 148 | def all_subtests 149 | subtests.map(&:all_subtests).flatten 150 | end 151 | end 152 | 153 | # - ActionTestMetadata 154 | # * Supertype: ActionTestSummaryIdentifiableObject 155 | # * Kind: object 156 | # * Properties: 157 | # + testStatus: String 158 | # + duration: Double? 159 | # + summaryRef: Reference? 160 | # + performanceMetricsCount: Int 161 | # + failureSummariesCount: Int 162 | # + activitySummariesCount: Int 163 | class ActionTestMetadata < ActionTestSummaryIdentifiableObject 164 | attr_accessor :test_status 165 | attr_accessor :duration 166 | attr_accessor :summary_ref 167 | attr_accessor :performance_metrics_count 168 | attr_accessor :failure_summaries_count 169 | attr_accessor :activity_summaries_count 170 | def initialize(data, parent) 171 | self.test_status = fetch_value(data, 'testStatus') 172 | self.duration = fetch_value(data, 'duration').to_f 173 | self.summary_ref = Reference.new(data['summaryRef']) if data['summaryRef'] 174 | self.performance_metrics_count = fetch_value(data, 'performanceMetricsCount') 175 | self.failure_summaries_count = fetch_value(data, 'failureSummariesCount') 176 | self.activity_summaries_count = fetch_value(data, 'activitySummariesCount') 177 | super(data, parent) 178 | end 179 | 180 | def all_subtests 181 | [self] 182 | end 183 | 184 | def find_failure(failures) 185 | if test_status == 'Failure' 186 | # Tries to match failure on test case name 187 | # Example TestFailureIssueSummary: 188 | # producingTarget: "TestThisDude" 189 | # test_case_name: "TestThisDude.testFailureJosh2()" (when Swift) 190 | # or "-[TestThisDudeTests testFailureJosh2]" (when Objective-C) 191 | # Example ActionTestMetadata 192 | # identifier: "TestThisDude/testFailureJosh2()" (when Swift) 193 | # or identifier: "TestThisDude/testFailureJosh2" (when Objective-C) 194 | 195 | found_failure = failures.find do |failure| 196 | # Clean test_case_name to match identifier format 197 | # Sanitize for Swift by replacing "." for "/" 198 | # Sanitize for Objective-C by removing "-", "[", "]", and replacing " " for ?/ 199 | sanitized_test_case_name = failure.test_case_name 200 | .tr('.', '/') 201 | .tr('-', '') 202 | .tr('[', '') 203 | .tr(']', '') 204 | .tr(' ', '/') 205 | identifier == sanitized_test_case_name 206 | end 207 | found_failure 208 | end 209 | end 210 | end 211 | 212 | # - ActionsInvocationRecord 213 | # * Kind: object 214 | # * Properties: 215 | # + metadataRef: Reference? 216 | # + metrics: ResultMetrics 217 | # + issues: ResultIssueSummaries 218 | # + actions: [ActionRecord] 219 | # + archive: ArchiveInfo? 220 | class ActionsInvocationRecord < AbstractObject 221 | attr_accessor :actions 222 | attr_accessor :issues 223 | def initialize(data) 224 | self.actions = fetch_values(data, 'actions').map do |action_data| 225 | ActionRecord.new(action_data) 226 | end 227 | self.issues = ResultIssueSummaries.new(data['issues']) 228 | super 229 | end 230 | end 231 | 232 | # - ActionRecord 233 | # * Kind: object 234 | # * Properties: 235 | # + schemeCommandName: String 236 | # + schemeTaskName: String 237 | # + title: String? 238 | # + startedTime: Date 239 | # + endedTime: Date 240 | # + runDestination: ActionRunDestinationRecord 241 | # + buildResult: ActionResult 242 | # + actionResult: ActionResult 243 | class ActionRecord < AbstractObject 244 | attr_accessor :scheme_command_name 245 | attr_accessor :scheme_task_name 246 | attr_accessor :title 247 | attr_accessor :build_result 248 | attr_accessor :action_result 249 | def initialize(data) 250 | self.scheme_command_name = fetch_value(data, 'schemeCommandName') 251 | self.scheme_task_name = fetch_value(data, 'schemeTaskName') 252 | self.title = fetch_value(data, 'title') 253 | self.build_result = ActionResult.new(data['buildResult']) 254 | self.action_result = ActionResult.new(data['actionResult']) 255 | super 256 | end 257 | end 258 | 259 | # - ActionResult 260 | # * Kind: object 261 | # * Properties: 262 | # + resultName: String 263 | # + status: String 264 | # + metrics: ResultMetrics 265 | # + issues: ResultIssueSummaries 266 | # + coverage: CodeCoverageInfo 267 | # + timelineRef: Reference? 268 | # + logRef: Reference? 269 | # + testsRef: Reference? 270 | # + diagnosticsRef: Reference? 271 | class ActionResult < AbstractObject 272 | attr_accessor :result_name 273 | attr_accessor :status 274 | attr_accessor :issues 275 | attr_accessor :coverage 276 | attr_accessor :timeline_ref 277 | attr_accessor :log_ref 278 | attr_accessor :tests_ref 279 | attr_accessor :diagnostics_ref 280 | def initialize(data) 281 | self.result_name = fetch_value(data, 'resultName') 282 | self.status = fetch_value(data, 'status') 283 | self.issues = ResultIssueSummaries.new(data['issues']) 284 | self.coverage = CodeCoverageInfo.new(data['coverage']) 285 | 286 | self.timeline_ref = Reference.new(data['timelineRef']) if data['timelineRef'] 287 | self.log_ref = Reference.new(data['logRef']) if data['logRef'] 288 | self.tests_ref = Reference.new(data['testsRef']) if data['testsRef'] 289 | self.diagnostics_ref = Reference.new(data['diagnosticsRef']) if data['diagnosticsRef'] 290 | super 291 | end 292 | end 293 | 294 | # - CodeCoverageInfo 295 | # * Kind: object 296 | # * Properties: 297 | # + hasCoverageData: Bool 298 | # + reportRef: Reference? 299 | # + archiveRef: Reference? 300 | class CodeCoverageInfo < AbstractObject 301 | attr_accessor :has_coverage_data 302 | attr_accessor :report_ref 303 | attr_accessor :archive_ref 304 | def initialize(data) 305 | self.has_coverage_data = fetch_value(data, 'hasCoverageData') 306 | self.report_ref = Reference.new(data['reportRef']) if data['reportRef'] 307 | self.archive_ref = Reference.new(data['archiveRef']) if data['archiveRef'] 308 | end 309 | end 310 | 311 | # - Reference 312 | # * Kind: object 313 | # * Properties: 314 | # + id: String 315 | # + targetType: TypeDefinition? 316 | class Reference < AbstractObject 317 | attr_accessor :id 318 | attr_accessor :target_type 319 | def initialize(data) 320 | self.id = fetch_value(data, 'id') 321 | self.target_type = TypeDefinition.new(data['targetType']) if data['targetType'] 322 | super 323 | end 324 | end 325 | 326 | # - TypeDefinition 327 | # * Kind: object 328 | # * Properties: 329 | # + name: String 330 | # + supertype: TypeDefinition? 331 | class TypeDefinition < AbstractObject 332 | attr_accessor :name 333 | attr_accessor :supertype 334 | def initialize(data) 335 | self.name = fetch_value(data, 'name') 336 | self.supertype = TypeDefinition.new(data['supertype']) if data['supertype'] 337 | super 338 | end 339 | end 340 | 341 | # - DocumentLocation 342 | # * Kind: object 343 | # * Properties: 344 | # + url: String 345 | # + concreteTypeName: String 346 | class DocumentLocation < AbstractObject 347 | attr_accessor :url 348 | attr_accessor :concrete_type_name 349 | def initialize(data) 350 | self.url = fetch_value(data, 'url') 351 | self.concrete_type_name = data['concreteTypeName']['_value'] 352 | super 353 | end 354 | end 355 | 356 | # - IssueSummary 357 | # * Kind: object 358 | # * Properties: 359 | # + issueType: String 360 | # + message: String 361 | # + producingTarget: String? 362 | # + documentLocationInCreatingWorkspace: DocumentLocation? 363 | class IssueSummary < AbstractObject 364 | attr_accessor :issue_type 365 | attr_accessor :message 366 | attr_accessor :producing_target 367 | attr_accessor :document_location_in_creating_workspace 368 | def initialize(data) 369 | self.issue_type = fetch_value(data, 'issueType') 370 | self.message = fetch_value(data, 'message') 371 | self.producing_target = fetch_value(data, 'producingTarget') 372 | self.document_location_in_creating_workspace = DocumentLocation.new(data['documentLocationInCreatingWorkspace']) if data['documentLocationInCreatingWorkspace'] 373 | super 374 | end 375 | end 376 | 377 | # - ResultIssueSummaries 378 | # * Kind: object 379 | # * Properties: 380 | # + analyzerWarningSummaries: [IssueSummary] 381 | # + errorSummaries: [IssueSummary] 382 | # + testFailureSummaries: [TestFailureIssueSummary] 383 | # + warningSummaries: [IssueSummary] 384 | class ResultIssueSummaries < AbstractObject 385 | attr_accessor :analyzer_warning_summaries 386 | attr_accessor :error_summaries 387 | attr_accessor :test_failure_summaries 388 | attr_accessor :warning_summaries 389 | def initialize(data) 390 | self.analyzer_warning_summaries = fetch_values(data, 'analyzerWarningSummaries').map do |summary_data| 391 | IssueSummary.new(summary_data) 392 | end 393 | self.error_summaries = fetch_values(data, 'errorSummaries').map do |summary_data| 394 | IssueSummary.new(summary_data) 395 | end 396 | self.test_failure_summaries = fetch_values(data, 'testFailureSummaries').map do |summary_data| 397 | TestFailureIssueSummary.new(summary_data) 398 | end 399 | self.warning_summaries = fetch_values(data, 'warningSummaries').map do |summary_data| 400 | IssueSummary.new(summary_data) 401 | end 402 | super 403 | end 404 | end 405 | 406 | # - TestFailureIssueSummary 407 | # * Supertype: IssueSummary 408 | # * Kind: object 409 | # * Properties: 410 | # + testCaseName: String 411 | class TestFailureIssueSummary < IssueSummary 412 | attr_accessor :test_case_name 413 | def initialize(data) 414 | self.test_case_name = fetch_value(data, 'testCaseName') 415 | super 416 | end 417 | 418 | def failure_message 419 | new_message = message 420 | if document_location_in_creating_workspace 421 | file_path = document_location_in_creating_workspace.url.gsub('file://', '') 422 | new_message += " (#{file_path})" 423 | end 424 | 425 | new_message 426 | end 427 | end 428 | 429 | # - ActionTestSummary 430 | # * Supertype: ActionTestSummaryIdentifiableObject 431 | # * Kind: object 432 | # * Properties: 433 | # + testStatus: String 434 | # + duration: Double 435 | # + performanceMetrics: [ActionTestPerformanceMetricSummary] 436 | # + failureSummaries: [ActionTestFailureSummary] 437 | # + activitySummaries: [ActionTestActivitySummary] 438 | class ActionTestSummary < ActionTestSummaryIdentifiableObject 439 | attr_accessor :test_status 440 | attr_accessor :duration 441 | attr_accessor :activity_summaries 442 | def initialize(data, parent = nil) 443 | self.test_status = fetch_value(data, 'testStatus') 444 | self.duration = fetch_value(data, 'duration').to_f 445 | self.activity_summaries = fetch_values(data, 'activitySummaries').map do |summary_data| 446 | ActionTestActivitySummary.new(summary_data) 447 | end 448 | super(data, parent) 449 | end 450 | end 451 | 452 | # - ActionTestActivitySummary 453 | # * Kind: object 454 | # * Properties: 455 | # + title: String 456 | # + activityType: String 457 | # + uuid: String 458 | # + start: Date? 459 | # + finish: Date? 460 | # + attachments: [ActionTestAttachment] 461 | # + subactivities: [ActionTestActivitySummary] 462 | class ActionTestActivitySummary < AbstractObject 463 | attr_accessor :title 464 | attr_accessor :activity_type 465 | attr_accessor :uuid 466 | attr_accessor :start 467 | attr_accessor :finish 468 | attr_accessor :attachments 469 | attr_accessor :subactivities 470 | def initialize(data) 471 | self.title = fetch_value(data, 'title') 472 | self.activity_type = fetch_value(data, 'activityType') 473 | self.uuid = fetch_value(data, 'uuid') 474 | self.start = Time.parse(fetch_value(data, 'start')) if data['start'] 475 | self.finish = Time.parse(fetch_value(data, 'finish')) if data['finish'] 476 | self.attachments = fetch_values(data, 'attachments').map do |attachment_data| 477 | ActionTestAttachment.new(attachment_data) 478 | end 479 | self.subactivities = fetch_values(data, 'subactivities').map do |summary_data| 480 | ActionTestActivitySummary.new(summary_data) 481 | end 482 | super(data) 483 | end 484 | end 485 | 486 | # - ActionTestAttachment 487 | # * Kind: object 488 | # * Properties: 489 | # + uniformTypeIdentifier: String 490 | # + name: String? 491 | # + timestamp: Date? 492 | # + userInfo: SortedKeyValueArray? 493 | # + lifetime: String 494 | # + inActivityIdentifier: Int 495 | # + filename: String? 496 | # + payloadRef: Reference? 497 | # + payloadSize: Int 498 | class ActionTestAttachment < AbstractObject 499 | attr_accessor :uniform_type_identifier 500 | attr_accessor :name 501 | attr_accessor :timestamp 502 | attr_accessor :user_info 503 | attr_accessor :lifetime 504 | attr_accessor :in_activity_identifier 505 | attr_accessor :filename 506 | attr_accessor :payload_ref 507 | attr_accessor :payload_size 508 | def initialize(data) 509 | self.uniform_type_identifier = fetch_value(data, 'uniformTypeIdentifier') 510 | self.name = fetch_value(data, 'name') 511 | self.timestamp = Time.parse(fetch_value(data, 'timestamp')) if data['timestamp'] 512 | self.user_info = SortedKeyValueArray.new(data['userInfo']) if data['userInfo'] 513 | self.lifetime = fetch_value(data, 'lifetime') 514 | self.in_activity_identifier = fetch_value(data, 'inActivityIdentifier').to_i 515 | self.filename = fetch_value(data, 'filename') 516 | self.payload_ref = Reference.new(data['payloadRef']) if data['payloadRef'] 517 | self.payload_size = fetch_value(data, 'payloadSize').to_i 518 | super(data) 519 | end 520 | end 521 | 522 | # - SortedKeyValueArray 523 | # * Kind: object 524 | # * Properties: 525 | # + storage: [SortedKeyValueArrayPair] 526 | class SortedKeyValueArray < AbstractObject 527 | attr_accessor :storage 528 | def initialize(data) 529 | self.storage = fetch_values(data, 'storage').map do |pair_data| 530 | SortedKeyValueArrayPair.new(pair_data) 531 | end 532 | super(data) 533 | end 534 | end 535 | 536 | # - SortedKeyValueArrayPair 537 | # * Kind: object 538 | # * Properties: 539 | # + key: String 540 | # + value: SchemaSerializable 541 | class SortedKeyValueArrayPair < AbstractObject 542 | attr_accessor :key 543 | attr_accessor :value 544 | def initialize(data) 545 | self.key = fetch_value(data, 'key') 546 | self.value = fetch_value(data, 'value') 547 | super(data) 548 | end 549 | end 550 | end 551 | -------------------------------------------------------------------------------- /lib/xcresult/parser.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'shellwords' 4 | require 'json' 5 | 6 | module XCResult 7 | class Parser 8 | attr_accessor :path, :result_bundle_json, :actions_invocation_record 9 | 10 | def initialize(path: nil) 11 | @path = Shellwords.escape(path) 12 | 13 | result_bundle_json_raw = get_result_bundle_json 14 | @result_bundle_json = JSON.parse(result_bundle_json_raw) 15 | 16 | @actions_invocation_record = XCResult::ActionsInvocationRecord.new(@result_bundle_json) 17 | end 18 | 19 | def action_test_plan_summaries 20 | return @action_test_plan_summaries if @action_test_plan_summaries 21 | 22 | # Parses JSON into ActionsInvocationRecord to find a list of all ids for ActionTestPlanRunSummaries 23 | test_refs = actions_invocation_record.actions.map do |action| 24 | action.action_result.tests_ref 25 | end.compact 26 | ids = test_refs.map(&:id) 27 | 28 | # Maps ids into ActionTestPlanRunSummaries by executing xcresulttool to get JSON 29 | # containing specific information for each test summary 30 | @action_test_plan_summaries = ids.map do |id| 31 | raw = execute_cmd(xcresulttool_command("get", "--format json --path #{path} --id #{id}")) 32 | json = JSON.parse(raw) 33 | XCResult::ActionTestPlanRunSummaries.new(json) 34 | end 35 | 36 | @action_test_plan_summaries 37 | end 38 | 39 | def export_xccovreports(destination: nil) 40 | destination ||= Dir.pwd 41 | 42 | # Collects report references 43 | report_refs = actions_invocation_record.actions.map do |action| 44 | action.action_result.coverage.report_ref 45 | end.compact 46 | ids = report_refs.map(&:id) 47 | 48 | # Exports all xccovreport files from the report references 49 | ids.each_with_index.map do |id, i| 50 | output_path = File.join(destination, "action_#{i}.xccovreport") 51 | cmd = xcresulttool_command("export", "--path #{path} --id '#{id}' --output-path #{output_path} --type file") 52 | execute_cmd(cmd) 53 | 54 | output_path 55 | end 56 | end 57 | 58 | def export_xccovarchives(destination: nil) 59 | destination ||= Dir.pwd 60 | 61 | # Collects archive references 62 | archive_refs = actions_invocation_record.actions.map do |action| 63 | action.action_result.coverage.archive_ref 64 | end.compact 65 | ids = archive_refs.map(&:id) 66 | 67 | # Exports all xcovarchive directories from the archive references 68 | ids.each_with_index.map do |id, i| 69 | output_path = File.join(destination, "action_#{i}.xccovarchive") 70 | cmd = xcresulttool_command("export", "--path #{path} --id '#{id}' --output-path #{output_path} --type directory") 71 | execute_cmd(cmd) 72 | 73 | output_path 74 | end 75 | end 76 | 77 | private 78 | 79 | def get_result_bundle_json(id: nil) 80 | cmd = xcresulttool_command("get", "--format json --path #{path}") 81 | cmd += " --id #{id}" if id 82 | execute_cmd(cmd) 83 | end 84 | 85 | def xcresulttool_command(subcommand, args) 86 | # Find the current xcresulttool version based on Fastlane's implementation 87 | # xcresulttool version 23024, format version 3.53 (current) 88 | match = `xcrun xcresulttool version`.match(/xcresulttool version (?\d+),/) 89 | 90 | version = match[:version]&.to_f 91 | 92 | requires_legacy = version >= 23_021.0 93 | legacy_flag = requires_legacy ? ' --legacy' : '' 94 | 95 | cmd = "xcrun xcresulttool #{subcommand}#{legacy_flag} #{args}" 96 | end 97 | 98 | def execute_cmd(cmd) 99 | output = `#{cmd}` 100 | raise "Failed to execute - #{cmd}" unless $?.success? 101 | 102 | output 103 | end 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /lib/xcresult/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module XCResult 4 | VERSION = '0.2.2' 5 | end 6 | -------------------------------------------------------------------------------- /spec/fixtures/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/.DS_Store -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~-fWjWEWCzcI3kbEATPLi73ZRjzFaPceON-c-2yw7WSTUxsm5VWOP9PFcNhFE5DnNOKTg2fpL9tdqdZDsEG4ObA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~-fWjWEWCzcI3kbEATPLi73ZRjzFaPceON-c-2yw7WSTUxsm5VWOP9PFcNhFE5DnNOKTg2fpL9tdqdZDsEG4ObA== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~2LVFAe2LWJ7FCnOsKan5UgGk7WChVJYuZlxPILKyxdpmfjsMrwjBJ2wUhaJQJ36Per_GRUfTI1cKeO2QiGvB8Q==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~2LVFAe2LWJ7FCnOsKan5UgGk7WChVJYuZlxPILKyxdpmfjsMrwjBJ2wUhaJQJ36Per_GRUfTI1cKeO2QiGvB8Q== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~2fEViB_AHXXtEV42Omd60EKOGf74t700IKvBhXCZpWL3ndppdyTcXPsE54O3l9tNul8fGatXPWv6I-8v9l978A==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~2fEViB_AHXXtEV42Omd60EKOGf74t700IKvBhXCZpWL3ndppdyTcXPsE54O3l9tNul8fGatXPWv6I-8v9l978A== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw==: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~7gHa7zyvbiYnQIuODyLD1ukApdh2A0EwOBjrYL1tEcPIhZSAlzLelm23NnBNHwCx5oVGu0IqpIEgA3etA18T6A==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~7gHa7zyvbiYnQIuODyLD1ukApdh2A0EwOBjrYL1tEcPIhZSAlzLelm23NnBNHwCx5oVGu0IqpIEgA3etA18T6A== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~9M0Qj-xDamLky3tGXmCgU_wx5rjhR1r8tYtaK3c-yB-i4SA-CvV3ItI5_cCQ2tK0EA3PMJjaBwbEFWX_JRxbXQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~9M0Qj-xDamLky3tGXmCgU_wx5rjhR1r8tYtaK3c-yB-i4SA-CvV3ItI5_cCQ2tK0EA3PMJjaBwbEFWX_JRxbXQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~BrBB-2dagXo2_PtM2FTu-_HIiATuzrVO87XD0QPytFcnVrccCCkAfZgrkY8tSo6YsOD532s8xL201SpFKp_T7Q==: -------------------------------------------------------------------------------- 1 | [{"name":"remote-container","type":2}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~C1-P2gA8JuyI122raUqhJy68V5bzoHcEvA_youn2viwJ_pROYvVcN9wIswiUzJrINKVPfib6lHEjfFh6jGQBbg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~C1-P2gA8JuyI122raUqhJy68V5bzoHcEvA_youn2viwJ_pROYvVcN9wIswiUzJrINKVPfib6lHEjfFh6jGQBbg== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~CdulzYX7TAIgZKzYi6GAT_wOECoumVWoJhKrUPnBu3EUDWHxYWmnuPptnrykWZfHOb5nhaN_J4ZSH7lDOzsFFg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~CdulzYX7TAIgZKzYi6GAT_wOECoumVWoJhKrUPnBu3EUDWHxYWmnuPptnrykWZfHOb5nhaN_J4ZSH7lDOzsFFg== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~D-Jl7yn8lDlPMEfhM58Omu6yT3Kc2RhOF5Ftz4-Z-6ttHukpVjPI7_yu2J9VbCmX3XcdgfeXzgo8Y97QP42wOA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~D-Jl7yn8lDlPMEfhM58Omu6yT3Kc2RhOF5Ftz4-Z-6ttHukpVjPI7_yu2J9VbCmX3XcdgfeXzgo8Y97QP42wOA== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~J1CqCYY6tVPP1hyR1Y5QPDCxM2e8qGoXgPJ6yjB64pSb8sagiCpZ0lZBG56CivllcXpHlV9UYrZEVYveSkFihQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~J1CqCYY6tVPP1hyR1Y5QPDCxM2e8qGoXgPJ6yjB64pSb8sagiCpZ0lZBG56CivllcXpHlV9UYrZEVYveSkFihQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~LUdKF1UnPtfSu3zwPp58lZBAB3ff_IepvEY6xIJrn21CmFBfSTyJk0gXqq9X5jJyKoZG0kzjJinRz8_zzMbteQ==: -------------------------------------------------------------------------------- 1 | [{"name":"TestUITests-7D388F31-FD47-417C-9782-BA1E26EC5FFC","type":2},{"name":"scheduling.log","type":1}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~MOLiLjVAm7XOBW-XO5XIaCRjXsEfoFBHd636kaoqJRDZd0MAkKfhT9pJI1NEZL_F7rU1bdXjvNV3vdRi_KPrTQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~MOLiLjVAm7XOBW-XO5XIaCRjXsEfoFBHd636kaoqJRDZd0MAkKfhT9pJI1NEZL_F7rU1bdXjvNV3vdRi_KPrTQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~Mv3qbi23MXIDzPEPgJ9KsTi7ro2YUP8bDbdP3vH1W4EalY5rZerLPEmxf7jQiM2XYZKuBm0-8bQfyAYYNXSVGQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~Mv3qbi23MXIDzPEPgJ9KsTi7ro2YUP8bDbdP3vH1W4EalY5rZerLPEmxf7jQiM2XYZKuBm0-8bQfyAYYNXSVGQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~Ns-bzKQx8G36fLzi7rojTuwSmp8ll6sTNBKWHoIGsFwtx78P-7o8OXBT6h-BdyUWppLQ8y2XWq9xANOdcLxM6w==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~Ns-bzKQx8G36fLzi7rojTuwSmp8ll6sTNBKWHoIGsFwtx78P-7o8OXBT6h-BdyUWppLQ8y2XWq9xANOdcLxM6w== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~OYl0nlXqB-ZHe4aHqwi4KqKpmjPsT1uG9iTB85qRck0MdoX_PuVHoJpsjmRzbENZQKlpIlWWjNLlZK8N8ouRQg==: -------------------------------------------------------------------------------- 1 | [{"name":"tmp","type":2}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~Q8sTyAcSG_vQ7QvWvQLAXn6XGWh9PM_OIMsDBFAv0wx1Eqv8jeNCM6LN2jM5ARGnlLugCrMbBsoDR6Jc6EGTrw==: -------------------------------------------------------------------------------- 1 | [{"name":"7B8A91CB-F3CC-4FCC-A6A9-6935655B53E4","type":2}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~TE2FhTmJYZ2fpDbV9KOH_GYVYzM8w7I1kG31UQfZSg2zOsFVQ_ILMkKXfD2tGug3gqncLudmXhqVa7agzDoWtw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~TE2FhTmJYZ2fpDbV9KOH_GYVYzM8w7I1kG31UQfZSg2zOsFVQ_ILMkKXfD2tGug3gqncLudmXhqVa7agzDoWtw== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~Tb67rfKaWyD6tF7TA9Eig401NC9Txmq2o32ySXFDX5XkQ_UaMsBea6lYolT1EKt1wyeW2Sw04mno5Tj5TAqqWw==: -------------------------------------------------------------------------------- 1 | [{"name":"tmp","type":2}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~VY8CqbDqQGlciToyYBfYzPYKuVkzTPQgQIRpSWAdlnlEN1xhUI91vxf8n9bZ4KNrJv-DuV-BK914NGUZGE1vgg==: -------------------------------------------------------------------------------- 1 | [{"name":"TestUITests-7B8A91CB-F3CC-4FCC-A6A9-6935655B53E4.xctestconfiguration","type":1}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~WBxsxjslHvapVgvmKeyHG8WwjVBLV8I6q_2RoBB269DBLoDJejrjkNqu2Bt9uud1VMpwo0m6Vp3IEt4i4qI34A==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~WBxsxjslHvapVgvmKeyHG8WwjVBLV8I6q_2RoBB269DBLoDJejrjkNqu2Bt9uud1VMpwo0m6Vp3IEt4i4qI34A== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~XFCwqVKYQEhKveeH-nDRknBOg9_cT9XM8VRSpI9Bqxj1nqnpXX2fX3Pqx-_LUZLFgT4XKDUfCGe1QsSzRYPZ-w==: -------------------------------------------------------------------------------- 1 | [{"name":"D8FAA25F-3D84-4A1C-BE07-0E5216D512F6","type":2}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~Y-LxNPpMhhlXlJMGILjd_s1DuOFlYoWFLz59WGxlMhUSvYAiMhdtZ18iERc8I3TlEmBgRJthjAi40wa-c2YxHw==: -------------------------------------------------------------------------------- 1 | [{"name":"TestThisDude-91BEB0B4-B34A-4373-A669-422AD8A76A9A","type":2},{"name":"scheduling.log","type":1}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~YhpPJjwAaYK49y6xtCTPhXjRd5h67H-_UIC03bX0X9r8duD2jFu93rGZ88WU1Jh4zApifUxA1odQkx2TQeBEow==: -------------------------------------------------------------------------------- 1 | [{"name":"testmanagerd.log","type":1}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~Z1eUZtKuKH4U6Z5CcijzzaTBvbS8_btB4hat3B6VGpFb2M7z22GNRBMaRrnODcI3kcwavyLRPOs_Q-3oSGczRA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~Z1eUZtKuKH4U6Z5CcijzzaTBvbS8_btB4hat3B6VGpFb2M7z22GNRBMaRrnODcI3kcwavyLRPOs_Q-3oSGczRA== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~an-MjwYPv5jGpBO4LOh5e6MfvCwh1oiicTdOxfKguEnBB5RCmqE-bWjWX2hq8WlXv4tWh6NREHXJRzJLv87cSw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~an-MjwYPv5jGpBO4LOh5e6MfvCwh1oiicTdOxfKguEnBB5RCmqE-bWjWX2hq8WlXv4tWh6NREHXJRzJLv87cSw== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~ca2Nyd-DQTvSubqeVe3fuPpYe2Zhc1sJ38Cn5zWbzecmaSkQHFmscQOlERucFvLJ6iF5JwG9IgIAkwNpfz4g4w==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~ca2Nyd-DQTvSubqeVe3fuPpYe2Zhc1sJ38Cn5zWbzecmaSkQHFmscQOlERucFvLJ6iF5JwG9IgIAkwNpfz4g4w== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~cig9aU8wbVYC1FRjSNPQteGAH75x-AzwDjui6xIo0tNAzLCA5Ixi_clkgR4gsbn9b0D0z5iQ2VJ7sZ8XJAqENQ==: -------------------------------------------------------------------------------- 1 | [{"name":"TestThisDude-D8FAA25F-3D84-4A1C-BE07-0E5216D512F6.xctestconfiguration","type":1}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~fKDNQVWmg4-bXvTNVQyY9rCWHRMvAzkIP7iFGfkkQcOqINkYsctuvEIqYWi55L7z5AORwoHt3t3WNuo13iSTnQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~fKDNQVWmg4-bXvTNVQyY9rCWHRMvAzkIP7iFGfkkQcOqINkYsctuvEIqYWi55L7z5AORwoHt3t3WNuo13iSTnQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~gci9xFlEq0G4qP789bnD7Gp_YXpUGLSc7bYUjihQJk6fus1sIO1ZAQlwaxlwXkx2_TBEeWA1WegjrWHn-rUN0w==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~gci9xFlEq0G4qP789bnD7Gp_YXpUGLSc7bYUjihQJk6fus1sIO1ZAQlwaxlwXkx2_TBEeWA1WegjrWHn-rUN0w== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~jbHx1Hn8RN5tZGPJ9dVIovExaTAeOcS1nJFfioYZTwBQtNoZKp0Kuho1AmV4hNcGRbzFTkrZ2acfx0jgMRA_LQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~jbHx1Hn8RN5tZGPJ9dVIovExaTAeOcS1nJFfioYZTwBQtNoZKp0Kuho1AmV4hNcGRbzFTkrZ2acfx0jgMRA_LQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~lD1FMB_PbaosCwmDMM0SltEeOWJl4T4KouTBmxuJC38u1kTi19u4xmkmcUpliaKqo0xhMwTgYQZrgT3J7qBhPA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~lD1FMB_PbaosCwmDMM0SltEeOWJl4T4KouTBmxuJC38u1kTi19u4xmkmcUpliaKqo0xhMwTgYQZrgT3J7qBhPA== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~lumBJu_i3Jb05RQxPDi9paJmQhq64l-r1p7LsBLKAUZBaOgeBlB1fuMvLE28kBpa4THoPvGmfj1cc3QfYTYcvg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~lumBJu_i3Jb05RQxPDi9paJmQhq64l-r1p7LsBLKAUZBaOgeBlB1fuMvLE28kBpa4THoPvGmfj1cc3QfYTYcvg== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~rTfC2vU6ZXnhBsRZZliZJVFQpvn-w7HPCQE_gNlEdiAf5wCkvvSlIIMlyOk73iGjSstM5RNUNSEtNVAPQwR0Yg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~rTfC2vU6ZXnhBsRZZliZJVFQpvn-w7HPCQE_gNlEdiAf5wCkvvSlIIMlyOk73iGjSstM5RNUNSEtNVAPQwR0Yg== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~s_ij9vBr3bcJMMjqQuE5efqmOwB_ncnzJix9goq3iderASwacda-Q24RCgdWsEq4L7dVEPC_UuMJxOu8KAYXqw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~s_ij9vBr3bcJMMjqQuE5efqmOwB_ncnzJix9goq3iderASwacda-Q24RCgdWsEq4L7dVEPC_UuMJxOu8KAYXqw== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~wp21HLmd5m-UM-XZ_zFAoky6NJEPevfr_pbRfBxddabQ34Tk7HjchlwxyBz7t-JwKAxsXI67jYaPWgX_iV9C5w==: -------------------------------------------------------------------------------- 1 | [{"name":"remote-container","type":2}] -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/data.0~x887GlUHa8RnHzB4uvJReg0Mb9X2BgP1dNB0uq8vkpSe6Vjq3DtNDTaWHg5i2WNR8AQDsuh8ZBKFB0HS1yCz-w==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/data.0~x887GlUHa8RnHzB4uvJReg0Mb9X2BgP1dNB0uq8vkpSe6Vjq3DtNDTaWHg5i2WNR8AQDsuh8ZBKFB0HS1yCz-w== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~-fWjWEWCzcI3kbEATPLi73ZRjzFaPceON-c-2yw7WSTUxsm5VWOP9PFcNhFE5DnNOKTg2fpL9tdqdZDsEG4ObA==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~2LVFAe2LWJ7FCnOsKan5UgGk7WChVJYuZlxPILKyxdpmfjsMrwjBJ2wUhaJQJ36Per_GRUfTI1cKeO2QiGvB8Q==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~2LVFAe2LWJ7FCnOsKan5UgGk7WChVJYuZlxPILKyxdpmfjsMrwjBJ2wUhaJQJ36Per_GRUfTI1cKeO2QiGvB8Q== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~2fEViB_AHXXtEV42Omd60EKOGf74t700IKvBhXCZpWL3ndppdyTcXPsE54O3l9tNul8fGatXPWv6I-8v9l978A==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~7gHa7zyvbiYnQIuODyLD1ukApdh2A0EwOBjrYL1tEcPIhZSAlzLelm23NnBNHwCx5oVGu0IqpIEgA3etA18T6A==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~9M0Qj-xDamLky3tGXmCgU_wx5rjhR1r8tYtaK3c-yB-i4SA-CvV3ItI5_cCQ2tK0EA3PMJjaBwbEFWX_JRxbXQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~9M0Qj-xDamLky3tGXmCgU_wx5rjhR1r8tYtaK3c-yB-i4SA-CvV3ItI5_cCQ2tK0EA3PMJjaBwbEFWX_JRxbXQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~BrBB-2dagXo2_PtM2FTu-_HIiATuzrVO87XD0QPytFcnVrccCCkAfZgrkY8tSo6YsOD532s8xL201SpFKp_T7Q==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~BrBB-2dagXo2_PtM2FTu-_HIiATuzrVO87XD0QPytFcnVrccCCkAfZgrkY8tSo6YsOD532s8xL201SpFKp_T7Q== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~C1-P2gA8JuyI122raUqhJy68V5bzoHcEvA_youn2viwJ_pROYvVcN9wIswiUzJrINKVPfib6lHEjfFh6jGQBbg==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~CdulzYX7TAIgZKzYi6GAT_wOECoumVWoJhKrUPnBu3EUDWHxYWmnuPptnrykWZfHOb5nhaN_J4ZSH7lDOzsFFg==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~D-Jl7yn8lDlPMEfhM58Omu6yT3Kc2RhOF5Ftz4-Z-6ttHukpVjPI7_yu2J9VbCmX3XcdgfeXzgo8Y97QP42wOA==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~J1CqCYY6tVPP1hyR1Y5QPDCxM2e8qGoXgPJ6yjB64pSb8sagiCpZ0lZBG56CivllcXpHlV9UYrZEVYveSkFihQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~J1CqCYY6tVPP1hyR1Y5QPDCxM2e8qGoXgPJ6yjB64pSb8sagiCpZ0lZBG56CivllcXpHlV9UYrZEVYveSkFihQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~LUdKF1UnPtfSu3zwPp58lZBAB3ff_IepvEY6xIJrn21CmFBfSTyJk0gXqq9X5jJyKoZG0kzjJinRz8_zzMbteQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~LUdKF1UnPtfSu3zwPp58lZBAB3ff_IepvEY6xIJrn21CmFBfSTyJk0gXqq9X5jJyKoZG0kzjJinRz8_zzMbteQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~MOLiLjVAm7XOBW-XO5XIaCRjXsEfoFBHd636kaoqJRDZd0MAkKfhT9pJI1NEZL_F7rU1bdXjvNV3vdRi_KPrTQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~Mv3qbi23MXIDzPEPgJ9KsTi7ro2YUP8bDbdP3vH1W4EalY5rZerLPEmxf7jQiM2XYZKuBm0-8bQfyAYYNXSVGQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~Ns-bzKQx8G36fLzi7rojTuwSmp8ll6sTNBKWHoIGsFwtx78P-7o8OXBT6h-BdyUWppLQ8y2XWq9xANOdcLxM6w==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~OYl0nlXqB-ZHe4aHqwi4KqKpmjPsT1uG9iTB85qRck0MdoX_PuVHoJpsjmRzbENZQKlpIlWWjNLlZK8N8ouRQg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~OYl0nlXqB-ZHe4aHqwi4KqKpmjPsT1uG9iTB85qRck0MdoX_PuVHoJpsjmRzbENZQKlpIlWWjNLlZK8N8ouRQg== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~Q8sTyAcSG_vQ7QvWvQLAXn6XGWh9PM_OIMsDBFAv0wx1Eqv8jeNCM6LN2jM5ARGnlLugCrMbBsoDR6Jc6EGTrw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~Q8sTyAcSG_vQ7QvWvQLAXn6XGWh9PM_OIMsDBFAv0wx1Eqv8jeNCM6LN2jM5ARGnlLugCrMbBsoDR6Jc6EGTrw== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~TE2FhTmJYZ2fpDbV9KOH_GYVYzM8w7I1kG31UQfZSg2zOsFVQ_ILMkKXfD2tGug3gqncLudmXhqVa7agzDoWtw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~TE2FhTmJYZ2fpDbV9KOH_GYVYzM8w7I1kG31UQfZSg2zOsFVQ_ILMkKXfD2tGug3gqncLudmXhqVa7agzDoWtw== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~Tb67rfKaWyD6tF7TA9Eig401NC9Txmq2o32ySXFDX5XkQ_UaMsBea6lYolT1EKt1wyeW2Sw04mno5Tj5TAqqWw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~Tb67rfKaWyD6tF7TA9Eig401NC9Txmq2o32ySXFDX5XkQ_UaMsBea6lYolT1EKt1wyeW2Sw04mno5Tj5TAqqWw== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~VY8CqbDqQGlciToyYBfYzPYKuVkzTPQgQIRpSWAdlnlEN1xhUI91vxf8n9bZ4KNrJv-DuV-BK914NGUZGE1vgg==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~VY8CqbDqQGlciToyYBfYzPYKuVkzTPQgQIRpSWAdlnlEN1xhUI91vxf8n9bZ4KNrJv-DuV-BK914NGUZGE1vgg== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~WBxsxjslHvapVgvmKeyHG8WwjVBLV8I6q_2RoBB269DBLoDJejrjkNqu2Bt9uud1VMpwo0m6Vp3IEt4i4qI34A==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~WBxsxjslHvapVgvmKeyHG8WwjVBLV8I6q_2RoBB269DBLoDJejrjkNqu2Bt9uud1VMpwo0m6Vp3IEt4i4qI34A== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~XFCwqVKYQEhKveeH-nDRknBOg9_cT9XM8VRSpI9Bqxj1nqnpXX2fX3Pqx-_LUZLFgT4XKDUfCGe1QsSzRYPZ-w==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~XFCwqVKYQEhKveeH-nDRknBOg9_cT9XM8VRSpI9Bqxj1nqnpXX2fX3Pqx-_LUZLFgT4XKDUfCGe1QsSzRYPZ-w== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~Y-LxNPpMhhlXlJMGILjd_s1DuOFlYoWFLz59WGxlMhUSvYAiMhdtZ18iERc8I3TlEmBgRJthjAi40wa-c2YxHw==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~Y-LxNPpMhhlXlJMGILjd_s1DuOFlYoWFLz59WGxlMhUSvYAiMhdtZ18iERc8I3TlEmBgRJthjAi40wa-c2YxHw== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~YhpPJjwAaYK49y6xtCTPhXjRd5h67H-_UIC03bX0X9r8duD2jFu93rGZ88WU1Jh4zApifUxA1odQkx2TQeBEow==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~YhpPJjwAaYK49y6xtCTPhXjRd5h67H-_UIC03bX0X9r8duD2jFu93rGZ88WU1Jh4zApifUxA1odQkx2TQeBEow== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~Z1eUZtKuKH4U6Z5CcijzzaTBvbS8_btB4hat3B6VGpFb2M7z22GNRBMaRrnODcI3kcwavyLRPOs_Q-3oSGczRA==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~Z1eUZtKuKH4U6Z5CcijzzaTBvbS8_btB4hat3B6VGpFb2M7z22GNRBMaRrnODcI3kcwavyLRPOs_Q-3oSGczRA== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~an-MjwYPv5jGpBO4LOh5e6MfvCwh1oiicTdOxfKguEnBB5RCmqE-bWjWX2hq8WlXv4tWh6NREHXJRzJLv87cSw==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~ca2Nyd-DQTvSubqeVe3fuPpYe2Zhc1sJ38Cn5zWbzecmaSkQHFmscQOlERucFvLJ6iF5JwG9IgIAkwNpfz4g4w==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~cig9aU8wbVYC1FRjSNPQteGAH75x-AzwDjui6xIo0tNAzLCA5Ixi_clkgR4gsbn9b0D0z5iQ2VJ7sZ8XJAqENQ==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~cig9aU8wbVYC1FRjSNPQteGAH75x-AzwDjui6xIo0tNAzLCA5Ixi_clkgR4gsbn9b0D0z5iQ2VJ7sZ8XJAqENQ== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~fKDNQVWmg4-bXvTNVQyY9rCWHRMvAzkIP7iFGfkkQcOqINkYsctuvEIqYWi55L7z5AORwoHt3t3WNuo13iSTnQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~gci9xFlEq0G4qP789bnD7Gp_YXpUGLSc7bYUjihQJk6fus1sIO1ZAQlwaxlwXkx2_TBEeWA1WegjrWHn-rUN0w==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~jbHx1Hn8RN5tZGPJ9dVIovExaTAeOcS1nJFfioYZTwBQtNoZKp0Kuho1AmV4hNcGRbzFTkrZ2acfx0jgMRA_LQ==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~lD1FMB_PbaosCwmDMM0SltEeOWJl4T4KouTBmxuJC38u1kTi19u4xmkmcUpliaKqo0xhMwTgYQZrgT3J7qBhPA==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~lumBJu_i3Jb05RQxPDi9paJmQhq64l-r1p7LsBLKAUZBaOgeBlB1fuMvLE28kBpa4THoPvGmfj1cc3QfYTYcvg==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~oRMi0sbQLktfDDDGUS-SqBKpdDiD6HCztVES_ShfGr0KVcYENoIq7y9oUSDWL5B_P2gkdtWG8JEsJLxPbdWOZA==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~rTfC2vU6ZXnhBsRZZliZJVFQpvn-w7HPCQE_gNlEdiAf5wCkvvSlIIMlyOk73iGjSstM5RNUNSEtNVAPQwR0Yg==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~s_ij9vBr3bcJMMjqQuE5efqmOwB_ncnzJix9goq3iderASwacda-Q24RCgdWsEq4L7dVEPC_UuMJxOu8KAYXqw==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~wp21HLmd5m-UM-XZ_zFAoky6NJEPevfr_pbRfBxddabQ34Tk7HjchlwxyBz7t-JwKAxsXI67jYaPWgX_iV9C5w==: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastlane-community/xcresult/e369a2c781d6912be69437b1da65a39c5efd5007/spec/fixtures/Test.xcresult/Data/refs.0~wp21HLmd5m-UM-XZ_zFAoky6NJEPevfr_pbRfBxddabQ34Tk7HjchlwxyBz7t-JwKAxsXI67jYaPWgX_iV9C5w== -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Data/refs.0~x887GlUHa8RnHzB4uvJReg0Mb9X2BgP1dNB0uq8vkpSe6Vjq3DtNDTaWHg5i2WNR8AQDsuh8ZBKFB0HS1yCz-w==: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/Test.xcresult/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | dateCreated 6 | 2020-04-28T01:36:50Z 7 | externalLocations 8 | 9 | rootId 10 | 11 | hash 12 | 0~WBxsxjslHvapVgvmKeyHG8WwjVBLV8I6q_2RoBB269DBLoDJejrjkNqu2Bt9uud1VMpwo0m6Vp3IEt4i4qI34A== 13 | 14 | storage 15 | 16 | backend 17 | fileBacked2 18 | compression 19 | standard 20 | 21 | version 22 | 23 | major 24 | 3 25 | minor 26 | 24 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/setup' 4 | require 'xcresult' 5 | 6 | RSpec.configure do |config| 7 | # Enable flags like --only-failures and --next-failure 8 | config.example_status_persistence_file_path = '.rspec_status' 9 | 10 | # Disable RSpec exposing methods globally on `Module` and `main` 11 | config.disable_monkey_patching! 12 | 13 | config.expect_with :rspec do |c| 14 | c.syntax = :expect 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/xcresult_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe "XCResult Version" do 4 | let(:path) { File.absolute_path("./spec/fixtures/Test.xcresult") } 5 | let(:summary_id) { "0~2LVFAe2LWJ7FCnOsKan5UgGk7WChVJYuZlxPILKyxdpmfjsMrwjBJ2wUhaJQJ36Per_GRUfTI1cKeO2QiGvB8Q==" } 6 | let!(:subject) { XCResult::Parser.new(path: path) } 7 | let(:command) { subject.send(:xcresulttool_command, "get", "--format json --path #{path} --id #{summary_id}") } 8 | 9 | before do 10 | allow(subject).to receive(:`).with('xcrun xcresulttool version').and_return(xcresulttool_version) 11 | end 12 | 13 | context 'with below 23_021.0 ' do 14 | let(:xcresulttool_version) { 'xcresulttool version 23020, format version 3.53 (current)' } 15 | let(:expected) { "xcrun xcresulttool get --format json --path #{path} --id #{summary_id}" } 16 | 17 | it 'should not have --legacy' do 18 | expect(command).to eq(expected) 19 | end 20 | end 21 | 22 | context 'with 23_021.0 and above' do 23 | let(:xcresulttool_version) { 'xcresulttool version 23022, format version 3.53 (current)' } 24 | let(:expected) { "xcrun xcresulttool get --legacy --format json --path #{path} --id #{summary_id}" } 25 | 26 | it 'should have --legacy' do 27 | expect(command).to eq(expected) 28 | end 29 | end 30 | end 31 | 32 | RSpec.describe "XCResult Test Summaries" do 33 | let(:path) { File.absolute_path("./spec/fixtures/Test.xcresult") } 34 | let(:summary_id) { "0~2LVFAe2LWJ7FCnOsKan5UgGk7WChVJYuZlxPILKyxdpmfjsMrwjBJ2wUhaJQJ36Per_GRUfTI1cKeO2QiGvB8Q==" } 35 | 36 | it 'has a version number' do 37 | expect(XCResult::VERSION).not_to be nil 38 | end 39 | 40 | it 'parse xccov report paths' do 41 | require 'tmpdir' 42 | destination = Dir.mktmpdir 43 | 44 | parser = XCResult::Parser.new(path: path) 45 | export_xccovreport_paths = parser.export_xccovreports(destination: destination) 46 | 47 | expect(export_xccovreport_paths.count).to eq(1) 48 | end 49 | 50 | it 'parse test plan summaries' do 51 | parser = XCResult::Parser.new(path: path) 52 | 53 | expect(parser).to receive(:execute_cmd).with(lambda { |command| 54 | is_valid_xcresulttool_command_regex = /^xcrun xcresulttool get( --legacy)? --format json --path .+ --id [a-zA-Z0-9_\~\=]+$/ 55 | is_valid_xcresulttool_command_regex.match(command) != nil 56 | }).and_call_original 57 | 58 | summaries = parser.action_test_plan_summaries 59 | 60 | testable_summary = summaries[0].summaries[0].testable_summaries[0] 61 | 62 | expect(summaries.count).to eq(1) 63 | expect(summaries[0].summaries.count).to eq(1) 64 | expect(summaries[0].summaries[0].name).to eq("Test Scheme Action") 65 | 66 | expect(testable_summary.tests.count).to eq(1) 67 | expect(testable_summary.tests[0].duration).to eq(9.394425988197327) 68 | expect(testable_summary.tests[0].subtests.count).to eq(1) 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /xcresult.gemspec: -------------------------------------------------------------------------------- 1 | lib = File.expand_path('lib', __dir__) 2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 3 | require 'xcresult/version' 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = 'xcresult' 7 | spec.version = XCResult::VERSION 8 | spec.authors = ['Josh Holtz'] 9 | spec.email = ['me@joshholtz.com'] 10 | 11 | spec.summary = 'Parses xcresult files' 12 | spec.description = 'Parses xcresult files for viewing test summaries and code coverages' 13 | spec.homepage = 'https://github.com/fastlane-community/xcresult' 14 | spec.license = 'MIT' 15 | 16 | # Specify which files should be added to the gem when it is released. 17 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 18 | spec.files = Dir.chdir(File.expand_path(__dir__)) do 19 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 20 | end 21 | spec.bindir = "exe" 22 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 23 | spec.require_paths = ['lib'] 24 | 25 | spec.add_development_dependency 'bundler', '~> 2.0' 26 | spec.add_development_dependency 'rake', '~> 13.0' 27 | spec.add_development_dependency 'rspec', '~> 3.0' 28 | spec.add_development_dependency 'rubocop', '~> 1.65' 29 | end 30 | --------------------------------------------------------------------------------