code_snippet 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/build.yml +23 -0
- data/.gitignore +20 -0
- data/.rubocop.yml +20 -0
- data/.ruby-version +1 -0
- data/CONTRIBUTING.md +51 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +158 -0
- data/LICENCE +21 -0
- data/README.md +78 -0
- data/Rakefile +18 -0
- data/bin/snippet +62 -0
- data/bitbucket-pipelines.yml +18 -0
- data/code_snippet.gemspec +38 -0
- data/lib/code_snippet/cli/commands.rb +82 -0
- data/lib/code_snippet/cli/presenters.rb +42 -0
- data/lib/code_snippet/cli.rb +52 -0
- data/lib/code_snippet/manager.rb +50 -0
- data/lib/code_snippet/snip.rb +35 -0
- data/lib/code_snippet/version.rb +3 -0
- data/lib/code_snippet.rb +7 -0
- data/spec/snippet/cli/commands_spec.rb +104 -0
- data/spec/snippet/cli/presenters_spec.rb +72 -0
- data/spec/snippet/cli_spec.rb +91 -0
- data/spec/snippet/manager_spec.rb +166 -0
- data/spec/snippet/snip_spec.rb +78 -0
- data/spec/spec_helper.rb +27 -0
- metadata +312 -0
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            require 'code_snippet/cli/commands'
         | 
| 2 | 
            +
            require 'code_snippet/cli/presenters'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'logger'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module CodeSnippet
         | 
| 7 | 
            +
              # Command line interface helpers and actions
         | 
| 8 | 
            +
              module CLI
         | 
| 9 | 
            +
                # CLI Helpers
         | 
| 10 | 
            +
                class <<self
         | 
| 11 | 
            +
                  ##
         | 
| 12 | 
            +
                  # Retrieves snippet dir from environment
         | 
| 13 | 
            +
                  #
         | 
| 14 | 
            +
                  def snip_dir
         | 
| 15 | 
            +
                    @snippet_dir = ENV['SNIPPET_DIR']
         | 
| 16 | 
            +
                    raise 'SNIPPET_DIR environment variable not set' unless @snippet_dir
         | 
| 17 | 
            +
                    unless File.exist?(@snippet_dir)
         | 
| 18 | 
            +
                      raise "SNIPPET_DIR #{@snippet_dir} does not exist"
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    @snippet_dir
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  ##
         | 
| 25 | 
            +
                  # Creates logger for printing messages
         | 
| 26 | 
            +
                  #
         | 
| 27 | 
            +
                  def logger
         | 
| 28 | 
            +
                    @logger ||= Logger.new(STDOUT)
         | 
| 29 | 
            +
                    @logger.formatter = proc do |_sev, _time, _prog, msg|
         | 
| 30 | 
            +
                      "#{msg}\n"
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    @logger
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  ##
         | 
| 37 | 
            +
                  # Prints command line message to CLI
         | 
| 38 | 
            +
                  #
         | 
| 39 | 
            +
                  def print_message(message)
         | 
| 40 | 
            +
                    logger.info(message)
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  ##
         | 
| 44 | 
            +
                  # Prints a message and then exits with given status code
         | 
| 45 | 
            +
                  #
         | 
| 46 | 
            +
                  def print_message_and_exit(message, exit_code = 1)
         | 
| 47 | 
            +
                    print_message(message)
         | 
| 48 | 
            +
                    exit(exit_code)
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            module CodeSnippet
         | 
| 2 | 
            +
              # Manager looks after a set of snippets
         | 
| 3 | 
            +
              class Manager
         | 
| 4 | 
            +
                DEFAULT_QUERY = ->(_snip) { return true }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                attr_reader :snippets
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def initialize(snippet_dir)
         | 
| 9 | 
            +
                  @snippet_dir = snippet_dir
         | 
| 10 | 
            +
                  @snippets = []
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def load_snippets
         | 
| 14 | 
            +
                  Dir.glob(File.join(@snippet_dir, '**', '*')).each do |file|
         | 
| 15 | 
            +
                    next if File.directory?(file)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    @snippets << CodeSnippet::Snip.new_from_file(file)
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def filter(query = DEFAULT_QUERY)
         | 
| 22 | 
            +
                  @snippets.select do |snip|
         | 
| 23 | 
            +
                    query.call(snip)
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def find(search_term, lang = nil)
         | 
| 28 | 
            +
                  name_query = lambda do |snip|
         | 
| 29 | 
            +
                    snip.name.include?(search_term)
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  results = filter(name_query)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  unless lang.nil?
         | 
