twig 1.6 → 1.7
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 +4 -4
- data/.travis.yml +2 -0
- data/HISTORY.md +27 -0
- data/README.md +41 -22
- data/bin/twig +12 -4
- data/bin/twig-checkout-child +56 -25
- data/bin/twig-checkout-parent +54 -26
- data/bin/twig-create-branch +40 -15
- data/bin/twig-diff +44 -25
- data/bin/twig-gh-open +43 -17
- data/bin/twig-gh-open-issue +51 -23
- data/bin/twig-gh-update +46 -20
- data/bin/twig-help +49 -5
- data/bin/twig-init +46 -13
- data/bin/twig-init-completion +46 -19
- data/bin/twig-init-completion-bash +50 -25
- data/bin/twig-init-config +77 -0
- data/bin/twig-rebase +85 -33
- data/config/twigconfig +47 -0
- data/lib/twig.rb +16 -10
- data/lib/twig/branch.rb +19 -12
- data/lib/twig/cli.rb +118 -183
- data/lib/twig/cli/help.rb +174 -0
- data/lib/twig/commit_time.rb +69 -14
- data/lib/twig/display.rb +19 -6
- data/lib/twig/github.rb +10 -8
- data/lib/twig/options.rb +22 -14
- data/lib/twig/subcommands.rb +13 -1
- data/lib/twig/system.rb +0 -2
- data/lib/twig/util.rb +0 -2
- data/lib/twig/version.rb +1 -1
- data/spec/spec_helper.rb +4 -3
- data/spec/twig/branch_spec.rb +100 -13
- data/spec/twig/cli/help_spec.rb +187 -0
- data/spec/twig/cli_spec.rb +34 -189
- data/spec/twig/commit_time_spec.rb +185 -16
- data/spec/twig/display_spec.rb +69 -48
- data/spec/twig/github_spec.rb +29 -15
- data/spec/twig/options_spec.rb +42 -13
- data/spec/twig/subcommands_spec.rb +35 -2
- data/spec/twig/system_spec.rb +5 -6
- data/spec/twig/util_spec.rb +20 -20
- data/spec/twig_spec.rb +21 -6
- data/twig.gemspec +14 -16
- metadata +23 -27
    
        data/lib/twig/subcommands.rb
    CHANGED
    
    | @@ -1,6 +1,5 @@ | |
| 1 1 | 
             
            class Twig
         | 
| 2 2 | 
             
              module Subcommands
         | 
| 3 | 
            -
             | 
| 4 3 | 
             
                BIN_PREFIX = 'twig-'
         | 
| 5 4 |  | 
| 6 5 | 
             
                def self.all_names
         | 
| @@ -22,5 +21,18 @@ class Twig | |
| 22 21 | 
             
                  ENV['PATH'].split(':')
         | 
| 23 22 | 
             
                end
         | 
| 24 23 |  | 
| 24 | 
            +
                def self.exec_subcommand_if_any(cli_args)
         | 
| 25 | 
            +
                  # Run subcommand binary, if any, and exit here
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  subcommand_name = cli_args[0]
         | 
| 28 | 
            +
                  bin_name = Twig::Subcommands::BIN_PREFIX + subcommand_name
         | 
| 29 | 
            +
                  subcommand_path = Twig.run("which #{bin_name} 2>/dev/null")
         | 
| 30 | 
            +
                  return if subcommand_path.empty?
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  subcommand_args = cli_args[1..-1]
         | 
| 33 | 
            +
                  command = ([subcommand_path] + subcommand_args).join(' ')
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  exec(command)
         | 
| 36 | 
            +
                end
         | 
| 25 37 | 
             
              end
         | 
| 26 38 | 
             
            end
         | 
    
        data/lib/twig/system.rb
    CHANGED
    
    
    
        data/lib/twig/util.rb
    CHANGED
    
    
    
        data/lib/twig/version.rb
    CHANGED
    
    
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -1,9 +1,10 @@ | |
| 1 1 | 
             
            require 'twig'
         | 
