
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
Uspec is a shiny little testing framework for your apps!
Uspec is just Ruby!
No more digging around in your test framework's documentation to figure out what matcher you're supposed to use. Because you just use Ruby!
Uspec is well under 500 lines of code. Most of that is there to gracefully handle the weird edge cases that pop up all the time during development and testing of software. Uspec will catch issues at every stage and display a nicely formatted message to provide hints at what might have gone wrong.
Uspec is tiny, painless, and easy to use. Download it and give it a try!
Uspec is deceptively simple. You only need to remember one method: spec
.
Writing a spec is easy:
spec 'AwesomeMcCoolname.generate creates a cool name' do
AwesomeMcCoolname.generate.include? 'Cool'
end
That's it!
gem install uspec
echo 'gem "uspec"' >> Gemfile && bundle install
uspec
directory to keep your specs in_spec.rb
spec
method (example above)uspec
executable to run your specsAnd always remember that Uspec is just Ruby!
$ uspec --help
uspec - minimalistic ruby testing framework
usage: uspec [<file_or_path>...]
uspec
command will automatically look for a uspec
directory and load any *_spec.rb
files inside it.uspec
will scan for and run any specs inside them.0
if none.Uspec's output is in beautiful ANSI technicolor, with red for failures, green for successes, and yellow for pending specs.
A brief explanation of uspec
's output to show you what it can do!
If a spec passes (returns true
):
-- AwesomeMcCoolname.generate creates a cool name: true
If a spec fails (returns false
):
-- AwesomeMcCoolname.generate creates a cool name: false
If the spec encounters an error (raises an Exception
):
-- AwesomeMcCoolname.generate creates a cool name: Exception
Encountered an Exception while running spec
in spec at uspec/awesome_mc_coolname_spec.rb:3: in `<main>'
RuntimeError < StandardError: 'wtf'
/Users/Dude/Projects/Awesome/lib/awesome_mc_coolname.rb:18:in `explode'
uspec/awesome_mc_coolname_spec.rb:4:in `block in <main>'
If you create a spec that doesn't return a boolean value (nil
doesn't count either!) like this:
spec 'AwesomeMcCoolname.generate creates a cool name' do
AwesomeMcCoolname.generate =~ /Badass/
end
Then Uspec will let you know so you can debug it:
-- AwesomeMcCoolname.generate creates a badass name: Failed
Spec did not return a boolean value
in spec at uspec/awesome_mc_coolname_spec.rb:6: in `<main>'
Integer < Numeric: 5
If you aren't ready to fill out a spec, maybe as a reminder to add functionality later, just leave off the block and it will be marked as pending
:
spec 'a feature I have not implemented yet'
When you run the test Uspec will helpfully display:
-- a feature I have not implemented yet: pending
Test code reuse doesn't require doing anything special. It's just like any other Ruby code. But here are a few examples!
Hint: A lot of people put require_relative 'spec_helper'
at the top of their test files and put shared code and helper methods in a file called spec_helper.rb
.
If you find yourself repeating the same code in tests several times you can extract that code into a method and then call it within your spec
blocks.
def new_generator
AwesomeMcCoolname.new max_length: 15
end
spec 'generates a cool name' do
new_generator.generate.include? 'Badass'
end
This also works for instance variables!
@favorite_color = 'fuschia'
spec 'remembers favorite color' do
ColorDB.fetch(:favorite) == @favorite_color
end
By combining the previous two capabilities of Ruby, it is trivial to memoize method output as well:
def reusable_generator
@reusable_generator ||= AwesomeMcCoolname.new max_length: 15
end
spec 'generates a cool name' do
reusable_generator.generate.include? 'Badass'
end
This is all the same kind of code that you use when writing any other Ruby object. You can put methods into objects and use those if you like too!
When the spec
block is evaluated the return
value is used (in a very Ruby-like way) to determine if the test has passed or failed. Standard Ruby comparisons are your friend!
Because there's no matchers and only one method there's no need for specialized reference documentation, but here are some ideas to get you going!
Instead of =~
(which returns either an Integer
index or nil
) Ruby has the nifty include?
method, which returns a boolean:
spec 'AwesomeMcCoolname.generate creates a cool name' do
AwesomeMcCoolname.generate.include? 'Badass'
end
If you really need to regex, you can always use Ruby's !!
idiom to coerce a boolean out of any result,
but its more precise to specify the index if you know it.
And you can always toss in an ||
to drop in more information if a comparison fails too:
spec 'AwesomeMcCoolname.generate creates a cool name' do
index = AwesomeMcCoolname.generate =~ /Badass/
index == 0 || index
end
What if you want to test that an error has occured? Just use Ruby!
spec 'calling AwesomeMcCoolname.awesomeness without specifying the awesomeness level should explode' do
begin
AwesomeMcCoolname.awesomeness
rescue ArgumentError => error
error.message.include?("Needs awesomeness level!") || raise
end
end
If there's no error, then Uspec will see the result of the method call (whatever it might be).
If the wrong Exception is raised, then because of reraising (by just calling raise
without parameters), Ruby will dutifully pass along the error for Uspec to display.
Since uspec
is a very straight forward testing utility it is easy to use any of the standard Ruby mocking frameworks with it. However, the Impasta gem was made specifically for simple but comprehensive mocking, stubbing, and spying.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)Anthony M. Cook 2013-2024
FAQs
Unknown package
We found that uspec 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
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.