├── .github ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── codeql-analysis.yml │ └── publish.yml ├── .gitignore ├── .rspec ├── .rubocop.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── docs └── screenshot.png ├── lib └── rspec │ ├── github.rb │ └── github │ ├── formatter.rb │ ├── notification_decorator.rb │ └── version.rb ├── rspec-github.gemspec └── spec ├── integration ├── failing_spec.rb └── relative_path │ └── pending_spec.rb ├── rspec └── github │ ├── formatter_spec.rb │ └── version_spec.rb └── spec_helper.rb /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: bundler 9 | directory: '/' 10 | schedule: 11 | interval: weekly 12 | open-pull-requests-limit: 99 13 | 14 | - package-ecosystem: github-actions 15 | directory: '/' 16 | schedule: 17 | interval: weekly 18 | open-pull-requests-limit: 99 19 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches-ignore: 5 | - 'dependabot/**' 6 | pull_request: 7 | jobs: 8 | reviewdog: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Check out code 12 | uses: actions/checkout@v4 13 | - uses: ruby/setup-ruby@v1 14 | with: 15 | ruby-version: '3.3' 16 | bundler-cache: true 17 | - name: rubocop 18 | uses: reviewdog/action-rubocop@v2 19 | with: 20 | rubocop_version: gemfile 21 | github_token: ${{ secrets.github_token }} 22 | reporter: github-check 23 | rspec: 24 | runs-on: ubuntu-latest 25 | strategy: 26 | matrix: 27 | ruby: 28 | - '3.1' 29 | - '3.2' 30 | - '3.3' 31 | - '3.4' 32 | name: RSpec tests ruby ${{ matrix.ruby }} 33 | steps: 34 | - name: Check out code 35 | uses: actions/checkout@v4 36 | - uses: ruby/setup-ruby@v1 37 | with: 38 | ruby-version: ${{ matrix.ruby }} 39 | bundler-cache: true 40 | - name: Run RSpec 41 | run: bundle exec rspec spec/rspec 42 | e2e: 43 | runs-on: ubuntu-latest 44 | steps: 45 | - name: Check out code 46 | uses: actions/checkout@v4 47 | - uses: ruby/setup-ruby@v1 48 | with: 49 | ruby-version: '3.3' 50 | bundler-cache: true 51 | - name: Run RSpec in GITHUB_WORKSPACE 52 | run: '! bundle exec rspec spec/integration/failing_spec.rb' 53 | - name: Run RSpec in sub-directory of GITHUB_WORKSPACE 54 | run: | 55 | cd spec/integration 56 | bundle exec rspec relative_path/pending_spec.rb --require ../spec_helper --format RSpec::Github::Formatter 57 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '31 22 * * 5' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'ruby' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v4 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v3 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v3 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v3 71 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | on: 3 | release: 4 | types: [published] 5 | 6 | jobs: 7 | publish: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout repo 11 | uses: actions/checkout@v4 12 | - uses: ruby/setup-ruby@v1 13 | with: 14 | ruby-version: '3.3' 15 | - name: Replace version by tag value 16 | run: sed -i "s/'[0-9]\.[0-9]\..*'/'${GITHUB_REF##*/}'/" lib/rspec/github/version.rb 17 | - name: Publish to RubyGems 18 | run: | 19 | mkdir -p $HOME/.gem 20 | touch $HOME/.gem/credentials 21 | chmod 0600 $HOME/.gem/credentials 22 | printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials 23 | gem build *.gemspec 24 | gem push *.gem 25 | env: 26 | GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}} 27 | -------------------------------------------------------------------------------- /.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 | 13 | # Rubymine stuff 14 | .rakeTasks 15 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | --format documentation 4 | --format RSpec::Github::Formatter 5 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | TargetRubyVersion: 3.1 3 | NewCops: enable 4 | 5 | # A top class comment is not needed for this simple gem 6 | Style/Documentation: 7 | Enabled: false 8 | 9 | # 80 chars is really short. Screens got bigger you know. 10 | Layout/LineLength: 11 | Max: 120 12 | 13 | Metrics/BlockLength: 14 | Exclude: 15 | - 'spec/**/*.rb' # Specs just have large blocks 16 | - '*.gemspec' # Is just one block 17 | 18 | # We don't support MFA publishing 19 | Gemspec/RequireMFA: 20 | Enabled: false 21 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | # Specify your gem's dependencies in rspec-github.gemspec 6 | gemspec 7 | 8 | group :development do 9 | gem 'rspec', '~> 3.13' 10 | gem 'rubocop', '~> 1.68.0' 11 | end 12 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | rspec-github (1.0.0.develop) 5 | rspec-core (~> 3.0) 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | ast (2.4.2) 11 | diff-lcs (1.5.1) 12 | json (2.7.5) 13 | language_server-protocol (3.17.0.3) 14 | parallel (1.26.3) 15 | parser (3.3.5.1) 16 | ast (~> 2.4.1) 17 | racc 18 | racc (1.8.1) 19 | rainbow (3.1.1) 20 | regexp_parser (2.9.2) 21 | rspec (3.13.0) 22 | rspec-core (~> 3.13.0) 23 | rspec-expectations (~> 3.13.0) 24 | rspec-mocks (~> 3.13.0) 25 | rspec-core (3.13.2) 26 | rspec-support (~> 3.13.0) 27 | rspec-expectations (3.13.0) 28 | diff-lcs (>= 1.2.0, < 2.0) 29 | rspec-support (~> 3.13.0) 30 | rspec-mocks (3.13.0) 31 | diff-lcs (>= 1.2.0, < 2.0) 32 | rspec-support (~> 3.13.0) 33 | rspec-support (3.13.1) 34 | rubocop (1.68.0) 35 | json (~> 2.3) 36 | language_server-protocol (>= 3.17.0) 37 | parallel (~> 1.10) 38 | parser (>= 3.3.0.2) 39 | rainbow (>= 2.2.2, < 4.0) 40 | regexp_parser (>= 2.4, < 3.0) 41 | rubocop-ast (>= 1.32.2, < 2.0) 42 | ruby-progressbar (~> 1.7) 43 | unicode-display_width (>= 2.4.0, < 3.0) 44 | rubocop-ast (1.33.1) 45 | parser (>= 3.3.1.0) 46 | ruby-progressbar (1.13.0) 47 | unicode-display_width (2.6.0) 48 | 49 | PLATFORMS 50 | ruby 51 | 52 | DEPENDENCIES 53 | rspec (~> 3.13) 54 | rspec-github! 55 | rubocop (~> 1.68.0) 56 | 57 | BUNDLED WITH 58 | 2.6.0 59 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Stef Schenkelaars 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 | # Rspec::Github 2 | [![CI](https://github.com/Drieam/rspec-github/actions/workflows/ci.yml/badge.svg)](https://github.com/Drieam/rspec-github/actions/workflows/ci.yml) 3 | [![Gem Version](https://badge.fury.io/rb/rspec-github.svg)](https://badge.fury.io/rb/rspec-github) 4 | 5 | [RSpec](https://rspec.info/) formatter compatible with [GitHub Action](https://github.com/features/actions)'s annotations. It supports multiline errors and will set pending specs as warnings: 6 | 7 | ![screenshot.png](docs/screenshot.png) 8 | 9 | ## Installation 10 | Add the gem to your application's `Gemfile` `test` group: 11 | 12 | ```ruby 13 | group :test do 14 | gem 'rspec-github', require: false 15 | end 16 | ``` 17 | 18 | And then of course install the gem by executing: 19 | 20 | ```bash 21 | bundle install 22 | ``` 23 | 24 | ## Usage 25 | You can specify the formatter with a command line argument: 26 | 27 | ```bash 28 | rspec --format RSpec::Github::Formatter 29 | ``` 30 | 31 | And to always run it with this formatter, you can set it in the `.rspec` file: 32 | 33 | ``` 34 | # other configuration 35 | --format RSpec::Github::Formatter 36 | ``` 37 | 38 | And to register the formatter in configuration, you can add the following to `spec/spec_helper.rb`: 39 | 40 | ```ruby 41 | RSpec.configure do |config| 42 | # Use the GitHub Annotations formatter for CI 43 | if ENV['GITHUB_ACTIONS'] == 'true' 44 | require 'rspec/github' 45 | config.add_formatter RSpec::Github::Formatter 46 | end 47 | end 48 | ``` 49 | 50 | Note that you can select multiple formatters so that you can also see other output: 51 | ```bash 52 | rspec --format RSpec::Github::Formatter --format progress 53 | rspec --format RSpec::Github::Formatter --format documentation 54 | ``` 55 | 56 | If you want to disable annotations for pending specs you can do that by adding `--tag ~skip` to your command: 57 | ```bash 58 | rspec --format RSpec::Github::Formatter --tag ~skip 59 | ``` 60 | 61 | ## Development 62 | After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests. 63 | Publishing a new version is handled by the [publish workflow](.github/workflows/publish.yml). This workflow publishes a GitHub release to [rubygems](https://rubygems.org/) with the version defined in the release. 64 | 65 | ### Useful references 66 | - https://help.github.com/en/actions/reference/development-tools-for-github-actions 67 | - https://developer.github.com/apps/quickstart-guides/creating-ci-tests-with-the-checks-api 68 | 69 | ## License 70 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 71 | -------------------------------------------------------------------------------- /docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Drieam/rspec-github/8a1c0332ddf3b8dfc8da2c0b87d43b6ecd94561c/docs/screenshot.png -------------------------------------------------------------------------------- /lib/rspec/github.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rspec/github/version' 4 | require 'rspec/github/formatter' 5 | 6 | module RSpec 7 | module Github 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/rspec/github/formatter.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rspec/core' 4 | require 'rspec/core/formatters/base_formatter' 5 | require 'rspec/github/notification_decorator' 6 | 7 | module RSpec 8 | module Github 9 | class Formatter < RSpec::Core::Formatters::BaseFormatter 10 | RSpec::Core::Formatters.register self, :example_failed, :example_pending, :seed 11 | 12 | def example_failed(failure) 13 | notification = NotificationDecorator.new(failure) 14 | 15 | output.puts "\n::error file=#{notification.path},line=#{notification.line}::#{notification.annotation}" 16 | end 17 | 18 | def example_pending(pending) 19 | notification = NotificationDecorator.new(pending) 20 | 21 | output.puts "\n::warning file=#{notification.path},line=#{notification.line}::#{notification.annotation}" 22 | end 23 | 24 | def seed(notification) 25 | return unless notification.seed_used? 26 | 27 | output.puts notification.fully_formatted 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/rspec/github/notification_decorator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RSpec 4 | module Github 5 | class NotificationDecorator 6 | # See https://github.community/t/set-output-truncates-multiline-strings/16852/3. 7 | ESCAPE_MAP = { 8 | '%' => '%25', 9 | "\n" => '%0A', 10 | "\r" => '%0D' 11 | }.freeze 12 | 13 | def initialize(notification) 14 | @notification = notification 15 | end 16 | 17 | def line 18 | example.location.split(':')[1] 19 | end 20 | 21 | def annotation 22 | "#{example.full_description}\n\n#{message}" 23 | .gsub(Regexp.union(ESCAPE_MAP.keys), ESCAPE_MAP) 24 | end 25 | 26 | def path 27 | # TODO: use `delete_prefix` when dropping ruby 2.4 support 28 | File.realpath(raw_path).sub(/\A#{workspace}#{File::SEPARATOR}/, '') 29 | end 30 | 31 | private 32 | 33 | def example 34 | @notification.example 35 | end 36 | 37 | def message 38 | if @notification.respond_to?(:message_lines) 39 | @notification.message_lines.join("\n") 40 | else 41 | "#{example.skip ? 'Skipped' : 'Pending'}: #{example.execution_result.pending_message}" 42 | end 43 | end 44 | 45 | def raw_path 46 | example.location.split(':')[0] 47 | end 48 | 49 | def workspace 50 | File.realpath(ENV.fetch('GITHUB_WORKSPACE', '.')) 51 | end 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/rspec/github/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RSpec 4 | module Github 5 | VERSION = '1.0.0.develop' 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /rspec-github.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'lib/rspec/github/version' 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = 'rspec-github' 7 | spec.version = RSpec::Github::VERSION 8 | spec.authors = ['Stef Schenkelaars'] 9 | spec.email = ['stef.schenkelaars@gmail.com'] 10 | 11 | spec.summary = 'Formatter for RSpec to show errors in GitHub action annotations' 12 | spec.description = 'Formatter for RSpec to show errors in GitHub action annotations' 13 | spec.homepage = 'https://drieam.github.io/rspec-github' 14 | spec.license = 'MIT' 15 | spec.required_ruby_version = Gem::Requirement.new('>= 3.1') 16 | 17 | spec.metadata['allowed_push_host'] = 'https://rubygems.org' 18 | spec.metadata['homepage_uri'] = spec.homepage 19 | spec.metadata['source_code_uri'] = 'https://github.com/drieam/rspec-github' 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | spec.files = Dir['{lib}/**/*'] 23 | 24 | spec.add_runtime_dependency 'rspec-core', '~> 3.0' 25 | end 26 | -------------------------------------------------------------------------------- /spec/integration/failing_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe RSpec::Github::Formatter do 4 | it 'creates an error annotation for failing specs' do 5 | expect(true).to eq false 6 | end 7 | 8 | it 'creates a warning annotation for unimplemented specs' 9 | 10 | it 'creates a warning annotation for pending specs' do 11 | pending 'because it is failing' 12 | raise 13 | end 14 | 15 | it 'creates a warning annotation for skipped specs' do 16 | skip 'because reasons' 17 | end 18 | 19 | it 'does not create an annotiation for passing specs' do 20 | expect(true).to eq true 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/integration/relative_path/pending_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe RSpec::Github::Formatter do 4 | it 'adds annotiations correctly when running in a subdirectory' 5 | end 6 | -------------------------------------------------------------------------------- /spec/rspec/github/formatter_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'tmpdir' 4 | 5 | RSpec.describe RSpec::Github::Formatter do 6 | let(:output) { StringIO.new } 7 | let(:formatter) { described_class.new(output) } 8 | subject(:output_string) { output.string } 9 | let(:skip) { false } 10 | 11 | let(:location) { './spec/models/user_spec.rb:12' } 12 | 13 | let(:pending_message) { 'Not yet implemented' } 14 | 15 | let(:execution_result) do 16 | double( 17 | 'RSpec::Core::Example::ExecutionResult', 18 | pending_message: pending_message 19 | ) 20 | end 21 | 22 | let(:example) do 23 | double( 24 | 'RSpec::Core::Example', 25 | execution_result: execution_result, 26 | full_description: 'User is expected to validate presence of name', 27 | description: 'is expected to validate presence of name', 28 | location: location, 29 | skip: skip 30 | ) 31 | end 32 | 33 | before do 34 | allow(File).to receive(:realpath).and_call_original 35 | allow(File).to receive(:realpath).with('./spec/models/user_spec.rb') 36 | .and_return(File.join(Dir.pwd, 'spec/models/user_spec.rb')) 37 | end 38 | 39 | describe '#example_failed' do 40 | before { formatter.example_failed(notification) } 41 | 42 | let(:notification) do 43 | double( 44 | 'RSpec::Core::Notifications::FailedExampleNotification', 45 | example: example, 46 | message_lines: [ 47 | 'Failure/Error: it { is_expected.to validate_presence_of :name }', 48 | '', 49 | ' Expected User to validate that :name cannot be empty/falsy, but this', 50 | ' could not be proved.', 51 | ' After setting :name to ‹""›, the matcher expected the User to be', 52 | ' invalid, but it was valid instead.' 53 | ] 54 | ) 55 | end 56 | 57 | it 'outputs the GitHub annotation formatted error' do 58 | is_expected.to eq <<~MESSAGE 59 | 60 | ::error file=spec/models/user_spec.rb,line=12::#{example.full_description}%0A%0A#{notification.message_lines.join('%0A')} 61 | MESSAGE 62 | end 63 | 64 | context 'relative_path to GITHUB_WORKSPACE' do 65 | around do |example| 66 | saved_github_workspace = ENV.fetch('GITHUB_WORKSPACE', nil) 67 | ENV['GITHUB_WORKSPACE'] = tmpdir 68 | 69 | FileUtils.mkpath File.dirname(absolute_path) 70 | FileUtils.touch absolute_path 71 | 72 | Dir.chdir tmpdir do 73 | example.run 74 | end 75 | ensure 76 | FileUtils.rm_r tmpdir 77 | ENV['GITHUB_WORKSPACE'] = saved_github_workspace 78 | end 79 | 80 | let(:tmpdir) { Dir.mktmpdir } 81 | let(:relative_path) { 'this/is/a/relative_path.rb' } 82 | let(:absolute_path) { File.join(tmpdir, relative_path) } 83 | 84 | context 'inside root dir' do 85 | let(:github_workspace) { tmpdir } 86 | let(:location) { './this/is/a/relative_path.rb' } 87 | 88 | it 'returns the relative path' do 89 | is_expected.to include 'this/is/a/relative_path.rb' 90 | end 91 | end 92 | context 'inside subdirectory dir' do 93 | let(:github_workspace) { tmpdir } 94 | let(:location) { './a/relative_path.rb' } 95 | around do |example| 96 | Dir.chdir 'this/is' do 97 | example.run 98 | end 99 | end 100 | 101 | it 'returns the relative path' do 102 | is_expected.to include 'this/is/a/relative_path.rb' 103 | end 104 | end 105 | end 106 | end 107 | 108 | describe '#example_pending' do 109 | before { formatter.example_pending(notification) } 110 | 111 | let(:notification) do 112 | double( 113 | 'RSpec::Core::Notifications::SkippedExampleNotification', 114 | example: example 115 | ) 116 | end 117 | 118 | context 'when pending' do 119 | it 'outputs the GitHub annotation formatted warning' do 120 | is_expected.to eq <<~MESSAGE 121 | 122 | ::warning file=spec/models/user_spec.rb,line=12::#{example.full_description}%0A%0APending: #{pending_message} 123 | MESSAGE 124 | end 125 | end 126 | 127 | context 'when skipped' do 128 | let(:skip) { true } 129 | 130 | it 'outputs the GitHub annotation formatted warning' do 131 | is_expected.to eq <<~MESSAGE 132 | 133 | ::warning file=spec/models/user_spec.rb,line=12::#{example.full_description}%0A%0ASkipped: #{pending_message} 134 | MESSAGE 135 | end 136 | end 137 | end 138 | 139 | describe '#seed' do 140 | before { formatter.seed(notification) } 141 | 142 | context 'when seed used' do 143 | let(:notification) do 144 | RSpec::Core::Notifications::SeedNotification.new(4242, true) 145 | end 146 | 147 | it 'outputs the fully formatted seed notification' do 148 | is_expected.to eq "\nRandomized with seed 4242\n" 149 | end 150 | end 151 | 152 | context 'when seed not used' do 153 | let(:notification) do 154 | RSpec::Core::Notifications::SeedNotification.new(nil, false) 155 | end 156 | 157 | it { is_expected.to be_empty } 158 | end 159 | end 160 | end 161 | -------------------------------------------------------------------------------- /spec/rspec/github/version_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe RSpec::Github do 4 | it 'has a predefined version since this will be changed by the release action' do 5 | expect(described_class::VERSION).to eq '1.0.0.develop' 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/setup' 4 | require 'rspec/github' 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 | --------------------------------------------------------------------------------