| 35 | 
            +
                    results = results.select do |snip|
         | 
| 36 | 
            +
                      snip.ext == lang
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  results
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def filter_by_extension(ext)
         | 
| 44 | 
            +
                  ext = ".#{ext}" unless ext.start_with?('.')
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  ext_query = ->(snip) { snip.ext == ext }
         | 
| 47 | 
            +
                  filter(ext_query)
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            module CodeSnippet
         | 
| 2 | 
            +
              # Snip is a file with a code snippet
         | 
| 3 | 
            +
              class Snip
         | 
| 4 | 
            +
                attr_reader :path, :ext
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def self.new_from_file(path)
         | 
| 7 | 
            +
                  new(
         | 
| 8 | 
            +
                    path,
         | 
| 9 | 
            +
                    File.basename(path),
         | 
| 10 | 
            +
                    File.extname(path)
         | 
| 11 | 
            +
                  )
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def initialize(path, name, ext)
         | 
| 15 | 
            +
                  @path = path
         | 
| 16 | 
            +
                  @name = name
         | 
| 17 | 
            +
                  @ext = ext
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def name
         | 
| 21 | 
            +
                  @name
         | 
| 22 | 
            +
                    .gsub(@ext, '')
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def exist?
         | 
| 26 | 
            +
                  File.exist?(@path)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def content
         | 
| 30 | 
            +
                  raise 'cannot read snippet code' unless exist?
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  File.read(@path)
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
    
        data/lib/code_snippet.rb
    ADDED
    
    
| @@ -0,0 +1,104 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec.describe CodeSnippet::CLI::Commands do
         | 
| 4 | 
            +
              let(:snippet_dir) { 'path/to/snippets' }
         | 
| 5 | 
            +
              let(:lang) { '.rb' }
         | 
| 6 | 
            +
              let(:copy) { false }
         | 
| 7 | 
            +
              let(:vars) { [] }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              before do
         | 
| 10 | 
            +
                allow(ENV)
         | 
| 11 | 
            +
                  .to receive(:[]).with('SNIPPET_DIR')
         | 
| 12 | 
            +
                                  .and_return(snippet_dir)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                allow(File)
         | 
| 15 | 
            +
                  .to receive(:exist?)
         | 
| 16 | 
            +
                  .with(snippet_dir)
         | 
| 17 | 
            +
                  .and_return(true)
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              describe '.show' do
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              describe '.list' do
         | 
| 24 | 
            +
                let(:manager) { double(CodeSnippet::Manager) }
         | 
| 25 | 
            +
                let(:lang) { nil }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                let(:snip) { double(CodeSnippet::Snip) }
         | 
| 28 | 
            +
                let(:filtered_snips) { [snip, snip] }
         | 
| 29 | 
            +
                let(:all_snips) { [snip, snip, snip, snip] }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                before do
         | 
| 32 | 
            +
                  allow(CodeSnippet::CLI).to receive(:snip_dir)
         | 
| 33 | 
            +
                    .and_return('path/to/snips')
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  allow(CodeSnippet::Manager)
         | 
| 36 | 
            +
                    .to receive(:new)
         | 
| 37 | 
            +
                    .and_return(manager)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  allow(manager).to receive(:load_snippets)
         | 
| 40 | 
            +
                  allow(manager)
         | 
| 41 | 
            +
                    .to receive(:filter_by_extension)
         | 
| 42 | 
            +
                    .and_return(filtered_snips)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  allow(manager)
         | 
| 45 | 
            +
                    .to receive(:snippets)
         | 
| 46 | 
            +
                    .and_return(all_snips)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  allow(CodeSnippet::CLI::Presenters)
         | 
| 49 | 
            +
                    .to receive(:list_snippets)
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  described_class.list(lang, copy, vars)
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                it 'loads snippets' do
         | 
| 55 | 
            +
                  expect(manager).to have_received(:load_snippets)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it 'presents a list of snippets' do
         | 
| 59 | 
            +
                  expect(CodeSnippet::CLI::Presenters)
         | 
| 60 | 
            +
                    .to have_received(:list_snippets)
         | 
| 61 | 
            +
                    .with(all_snips)
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                context 'when language filter is applied' do
         | 
| 65 | 
            +
                  let(:lang) { '.rb' }
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  it 'presents a list of filtered snippets' do
         | 
| 68 | 
            +
                    expect(CodeSnippet::CLI::Presenters)
         | 
