Skip to content

Commit

Permalink
Feature/RSpec integration (#27)
Browse files Browse the repository at this point in the history
* Added DnsMock::TestFramework::RSpec::Interface, tests
* Added DnsMock::TestFramework::RSpec::Helper, tests
* Added RSpec DnsMock config
* Updated gem version, documentation, changelog
  • Loading branch information
bestwebua authored Feb 1, 2021
1 parent 130779a commit 819726d
Show file tree
Hide file tree
Showing 12 changed files with 296 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ detectors:
- DnsMock::ServerHelper#start_random_server
- DnsMock::ServerHelper#stop_all_running_servers
- DnsMock::Server::RecordsDictionaryBuilder#rdns_lookup_prefix
- DnsMock::ContextGeneratorHelper#random_port_number
- DnsMock::TestFramework::RSpec::Helper#dns_mock_server

ControlParameter:
exclude:
Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,40 @@

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.0] - 2021-02-01

### RSpec native support

Added DnsMock helper which can simplify integration with RSpec.

```ruby
# spec/support/config/dns_mock.rb
require 'dns_mock/test_framework/rspec'

RSpec.configure do |config|
config.include DnsMock::TestFramework::RSpec::Helper
end

# your awesome first_a_record_spec.rb
RSpec.describe FirstARecord do
subject(:service) do
described_class.call(
hostname,
dns_gateway_host: 'localhost',
dns_gateway_port: dns_mock_server.port
)
end

let(:hostname) { 'example.com' }
let(:first_a_record) { '1.2.3.4' }
let(:records) { { hostname => { a: [first_a_record] } } }

before { dns_mock_server.assign_mocks(records) }

it { is_expected.to eq(first_a_record) }
end
```

## [1.0.0] - 2021-01-29

### Configurable record not found behaviour
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
dns_mock (1.0.0)
dns_mock (1.1.0)

