From f935cc066814e4ebf1d13d5bfb0fa43f4273afa5 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 4 Feb 2026 17:47:19 +0200 Subject: [PATCH 1/3] - Drop support for Ruby <= 3.1 --- .github/workflows/test.yml | 4 ++-- .rspec | 1 + intrinio.gemspec | 15 +++++++++++---- spec/intrinio/api_spec.rb | 2 -- spec/intrinio/bin_spec.rb | 2 -- spec/intrinio/command_line_spec.rb | 2 -- spec/spec_helper.rb | 1 - 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2dc5a91..bf759e9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,14 +10,14 @@ jobs: runs-on: ubuntu-latest strategy: - matrix: { ruby: ['2.4', '2.5', '2.6', '2.7', '3.0'] } + matrix: { ruby: ['3.2', '3.3', '3.4', '4.0'] } env: INTRINIO_AUTH: ${{ secrets.INTRINIO_AUTH }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install OS dependencies run: sudo apt-get -y install libyaml-dev diff --git a/.rspec b/.rspec index e41f336..fd2aa2d 100644 --- a/.rspec +++ b/.rspec @@ -1,3 +1,4 @@ +--require spec_helper --color --format documentation --fail-fast \ No newline at end of file diff --git a/intrinio.gemspec b/intrinio.gemspec index ec4b6c8..64b8684 100644 --- a/intrinio.gemspec +++ b/intrinio.gemspec @@ -15,9 +15,16 @@ Gem::Specification.new do |s| s.executables = ["intrinio"] s.homepage = 'https://github.com/DannyBen/intrinio' s.license = 'MIT' - s.required_ruby_version = ">= 2.0.0" + s.required_ruby_version = ">= 3.2" - s.add_runtime_dependency 'super_docopt', '~> 0.1' - s.add_runtime_dependency 'lp', '~> 0.2' - s.add_runtime_dependency 'apicake', '~> 0.1' + s.add_dependency 'apicake', '~> 0.2' + s.add_dependency 'lp', '~> 0.2' + s.add_dependency 'super_docopt', '~> 0.2' + + s.metadata = { + 'bug_tracker_uri' => 'https://github.com/dannyben/intrinio/issues', + 'changelog_uri' => 'https://github.com/dannyben/intrinio/blob/master/CHANGELOG.md', + 'source_code_uri' => 'https://github.com/dannyben/intrinio', + 'rubygems_mfa_required' => 'true', + } end diff --git a/spec/intrinio/api_spec.rb b/spec/intrinio/api_spec.rb index dea3b8d..717ee69 100644 --- a/spec/intrinio/api_spec.rb +++ b/spec/intrinio/api_spec.rb @@ -1,5 +1,3 @@ -require 'spec_helper' - describe API do before :all do ENV['INTRINIO_AUTH'] or raise "Please set INTRINIO_AUTH=user:pass before running tests" diff --git a/spec/intrinio/bin_spec.rb b/spec/intrinio/bin_spec.rb index 3c86c9b..21640c3 100644 --- a/spec/intrinio/bin_spec.rb +++ b/spec/intrinio/bin_spec.rb @@ -1,5 +1,3 @@ -require 'spec_helper' - describe 'bin/intrinio' do it "shows usage patterns" do expect(`bin/intrinio`).to match /Usage:/ diff --git a/spec/intrinio/command_line_spec.rb b/spec/intrinio/command_line_spec.rb index bd17ceb..0ccf1b5 100644 --- a/spec/intrinio/command_line_spec.rb +++ b/spec/intrinio/command_line_spec.rb @@ -1,5 +1,3 @@ -require 'spec_helper' - describe CommandLine do let(:cli) { Intrinio::CommandLine } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 457e8a7..fafe9eb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,6 @@ require 'simplecov' SimpleCov.start -require 'rubygems' require 'bundler' Bundler.require :default, :development From aee205339ba538f604ada7c8a9c6f443ba97f01b Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 4 Feb 2026 17:49:18 +0200 Subject: [PATCH 2/3] add repocard --- .repocard.conf | 13 +++++++++++++ .rubocop.yml | 15 +++++++++++++++ README.md | 2 ++ repocard.svg | 27 +++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 .repocard.conf create mode 100644 .rubocop.yml create mode 100644 repocard.svg diff --git a/.repocard.conf b/.repocard.conf new file mode 100644 index 0000000..834efa4 --- /dev/null +++ b/.repocard.conf @@ -0,0 +1,13 @@ +# repocard (https://github.com/dannyben/repocard) + +# Project Maturity: Experimental, Alpha, Beta, Stable, Legacy, Archived +item=Project Maturity|yellow|Beta + +# API Policy: Unstable, Mostly Stable, SemVer, Locked +item=API Policy|yellow|Mostly Stable + +# Maintenance Status: Active, Passive, Bugfix Only, Sunset +item=Maintenance Status|orange|Passive + +# Intended Audience: Developers, Power Users, End Users, [Specific Group] +item=Intended Audience|blue|End Users diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..5a9a7de --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,15 @@ +plugins: + - rubocop-performance + - rubocop-rspec + +inherit_gem: + rentacop: + - rentacop.yml + - rspec.yml + +AllCops: + TargetRubyVersion: 3.2 + SuggestExtensions: false + Exclude: + - 'dev/**/*' + diff --git a/README.md b/README.md index 8a27f05..d0a4e53 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Intrinio API Library and Command Line +![repocard](repocard.svg) + This gem provides both a Ruby library and a command line interface for the [Intrinio][1] data service. diff --git a/repocard.svg b/repocard.svg new file mode 100644 index 0000000..1032fd1 --- /dev/null +++ b/repocard.svg @@ -0,0 +1,27 @@ + + + + +Repo Card + + +PROJECT MATURITY +Beta + + +API POLICY +Mostly Stable + + +MAINTENANCE STATUS +Passive + + +INTENDED AUDIENCE +End Users + From df209c45d64f27aba7ad6b88c1886b6c9ea70e98 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Wed, 4 Feb 2026 17:56:38 +0200 Subject: [PATCH 3/3] rubocop --- Gemfile | 3 +- bin/intrinio | 4 +- intrinio.gemspec | 13 ++-- lib/intrinio/api.rb | 57 ++++++++-------- lib/intrinio/command_line.rb | 23 +++---- lib/intrinio/exceptions.rb | 2 +- lib/intrinio/version.rb | 4 +- spec/intrinio/api_spec.rb | 45 ++++++------ spec/intrinio/bin_spec.rb | 31 ++++----- spec/intrinio/command_line_spec.rb | 106 +++++++++++++++-------------- 10 files changed, 144 insertions(+), 144 deletions(-) diff --git a/Gemfile b/Gemfile index c6a346f..84e40ba 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source "https://rubygems.org" +source 'https://rubygems.org' gem 'byebug' gem 'rspec' @@ -8,4 +8,3 @@ gem 'runfile-tasks' gem 'simplecov' gemspec - diff --git a/bin/intrinio b/bin/intrinio index eab6aa1..7d99202 100644 --- a/bin/intrinio +++ b/bin/intrinio @@ -5,7 +5,7 @@ require 'intrinio' begin Intrinio::CommandLine.execute ARGV rescue APICake::BadResponse => e - STDERR.puts "#{e.class} - #{e.message}" + $stderr.puts "#{e.class} - #{e.message}" rescue Intrinio::MissingAuth => e - STDERR.puts e.message + $stderr.puts e.message end diff --git a/intrinio.gemspec b/intrinio.gemspec index 64b8684..f451ad7 100644 --- a/intrinio.gemspec +++ b/intrinio.gemspec @@ -1,4 +1,4 @@ -lib = File.expand_path('../lib', __FILE__) +lib = File.expand_path('lib', __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'date' require 'intrinio/version' @@ -6,16 +6,15 @@ require 'intrinio/version' Gem::Specification.new do |s| s.name = 'intrinio' s.version = Intrinio::VERSION - s.date = Date.today.to_s - s.summary = "Intrinio API Library and Command Line" - s.description = "Easy to use API for Intrinio data service with a command line interface" - s.authors = ["Danny Ben Shitrit"] + s.summary = 'Intrinio API Library and Command Line' + s.description = 'Easy to use API for Intrinio data service with a command line interface' + s.authors = ['Danny Ben Shitrit'] s.email = 'db@dannyben.com' s.files = Dir['README.md', 'lib/**/*.*'] - s.executables = ["intrinio"] + s.executables = ['intrinio'] s.homepage = 'https://github.com/DannyBen/intrinio' s.license = 'MIT' - s.required_ruby_version = ">= 3.2" + s.required_ruby_version = '>= 3.2' s.add_dependency 'apicake', '~> 0.2' s.add_dependency 'lp', '~> 0.2' diff --git a/lib/intrinio/api.rb b/lib/intrinio/api.rb index 3ca1587..71dea1f 100644 --- a/lib/intrinio/api.rb +++ b/lib/intrinio/api.rb @@ -1,28 +1,29 @@ -require 'apicake' - -module Intrinio - # Provides access to all the Intrinio API endpoints with dynamic methods - # anc caching. - class API < APICake::Base - base_uri 'https://api.intrinio.com' - - attr_reader :username, :password - - def initialize(opts={}) - if opts[:auth] - opts[:username], opts[:password] = opts[:auth].split ':' - opts.delete :auth - end - - @username, @password = opts[:username], opts[:password] - - cache.disable unless opts[:use_cache] - cache.dir = opts[:cache_dir] if opts[:cache_dir] - cache.life = opts[:cache_life] if opts[:cache_life] - end - - def default_params - { basic_auth: { username: username, password: password } } - end - end -end \ No newline at end of file +require 'apicake' + +module Intrinio + # Provides access to all the Intrinio API endpoints with dynamic methods + # anc caching. + class API < APICake::Base + base_uri 'https://api.intrinio.com' + + attr_reader :username, :password + + def initialize(opts = {}) + if opts[:auth] + opts[:username], opts[:password] = opts[:auth].split ':' + opts.delete :auth + end + + @username = opts[:username] + @password = opts[:password] + + cache.disable unless opts[:use_cache] + cache.dir = opts[:cache_dir] if opts[:cache_dir] + cache.life = opts[:cache_life] if opts[:cache_life] + end + + def default_params + { basic_auth: { username: username, password: password } } + end + end +end diff --git a/lib/intrinio/command_line.rb b/lib/intrinio/command_line.rb index 369d2e7..c7891ca 100644 --- a/lib/intrinio/command_line.rb +++ b/lib/intrinio/command_line.rb @@ -3,12 +3,11 @@ require 'lp' module Intrinio - # Handles the command line interface class CommandLine < SuperDocopt::Base version VERSION docopt File.expand_path 'docopt.txt', __dir__ - subcommands ['get', 'pretty', 'see', 'url', 'save'] + subcommands %w[get pretty see url save] attr_reader :path, :params, :file, :csv @@ -18,9 +17,9 @@ def before_execute @file = args['FILE'] @csv = args['--csv'] - if intrinio_auth.empty? - raise Intrinio::MissingAuth, "Missing Authentication\nPlease set INTRINIO_AUTH=username:password" - end + return unless intrinio_auth.empty? + + raise Intrinio::MissingAuth, "Missing Authentication\nPlease set INTRINIO_AUTH=username:password" end def get @@ -33,12 +32,12 @@ def get end def save - if csv - success = intrinio.save_csv file, path, params + success = if csv + intrinio.save_csv file, path, params else - success = intrinio.save file, path, params + intrinio.save file, path, params end - puts success ? "Saved #{file}" : "Saving failed" + puts success ? "Saved #{file}" : 'Saving failed' end def pretty @@ -59,6 +58,7 @@ def url def translate_params(pairs) result = {} return result if pairs.empty? + pairs.each do |pair| key, value = pair.split ':' result[key.to_sym] = value @@ -70,7 +70,7 @@ def intrinio @intrinio ||= intrinio! end - private + private def intrinio! Intrinio::API.new options @@ -79,7 +79,7 @@ def intrinio! def options result = { username: username, password: password } return result unless cache_dir || cache_life - + result[:use_cache] = true result[:cache_dir] = cache_dir if cache_dir result[:cache_life] = cache_life.to_i if cache_life @@ -105,6 +105,5 @@ def cache_dir def cache_life ENV['INTRINIO_CACHE_LIFE'] end - end end diff --git a/lib/intrinio/exceptions.rb b/lib/intrinio/exceptions.rb index 3214f05..6f46898 100644 --- a/lib/intrinio/exceptions.rb +++ b/lib/intrinio/exceptions.rb @@ -1,3 +1,3 @@ module Intrinio class MissingAuth < StandardError; end -end \ No newline at end of file +end diff --git a/lib/intrinio/version.rb b/lib/intrinio/version.rb index 1fb9d98..a528d66 100644 --- a/lib/intrinio/version.rb +++ b/lib/intrinio/version.rb @@ -1,3 +1,3 @@ module Intrinio - VERSION = "0.1.6" -end \ No newline at end of file + VERSION = '0.1.6' +end diff --git a/spec/intrinio/api_spec.rb b/spec/intrinio/api_spec.rb index 717ee69..45b6756 100644 --- a/spec/intrinio/api_spec.rb +++ b/spec/intrinio/api_spec.rb @@ -1,30 +1,30 @@ describe API do before :all do - ENV['INTRINIO_AUTH'] or raise "Please set INTRINIO_AUTH=user:pass before running tests" + ENV['INTRINIO_AUTH'] or raise 'Please set INTRINIO_AUTH=user:pass before running tests' end - let(:intrinio) { API.new auth: ENV['INTRINIO_AUTH'], use_cache: true } + let(:intrinio) { described_class.new auth: ENV['INTRINIO_AUTH'], use_cache: true } describe '#new' do - it "initializes with credentials" do - intrinio = API.new username: 'me', password: 'secret' + it 'initializes with credentials' do + intrinio = described_class.new username: 'me', password: 'secret' expect(intrinio.username).to eq 'me' expect(intrinio.password).to eq 'secret' end - it "initializes with compact credentials" do - intrinio = API.new auth: 'me:secret' + it 'initializes with compact credentials' do + intrinio = described_class.new auth: 'me:secret' expect(intrinio.username).to eq 'me' expect(intrinio.password).to eq 'secret' end - it "starts with cache disabled" do - intrinio = API.new + it 'starts with cache disabled' do + intrinio = described_class.new expect(intrinio.cache).not_to be_enabled end - it "initializes with options" do - intrinio = API.new username: 'me', password: 'secret', + it 'initializes with options' do + intrinio = described_class.new username: 'me', password: 'secret', use_cache: true, cache_dir: 'custom', cache_life: 1337 @@ -33,23 +33,22 @@ expect(intrinio.cache.life).to eq 1337 expect(intrinio.cache).to be_enabled end - end describe '#get_csv' do - context "with a valid request" do - it "returns a csv string" do - result = intrinio.get_csv :historical_data, identifier: 'AAPL', - item: 'close_price', start_date: '2016-01-01', + context 'with a valid request' do + it 'returns a csv string' do + result = intrinio.get_csv :historical_data, identifier: 'AAPL', + item: 'close_price', start_date: '2016-01-01', end_date: '2016-01-31', sort_order: 'asc' - + expect(result).to match_approval('aapl.csv') end end - context "with an invalid request" do - it "raises an error" do - expect{intrinio.get_csv :bogus_endpoint}.to raise_error(APICake::BadResponse) + context 'with an invalid request' do + it 'raises an error' do + expect { intrinio.get_csv :bogus_endpoint }.to raise_error(APICake::BadResponse) end end end @@ -57,17 +56,17 @@ describe '#save_csv' do let(:filename) { 'tmp.csv' } - it "saves output to a file" do + it 'saves output to a file' do File.delete filename if File.exist? filename expect(File).not_to exist(filename) intrinio.save_csv filename, :historical_data, identifier: 'AAPL', - item: 'close_price', start_date: '2016-01-01', + item: 'close_price', start_date: '2016-01-01', end_date: '2016-01-31', sort_order: 'asc' - + expect(File).to exist(filename) expect(File.read filename).to match_approval('aapl.csv') - + File.delete filename end end diff --git a/spec/intrinio/bin_spec.rb b/spec/intrinio/bin_spec.rb index 21640c3..d3a073b 100644 --- a/spec/intrinio/bin_spec.rb +++ b/spec/intrinio/bin_spec.rb @@ -1,34 +1,33 @@ describe 'bin/intrinio' do - it "shows usage patterns" do - expect(`bin/intrinio`).to match /Usage:/ + it 'shows usage patterns' do + expect(`bin/intrinio`).to match(/Usage:/) end - it "shows help" do - expect(`bin/intrinio --help`).to match /Commands:/ + it 'shows help' do + expect(`bin/intrinio --help`).to match(/Commands:/) end - it "shows version" do + it 'shows version' do expect(`bin/intrinio --version`).to eq "#{VERSION}\n" end - context "with bad response" do - it "exits with honor" do + context 'with bad response' do + it 'exits with honor' do command = 'bin/intrinio get --csv historical_data identifier:asd 2>&1' expect(`#{command}`).to eq "APICake::BadResponse - 400 Bad Request\n" end end - context "without INTRINIO_AUTH" do - before do - @auth = ENV['INTRINIO_AUTH'] - ENV.delete 'INTRINIO_AUTH' + context 'without INTRINIO_AUTH' do + around do |example| + auth = ENV['INTRINIO_AUTH'] + ENV.delete('INTRINIO_AUTH') + example.run + ensure + ENV['INTRINIO_AUTH'] = auth end - after do - ENV['INTRINIO_AUTH'] = @auth - end - - it "shows a friendly error" do + it 'shows a friendly error' do command = 'bin/intrinio see indices page_size:1 2>&1' expect(`#{command}`).to eq "Missing Authentication\nPlease set INTRINIO_AUTH=username:password\n" end diff --git a/spec/intrinio/command_line_spec.rb b/spec/intrinio/command_line_spec.rb index 0ccf1b5..1e659f9 100644 --- a/spec/intrinio/command_line_spec.rb +++ b/spec/intrinio/command_line_spec.rb @@ -2,7 +2,7 @@ let(:cli) { Intrinio::CommandLine } before :all do - ENV['INTRINIO_AUTH'] or raise "Please set INTRINIO_AUTH=user:pass before running tests" + ENV['INTRINIO_AUTH'] or raise 'Please set INTRINIO_AUTH=user:pass before running tests' end before do @@ -13,19 +13,19 @@ describe '#initialize' do let(:cli) { Intrinio::CommandLine.clone.instance } - context "without environment variables" do + context 'without environment variables' do before do ENV['INTRINIO_CACHE_DIR'] = nil ENV['INTRINIO_CACHE_LIFE'] = nil end - it "has cache disabled" do + it 'has cache disabled' do expect(cli.intrinio.cache).not_to be_enabled end end - context "with CACHE_DIR" do - it "enables cache" do + context 'with CACHE_DIR' do + it 'enables cache' do ENV['INTRINIO_CACHE_DIR'] = 'hello' expect(cli.intrinio.cache).to be_enabled expect(cli.intrinio.cache.dir).to eq 'hello' @@ -33,8 +33,8 @@ end end - context "with CACHE_LIFE" do - it "enables cache" do + context 'with CACHE_LIFE' do + it 'enables cache' do ENV['INTRINIO_CACHE_LIFE'] = '123' expect(cli.intrinio.cache).to be_enabled expect(cli.intrinio.cache.life).to eq 123 @@ -44,84 +44,86 @@ end describe '#execute' do - context "without arguments" do - it "shows usage patterns" do - expect {cli.execute}.to output(/Usage:/).to_stdout + context 'without arguments' do + it 'shows usage patterns' do + expect { cli.execute }.to output(/Usage:/).to_stdout end end - context "without INTRINIO_AUTH" do + context 'without INTRINIO_AUTH' do let(:command) { %w[see indices page_size:1] } - before do - @auth = ENV['INTRINIO_AUTH'] - ENV.delete 'INTRINIO_AUTH' - end - - after do - ENV['INTRINIO_AUTH'] = @auth + around do |example| + auth = ENV['INTRINIO_AUTH'] + ENV.delete('INTRINIO_AUTH') + example.run + ensure + ENV['INTRINIO_AUTH'] = auth end - it "raises a MissingAuth error" do - expect {cli.execute command}.to raise_error(Intrinio::MissingAuth) + it 'raises a MissingAuth error' do + expect { cli.execute command }.to raise_error(Intrinio::MissingAuth) end end - context "with url command" do + context 'with url command' do let(:command) { %w[url doesnt really:matter] } - it "returns a url" do - expected = /api\.intrinio\.com\/doesnt\?really=matter/ - expect {cli.execute command}.to output(expected).to_stdout + it 'returns a url' do + expected = %r{api\.intrinio\.com/doesnt\?really=matter} + expect { cli.execute command }.to output(expected).to_stdout end end - context "with get command" do + context 'with get command' do let(:command) { %w[get indices page_size:1] } - it "prints json output" do + it 'prints json output' do expected = /\{"data":.*\}/ - expect {cli.execute command}.to output(expected).to_stdout + expect { cli.execute command }.to output(expected).to_stdout end end - context "with get --csv command" do + context 'with get --csv command' do let(:command) { %w[get --csv indices page_size:1] } - it "prints csv output" do + it 'prints csv output' do expected = /symbol,index_name/ - expect {cli.execute command}.to output(expected).to_stdout + expect { cli.execute command }.to output(expected).to_stdout end end - context "with pretty command" do + context 'with pretty command' do let(:command) { %w[pretty indices page_size:1] } - it "prints a prettified json output" do + it 'prints a prettified json output' do expected = /\{\n\s+"data": \[\n.*\}/m - expect {cli.execute command}.to output(expected).to_stdout + expect { cli.execute command }.to output(expected).to_stdout end end - context "with see command" do + context 'with see command' do let(:command) { %w[see indices page_size:1] } - it "lovely-prints output" do + it 'lovely-prints output' do expected = /data:.*index_name:/m - expect {cli.execute command}.to output(expected).to_stdout + expect { cli.execute command }.to output(expected).to_stdout end end - context "with save command" do - let(:command) { %W[save tmp.json historical_data identifier:AAPL item:close_price start_date:2016-01-01 end_date:2016-01-31 sort_order:asc] } + context 'with save command' do + let(:command) do + %w[save tmp.json historical_data identifier:AAPL item:close_price start_date:2016-01-01 end_date:2016-01-31 + sort_order:asc] + end let(:filename) { 'tmp.json' } - it "saves a file" do + it 'saves a file' do File.unlink filename if File.exist? filename expect(File).not_to exist filename expected = "Saved #{filename}\n" - expect {cli.execute command}.to output(expected).to_stdout + expect { cli.execute command }.to output(expected).to_stdout expect(File).to exist filename expect(File.read filename).to match_approval('aapl.json') @@ -129,16 +131,19 @@ end end - context "with save --csv command" do - let(:command) { %W[save --csv tmp.csv historical_data identifier:AAPL item:close_price start_date:2016-01-01 end_date:2016-01-31 sort_order:asc] } + context 'with save --csv command' do + let(:command) do + %w[save --csv tmp.csv historical_data identifier:AAPL item:close_price start_date:2016-01-01 end_date:2016-01-31 + sort_order:asc] + end let(:filename) { 'tmp.csv' } - it "saves a csv file" do + it 'saves a csv file' do File.unlink filename if File.exist? filename expect(File).not_to exist filename expected = "Saved #{filename}\n" - expect {cli.execute command}.to output(expected).to_stdout + expect { cli.execute command }.to output(expected).to_stdout expect(File).to exist filename expect(File.read filename).to match_approval('aapl.csv') @@ -146,13 +151,12 @@ end end - context "with an invalid path" do - let(:command) { %W[get not_here] } - - it "fails with honor" do - expect {cli.execute command}.to output(/

Not Found<\/h1>/).to_stdout + context 'with an invalid path' do + let(:command) { %w[get not_here] } + + it 'fails with honor' do + expect { cli.execute command }.to output(%r{

Not Found

}).to_stdout end end end - -end \ No newline at end of file +end