| 69 | 
            +
                      .to have_received(:list_snippets)
         | 
| 70 | 
            +
                      .with(filtered_snips)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              describe '.path' do
         | 
| 76 | 
            +
                before do
         | 
| 77 | 
            +
                  allow(CodeSnippet::CLI)
         | 
| 78 | 
            +
                    .to receive(:print_message)
         | 
| 79 | 
            +
                    .and_return(nil)
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  described_class.path(lang, copy, vars)
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                it 'prints snippet dir' do
         | 
| 85 | 
            +
                  expect(CodeSnippet::CLI).to have_received(:print_message)
         | 
| 86 | 
            +
                    .with(snippet_dir)
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
              describe '.version' do
         | 
| 91 | 
            +
                before do
         | 
| 92 | 
            +
                  allow(CodeSnippet::CLI)
         | 
| 93 | 
            +
                    .to receive(:print_message)
         | 
| 94 | 
            +
                    .and_return(nil)
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  described_class.version(lang, copy, vars)
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                it 'prints snippet version' do
         | 
| 100 | 
            +
                  expect(CodeSnippet::CLI).to have_received(:print_message)
         | 
| 101 | 
            +
                    .with(CodeSnippet::VERSION)
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
              end
         | 
| 104 | 
            +
            end
         | 
| @@ -0,0 +1,72 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec.describe CodeSnippet::CLI::Presenters do
         | 
| 4 | 
            +
              let(:snippets) { [snip, snip] }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              let(:snip) { double(CodeSnippet::Snip) }
         | 
| 7 | 
            +
              let(:name) { 'snippet' }
         | 
| 8 | 
            +
              let(:ext) { '.snip' }
         | 
| 9 | 
            +
              let(:path) { 'path/to/snippet' }
         | 
| 10 | 
            +
              let(:content) { 'snip-content' }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              before do
         | 
| 13 | 
            +
                allow(CodeSnippet::CLI).to receive(:print_message).and_return(double)
         | 
| 14 | 
            +
                allow(snip).to receive(:name).and_return(name)
         | 
| 15 | 
            +
                allow(snip).to receive(:ext).and_return(ext)
         | 
| 16 | 
            +
                allow(snip).to receive(:path).and_return(path)
         | 
| 17 | 
            +
                allow(snip).to receive(:content).and_return(content)
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
              describe '.pick_from' do
         | 
| 20 | 
            +
                let(:question) { 'are you sure?' }
         | 
| 21 | 
            +
                let(:snips) { [snip, snip] }
         | 
| 22 | 
            +
                let(:prompt) { double(TTY::Prompt) }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                before do
         | 
| 25 | 
            +
                  allow(TTY::Prompt).to receive(:new).and_return(prompt)
         | 
| 26 | 
            +
                  allow(prompt).to receive(:select).and_return(path)
         | 
| 27 | 
            +
                  @choice = subject.pick_from(question, snips)
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                it 'asks which path' do
         | 
| 31 | 
            +
                  expect(prompt).to have_received(:select)
         | 
| 32 | 
            +
                    .with(question, [path, path])
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                it 'returns chosen path' do
         | 
| 36 | 
            +
                  expect(@choice).to eq snip
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              describe '.show' do
         | 
| 41 | 
            +
                before do
         | 
| 42 | 
            +
                  described_class.show(snip)
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                it 'puts content to STDOUT' do
         | 
| 46 | 
            +
                  expect(CodeSnippet::CLI).to have_received(:print_message).with(content)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              describe '.list_snippets' do
         | 
| 51 | 
            +
                let(:table) { double(TTY::Table) }
         | 
| 52 | 
            +
                before do
         | 
| 53 | 
            +
                  allow(TTY::Table).to receive(:new).and_return(table)
         | 
| 54 | 
            +
                  allow(table).to receive(:render)
         | 
| 55 | 
            +
                  described_class.list_snippets(snippets)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it 'sets up render' do
         | 
| 59 | 
            +
                  expect(TTY::Table).to have_received(:new).with(
         | 
| 60 | 
            +
                    %w[NAME LANG PATH],
         | 
| 61 | 
            +
                    [
         | 
| 62 | 
            +
                      [name, ext, path],
         | 
| 63 | 
            +
                      [name, ext, path]
         | 
| 64 | 
            +
                    ]
         | 
| 65 | 
            +
                  )
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                it 'renders table' do
         | 
| 69 | 
            +
                  expect(table).to have_received(:render).with(:ascii)
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
            end
         | 
