<commit_before>require 'spec_helper'
require 'sample_app'

describe Copt::App do
  before(:each) { SampleApp.reset }

  let(:commands) { SampleApp.send :commands }
  let(:current_command) { SampleApp.instance_variable_get(:@command) }

  def expect_failure(&block)
    expect(&block).to change(SampleApp.errors, :size).by(1)
  end

  def expect_success(&block)
    expect(&block).not_to change(SampleApp.errors, :size)
  end

  def command_context
    SampleApp.command(:edit, 'desc') do
      yield
      SampleApp.run {}
    end
  end

  describe '.app' do
    it "defines the app's description" do
      expect(SampleApp.description).to eq('Sample app')
    end

    it "defines the app's version number" do
      expect(SampleApp.version).to eq('0.0.1')
    end

    it "defines the app's configuration settings" do
      expect(SampleApp.config.keys).to eq([:version, :help])
    end
  end

  describe '.command' do
    it "defines a new command" do
      expect {
        SampleApp.command(:edit, 'desc') { SampleApp.run {} }
      }.to change(commands, :length).by(1)
    end

    it "fails in case of duplicate command name" do
      expect_failure do
        SampleApp.command(:show, 'description') { SampleApp.run {} }
      end
    end

    it "fails if no execution block is defined for the command" do
      expect_failure do
        SampleApp.command(:edit, 'desc') {}
      end
    end
  end

  describe '.option' do
    it "defines a new option for the current command" do
      command_context do
        expect { SampleApp.option :name, 'desc' }.to change(current_command.options, :size).by(1)
      end
    end

    it "fails in case of duplicate option keys" do
      command_context do
        expect_success { SampleApp.option :name, 'description', short: 'n', long: 'long' }
        expect_failure { SampleApp.option :none, 'description', short: 'n' }
        expect_failure { SampleApp.option :name, 'description' }
        expect_failure { SampleApp.option :long, 'description' }
      end
    end

    it "fails when option keys are invalid" do
      command_context do
        expect_failure { SampleApp.option :n, 'description' }
        expect_failure { SampleApp.option :one, 'description', short: 'long' }
        expect_failure { SampleApp.option :two, 'description', long: 's' }
      end
    end
  end

  describe '.check' do
    it 'sets a condition that must be checked upon execution of the command' do
      command_context do
        expect { SampleApp.check('Message') { true } }.to change(current_command.preconditions, :size).by(1)
      end
    end

    it 'fails if a block is not provided' do
      command_context do
        expect_failure { SampleApp.check('Message') }
      end
    end
  end

  describe '.run' do
    it "defines the block of code to execute for the current command" do
      SampleApp.command :edit, 'desc' do
        expect(current_command.block).to be_nil
        SampleApp.run {}
        expect(current_command.block).not_to be_nil
      end
    end

    it "does not allow to be called more than once per command" do
      SampleApp.command :edit, 'description' do
        expect_success { SampleApp.run {} }
        expect_failure { SampleApp.run {} }
      end
    end
  end

  describe '.run!' do
    it "recognizes options and arguments passed on the command line" do
      app = SampleApp.run! %w(show one --ignore-cache two three -ps)
      expect(app.args).to eq(%w(one two three))
      expect(app.opts).to eq(pager: true, summary: true, ignore_cache: true)
    end

    it 'processes non-flag options and their values correctly' do
      app = SampleApp.run! %w(complex --dest ~/tmp --quiet file.txt --num-lines 10 --since 2011-11-11)
      expect(app.args).to eq(%w(file.txt))
      expect(app.opts).to eq(quiet: true, dest: '~/tmp', num_lines: 10, since: Date.new(2011, 11, 11))
    end

    it 'recognizes flag options in negative form correctly' do
      app = SampleApp.run! %w(show one --no-ignore-cache)
      expect(app.opts).to eq(ignore_cache: false)
    end

    it 'leaves options at their default value when omitted' do
      app = SampleApp.run! %w(complex file.txt --num-lines 43)
      expect(app.opts).to eq(dest: ENV['HOME'], num_lines: 43, since: Date.new(2000, 1, 1))
    end

    it 'fails when a negative option form does not correspond to a flag option' do
      expect { SampleApp.run! %w(complex --no-dest) }.to raise_error(SystemExit)
      expect { SampleApp.run! %w(complex --no-quiet) }.not_to raise_error
    end

    it "recognizes the '--' argument marker properly" do
      app = SampleApp.run! %w(show one --pager -- two three -rs)
      expect(app.args).to eq(%w(one two three -rs))
      expect(app.opts).to eq({pager: true})
    end

    it "recognizes the specified subcommand and invokes the appropriate block" do
      app = SampleApp.run! %w(show)
      expect(app.command).to eq(:show)
      expect(SampleApp.footprint).to eq('Showing...')

      app = SampleApp.run! %w(list)
      expect(app.command).to eq(:list)
      expect(SampleApp.footprint).to eq('Listing...')
    end

    it "checks all the subcommand's preconditions, if any" do
      expect { SampleApp.run! %w(list hello) }.to raise_error(SystemExit)
    end

    context "when invoked with the --help option" do
      it "bypasses execution and prints the help message" do
        expect { SampleApp.run! %w(list --help) }.to raise_error(SystemExit)
        expect(SampleApp.footprint).not_to eq('Listing...')
      end
    end

    context "when invoked with an invalid subcommand name" do
      it "should fail execution and exit" do
        expect { SampleApp.run! %w(edit) }.to raise_error(SystemExit)
      end<commit_msg>Better organization in app spec file<commit_after>require 'spec_helper'
require 'sample_app'