| 2 2 | 
             
            require 'json'
         | 
| 3 | 
            -
            require 'rspec/radar'
         | 
| 4 3 |  | 
| 5 4 | 
             
            RSpec.configure do |config|
         | 
| 6 | 
            -
              config. | 
| 7 | 
            -
                 | 
| 5 | 
            +
              config.mock_with :rspec do |mocks|
         | 
| 6 | 
            +
                mocks.verify_doubled_constant_names = true
         | 
| 7 | 
            +
                mocks.verify_partial_doubles = true
         | 
| 8 | 
            +
                mocks.yield_receiver_to_any_instance_implementation_blocks = true
         | 
| 8 9 | 
             
              end
         | 
| 9 10 | 
             
            end
         | 
    
        data/spec/twig/branch_spec.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            # encoding: UTF-8
         | 
| 2 2 | 
             
            require 'spec_helper'
         | 
| 3 | 
            +
            require 'shellwords'
         | 
| 3 4 |  | 
| 4 5 | 
             
            describe Twig::Branch do
         | 
| 5 6 | 
             
              before :each do
         | 
| @@ -13,16 +14,18 @@ describe Twig::Branch do | |
| 13 14 | 
             
                    fix_some_other_of_the_things
         | 
| 14 15 | 
             
                    fix_nothing
         | 
| 15 16 | 
             
                  ]
         | 