| @@ -0,0 +1,91 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec.describe CodeSnippet::CLI do
         | 
| 4 | 
            +
              let(:logger) { double(Logger) }
         | 
| 5 | 
            +
              let(:message) { 'lorem ipsum' }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              before do
         | 
| 8 | 
            +
                allow(described_class).to receive(:exit).and_return(double)
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              describe '.snip_dir' do
         | 
| 12 | 
            +
                let(:snippet_dir) { 'path/to/snippets' }
         | 
| 13 | 
            +
                let(:exists) { true }
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                before do
         | 
| 16 | 
            +
                  allow(ENV)
         | 
| 17 | 
            +
                    .to receive(:[])
         | 
| 18 | 
            +
                    .with('SNIPPET_DIR')
         | 
| 19 | 
            +
                    .and_return(snippet_dir)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  allow(File).to receive(:exist?).and_return(exists)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                it 'returns path to snippets' do
         | 
| 25 | 
            +
                  expect(described_class.snip_dir).to eq snippet_dir
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                context 'when the environment variable is not set' do
         | 
| 29 | 
            +
                  let(:snippet_dir) { nil }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  it 'raises error' do
         | 
| 32 | 
            +
                    expect do
         | 
| 33 | 
            +
                      described_class.snip_dir
         | 
| 34 | 
            +
                    end.to raise_error 'SNIPPET_DIR environment variable not set'
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                context 'when the snippet directory does not exist' do
         | 
| 39 | 
            +
                  let(:exists) { false }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  it 'raises error' do
         | 
| 42 | 
            +
                    expect do
         | 
| 43 | 
            +
                      described_class.snip_dir
         | 
| 44 | 
            +
                    end.to raise_error "SNIPPET_DIR #{snippet_dir} does not exist"
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              describe '.logger' do
         | 
| 50 | 
            +
                before do
         | 
| 51 | 
            +
                  allow(Logger).to receive(:new).and_return(logger)
         | 
| 52 | 
            +
                  allow(logger).to receive(:formatter=)
         | 
| 53 | 
            +
                  @logger = subject.logger
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                it 'creates a new logger to STDOUT' do
         | 
| 57 | 
            +
                  expect(Logger).to have_received(:new).with(STDOUT)
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              describe '.print_message' do
         | 
| 62 | 
            +
                let(:logger) { double(Logger) }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                before do
         | 
| 65 | 
            +
                  allow(described_class).to receive(:logger).and_return(logger)
         | 
| 66 | 
            +
                  allow(logger).to receive(:info)
         | 
| 67 | 
            +
                  described_class.print_message(message)
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it 'prints message to stdout' do
         | 
| 71 | 
            +
                  expect(logger).to have_received(:info).with(message)
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              describe '.print_message_and_exit' do
         | 
| 76 | 
            +
                let(:exit_code) { 2 }
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                before do
         | 
| 79 | 
            +
                  allow(described_class).to receive(:print_message)
         | 
| 80 | 
            +
                  described_class.print_message_and_exit(message, exit_code)
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                it 'prints message' do
         | 
| 84 | 
            +
                  expect(described_class).to have_received(:print_message).with(message)
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                it 'exits with set status' do
         | 
| 88 | 
            +
                  expect(described_class).to have_received(:exit).with(exit_code)
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
            end
         | 
| @@ -0,0 +1,166 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec.describe CodeSnippet::Manager do
         | 
| 4 | 
            +
              let(:snippet_dir) { 'path/to/snippets' }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              subject do
         | 
| 7 | 
            +
                described_class.new(snippet_dir)
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              describe '#load_snippets' do
         | 
| 11 | 
            +
                let(:directory) { File.join(snippet_dir, 'path/to/dir') }
         | 
| 12 | 
            +
                let(:file)      { File.join(snippet_dir, 'path/to/dir/file') }
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                let(:file_snip) { double(CodeSnippet::Snip) }
         | 
| 15 | 
            +
                let(:files) do
         | 
| 16 | 
            +
                  [
         | 
| 17 | 
            +
                    directory,
         | 
| 18 | 
            +
                    directory,
         | 
| 19 | 
            +
                    file,
         | 
| 20 | 
            +
                    file
         | 
| 21 | 
            +
                  ]
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                before do
         | 
| 25 | 
            +
                  allow(File).to receive(:directory?).with(directory)
         | 
| 26 | 
            +
                                                     .and_return(true)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  allow(File).to receive(:directory?).with(file)
         | 