describe Copt::App do
  before(:each) { SampleApp.reset }

  let(:commands) { SampleApp.send :commands }
  let(:current_command) { SampleApp.instance_variable_get(:@command) }

  def expect_failure(&block)
    expect(&block).to change(SampleApp.errors, :size).by(1)
  end

  def expect_success(&block)
    expect(&block).not_to change(SampleApp.errors, :size)
  end

  def command_context
    SampleApp.command(:edit, 'desc') do
      yield
      SampleApp.run {}
    end
  end

  describe '.app' do
    it "defines the app's description" do
      expect(SampleApp.description).to eq('Sample app')
    end

    it "defines the app's version number" do
      expect(SampleApp.version).to eq('0.0.1')
    end

    it "defines the app's configuration settings" do
      expect(SampleApp.config.keys).to eq([:version, :help])
    end
  end

  describe '.command' do
    it "defines a new command" do
      expect {
        SampleApp.command(:edit, 'desc') { SampleApp.run {} }
      }.to change(commands, :length).by(1)
    end

    it "fails in case of duplicate command name" do
      expect_failure do
        SampleApp.command(:show, 'description') { SampleApp.run {} }
      end
    end

    it "fails if no execution block is defined for the command" do
      expect_failure do
        SampleApp.command(:edit, 'desc') {}
      end
    end
  end

  describe '.option' do
    it "defines a new option for the current command" do
      command_context do
        expect { SampleApp.option :name, 'desc' }.to change(current_command.options, :size).by(1)
      end
    end

    it "fails in case of duplicate option keys" do
      command_context do
        expect_success { SampleApp.option :name, 'description', short: 'n', long: 'long' }
        expect_failure { SampleApp.option :none, 'description', short: 'n' }
        expect_failure { SampleApp.option :name, 'description' }
        expect_failure { SampleApp.option :long, 'description' }
      end
    end

    it "fails when option keys are invalid" do
      command_context do
        expect_failure { SampleApp.option :n, 'description' }
        expect_failure { SampleApp.option :one, 'description', short: 'long' }
        expect_failure { SampleApp.option :two, 'description', long: 's' }
      end
    end
  end

  describe '.check' do
    it 'sets a condition that must be checked upon execution of the command' do
      command_context do
        expect { SampleApp.check('Message') { true } }.to change(current_command.preconditions, :size).by(1)
      end
    end

    it 'fails if a block is not provided' do
      command_context do
        expect_failure { SampleApp.check('Message') }
      end
    end
  end

  describe '.run' do
    it "defines the block of code to execute for the current command" do
      SampleApp.command :edit, 'desc' do
        expect(current_command.block).to be_nil
        SampleApp.run {}
        expect(current_command.block).not_to be_nil
      end
    end

    it "does not allow to be called more than once per command" do
      SampleApp.command :edit, 'description' do
        expect_success { SampleApp.run {} }
        expect_failure { SampleApp.run {} }
      end
    end
  end

  describe 'parsing command line arguments' do
    it "recognizes options and arguments passed on the command line" do
      app = SampleApp.run! %w(show one --ignore-cache two three -ps)
      expect(app.args).to eq(%w(one two three))
      expect(app.opts).to eq(pager: true, summary: true, ignore_cache: true)
    end

    it 'processes non-flag options and their values correctly' do
      app = SampleApp.run! %w(complex --dest ~/tmp --quiet file.txt --num-lines 10 --since 2011-11-11)
      expect(app.args).to eq(%w(file.txt))
      expect(app.opts).to eq(quiet: true, dest: '~/tmp', num_lines: 10, since: Date.new(2011, 11, 11))
    end

    it 'recognizes flag options in negative form correctly' do
      app = SampleApp.run! %w(show one --no-ignore-cache)
      expect(app.opts).to eq(ignore_cache: false)
    end

    it 'leaves options at their default value when omitted' do
      app = SampleApp.run! %w(complex file.txt --num-lines 43)
      expect(app.opts).to eq(dest: ENV['HOME'], num_lines: 43, since: Date.new(2000, 1, 1))
    end

    it 'fails when a negative option form does not correspond to a flag option' do
      expect { SampleApp.run! %w(complex --no-dest) }.to raise_error(SystemExit)
      expect { SampleApp.run! %w(complex --no-quiet) }.not_to raise_error
    end

    it "recognizes the '--' argument marker properly" do
      app = SampleApp.run! %w(show one --pager -- two three -rs)
      expect(app.args).to eq(%w(one two three -rs))
      expect(app.opts).to eq({pager: true})
    end

    it "recognizes the specified subcommand and invokes the appropriate block" do
      app = SampleApp.run! %w(show)
      expect(app.command).to eq(:show)
      expect(SampleApp.footprint).to eq('Showing...')

      app = SampleApp.run! %w(list)
      expect(app.command).to eq(:list)
      expect(SampleApp.footprint).to eq('Listing...')
    end
  end

  describe '.run!' do
    it "checks all the subcommand's preconditions, if any" do
      expect { SampleApp.run! %w(list hello) }.to raise_error(SystemExit)
    end

    context "when invoked with the --help option" do
      it "bypasses execution and prints the help message" do
        expect { SampleApp.run! %w(list --help) }.to raise_error(SystemExit)
        expect(SampleApp.footprint).not_to eq('Listing...')
      end
    end

    context "when invoked with an invalid subcommand name" do
      it "should fail execution and exit" do
        expect { SampleApp.run! %w(edit) }.to raise_error(SystemExit)
      end
{'fraction_non_alphanumeric': 0.11109179415855355, 'fraction_numerical': 0.006432545201668985, 'mean_word_length': 2.78827790582812, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7519082', 'n_tokens_mistral': 3611, 'n_tokens_neox': 3475, 'n_words': 1129}