GEM
remote: https://rubygems.org/
Expand Down
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
- [RSpec](#rspec)
- [Contributing](#contributing)
- [License](#license)
- [Code of Conduct](#code-of-conduct)
Expand Down Expand Up @@ -110,6 +111,68 @@ DnsMock.running_servers # => [DnsMock::Server instance]
DnsMock.stop_running_servers! # => true
```

### RSpec

Require this either in your Gemfile or in RSpec's support scripts. So either:

```ruby
# Gemfile
group :test do
gem 'rspec'
gem 'dns_mock', require: 'dns_mock/test_framework/rspec'
end
```

or

```ruby
# spec/support/config/dns_mock.rb
require 'dns_mock/test_framework/rspec'
```

#### DnsMock RSpec helper

Just add `DnsMock::TestFramework::RSpec::Helper` if you wanna have shortcut for DnsMock server instance into your RSpec.describe blocks:

```ruby
# spec/support/config/dns_mock.rb
RSpec.configure do |config|
config.include DnsMock::TestFramework::RSpec::Helper
end
```

```ruby
# your awesome first_a_record_spec.rb
RSpec.describe FirstARecord do
subject(:service) do
described_class.call(
hostname,
dns_gateway_host: 'localhost',
dns_gateway_port: dns_mock_server.port
)
end

let(:hostname) { 'example.com' }
let(:first_a_record) { '1.2.3.4' }
let(:records) { { hostname => { a: [first_a_record] } } }

before { dns_mock_server.assign_mocks(records) }

it { is_expected.to eq(first_a_record) }
end
```

#### DnsMock RSpec interface

If you won't use `DnsMock::TestFramework::RSpec::Helper` you can use `DnsMock::TestFramework::RSpec::Interface` directly instead:

```ruby
DnsMock::TestFramework::RSpec::Interface.start_server # creates and runs DnsMock server instance
DnsMock::TestFramework::RSpec::Interface.stop_server! # stops current DnsMock server instance
DnsMock::TestFramework::RSpec::Interface.reset_mocks! # resets mocks in current DnsMock server instance
DnsMock::TestFramework::RSpec::Interface.clear_server! # stops and clears current DnsMock server instance
```

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/mocktools/ruby-dns-mock. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. Please check the [open tikets](https://github.com/mocktools/ruby-dns-mock/issues). Be shure to follow Contributor Code of Conduct below and our [Contributing Guidelines](CONTRIBUTING.md).
Expand Down
12 changes: 12 additions & 0 deletions lib/dns_mock/test_framework/rspec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require 'rspec/core'
require_relative '../../dns_mock'
require_relative './rspec/interface'
require_relative './rspec/helper'

RSpec.configure do |config|
config.before(:suite) { DnsMock::TestFramework::RSpec::Interface.start_server }
config.after(:suite) { DnsMock::TestFramework::RSpec::Interface.stop_server! }
config.after { DnsMock::TestFramework::RSpec::Interface.reset_mocks! }
end
15 changes: 15 additions & 0 deletions lib/dns_mock/test_framework/rspec/helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require_relative './interface'

module DnsMock
module TestFramework
module RSpec
module Helper
def dns_mock_server(**options)
DnsMock::TestFramework::RSpec::Interface.start_server(**options)
end
end
end
end
end
35 changes: 35 additions & 0 deletions lib/dns_mock/test_framework/rspec/interface.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

module DnsMock
module TestFramework
module RSpec
module Interface
class << self
def start_server(**options)
@dns_mock_server ||= DnsMock.start_server(**options) # rubocop:disable Naming/MemoizedInstanceVariableName
end

def stop_server!
return unless dns_mock_server

dns_mock_server.stop!
end

def reset_mocks!
return unless dns_mock_server

dns_mock_server.reset_mocks!
end

def clear_server!
@dns_mock_server = nil
end

private

attr_reader :dns_mock_server
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/dns_mock/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module DnsMock
VERSION = '1.0.0'
VERSION = '1.1.0'
end
42 changes: 42 additions & 0 deletions spec/dns_mock/test_framework/rspec/helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require_relative '../../../../lib/dns_mock/test_framework/rspec/helper'

class TestClass
include DnsMock::TestFramework::RSpec::Helper
end

RSpec.describe DnsMock::TestFramework::RSpec::Helper do
let(:test_class_instance) { TestClass.new }

describe '.dns_mock_server' do
let(:dns_mock_server_instance) { instance_double('DnsMockServerInstance') }

context 'with kwargs' do
subject(:helper) { test_class_instance.dns_mock_server(**options) }

let(:records) { random_records }
let(:port) { random_port_number }
let(:options) { { records: records, port: port } }

it do
expect(DnsMock::TestFramework::RSpec::Interface)
.to receive(:start_server)
.with(**options)
.and_return(dns_mock_server_instance)
expect(helper).to eq(dns_mock_server_instance)
end
end

context 'without kwargs' do
subject(:helper) { test_class_instance.dns_mock_server }

it do
expect(DnsMock::TestFramework::RSpec::Interface)
.to receive(:start_server)
.and_return(dns_mock_server_instance)
expect(helper).to eq(dns_mock_server_instance)
end
end
end
end
71 changes: 71 additions & 0 deletions spec/dns_mock/test_framework/rspec/interface_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# frozen_string_literal: true

require_relative '../../../../lib/dns_mock/test_framework/rspec/interface'

RSpec.describe DnsMock::TestFramework::RSpec::Interface do
after { described_class.clear_server! }

describe '.start_server' do
let(:dns_mock_server_instance) { instance_double('DnsMockServerInstance') }

context 'with kwargs' do
subject(:start_server) { described_class.start_server(**options) }

let(:records) { random_records }
let(:port) { random_port_number }
let(:options) { { records: records, port: port } }

it do
expect(DnsMock).to receive(:start_server).with(**options).and_return(dns_mock_server_instance)
expect(start_server).to eq(dns_mock_server_instance)
end
end

context 'without kwargs' do
subject(:start_server) { described_class.start_server }

it do
expect(DnsMock).to receive(:start_server).and_return(dns_mock_server_instance)
expect(start_server).to eq(dns_mock_server_instance)
end
end
end

describe '.stop_server!' do
subject(:stop_server) { described_class.stop_server! }

context 'when dns mock server exists' do
before { described_class.start_server }

after { stop_all_running_servers }

it { is_expected.to be(true) }
end

context 'when dns mock server not exists' do
it { is_expected.to be_nil }
end
end

describe '.reset_mocks!' do
subject(:stop_server) { described_class.reset_mocks! }

context 'when dns mock server exists' do
before { described_class.start_server }

after { stop_all_running_servers }

it { is_expected.to be(true) }
end

context 'when dns mock server not exists' do
it { is_expected.to be_nil }
end
end

describe 'clear_server!' do
subject(:clear_server) { described_class.clear_server! }

it { is_expected.to be_nil }
end
end
4 changes: 4 additions & 0 deletions spec/support/helpers/context_generator_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ def random_records
{ hostname => records[hostname].slice(*random_dns_record_types) }
end

def random_port_number
::Random.rand(DnsMock::Server::RandomAvailablePort::MIN_DYNAMIC_PORT_NUMBER..DnsMock::Server::RandomAvailablePort::MAX_DYNAMIC_PORT_NUMBER)
end

module_function

def random_hostname
Expand Down
16 changes: 16 additions & 0 deletions spec/support/helpers/context_generator_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,20 @@
expect(DnsMock::AVAILABLE_DNS_RECORD_TYPES).to include(*records_by_hostname.keys)
end
end

describe 'random_port_number' do
subject(:helper) { random_port_number }

let(:port_number) { 42 }

before do
stub_const('DnsMock::Server::RandomAvailablePort::MIN_DYNAMIC_PORT_NUMBER', port_number)
stub_const('DnsMock::Server::RandomAvailablePort::MAX_DYNAMIC_PORT_NUMBER', port_number)
end

it 'returns random port number as Integer' do
expect(::Random).to receive(:rand).and_call_original
expect(helper).to eq(port_number)
end
end
end

0 comments on commit 819726d

Please sign in to comment.