| 29 | 
            +
                                                     .and_return(false)
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  allow(Dir).to receive(:glob).and_return(files)
         | 
| 32 | 
            +
                  allow(CodeSnippet::Snip).to receive(:new_from_file)
         | 
| 33 | 
            +
                    .and_return(file_snip)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  subject.load_snippets
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                it 'creates snips from files' do
         | 
| 39 | 
            +
                  expect(subject.snippets.count).to be 2
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  subject.snippets.each do |snip|
         | 
| 42 | 
            +
                    expect(snip).to eq file_snip
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              describe '#filter' do
         | 
| 48 | 
            +
                let(:query) do
         | 
| 49 | 
            +
                  ->(snip) { snip == target_snip }
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                let(:snip) { double(CodeSnippet::Snip) }
         | 
| 53 | 
            +
                let(:target_snip) { double(CodeSnippet::Snip) }
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                let(:snips) do
         | 
| 56 | 
            +
                  [
         | 
| 57 | 
            +
                    snip,
         | 
| 58 | 
            +
                    snip,
         | 
| 59 | 
            +
                    target_snip
         | 
| 60 | 
            +
                  ]
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                before do
         | 
| 64 | 
            +
                  subject.instance_variable_set(:@snippets, snips)
         | 
| 65 | 
            +
                  @result = subject.filter(query)
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                it 'finds target snip in set' do
         | 
| 69 | 
            +
                  expect(@result.count).to be 1
         | 
| 70 | 
            +
                  expect(@result.first).to eq target_snip
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                context 'when no query is defined' do
         | 
| 74 | 
            +
                  before do
         | 
| 75 | 
            +
                    @results = subject.filter
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  it 'returns everything' do
         | 
| 79 | 
            +
                    expect(@results.count).to eq 3
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              describe '#find' do
         | 
| 85 | 
            +
                let(:search_term) { 'foo' }
         | 
| 86 | 
            +
                let(:lang) { '.rb' }
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                let(:snip) do
         | 
| 89 | 
            +
                  CodeSnippet::Snip.new('path/to/snip.rb', 'snip.rb', '.rb')
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                let(:target_snip) do
         | 
| 93 | 
            +
                  CodeSnippet::Snip.new('path/to/snip.rb', 'foo.rb', '.rb')
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                let(:almost_target_snip) do
         | 
| 97 | 
            +
                  CodeSnippet::Snip.new('path/to/snip.rb', 'foo.go', '.go')
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                let(:snips) do
         | 
| 101 | 
            +
                  [
         | 
| 102 | 
            +
                    snip,
         | 
| 103 | 
            +
                    snip,
         | 
| 104 | 
            +
                    target_snip,
         | 
| 105 | 
            +
                    almost_target_snip
         | 
| 106 | 
            +
                  ]
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                before do
         | 
| 110 | 
            +
                  subject.instance_variable_set(:@snippets, snips)
         | 
| 111 | 
            +
                  @result = subject.find(search_term, lang)
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                it 'returns expected snip' do
         | 
| 115 | 
            +
                  expect(@result.count).to be 1
         | 
| 116 | 
            +
                  expect(@result.first).to eq target_snip
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                context 'when language filter is not provided' do
         | 
| 120 | 
            +
                  let(:lang) { nil }
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                  it 'returns expected snips' do
         | 
| 123 | 
            +
                    expect(@result.count).to be 2
         | 
| 124 | 
            +
                    expect(@result[0]).to be target_snip
         | 
| 125 | 
            +
                    expect(@result[1]).to be almost_target_snip
         | 
| 126 | 
            +
                  end
         | 
| 127 | 
            +
                end
         | 
| 128 | 
            +
              end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
              describe '#filter_by_extension' do
         | 
| 131 | 
            +
                let(:search_term) { 'foo' }
         | 
| 132 | 
            +
                let(:lang) { '.rb' }
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                let(:snip) do
         | 
| 135 | 
            +
                  CodeSnippet::Snip.new('path/to/snip.rb', 'snip.go', '.go')
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                let(:target_snip) do
         | 
| 139 | 
            +
                  CodeSnippet::Snip.new('path/to/snip.rb', 'foo.rb', '.rb')
         | 
| 140 | 
            +
                end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                let(:another_target_snip) do
         | 
| 143 | 
            +
                  CodeSnippet::Snip.new('path/to/snip.rb', 'bar.rb', '.rb')
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                let(:snips) do
         | 
