Atalyk
Atalyk

Reputation: 525

How do I write test for homebrew formula?

I made an homebrew formula which is now accessible only on my local taps. I want to send pull request to homebrew-core. Now I am required to write test for my formula. How to write that based on example below?

test do
  output = shell_output("#{bin}/balance 2>&1", 64)
  assert_match "this is balance #{version}", output
end

My formula

#!/usr/bin/env ruby

def match
  files = Dir.glob("*")

  if ARGV.length == 0 
  puts "usage: match <keyword>"
  return
 end

files.each { |x| 
if File.directory?(x) 
    puts "#{x}_ found directory"
    puts "***"
next
end

found = false

File.open(x).each_line.with_index do |line, index|
    if line.include? ARGV[0]
       puts "#{x}_ #{index+1}  #{line}" 
       found = true
    end
end

puts "***" if found  
}
end

match

Brew formula

class Match < Formula
desc "Browse all files inside any directory for a keyword"
homepage "https://github.com/aatalyk/homebrew-match"
url ""
sha256 ""

def install
   bin.install "match"     
end
end

Upvotes: 3

Views: 2526

Answers (1)

bfontaine
bfontaine

Reputation: 19830

Tests for shell commands in Homebrew formulae usually usually follow this scenario:

  1. create a context usable by the command : a git repository, a directories hierarchy, a sample file, etc.
  2. run the command
  3. assert the result is correct

In your case since match is a grep -R -like you could create a bunch of files with some content, then run match <something> and ensure it finds the correct files.

You can use any Ruby code in your tests as well as Homebrew utilities such as shell_output("...command...") to get the output of a command.

Here is an example of test you could write:

class Match < Formula
  # ...

  test do
    # Create two dummy files
    (testpath/"file1").write "foo\nbar\nqux"
    (testpath/"file2").write "bar\nabc"

    # Ensure `match bar` finds both files
    assert_match "file1_ 2  bar\n***\nfile2_ 1  bar",
      shell_output("#{bin}/match bar")

    # Ensure `match abc` finds the second file
    assert_match "file2_ 2  abc", shell_output("#{bin}/match abc")

    # Ensure `match idontmatchanything` doesn’t match any of the files
    assert_not_match(/file[12]/,
      shell_output("#{bin}/match idontmatchanything"))
  end
end

assert_match "something", shell_output("command") ensures that (1) command runs successfully and (2) its output contains "something".

Upvotes: 10

Related Questions