├── .github └── workflows │ └── github-actions-demo.yml ├── .gitignore ├── .rspec ├── .rubocop.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── lib ├── rubyai.rb └── rubyai │ ├── client.rb │ ├── configuration.rb │ ├── http.rb │ └── version.rb ├── pull_request_template.md ├── rubyai.gemspec └── spec ├── client_spec.rb ├── configuration_spec.rb └── spec_helper.rb /.github/workflows/github-actions-demo.yml: -------------------------------------------------------------------------------- 1 | name: GitHub Actions Demo 2 | run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 3 | on: [push] 4 | jobs: 5 | Explore-GitHub-Actions: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." 9 | - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" 10 | - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." 11 | - name: Check out repository code 12 | uses: actions/checkout@v4 13 | - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." 14 | - run: echo "🖥️ The workflow is now ready to test your code on the runner." 15 | - name: List files in the repository 16 | run: | 17 | ls ${{ github.workspace }} 18 | - run: echo "🍏 This job's status is ${{ job.status }}." 19 | -------------------------------------------------------------------------------- /.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 | .env 13 | *.gem 14 | 15 | lib/.DS_Store 16 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | TargetRubyVersion: 2.6 3 | NewCops: enable 4 | SuggestExtensions: false 5 | 6 | Style/Documentation: 7 | # Skips checking to make sure top level modules / classes have a comment. 8 | Enabled: false 9 | 10 | Layout/LineLength: 11 | Max: 100 12 | Exclude: 13 | - "**/*.gemspec" 14 | 15 | Lint/AmbiguousOperator: 16 | # https://github.com/rubocop/rubocop/issues/4294 17 | Exclude: 18 | - "lib/rubyai.rb" 19 | 20 | Metrics/AbcSize: 21 | Max: 20 22 | 23 | Metrics/BlockLength: 24 | Exclude: 25 | - "spec/**/*" 26 | 27 | Style/StringLiterals: 28 | EnforcedStyle: double_quotes 29 | 30 | Style/FrozenStringLiteralComment: 31 | Enabled: false 32 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | 9 | ## [0.3.2] - 2024-11-21 10 | 11 | ### Added 12 | 13 | - Update Gemspec and dependencies 14 | 15 | ## [0.3] - 2024-11-21 16 | 17 | ### Added 18 | 19 | - gpt-4-turbo 20 | - gpt-4o-mini 21 | - o1-mini 22 | - o1-preview 23 | 24 | - Remove outdated GPT 3.5 models 25 | 26 | ## [0.2] - 2024-04-20 27 | 28 | ### Added 29 | 30 | - New version 31 | 32 | ## [0.1.0] - 2024-01-21 33 | 34 | ### Added 35 | 36 | - Github Action 37 | - Faraday gem 38 | 39 | ## [0.0.3] - 2024-02-22 40 | 41 | ### Added 42 | 43 | - Rubocop gem 44 | 45 | ## [0.0.2] - 2024-02-23 46 | 47 | ### Added 48 | 49 | - Models GPT-4 50 | 51 | ## [0.0.1] - 2023-03-20 52 | 53 | ### Added 54 | 55 | - Initialise repository. 56 | - Add RubyAI::Client to connect to OpenAI API using user credentials. 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at alexrudall@users.noreply.github.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [https://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: https://contributor-covenant.org 74 | [version]: https://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Bug reports and pull requests are welcome on GitHub at https://github.com/alexshapalov/rubyai. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/alexshapalov/rubyai/blob/main/CODE_OF_CONDUCT.md). 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby '>= 2.7' 4 | 5 | gem 'faraday' 6 | gem 'faraday-net_http_persistent' 7 | gem 'rspec' 8 | gem 'webmock' 9 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.8.6) 5 | public_suffix (>= 2.0.2, < 6.0) 6 | bigdecimal (3.1.6) 7 | connection_pool (2.4.1) 8 | crack (1.0.0) 9 | bigdecimal 10 | rexml 11 | diff-lcs (1.5.1) 12 | faraday (2.12.0) 13 | faraday-net_http (>= 2.0, < 3.4) 14 | json 15 | logger 16 | faraday-net_http (3.3.0) 17 | net-http 18 | faraday-net_http_persistent (2.3.0) 19 | faraday (~> 2.5) 20 | net-http-persistent (>= 4.0.4, < 5) 21 | hashdiff (1.1.0) 22 | json (2.7.2) 23 | logger (1.6.1) 24 | net-http (0.4.1) 25 | uri 26 | net-http-persistent (4.0.4) 27 | connection_pool (~> 2.2) 28 | public_suffix (5.0.4) 29 | rexml (3.2.6) 30 | rspec (3.13.0) 31 | rspec-core (~> 3.13.0) 32 | rspec-expectations (~> 3.13.0) 33 | rspec-mocks (~> 3.13.0) 34 | rspec-core (3.13.0) 35 | rspec-support (~> 3.13.0) 36 | rspec-expectations (3.13.0) 37 | diff-lcs (>= 1.2.0, < 2.0) 38 | rspec-support (~> 3.13.0) 39 | rspec-mocks (3.13.0) 40 | diff-lcs (>= 1.2.0, < 2.0) 41 | rspec-support (~> 3.13.0) 42 | rspec-support (3.13.0) 43 | uri (0.13.1) 44 | webmock (3.22.0) 45 | addressable (>= 2.8.0) 46 | crack (>= 0.3.2) 47 | hashdiff (>= 0.4.0, < 2.0.0) 48 | 49 | PLATFORMS 50 | ruby 51 | x86_64-linux 52 | 53 | DEPENDENCIES 54 | faraday 55 | faraday-net_http_persistent 56 | rspec 57 | webmock 58 | 59 | RUBY VERSION 60 | ruby 3.3.0p0 61 | 62 | BUNDLED WITH 63 | 2.5.4 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Alex Shapalov 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RubyAI - OpenAI integration Ruby gem 2 | 3 | [![Gem Version](https://badge.fury.io/rb/rubyai.svg)](https://badge.fury.io/rb/rubyai) 4 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/alexshapalov/rubyai/blob/main/LICENSE) 5 | 6 | ## Use the [OpenAI API 🤖 ](https://openai.com/blog/openai-api/) with Ruby! ❤️ 7 | 8 | Generate text with ChatGPT (Generative Pre-trained Transformer) 9 | 10 | 11 | # Installation 12 | 13 | Add this line to your application's Gemfile: 14 | 15 | ```ruby 16 | gem "rubyai" 17 | ``` 18 | 19 | And then execute: 20 | 21 | $ bundle install 22 | 23 | 24 | Or install with: 25 | 26 | $ gem install rubyai 27 | 28 | and require with: 29 | 30 | ```ruby 31 | require "rubyai" 32 | ``` 33 | 34 | # Usage 35 | 36 | - Get your API key from [https://beta.openai.com/account/api-keys](https://beta.openai.com/account/api-keys) 37 | 38 | - If you belong to multiple organizations, you can get your Organization ID from [https://beta.openai.com/account/org-settings](https://beta.openai.com/account/org-settings) 39 | 40 | ### Quickstart 41 | 42 | For a quick test you can pass your token directly to a new client: 43 | 44 | ```ruby 45 | result = RubyAI::Client.new(access_token, messages).call 46 | ``` 47 | 48 | ### ChatGPT 49 | 50 | ChatGPT is a conversational-style text generation model. 51 | You can use it to [generate a response](https://platform.openai.com/docs/api-reference/chat/create) to a sequence of [messages](https://platform.openai.com/docs/guides/chat/introduction): 52 | 53 | ```ruby 54 | api_key = "YOUR API KEY" 55 | messages = "Who is the best chess player in history?" 56 | 57 | result = RubyAI::Client.new(api_key, messages, model: "gpt-4").call 58 | puts result.dig("choices", 0, "message", "content") 59 | 60 | # => As an AI language model, I do not have personal opinions, but according to historical records, Garry Kasparov is often considered as one of the best chess players in history. Other notable players include Magnus Carlsen, Bobby Fischer, and Jose Capablanca. 61 | ``` 62 | 63 | You can also pass client variables using the configuration file. 64 | Create configruation file like on example: 65 | ```ruby 66 | configuration = RubyAI::Configuration.new("YOUR API KEY", "Who is the best chess player in history?") 67 | client = RubyAI::Client.new(configuration) 68 | result = client.call 69 | puts result.dig("choices", 0, "message", "content") 70 | ``` 71 | 72 | Also (mostly) if you are using Rails you can use configure method: 73 | ```ruby 74 | RubyAI.configure do |config| 75 | config.api_key = "YOUR API KEY" 76 | config.messages = "Who is the best chess player in history?" 77 | config.model = "gpt-4o-mini" 78 | end 79 | ``` 80 | 81 | ## Models 82 | 83 | We support all popular GPT models: 84 | 85 | gpt-4-turbo: A powerful variant of GPT-4 optimized for efficiency and speed, perfect for high-demand tasks. 86 | 87 | gpt-4o-mini: A streamlined version of GPT-4, designed to provide a balance between performance and resource efficiency. 88 | 89 | o1-mini: A compact, yet effective model that is well-suited for lightweight tasks. 90 | 91 | o1-preview: A preview version of the o1 model, offering insights into upcoming advancements and features. 92 | 93 | 94 | ## Development 95 | 96 | After checking out the repo, run `bin/setup` to install dependencies. You can run `bin/console` for an interactive prompt that will allow you to experiment. 97 | 98 | To install this gem onto your local machine, run `bundle exec rake install`. 99 | 100 | 101 | ## Contributing 102 | 103 | Bug reports and pull requests are welcome on GitHub at . This project is intended to be a safe, welcoming space for collaboration, and contributors. 104 | 105 | ## License 106 | 107 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 108 | -------------------------------------------------------------------------------- /lib/rubyai.rb: -------------------------------------------------------------------------------- 1 | require 'faraday' 2 | require 'faraday/net_http_persistent' 3 | require 'json' 4 | 5 | require_relative "rubyai/client" 6 | require_relative "rubyai/configuration" 7 | require_relative "rubyai/http" 8 | require_relative "rubyai/version" 9 | 10 | module RubyAI 11 | class Error < StandardError; end 12 | end 13 | -------------------------------------------------------------------------------- /lib/rubyai/client.rb: -------------------------------------------------------------------------------- 1 | module RubyAI 2 | class Client 3 | attr_reader :configuration 4 | 5 | def initialize(config_hash = {}) 6 | @configuration = Configuration.new(config_hash) 7 | end 8 | 9 | def call 10 | response = connection.post do |req| 11 | req.url Configuration::BASE_URL 12 | req.headers.merge!(HTTP.build_headers(configuration.api_key)) 13 | req.body = HTTP.build_body(configuration.messages, configuration.model, configuration.temperature).to_json 14 | end 15 | 16 | JSON.parse(response.body) 17 | end 18 | 19 | private 20 | 21 | def connection 22 | @connection ||= Faraday.new do |faraday| 23 | faraday.adapter Faraday.default_adapter 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/rubyai/configuration.rb: -------------------------------------------------------------------------------- 1 | module RubyAI 2 | class Configuration 3 | BASE_URL = "https://api.openai.com/v1/chat/completions" 4 | 5 | MODELS = { 6 | "gpt-4" => "gpt-4", 7 | "gpt-4-32k" => "gpt-4-32k", 8 | "gpt-4-turbo" => "gpt-4-turbo", 9 | "gpt-4o-mini" => "gpt-4o-mini", 10 | "o1-mini" => "o1-mini", 11 | "o1-preview" => "o1-preview", 12 | "text-davinci-003" => "text-davinci-003" 13 | } 14 | 15 | DEFAULT_MODEL = "gpt-3.5-turbo" 16 | 17 | attr_accessor :api_key, :model, :messages, :temperature 18 | 19 | def initialize(config = {}) 20 | @api_key = config[:api_key] 21 | @model = config.fetch(:model, DEFAULT_MODEL) 22 | @messages = config.fetch(:messages, nil) 23 | @temperature = config.fetch(:temperature, 0.7) 24 | end 25 | end 26 | 27 | def self.configuration 28 | @configuration ||= Configuration.new 29 | end 30 | 31 | def self.configure 32 | yield(configuration) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/rubyai/http.rb: -------------------------------------------------------------------------------- 1 | module RubyAI 2 | module HTTP 3 | extend self 4 | 5 | def build_body(messages, model, temperature) 6 | { 7 | 'model': Configuration::MODELS[model], 8 | 'messages': [{ "role": "user", "content": messages }], 9 | 'temperature': temperature 10 | } 11 | end 12 | 13 | def build_headers(api_key) 14 | { 15 | 'Content-Type': 'application/json', 16 | 'Authorization': "Bearer #{api_key}" 17 | } 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/rubyai/version.rb: -------------------------------------------------------------------------------- 1 | module RubyAI 2 | VERSION = "0.5".freeze 3 | end 4 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## All Submissions: 2 | 3 | * [ ] Have you followed the guidelines in our [Contributing document](../blob/main/CONTRIBUTING.md)? 4 | * [ ] Have you checked to ensure there aren't other open [Pull Requests](../pulls) for the same update/change? 5 | * [ ] Have you added an explanation of what your changes do and why you'd like us to include them? 6 | -------------------------------------------------------------------------------- /rubyai.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |s| 2 | s.name = "rubyai" 3 | s.version = "0.5" 4 | s.summary = "A Ruby gem for the OpenAI (GPT-4) API" 5 | s.description = "RubyAI is a wrapper for the OpenAI API that allows you to interact with GPT-4 within Ruby/Rails applications. It provides simple methods for integrating language model capabilities into your Ruby projects." 6 | s.homepage = "https://github.com/alexshapalov/rubyai" 7 | s.authors = ["Alex Shapalov"] 8 | s.license = "MIT" 9 | 10 | s.files = Dir.chdir(File.expand_path(__dir__)) do 11 | Dir[ 12 | "{lib,spec}/**/*", 13 | "LICENSE", 14 | "README.md", 15 | "CHANGELOG.md", 16 | "Gemfile", 17 | "CODE_OF_CONDUCT.md", 18 | "CONTRIBUTING.md", 19 | "pull_request_template.md" 20 | ].select { |f| File.file?(f) } 21 | end 22 | 23 | # Specify the main file that will be required by default 24 | s.require_paths = ["lib"] 25 | s.required_ruby_version = ">= 2.6" 26 | 27 | # Dependencies 28 | s.add_dependency "faraday", "~> 2.0" 29 | s.add_dependency "faraday-net_http_persistent" 30 | s.add_development_dependency "rspec", "~> 3.10" 31 | 32 | # Metadata information (optional but useful for gem hosts) 33 | s.metadata = { 34 | "source_code_uri" => "https://github.com/alexshapalov/rubyai", 35 | "changelog_uri" => "https://github.com/alexshapalov/rubyai/CHANGELOG.md", 36 | "documentation_uri" => "https://github.com/alexshapalov/rubyai#readme" 37 | } 38 | end 39 | -------------------------------------------------------------------------------- /spec/client_spec.rb: -------------------------------------------------------------------------------- 1 | require 'webmock/rspec' 2 | require_relative '../lib/rubyai/client.rb' 3 | 4 | RSpec.describe RubyAI::Client do 5 | let(:api_key) { 'your_api_key' } 6 | let(:messages) { 'Hello, how are you?' } 7 | let(:temperature) { 0.7 } 8 | let(:model) { 'gpt-3.5-turbo' } 9 | let(:client) { described_class.new(api_key: api_key, messages: messages, temperature: temperature, model: model) } 10 | 11 | describe '#call' do 12 | let(:response_body) { { 'completion' => 'This is a response from the model.' } } 13 | let(:status) { 200 } 14 | 15 | before do 16 | stub_request(:post, RubyAI::Configuration::BASE_URL) 17 | .to_return(status: status, body: response_body.to_json, headers: { 'Content-Type' => 'application/json' }) 18 | end 19 | 20 | it 'returns parsed JSON response when passing through client directly' do 21 | expect(client.call).to eq(response_body) 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/configuration_spec.rb: -------------------------------------------------------------------------------- 1 | require 'webmock/rspec' 2 | require_relative '../lib/rubyai/client.rb' 3 | 4 | RSpec.describe RubyAI::Client do 5 | let(:api_key) { 'your_api_key' } 6 | let(:messages) { 'Hello, how are you?' } 7 | let(:temperature) { 0.7 } 8 | let(:model) { 'gpt-3.5-turbo' } 9 | 10 | before do 11 | RubyAI.configure do |config| 12 | config.api_key = api_key 13 | config.messages = messages 14 | end 15 | end 16 | 17 | describe '#call' do 18 | let(:response_body) { { 'choices' => [{ 'message' => { 'content' => 'This is a response from the model.' } }] } } 19 | let(:status) { 200 } 20 | 21 | before do 22 | stub_request(:post, RubyAI::Configuration::BASE_URL) 23 | .to_return(status: status, body: response_body.to_json, headers: { 'Content-Type' => 'application/json' }) 24 | end 25 | 26 | it 'returns parsed JSON response when passing through client via configuration' do 27 | configuration = { api_key: RubyAI.configuration.api_key, messages: RubyAI.configuration.messages } 28 | client = described_class.new(configuration) 29 | result = client.call 30 | expect(result.dig('choices', 0, 'message', 'content')).to eq('This is a response from the model.') 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file was generated by the `rspec --init` command. Conventionally, all 2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 3 | # The generated `.rspec` file contains `--require spec_helper` which will cause 4 | # this file to always be loaded, without a need to explicitly require it in any 5 | # files. 6 | # 7 | # Given that it is always loaded, you are encouraged to keep this file as 8 | # light-weight as possible. Requiring heavyweight dependencies from this file 9 | # will add to the boot time of your test suite on EVERY test run, even for an 10 | # individual file that may not need all of that loaded. Instead, consider making 11 | # a separate helper file that requires the additional dependencies and performs 12 | # the additional setup, and require it from the spec files that actually need 13 | # it. 14 | # 15 | # See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 16 | RSpec.configure do |config| 17 | # rspec-expectations config goes here. You can use an alternate 18 | # assertion/expectation library such as wrong or the stdlib/minitest 19 | # assertions if you prefer. 20 | config.expect_with :rspec do |expectations| 21 | # This option will default to `true` in RSpec 4. It makes the `description` 22 | # and `failure_message` of custom matchers include text for helper methods 23 | # defined using `chain`, e.g.: 24 | # be_bigger_than(2).and_smaller_than(4).description 25 | # # => "be bigger than 2 and smaller than 4" 26 | # ...rather than: 27 | # # => "be bigger than 2" 28 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 29 | end 30 | 31 | # rspec-mocks config goes here. You can use an alternate test double 32 | # library (such as bogus or mocha) by changing the `mock_with` option here. 33 | config.mock_with :rspec do |mocks| 34 | # Prevents you from mocking or stubbing a method that does not exist on 35 | # a real object. This is generally recommended, and will default to 36 | # `true` in RSpec 4. 37 | mocks.verify_partial_doubles = true 38 | end 39 | 40 | # This option will default to `:apply_to_host_groups` in RSpec 4 (and will 41 | # have no way to turn it off -- the option exists only for backwards 42 | # compatibility in RSpec 3). It causes shared context metadata to be 43 | # inherited by the metadata hash of host groups and examples, rather than 44 | # triggering implicit auto-inclusion in groups with matching metadata. 45 | config.shared_context_metadata_behavior = :apply_to_host_groups 46 | 47 | # The settings below are suggested to provide a good initial experience 48 | # with RSpec, but feel free to customize to your heart's content. 49 | =begin 50 | # This allows you to limit a spec run to individual examples or groups 51 | # you care about by tagging them with `:focus` metadata. When nothing 52 | # is tagged with `:focus`, all examples get run. RSpec also provides 53 | # aliases for `it`, `describe`, and `context` that include `:focus` 54 | # metadata: `fit`, `fdescribe` and `fcontext`, respectively. 55 | config.filter_run_when_matching :focus 56 | 57 | # Allows RSpec to persist some state between runs in order to support 58 | # the `--only-failures` and `--next-failure` CLI options. We recommend 59 | # you configure your source control system to ignore this file. 60 | config.example_status_persistence_file_path = "spec/examples.txt" 61 | 62 | # Limits the available syntax to the non-monkey patched syntax that is 63 | # recommended. For more details, see: 64 | # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ 65 | config.disable_monkey_patching! 66 | 67 | # This setting enables warnings. It's recommended, but in some cases may 68 | # be too noisy due to issues in dependencies. 69 | config.warnings = true 70 | 71 | # Many RSpec users commonly either run the entire suite or an individual 72 | # file, and it's useful to allow more verbose output when running an 73 | # individual spec file. 74 | if config.files_to_run.one? 75 | # Use the documentation formatter for detailed output, 76 | # unless a formatter has already been configured 77 | # (e.g. via a command-line flag). 78 | config.default_formatter = "doc" 79 | end 80 | 81 | # Print the 10 slowest examples and example groups at the 82 | # end of the spec run, to help surface which specs are running 83 | # particularly slow. 84 | config.profile_examples = 10 85 | 86 | # Run specs in random order to surface order dependencies. If you find an 87 | # order dependency and want to debug it, you can fix the order by providing 88 | # the seed, which is printed after each run. 89 | # --seed 1234 90 | config.order = :random 91 | 92 | # Seed global randomization in this process using the `--seed` CLI option. 93 | # Setting this allows you to use `--seed` to deterministically reproduce 94 | # test failures related to randomization by passing the same `--seed` value 95 | # as the one that triggered the failure. 96 | Kernel.srand config.seed 97 | =end 98 | end 99 | --------------------------------------------------------------------------------