
Security News
libxml2 Maintainer Ends Embargoed Vulnerability Reports, Citing Unsustainable Burden
Libxml2’s solo maintainer drops embargoed security fixes, highlighting the burden on unpaid volunteers who keep critical open source software secure.
🆎 Этот текст можно прочитать на русском языке: README-ru.md.
RSpecMagic is a set of extensions for writing compact and expressive tests.
💡 It's assumed that you've already set up RSpec in your project.
Add to your project's Gemfile
:
gem "rspec_magic"
#gem "rspec_magic", git: "https://github.com/dadooda/rspec_magic"
Add to your RSpec startup file (usually spec/spec_helper.rb
):
require "rspec_magic/stable"
require "rspec_magic/unstable"
RSpecMagic::Config.spec_path = File.expand_path(".", __dir__)
The spec_path
is used by some of the features, notably, include_dir_context.
The computed path should point to spec/
of the project's directory.
See Details.
alias_method
A matcher to check that a method is an alias of another method.
describe User do
it { is_expected.to alias_method(:admin?, :is_admin) }
end
context_when
Create a self-descriptive "when …"
context with one or more let
variables defined.
The blocks below are synonymous.
context_when name: "Joe", age: 25 do
it do
expect([name, age]).to eq ["Joe", 25]
end
end
context "when { name: \"Joe\", age: 25 }" do
let(:name) { "Joe" }
let(:age) { 25 }
it do
expect([name, age]).to eq ["Joe", 25]
end
end
See Details.
described_sym
Transform described_class
into underscored symbols described_sym
and me
.
describe UserProfile do
it { expect(described_sym).to eq :user_profile }
it { expect(me).to eq :user_profile }
end
Common usage with a factory:
describe UserProfile do
let(:uprof1) { create described_sym }
let(:uprof2) { create me }
…
end
include_dir_context
♒︎ This feature was added recently and may change.
Organize shared contexts (shared_context) in a hierarchy. Import relevant shared contexts into the given test.
Follow these steps:
Make sure that RSpecMagic::Config.spec_path
is configured correctly.
It must point to project's spec/
.
Across the spec directory tree, create the shared context files, each named _context.rb
.
A typical _context.rb
looks like this:
shared_context __dir__ do
…
end
Add to your hypothetical spec_helper.rb
:
# Load the shared contexts hierarchy.
Dir[File.expand_path("**/_context.rb", __dir__)].each { |fn| require fn }
In the given spec file, add a call to include_dir_context
in the body of the outermost describe
:
describe … do
include_dir_context __dir__
…
end
Say, our spec file is spec/app/controllers/api/player_controller_spec.rb
.
The main describe
will load the contexts from the following files, if any:
spec/_context.rb
spec/app/_context.rb
spec/app/controllers/_context.rb
spec/app/controllers/api/_context.rb
See Details.
use_letset
Define a method to create let
variables, which comprise a Hash
collection.
describe do
# Method is `let_a`. Collection is `attrs`.
use_letset :let_a, :attrs
# Declare `attrs` elements.
let_a(:age)
let_a(:name)
subject { attrs }
# None of the elements is set yet.
it { is_expected.to eq({}) }
# Set `name` and see it in the collection.
context_when name: "Joe" do
it { is_expected.to eq(name: "Joe") }
# Add `age` and see both in the collection.
context_when age: 25 do
it { is_expected.to eq(name: "Joe", age: 25) }
end
end
end
When used with a block, let_a
behaves like a regular let
:
describe do
use_letset :let_a, :attrs
let_a(:age) { 25 }
let_a(:name) { "Joe" }
it { expect(attrs).to eq(name: "Joe", age: 25) }
end
use_method_discovery
Create an automatic let
variable containing the method or action name,
computed from the description of the parent describe
.
describe do
use_method_discovery :m
subject { m }
describe "#first_name" do
it { is_expected.to eq :first_name }
end
describe ".some_stuff" do
it { is_expected.to eq :some_stuff }
end
describe "GET some_action" do
describe "intermediate context" do
it { is_expected.to eq :some_action } # (1)
end
end
end
m
finds the nearest usable context, whose description format allows
the extraction of the method name.
At the line marked (1) above, m
ignores the loosely formatted "intermediate context"
and grabs the data from "GET some_action"
.
stable
and unstable
are feature sets.
Set unstable
contains recently added features that may change in the coming versions.
It's possible to include specific features only. Example:
require "rspec_magic/stable/use_method_discovery"
context_when
The context can be temporarily excluded by prepending x
:
xcontext_when … do
…
end
It's possible to define a custom report line formatter:
describe "…" do
def self._context_when_formatter(h)
"when #{h.to_json}"
end
context_when … do
…
end
end
context_when
works nicely with use_letset,
usually to set the attributes of the object being tested.
The values of let
belong to the describe
level.
If you need values computed at the it
level, use the traditional let(…) { … }
inside the context.
include_dir_context
There's a cool thing in RSpec — shared_context.
The idea is simple: somewhere (in a hypothetical spec_helper.rb
) fold something reusable in a shared_context "this and that"
,
and then import that stuff via include_context "this and that"
where we need it.
We can put anything in shared_context
— reusable tests, let
variables, but most importantly —
methods, both belonging to the describe
level (def self.doit
) and the it
level (def doit
).
Sounds like a library, innit?
There's a pinch of salt though. Existing means of contexts management are very primitive and rely solely on unique global names.
RSpec doesn't let us organize shared contexts in a hierarchy, and import them automatically into groups of spec files, such as: all model tests get context M, all controller tests get context C, and all at once get context A.
In order to maintain minimal order, one has to come up with unique names for shared contexts, and list those contexts in each and every spec file:
describe … do
include_context "basic"
include_context "controllers"
include_context "api_controllers"
…
end
If you see anything like this, give your kudos to the author, as this is an advanced level. Most of the time, people don't even do that, but simply dump all of their extensions into some “helper”-like pile of cr%p, justifying it by stating that “there was no time to sort it out”.
What does include_dir_context
have to offer?
See the main chapter for a step-by-step example.
The product is free software distributed under the terms of the MIT license.
— © 2017-2024 Alex Fortuna
FAQs
Unknown package
We found that rspec_magic demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Libxml2’s solo maintainer drops embargoed security fixes, highlighting the burden on unpaid volunteers who keep critical open source software secure.
Research
Security News
Socket researchers uncover how browser extensions in trusted stores are used to hijack sessions, redirect traffic, and manipulate user behavior.
Research
Security News
An in-depth analysis of credential stealers, crypto drainers, cryptojackers, and clipboard hijackers abusing open source package registries to compromise Web3 development environments.