| 147 | 
            +
                  [
         | 
| 148 | 
            +
                    snip,
         | 
| 149 | 
            +
                    snip,
         | 
| 150 | 
            +
                    target_snip,
         | 
| 151 | 
            +
                    another_target_snip
         | 
| 152 | 
            +
                  ]
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                before do
         | 
| 156 | 
            +
                  subject.instance_variable_set(:@snippets, snips)
         | 
| 157 | 
            +
                  @result = subject.filter_by_extension(lang)
         | 
| 158 | 
            +
                end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                it 'returns files matching extension' do
         | 
| 161 | 
            +
                  expect(@result.count).to be 2
         | 
| 162 | 
            +
                  expect(@result[0]).to be target_snip
         | 
| 163 | 
            +
                  expect(@result[1]).to be another_target_snip
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
            end
         | 
| @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec.describe CodeSnippet::Snip do
         | 
| 4 | 
            +
              let(:file_name) { 'snippet-file' }
         | 
| 5 | 
            +
              let(:file_ext) { '.ext' }
         | 
| 6 | 
            +
              let(:snip_dir) { 'path/to/snippets' }
         | 
| 7 | 
            +
              let(:path) { "#{snip_dir}/path/to/#{file_name}#{file_ext}" }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              describe '.new_from_file' do
         | 
| 10 | 
            +
                before do
         | 
| 11 | 
            +
                  allow(CodeSnippet::CLI).to receive(:snip_dir)
         | 
| 12 | 
            +
                    .and_return(snip_dir)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  @snip = described_class.new_from_file(path)
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                it 'creates snip from path' do
         | 
| 18 | 
            +
                  expect(@snip.path).to eq path
         | 
| 19 | 
            +
                  expect(@snip.name).to eq file_name
         | 
| 20 | 
            +
                  expect(@snip.ext).to eq file_ext
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              subject { described_class.new_from_file(path) }
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              describe '#name' do
         | 
| 27 | 
            +
                it 'returns file name without snip_dir or file extension' do
         | 
| 28 | 
            +
                  expect(subject.name).to eq file_name
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              describe '#exist?' do
         | 
| 33 | 
            +
                let(:exists) { true }
         | 
| 34 | 
            +
                before do
         | 
| 35 | 
            +
                  allow(File).to receive(:exist?)
         | 
| 36 | 
            +
                    .with(path)
         | 
| 37 | 
            +
                    .and_return(exists)
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it 'returns true when file exists' do
         | 
| 41 | 
            +
                  expect(subject.exist?).to be true
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                context 'when file does not exist' do
         | 
| 45 | 
            +
                  let(:exists) { false }
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  it 'returns false' do
         | 
| 48 | 
            +
                    expect(subject.exist?).to be false
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              describe '#content' do
         | 
| 54 | 
            +
                let(:exist) { true }
         | 
| 55 | 
            +
                let(:content) { 'some-snippet' }
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                before do
         | 
| 58 | 
            +
                  allow(subject).to receive(:exist?).and_return(exist)
         | 
| 59 | 
            +
                  allow(File).to receive(:read)
         | 
| 60 | 
            +
                    .with(path)
         | 
| 61 | 
            +
                    .and_return(content)
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                it 'returns snippet file content' do
         | 
| 65 | 
            +
                  expect(subject.content).to eq content
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                context 'when file does not exist' do
         | 
| 69 | 
            +
                  let(:exist) { false }
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  it 'raises error' do
         | 
| 72 | 
            +
                    expect do
         | 
| 73 | 
            +
                      subject.content
         | 
| 74 | 
            +
                    end.to raise_error('cannot read snippet code')
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'simplecov'
         | 
| 4 | 
            +
            require 'pry'
         | 
| 5 | 
            +
            require 'bundler/setup'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            SimpleCov.start
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            SimpleCov.configure do
         | 
| 10 | 
            +
              add_filter 'config'
         | 
| 11 | 
            +
              add_filter 'spec'
         | 
| 12 | 
            +
              add_filter 'vendor'
         | 
| 13 | 
            +
              coverage_dir 'target/reports/coverage'
         | 
| 14 | 
            +
              minimum_coverage 10
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            require 'code_snippet'
         | 
| 18 | 
            +
            require 'code_snippet/cli'
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            RSpec.configure do |config|
         | 
| 21 | 
            +
              config.example_status_persistence_file_path = '.rspec_status'
         | 
| 22 | 
            +
              config.disable_monkey_patching!
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              config.expect_with :rspec do |c|
         | 
| 25 | 
            +
                c.syntax = :expect
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         |