### Install Sus Gem Source: https://github.com/socketry/sus/blob/main/guides/getting-started/readme.md Adds the sus gem to your Ruby project's Gemfile. ```bash $ bundle add sus ``` -------------------------------- ### Run Tests with Sus Source: https://github.com/socketry/sus/blob/main/guides/getting-started/readme.md Executes all tests in the project using the `sus` command. Shows example output indicating test results and performance metrics. ```bash $ sus 1 passed out of 1 total (1 assertions) ๐ŸŽ Finished in 47.0ยตs; 21272.535 assertions per second. ๐Ÿ‡ No slow tests found! Well done! ``` -------------------------------- ### Write a Basic Test Source: https://github.com/socketry/sus/blob/main/guides/getting-started/readme.md Demonstrates how to write a simple test case for a Ruby class using the sus testing framework. It includes setting up a subject and defining an expectation. ```ruby describe MyProject::MyClass do let(:instance) {subject.new} it "instantiates an object" do expect(instance).to be_a(Object) end end ``` -------------------------------- ### Run Tests in Parallel Source: https://github.com/socketry/sus/blob/main/guides/getting-started/readme.md Executes tests in parallel using the `sus-parallel` command for faster test suite execution. ```bash $ sus-parallel ``` -------------------------------- ### Before and After - Setup/Teardown Source: https://github.com/socketry/sus/blob/main/context/usage.md Illustrates the use of `before` and `after` blocks in Sus for executing setup and teardown logic. The `after` block includes error handling for cleanup even when tests fail with exceptions. ```ruby before do # Setup logic. end after do # Cleanup logic. end # Error handling in after: after do |error = nil| if error # The state of the test is unknown, so you may want to forcefully kill processes or clean up resources. Process.kill(:KILL, @child_pid) else # Normal cleanup logic. Process.kill(:TERM, @child_pid) end Process.waitpid(@child_pid) end ``` -------------------------------- ### Around - Setup/Teardown Source: https://github.com/socketry/sus/blob/main/context/usage.md Shows how to use the `around` block in Sus for more complex setup and teardown scenarios, including chaining logic with `super()`. ```ruby around do |&block| # Setup logic. super() do # Run the test. block.call end ensure # Cleanup logic. end ``` -------------------------------- ### Creating a Shared Fixture with Sus::Shared Source: https://github.com/socketry/sus/blob/main/context/shared.md Demonstrates how to define a reusable test context using `Sus::Shared`. This example creates a shared context for 'a user' with associated test examples and shared data (`let`). It requires the `sus/shared` library and defines the shared context within a Ruby module. ```ruby # fixtures/my_gem/a_user.rb require "sus/shared" module MyGem AUser = Sus::Shared("a user") do |role| let(:user) do { name: "Test User", email: "test@example.com", role: role } end it "has a name" do expect(user[:name]).not_to be_nil end it "has a valid email" do expect(user[:email]).to be(:include?, "@") end it "has a role" do expect(user[:role]).to be_a(String) end end end ``` -------------------------------- ### Basic Assertions Source: https://github.com/socketry/sus/blob/main/context/usage.md Provides examples of basic assertion methods available in Sus, including equality, comparison, truthiness, nil checks, and type checks. ```ruby expect(value).to be == expected exepct(value).to be >= 10 expect(value).to be <= 100 expect(value).to be > 0 expect(value).to be < 1000 expect(value).to be_truthy expect(value).to be_falsey expect(value).to be_nil expect(value).to be_equal(another_value) expect(value).to be_a(Class) ``` -------------------------------- ### Sus Configuration File Source: https://github.com/socketry/sus/blob/main/context/usage.md Example of a Sus configuration file (`config/sus.rb`). It includes requiring the 'covered/sus' gem for test coverage and defines `before_tests` and `after_tests` hooks for setting up and reporting test results. ```ruby # frozen_string_literal: true # Use the covered gem for test coverage reporting: require 'covered/sus' include Covered::Sus def before_tests(assertions, output: self.output) # Starts the clock and sets up the test environment: super end def after_tests(assertions, output: self.output) # Stops the clock and prints the test results: super end ``` -------------------------------- ### Enumerating Tests with Different Configurations using Shared Fixtures Source: https://github.com/socketry/sus/blob/main/context/shared.md Demonstrates how to use `Sus::Shared` to define a set of tests that can be run with various configurations, such as different database adapters. The example iterates through a list of adapters, applying the shared tests to each and using `unique: adapter.name` to ensure distinct reporting for each test iteration. ```ruby # test/my_gem/database_adapter.rb require "sus/shared" ADatabaseAdapter = Sus::Shared("a database adapter") do |adapter| let(:database) {adapter.new} it "connects to the database" do expect(database.connect).to be_truthy end it "can execute queries" do expect(database.execute("SELECT 1")).to be == [[1]] end end # Enumerate the tests with different adapters MyGem::DatabaseAdapters.each do |adapter| describe "with #{adapter}", unique: adapter.name do it_behaves_like ADatabaseAdapter, adapter end end ``` -------------------------------- ### Let - Lazy Variables Source: https://github.com/socketry/sus/blob/main/context/usage.md Explains the use of `let` in Sus for defining variables that are evaluated only when they are first accessed, promoting efficient test setup. ```ruby let(:helper) {subject.new} let(:test_data) {"test value"} it "uses the helper" do expect(helper.process(test_data)).to be_truthy end ``` -------------------------------- ### Using Specific Shared Fixtures for Different Scenarios Source: https://github.com/socketry/sus/blob/main/context/shared.md Demonstrates how to selectively apply different shared fixtures to test different scenarios within a single test file. This example uses `include` to integrate `AStandardUser` and `AnAdminUser` shared contexts, allowing tests to be written based on the specific user role. ```ruby # test/my_gem/authorization.rb require 'my_gem/users' describe MyGem::Authorization do with "standard user" do # If there are no arguments, you can use `include` directly: include MyGem::Users::AStandardUser it "denies admin access" do auth = subject.new expect(auth.can_admin?(user)).to be_falsey end end with "admin user" do include MyGem::Users::AnAdminUser it "allows admin access" do auth = subject.new expect(auth.can_admin?(user)).to be_truthy end end ``` -------------------------------- ### Running Sus Tests Source: https://github.com/socketry/sus/blob/main/context/usage.md Provides command-line instructions for running all tests or specific test files using the `bundle exec sus` command. ```bash # Run all tests bundle exec sus # Run specific test file bundle exec sus test/specific_test.rb ``` -------------------------------- ### Basic Sus Test Syntax Source: https://github.com/socketry/sus/blob/main/context/usage.md Demonstrates the fundamental syntax for writing tests with Sus, including `describe` for test groups, `let` for lazy variables, `with` for context or method specification, and `it` for individual test cases with `expect` assertions. ```ruby # frozen_string_literal: true describe MyThing do let(:my_thing) {subject.new} with "#my_method" do it "does something" do expect(my_thing.my_method).to be == 42 end end end ``` -------------------------------- ### Describe - Test Groups Source: https://github.com/socketry/sus/blob/main/context/usage.md Illustrates the use of the `describe` keyword in Sus to group related tests. It shows how to define the subject under test using `let`. ```ruby describe MyThing do # The subject will be whatever is described: let(:my_thing) {subject.new} end ``` -------------------------------- ### Sus Release Notes - v0.32.0 Source: https://github.com/socketry/sus/blob/main/readme.md Details from the v0.32.0 release of the Sus gem. This version introduces a `prepare_warnings!` hook in `Sus::Config` to enable deprecated warnings by default, improving developer awareness. ```ruby # v0.32.0 - `Sus::Config` now has a `prepare_warnings!` hook which enables deprecated warnings by default. This is generally considered good behaviour for a test framework. ``` -------------------------------- ### Mocking with `receive`, `and_return`, and `and_raise` Source: https://github.com/socketry/sus/blob/main/releases.md Demonstrates how to use the `receive` predicate with blocks for return values and how to use `and_raise` to simulate errors in method mocking. This enhances flexibility in testing by allowing custom return logic and error handling. ```ruby expect(interface).to receive(:implementation) {10} expect(interface).to receive(:implementation).and_return{FakeImplementation.new} expect(interface).to receive(:implementation).and_raise(StandardError, "An error occurred") ``` -------------------------------- ### It - Individual Tests Source: https://github.com/socketry/sus/blob/main/context/usage.md Shows how to define individual test cases using the `it` keyword in Sus. These blocks contain the actual test logic and assertions. ```ruby it "returns the expected value" do expect(result).to be == "expected" end ``` -------------------------------- ### With - Context and Method Blocks Source: https://github.com/socketry/sus/blob/main/context/usage.md Demonstrates the `with` keyword in Sus for creating context-specific test groups or specifying the method/class method being tested. It supports lazy variables and non-lazy state via keyword arguments. ```ruby with "valid input" do let(:input) {"valid input"} it "succeeds" do expect{my_thing.process(input)}.not.to raise_exception end end # Non-lazy state can be provided as keyword arguments: with "invalid input", input: nil do it "raises an error" do expect{my_thing.process(input)}.to raise_exception(ArgumentError) end end with "#my_method" do it "results a value" do expect(my_thing.method).to be == 42 end end with ".my_class_method" do it "returns a value" do expect(MyThing.class_method).to be == "class value" end end ``` -------------------------------- ### String Assertions Source: https://github.com/socketry/sus/blob/main/context/usage.md Demonstrates assertions specific to strings in Sus, such as checking for prefixes, suffixes, pattern matching, and substring inclusion. ```ruby expect(string).to be(:start_with?, "prefix") expect(string).to be(:end_with?, "suffix") expect(string).to be(:match?, /pattern/) expect(string).to be(:include?, "substring") ``` -------------------------------- ### Combining and Nesting Predicates Source: https://github.com/socketry/sus/blob/main/context/usage.md Demonstrates how to combine multiple predicates using logical operators (`and`, `or`) and nest predicates within attribute assertions for complex checks. ```ruby expect(user).to have_attributes( name: have_attributes( first: be == "John", last: be == "Doe" ), comments: have_value(be =~ /test comment/), created_at: be_within(1.minute).of(Time.now) ) expect(value).to (be > 10).and(be < 20) expect(value).to be_a(String).or(be_a(Symbol), be_a(Integer)) ``` -------------------------------- ### Range and Tolerance Assertions Source: https://github.com/socketry/sus/blob/main/context/usage.md Shows how to perform assertions on values within a specific range or tolerance, including absolute and percentage-based checks. ```ruby expect(value).to be_within(0.1).of(5.0) expect(value).to be_within(5).percent_of(100) ``` -------------------------------- ### Ruby Testing with Sus Source: https://github.com/socketry/sus/blob/main/readme.md This snippet demonstrates the core testing capabilities of the Sus framework in Ruby. It highlights the 'expect' style syntax and the use of predicates for assertions. Sus aims to be a more lightweight alternative to RSpec. ```ruby require 'sus' describe 'My Feature' do it 'does something correctly' do expect(1 + 1).to eq(2) end it 'handles exceptions' do expect { raise 'an error' }.to raise_error('an error') end end ``` -------------------------------- ### Temporary Directories for Isolated Tests Source: https://github.com/socketry/sus/blob/main/context/usage.md Utilizes `Dir.mktmpdir` to create isolated temporary directories for file operations within tests, ensuring clean test environments. ```ruby around do |block| Dir.mktmpdir do |root| @root = root block.call end end let(:test_path) {File.join(@root, "test.txt")} it "can create a file" do File.write(test_path, "content") expect(File).to be(:exist?, test_path) end ``` -------------------------------- ### Custom Predicates Source: https://github.com/socketry/sus/blob/main/context/usage.md Shows how to define custom predicates to encapsulate complex or reusable assertion logic. ```ruby def be_small_prime (be == 2).or(be == 3, be == 5, be == 7) end ``` -------------------------------- ### Using a Shared Fixture in a Test File Source: https://github.com/socketry/sus/blob/main/context/shared.md Shows how to incorporate a previously defined shared fixture (`MyGem::AUser`) into a test suite. It demonstrates requiring the shared fixture and then using `it_behaves_like` or `include_context` to apply its behaviors to a specific test description. ```ruby # test/my_gem/user_manager.rb require 'my_gem/a_user' describe MyGem::UserManager do it_behaves_like MyGem::AUser, "manager" # or include_context MyGem::AUser, "manager" end ``` -------------------------------- ### Sus Release Notes - v0.33.0 Source: https://github.com/socketry/sus/blob/main/readme.md Highlights from the v0.33.0 release of the Sus gem. This update includes support for the 'agent-context' gem and enhancements to the 'receive' matcher, allowing blocks and 'and_raise'. ```ruby # v0.33.0 - Add support for `agent-context` gem. - `receive` now supports blocks and `and_raise`. ``` -------------------------------- ### Informational Output in Tests Source: https://github.com/socketry/sus/blob/main/context/usage.md Uses the `inform` method to print informational messages during test execution, useful for debugging or providing context. ```ruby it "logs an informational message" do rate = copy_data(source, destination) inform "Copied data at #{rate}MB/s" expect(rate).to be > 0 end ``` -------------------------------- ### Block Expectations (Performance) Source: https://github.com/socketry/sus/blob/main/context/usage.md Tests the execution time of a block of code using `have_duration`, with notes on performance testing stability and related gems. ```ruby expect{operation}.to raise_exception(Error) expect{operation}.to have_duration(be < 1.0) expect{slow_operation}.to have_duration(be < 2.0) expect{fast_operation}.to have_duration(be < 0.1) ``` -------------------------------- ### Defining Multiple Shared Fixtures in a Module Source: https://github.com/socketry/sus/blob/main/context/shared.md Illustrates the creation of multiple, distinct shared test fixtures within a Ruby module. This approach helps organize related shared behaviors, such as different user roles ('standard user', 'admin user'), each with its own set of test expectations. ```ruby # fixtures/my_gem/users.rb module MyGem module Users AStandardUser = Sus::Shared("a standard user") do let(:user) do { name: "John Doe", role: "user", active: true } end it "is active" do expect(user[:active]).to be_truthy end end AnAdminUser = Sus::Shared("an admin user") do let(:user) do { name: "Admin User", role: "admin", active: true } end it "has admin role" do expect(user[:role]).to be == "admin" end end end ``` -------------------------------- ### Method Call Assertions Source: https://github.com/socketry/sus/blob/main/context/usage.md Illustrates how to assert the results of method calls on the expected object within Sus tests. ```ruby expect(array).to be(:include?, "value") expect(string).to be(:start_with?, "prefix") expect(object).to be(:respond_to?, :method_name) ``` -------------------------------- ### Collection Assertions Source: https://github.com/socketry/sus/blob/main/context/usage.md Asserts on the properties of collections like arrays and hashes, checking their length, values, and keys. ```ruby expect(array).to have_attributes(length: be == 1) expect(array).to have_value(be > 1) expect(hash).to have_keys(:key1, "key2") expect(hash).to have_keys(key1: be == 1, "key2" => be == 2) ``` -------------------------------- ### Defining Shared Behaviors in a Module Source: https://github.com/socketry/sus/blob/main/context/shared.md Shows how to encapsulate shared test behaviors within a Ruby module. When this module is included in a test context, it automatically defines specific tests and provides helper methods, promoting code reuse for common functionalities. ```ruby # fixtures/my_gem/shared_behaviors.rb module MyGem module SharedBehaviors def self.included(base) base.it "uses shared data" do expect(shared_data).to be == "some shared data" end end def shared_data "some shared data" end end end ``` -------------------------------- ### Attribute Testing Source: https://github.com/socketry/sus/blob/main/context/usage.md Tests the attributes of an object, allowing assertions on multiple attributes simultaneously with various predicate conditions. ```ruby expect(user).to have_attributes( name: be == "John", age: be >= 18, email: be(:include?, "@") ) ``` -------------------------------- ### Exception Assertions Source: https://github.com/socketry/sus/blob/main/context/usage.md Asserts that a block of code raises a specific exception, optionally checking the exception's message. ```ruby expect do risky_operation end.to raise_exception(RuntimeError, message: be =~ /expected error message/) ``` -------------------------------- ### Using Mock Objects for Method Replacement Source: https://github.com/socketry/sus/blob/main/context/mocking.md Replaces method implementations on an object within a block. This allows for intercepting calls, modifying arguments, and controlling execution flow. It is thread-local and suitable for complex behavior or when call order matters. ```ruby describe ApiClient do let(:http_client) {Object.new} let(:client) {ApiClient.new(http_client)} let(:users) {["Alice", "Bob"]} it "makes GET requests" do mock(http_client) do |mock| mock.replace(:get) do |url, headers: {}| expect(url).to be == "/api/users" expect(headers).to be == {"accept" => "application/json"} users.to_json end # or mock.before {|...| ...} # or mock.after {|...| ...} # or mock.wrap(:new) {|original, ...| original.call(...)} end expect(client.fetch_users).to be == users end end ``` -------------------------------- ### Setting Method Call Expectations Source: https://github.com/socketry/sus/blob/main/context/mocking.md Sets an expectation that a specific method will be called on an object. This does not enforce call order. It can be chained with `.with` for arguments, `.and_return` for return values, `.and_raise` for exceptions, and `.twice` or `.with_call_count` for multiple calls. ```ruby describe MyThing do let(:my_thing) {subject.new} it "calls the expected method" do expect(my_thing).to receive(:my_method) expect(my_thing.my_method).to be == 42 end end ``` ```ruby it "calls the method with arguments" do expect(object).to receive(:method_name).with(arg1, arg2) # or .with_arguments(be == [arg1, arg2]) # or .with_options(be == {option1: value1, option2: value2}) # or .with_block object.method_name(arg1, arg2) end ``` ```ruby it "returns a value" do expect(object).to receive(:method_name).and_return("expected value") result = object.method_name expect(result).to be == "expected value" end ``` ```ruby it "raises an exception" do expect(object).to receive(:method_name).and_raise(StandardError, "error message") expect{object.method_name}.to raise_exception(StandardError, message: "error message") end ``` ```ruby it "calls the method multiple times" do expect(object).to receive(:method_name).twice.and_return("result") # or .with_call_count(be == 2) expect(object.method_name).to be == "result" expect(object.method_name).to be == "result" end ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.