| 16 | 
            -
                  @commit_time_strings = [ | 
| 17 | 
            -
             | 
| 17 | 
            +
                  @commit_time_strings = %w[
         | 
| 18 | 
            +
                    2001-01-01
         | 
| 19 | 
            +
                    2002-02-02
         | 
| 20 | 
            +
                    2003-03-03
         | 
| 21 | 
            +
                  ]
         | 
| 18 22 | 
             
                  @command =
         | 
| 19 23 | 
             
                    %{git for-each-ref #{Twig::REF_PREFIX} --format="#{Twig::REF_FORMAT}"}
         | 
| 20 24 |  | 
| 21 25 | 
             
                  @branch_tuples = (0..2).map do |i|
         | 
| 22 26 | 
             
                    [
         | 
| 23 27 | 
             
                      @branch_names[i],
         | 
| 24 | 
            -
                      @commit_time_strings[i] | 
| 25 | 
            -
                      @commit_time_agos[i]
         | 
| 28 | 
            +
                      @commit_time_strings[i]
         | 
| 26 29 | 
             
                    ].join(Twig::REF_FORMAT_SEPARATOR)
         | 
| 27 30 | 
             
                  end.join("\n")
         | 
| 28 31 | 
             
                end
         | 
| @@ -34,15 +37,15 @@ describe Twig::Branch do | |
| 34 37 |  | 
| 35 38 | 
             
                  expect(branches[0].name).to eq(@branch_names[0])
         | 
| 36 39 | 
             
                  expect(branches[0].last_commit_time.to_s).to match(
         | 
| 37 | 
            -
                     | 
| 40 | 
            +
                    /#{@commit_time_strings[0]}/
         | 
| 38 41 | 
             
                  )
         | 
| 39 42 | 
             
                  expect(branches[1].name).to eq(@branch_names[1])
         | 
| 40 43 | 
             
                  expect(branches[1].last_commit_time.to_s).to match(
         | 
| 41 | 
            -
                     | 
| 44 | 
            +
                    /#{@commit_time_strings[1]}/
         | 
| 42 45 | 
             
                  )
         | 
| 43 46 | 
             
                  expect(branches[2].name).to eq(@branch_names[2])
         | 
| 44 47 | 
             
                  expect(branches[2].last_commit_time.to_s).to match(
         | 
| 45 | 
            -
                     | 
| 48 | 
            +
                    /#{@commit_time_strings[2]}/
         | 
| 46 49 | 
             
                  )
         | 
| 47 50 | 
             
                end
         | 
| 48 51 |  | 
| @@ -144,6 +147,26 @@ describe Twig::Branch do | |
| 144 147 | 
             
                end
         | 
| 145 148 | 
             
              end
         | 
| 146 149 |  | 
| 150 | 
            +
              describe '.shellescape_property_value' do
         | 
| 151 | 
            +
                it 'escapes backticks' do
         | 
| 152 | 
            +
                  value  = 'value_`ls`'
         | 
| 153 | 
            +
                  result = Twig::Branch.shellescape_property_value(value)
         | 
| 154 | 
            +
                  expect(result).to eql('value_\`ls\`')
         | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                it 'escapes dollar signs' do
         | 
| 158 | 
            +
                  value  = 'value_$PATH'
         | 
| 159 | 
            +
                  result = Twig::Branch.shellescape_property_value(value)
         | 
| 160 | 
            +
                  expect(result).to eql('value_\$PATH')
         | 
| 161 | 
            +
                end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                it 'does not escape spaces' do
         | 
| 164 | 
            +
                  value  = 'foo  bar'
         | 
| 165 | 
            +
                  result = Twig::Branch.shellescape_property_value(value)
         | 
| 166 | 
            +
                  expect(result).to eql('foo  bar')
         | 
| 167 | 
            +
                end
         | 
| 168 | 
            +
              end
         | 
| 169 | 
            +
             | 
| 147 170 | 
             
              describe '#initialize' do
         | 
| 148 171 | 
             
                it 'requires a name' do
         | 
| 149 172 | 
             
                  branch = Twig::Branch.new('test')
         | 
| @@ -155,7 +178,7 @@ describe Twig::Branch do | |
| 155 178 | 
             
                end
         | 
| 156 179 |  | 
| 157 180 | 
             
                it 'accepts a last commit time' do
         | 
| 158 | 
            -
                  commit_time = Twig::CommitTime.new(Time.now | 
| 181 | 
            +
                  commit_time = Twig::CommitTime.new(Time.now)
         | 
| 159 182 | 
             
                  branch = Twig::Branch.new('test', :last_commit_time => commit_time)
         | 
| 160 183 | 
             
                  expect(branch.last_commit_time).to eq(commit_time)
         | 
| 161 184 | 
             
                end
         | 
| @@ -172,7 +195,7 @@ describe Twig::Branch do | |
| 172 195 | 
             
                before :each do
         | 
| 173 196 | 
             
                  @branch = Twig::Branch.new('test')
         | 
| 174 197 | 
             
                  time = Time.parse('2000-01-01 18:30 UTC')
         | 
| 175 | 
            -
                  commit_time = Twig::CommitTime.new(time | 
| 198 | 
            +
                  commit_time = Twig::CommitTime.new(time)
         | 
| 176 199 | 
             
                  @time_string = time.iso8601
         | 
| 177 200 | 
             
                  allow(@branch).to receive(:last_commit_time) { commit_time }
         | 
| 178 201 | 
             
                end
         | 
| @@ -207,6 +230,24 @@ describe Twig::Branch do | |
| 207 230 | 
             
                end
         | 
| 208 231 | 
             
              end
         | 
| 209 232 |  | 
| 233 | 
            +
              describe '#parent_name' do
         | 
| 234 | 
            +
                before :each do
         | 
| 235 | 
            +
                  @branch = Twig::Branch.new('test')
         | 
| 236 | 
            +
                end
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                it 'returns the parent branch name' do
         | 
| 239 | 
            +
                  parent_name = 'parent'
         | 
| 240 | 
            +
                  allow(@branch).to receive(:get_property).with('diff-branch').and_return(parent_name)
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                  expect(@branch.parent_name).to eq(parent_name)
         | 
| 243 | 
            +
                end
         | 
| 244 | 
            +
             | 
| 245 | 
            +
                it 'returns nil if the parent branch is unknown' do
         | 
| 246 | 
            +
                  allow(@branch).to receive(:get_property).with('diff-branch')
         | 
| 247 | 
            +
                  expect(@branch.parent_name).to be_nil
         | 
| 248 | 
            +
                end
         | 
| 249 | 
            +
              end
         | 
| 250 | 
            +
             | 
| 210 251 | 
             
              describe '#sanitize_property' do
         | 
| 211 252 | 
             
                before :each do
         | 
| 212 253 | 
             
                  @branch = Twig::Branch.new('test')
         | 
| @@ -259,6 +300,7 @@ describe Twig::Branch do | |
| 259 300 | 
             
                  branch     = Twig::Branch.new('utf8_{・ิω・ิ}')
         | 
| 260 301 | 
             
                  properties = { 'test1' => 'value1' }
         | 
| 261 302 | 
             
                  git_result = "branch.#{branch}.test1 value1"
         | 
| 303 | 
            +
                  expect(Shellwords).to receive(:escape).with(branch.to_s) { branch.to_s }
         | 
| 262 304 | 
             
                  expect(Twig).to receive(:run).
         | 
| 263 305 | 
             
                    with(%{git config --get-regexp "branch.#{branch}.(test1)$"}).
         | 
| 264 306 | 
             
                    and_return(git_result)
         | 
| @@ -322,7 +364,7 @@ describe Twig::Branch do | |
| 322 364 | 
             
                  end
         | 
| 323 365 |  | 
| 324 366 | 
             
                  expect(expected_exception.message).to eq(
         | 
| 325 | 
            -
                    Twig::Branch:: | 
| 367 | 
            +
                    Twig::Branch::EmptyPropertyNameError::DEFAULT_MESSAGE
         | 
| 326 368 | 
             
                  )
         | 
| 327 369 | 
             
                end
         | 
| 328 370 | 
             
              end
         | 
| @@ -403,7 +445,7 @@ describe Twig::Branch do | |
| 403 445 | 
             
                  end
         | 
| 404 446 |  | 
| 405 447 | 
             
                  expect(expected_exception.message).to eq(
         | 
| 406 | 
            -
                    Twig::Branch:: | 
| 448 | 
            +
                    Twig::Branch::EmptyPropertyNameError::DEFAULT_MESSAGE
         | 
| 407 449 | 
             
                  )
         | 
| 408 450 | 
             
                end
         | 
| 409 451 |  | 
| @@ -483,6 +525,37 @@ describe Twig::Branch do | |
| 483 525 | 
             
                    %{Saved property "#{property}" as "#{value}" for branch "#{@branch}"}
         | 
| 484 526 | 
             
                  )
         | 
| 485 527 | 
             
                end
         | 
| 528 | 
            +
             | 
| 529 | 
            +
                it 'sets a property for a branch whose name contains a backtick' do
         | 
| 530 | 
            +
                  branch   = Twig::Branch.new('branch_`ls`')
         | 
| 531 | 
            +
                  property = 'test'
         | 
| 532 | 
            +
                  value    = 'value'
         | 
| 533 | 
            +
                  escaped_branch_name = branch.to_s.shellescape
         | 
| 534 | 
            +
                  expect(Twig).to receive(:run).
         | 
| 535 | 
            +
                    with(%{git config branch.#{escaped_branch_name}.#{property} "#{value}"}) do
         | 
| 536 | 
            +
                      `(exit 0)`; value # Set `$?` to `0`
         | 
| 537 | 
            +
                    end
         | 
| 538 | 
            +
             | 
| 539 | 
            +
                  result = branch.set_property(property, value)
         | 
| 540 | 
            +
                  expect(result).to include(
         | 
| 541 | 
            +
                    %{Saved property "#{property}" as "#{value}" for branch "#{branch}"}
         | 
| 542 | 
            +
                  )
         | 
| 543 | 
            +
                end
         | 
| 544 | 
            +
             | 
| 545 | 
            +
                it 'sets a property value that contains special shell characters' do
         | 
| 546 | 
            +
                  property      = 'test'
         | 
| 547 | 
            +
                  value         = 'value `ls` $PATH'
         | 
| 548 | 
            +
                  escaped_value = 'value \`ls\` \$PATH'
         | 
| 549 | 
            +
                  expect(Twig).to receive(:run).
         | 
| 550 | 
            +
                    with(%{git config branch.#{@branch}.#{property} "#{escaped_value}"}) do
         | 
| 551 | 
            +
                      `(exit 0)`; value # Set `$?` to `0`
         | 
| 552 | 
            +
                    end
         | 
| 553 | 
            +
             | 
| 554 | 
            +
                  result = @branch.set_property(property, value)
         | 
| 555 | 
            +
                  expect(result).to include(
         | 
| 556 | 
            +
                    %{Saved property "#{property}" as "#{value}" for branch "#{@branch}"}
         | 
| 557 | 
            +
                  )
         | 
| 558 | 
            +
                end
         | 
| 486 559 | 
             
              end
         | 
| 487 560 |  | 
| 488 561 | 
             
              describe '#unset_property' do
         | 
| @@ -519,7 +592,6 @@ describe Twig::Branch do | |
| 519 592 |  | 
| 520 593 | 
             
                it 'raises an error if the property name is an empty string' do
         | 
| 521 594 | 
             
                  bad_property = ' '
         | 
| 522 | 
            -
                  property     = ''
         | 
| 523 595 | 
             
                  expect(@branch).not_to receive(:get_property)
         | 
| 524 596 | 
             
                  expect(Twig).not_to receive(:run)
         | 
| 525 597 |  | 
| @@ -530,7 +602,7 @@ describe Twig::Branch do | |
| 530 602 | 
             
                  end
         | 
| 531 603 |  | 
| 532 604 | 
             
                  expect(expected_exception.message).to eq(
         | 
| 533 | 
            -
                    Twig::Branch:: | 
| 605 | 
            +
                    Twig::Branch::EmptyPropertyNameError::DEFAULT_MESSAGE
         | 
| 534 606 | 
             
                  )
         | 
| 535 607 | 
             
                end
         | 
| 536 608 |  | 
| @@ -548,6 +620,21 @@ describe Twig::Branch do | |
| 548 620 | 
             
                    %{The branch "#{@branch}" does not have the property "#{property}"}
         | 
| 549 621 | 
             
                  )
         | 
| 550 622 | 
             
                end
         | 
| 623 | 
            +
             | 
| 624 | 
            +
                it 'unsets a property for a branch whose name contains a backtick' do
         | 
| 625 | 
            +
                  branch   = Twig::Branch.new('branch_`ls`')
         | 
| 626 | 
            +
                  property = 'test'
         | 
| 627 | 
            +
                  expect(branch).to receive(:get_property).
         | 
| 628 | 
            +
                    with(property).and_return('value')
         | 
| 629 | 
            +
                  expect(Twig).to receive(:run).with(
         | 
| 630 | 
            +
                    %{git config --unset branch.#{branch.to_s.shellescape}.#{property}}
         | 
| 631 | 
            +
                  )
         | 
| 632 | 
            +
             | 
| 633 | 
            +
                  result = branch.unset_property(property)
         | 
| 634 | 
            +
                  expect(result).to include(
         | 
| 635 | 
            +
                    %{Removed property "#{property}" for branch "#{branch}"}
         | 
| 636 | 
            +
                  )
         | 
| 637 | 
            +
                end
         | 
| 551 638 | 
             
              end
         | 
| 552 639 |  | 
| 553 640 | 
             
            end
         | 
| @@ -0,0 +1,187 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Twig::Cli::Help do
         | 
| 4 | 
            +
              Help = Twig::Cli::Help
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              describe '.description' do
         | 
| 7 | 
            +
                before :each do
         | 
| 8 | 
            +
                  @twig = Twig.new
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                it 'returns short text in a single line' do
         | 
| 12 | 
            +
                  text = 'The quick brown fox.'
         | 
| 13 | 
            +
                  result = Help.description(text, :width => 80)
         | 
| 14 | 
            +
                  expect(result).to eq([text])
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                it 'returns long text in a string with line breaks' do
         | 
| 18 | 
            +
                  text = 'The quick brown fox jumps over the lazy, lazy dog.'
         | 
| 19 | 
            +
                  result = Help.description(text, :width => 20)
         | 
| 20 | 
            +
                  expect(result).to eq([
         | 
| 21 | 
            +
                    'The quick brown fox',
         | 
| 22 | 
            +
                    'jumps over the lazy,',
         | 
| 23 | 
            +
                    'lazy dog.'
         | 
| 24 | 
            +
                  ])
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                it 'breaks a long word by max line length' do
         | 
| 28 | 
            +
                  text = 'Thequickbrownfoxjumpsoverthelazydog.'
         | 
| 29 | 
            +
                  result = Help.description(text, :width => 20)
         | 
| 30 | 
            +
                  expect(result).to eq([
         | 
| 31 | 
            +
                    'Thequickbrownfoxjump',
         | 
| 32 | 
            +
                    'soverthelazydog.'
         | 
| 33 | 
            +
                  ])
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                it 'adds a blank line' do
         | 
| 37 | 
            +
                  text = 'The quick brown fox.'
         | 
| 38 | 
            +
                  result = Help.description(text, :width => 80, :add_blank_line => true)
         | 
| 39 | 
            +
                  expect(result).to eq([text, ' '])
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              describe '.description_for_custom_property' do
         | 
| 44 | 
            +
                before :each do
         | 
| 45 | 
            +
                  @twig = Twig.new
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                it 'returns a help string for a custom property' do
         | 
| 49 | 
            +
                  option_parser = OptionParser.new
         | 
| 50 | 
            +
                  expect(Help).to receive(:print_section) do |opt_parser, desc, options|
         | 
| 51 | 
            +
                    expect(opt_parser).to eq(option_parser)
         | 
| 52 | 
            +
                    expect(desc).to eq("      --test-option                Test option description\n")
         | 
| 53 | 
            +
                    expect(options).to eq(:trailing => "\n")
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  Help.description_for_custom_property(option_parser, [
         | 
| 57 | 
            +
                    ['--test-option', 'Test option description']
         | 
| 58 | 
            +
                  ])
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                it 'supports custom trailing whitespace' do
         | 
| 62 | 
            +
                  option_parser = OptionParser.new
         | 
| 63 | 
            +
                  expect(Help).to receive(:print_section) do |opt_parser, desc, options|
         | 
| 64 | 
            +
                    expect(opt_parser).to eq(option_parser)
         | 
| 65 | 
            +
                    expect(desc).to eq("      --test-option                Test option description\n")
         | 
| 66 | 
            +
                    expect(options).to eq(:trailing => '')
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  Help.description_for_custom_property(option_parser, [
         | 
| 70 | 
            +
                    ['--test-option', 'Test option description']
         | 
| 71 | 
            +
                  ], :trailing => '')
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              describe '.line_for_custom_property?' do
         | 
| 76 | 
            +
                before :each do
         | 
| 77 | 
            +
                  @twig = Twig.new
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                it 'returns true for `--except-foo`' do
         | 
| 81 | 
            +
                  expect(Help.line_for_custom_property?('  --except-foo  ')).to eql(true)
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                it 'returns false for `--except-branch`' do
         | 
| 85 | 
            +
                  expect(Help.line_for_custom_property?('  --except-branch  ')).to be_falsy
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                it 'returns false for `--except-property`' do
         | 
| 89 | 
            +
                  expect(Help.line_for_custom_property?('  --except-property  ')).to be_falsy
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                it 'returns false for `--except-PROPERTY`' do
         | 
| 93 | 
            +
                  expect(Help.line_for_custom_property?('  --except-PROPERTY  ')).to be_falsy
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                it 'returns true for `--only-foo`' do
         | 
| 97 | 
            +
                  expect(Help.line_for_custom_property?('  --only-foo  ')).to eql(true)
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                it 'returns false for `--only-branch`' do
         | 
| 101 | 
            +
                  expect(Help.line_for_custom_property?('  --only-branch  ')).to be_falsy
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                it 'returns false for `--only-property`' do
         | 
| 105 | 
            +
                  expect(Help.line_for_custom_property?('  --only-property  ')).to be_falsy
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                it 'returns false for `--only-PROPERTY`' do
         | 
| 109 | 
            +
                  expect(Help.line_for_custom_property?('  --only-PROPERTY  ')).to be_falsy
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                it 'returns true for `--foo-width`' do
         | 
| 113 | 
            +
                  expect(Help.line_for_custom_property?('  --foo-width  ')).to eql(true)
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                it 'returns false for `--branch-width`' do
         | 
| 117 | 
            +
                  expect(Help.line_for_custom_property?('  --branch-width  ')).to be_falsy
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                it 'returns false for `--PROPERTY-width`' do
         | 
| 121 | 
            +
                  expect(Help.line_for_custom_property?('  --PROPERTY-width  ')).to be_falsy
         | 
| 122 | 
            +
                end
         | 
| 123 | 
            +
              end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
              describe '.paragraph' do
         | 
| 126 | 
            +
                before :each do
         | 
| 127 | 
            +
                  @twig = Twig.new
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                it 'returns long text in a paragraph with line breaks' do
         | 
| 131 | 
            +
                  text = Array.new(5) do
         | 
| 132 | 
            +
                    'The quick brown fox jumps over the lazy dog.'
         | 
| 133 | 
            +
                  end.join(' ')
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  result = Help.paragraph(text)
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  expect(result).to eq([
         | 
| 138 | 
            +
                    'The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the',
         | 
| 139 | 
            +
                    'lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps',
         | 
| 140 | 
            +
                    'over the lazy dog. The quick brown fox jumps over the lazy dog.'
         | 
| 141 | 
            +
                  ].join("\n"))
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
              end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
              describe '.subcommand_descriptions' do
         | 
| 146 | 
            +
                it 'returns a word-wrapped list of subcommand descriptions' do
         | 
| 147 | 
            +
                  output_lines = Help.subcommand_descriptions
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                  # Some lines are actually multi-line descriptions. Split them so we can
         | 
| 150 | 
            +
                  # count characters per line.
         | 
| 151 | 
            +
                  output_lines = output_lines.map { |line| line.split("\n") }.flatten
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  output_line_max_width = output_lines.map { |line| line.length }.max
         | 
| 154 | 
            +
                  expect(output_line_max_width).to be <= Help.console_width
         | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
              end
         | 
| 157 | 
            +
             | 
| 158 | 
            +
              describe '.header' do
         | 
| 159 | 
            +
                it 'generates a header section' do
         | 
| 160 | 
            +
                  option_parser = double
         | 
| 161 | 
            +
                  text = 'Some header'
         | 
| 162 | 
            +
                  expected_text = "Some header\n==========="
         | 
| 163 | 
            +
                  expect(Help).to receive(:print_section).with(
         | 
| 164 | 
            +
                    option_parser,
         | 
| 165 | 
            +
                    expected_text,
         | 
| 166 | 
            +
                    :trailing => "\n\n"
         | 
| 167 | 
            +
                  )
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                  Help.header(option_parser, text)
         | 
| 170 | 
            +
                end
         | 
| 171 | 
            +
              end
         | 
| 172 | 
            +
             | 
| 173 | 
            +
              describe '.subheader' do
         | 
| 174 | 
            +
                it 'generates a subheader section' do
         | 
| 175 | 
            +
                  option_parser = double
         | 
| 176 | 
            +
                  text = 'Some subheader'
         | 
| 177 | 
            +
                  expected_text = "Some subheader\n--------------"
         | 
| 178 | 
            +
                  expect(Help).to receive(:print_section).with(
         | 
| 179 | 
            +
                    option_parser,
         | 
| 180 | 
            +
                    expected_text,
         | 
| 181 | 
            +
                    :trailing => "\n\n"
         | 
| 182 | 
            +
                  )
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                  Help.subheader(option_parser, text)
         | 
| 185 | 
            +
                end
         | 
| 186 | 
            +
              end
         | 
| 187 | 
            +
            end
         |