diff --git a/lib/linguist/shebang.rb b/lib/linguist/shebang.rb index 290dca70..7d1c0e8c 100644 --- a/lib/linguist/shebang.rb +++ b/lib/linguist/shebang.rb @@ -3,17 +3,20 @@ module Linguist # Public: Use shebang to detect language of the blob. # # blob - An object that quacks like a blob. + # candidates - A list of candidate languages. # # Examples # # Shebang.call(FileBlob.new("path/to/file")) # - # Returns an Array with one Language if the blob has a shebang with a valid - # interpreter, or empty if there is no shebang. - def self.call(blob, _ = nil) + # Returns an array of languages from the candidate list for which the + # blob's shebang is valid. Returns an empty list if there is no shebang. + # If the candidate list is empty, any language is a valid candidate. + def self.call(blob, candidates) return [] if blob.symlink? - Language.find_by_interpreter interpreter(blob.data) + languages = Language.find_by_interpreter interpreter(blob.data) + candidates.any? ? candidates & languages : languages end # Public: Get the interpreter from the shebang diff --git a/lib/linguist/strategy/extension.rb b/lib/linguist/strategy/extension.rb index 161dc34c..b5dd6e9f 100644 --- a/lib/linguist/strategy/extension.rb +++ b/lib/linguist/strategy/extension.rb @@ -2,8 +2,21 @@ module Linguist module Strategy # Detects language based on extension class Extension - def self.call(blob, _) - Language.find_by_extension(blob.name.to_s) + # Public: Use the file extension to detect the blob's language. + # + # blob - An object that quacks like a blob. + # candidates - A list of candidate languages. + # + # Examples + # + # Extension.call(FileBlob.new("path/to/file")) + # + # Returns an array of languages associated with a blob's file extension. + # Selected languages must be in the candidate list, except if it's empty, + # in which case any language is a valid candidate. + def self.call(blob, candidates) + languages = Language.find_by_extension(blob.name.to_s) + candidates.any? ? candidates & languages : languages end end end diff --git a/lib/linguist/strategy/filename.rb b/lib/linguist/strategy/filename.rb index f3656515..39b9ff1b 100644 --- a/lib/linguist/strategy/filename.rb +++ b/lib/linguist/strategy/filename.rb @@ -2,9 +2,22 @@ module Linguist module Strategy # Detects language based on filename class Filename - def self.call(blob, _) + # Public: Use the filename to detect the blob's language. + # + # blob - An object that quacks like a blob. + # candidates - A list of candidate languages. + # + # Examples + # + # Filename.call(FileBlob.new("path/to/file")) + # + # Returns an array of languages with a associated blob's filename. + # Selected languages must be in the candidate list, except if it's empty, + # in which case any language is a valid candidate. + def self.call(blob, candidates) name = blob.name.to_s - Language.find_by_filename(name) + languages = Language.find_by_filename(name) + candidates.any? ? candidates & languages : languages end end end diff --git a/test/fixtures/Perl/01-methods.pl b/test/fixtures/Perl/01-methods.pl new file mode 100644 index 00000000..251bd4b0 --- /dev/null +++ b/test/fixtures/Perl/01-methods.pl @@ -0,0 +1,51 @@ +#!perl +use Test::More; +use Test::Exception; + +use_ok 'Music::ScaleNote'; + +my $msn = Music::ScaleNote->new( + scale_note => 'C', + scale_name => 'pminor', +# verbose => 1, +); +isa_ok $msn, 'Music::ScaleNote'; + +my $x; + +throws_ok { $x = $msn->get_offset() } + qr/note_name, note_format or offset not provided/, 'invalid get_offset'; + +my $format = 'midinum'; +$x = $msn->get_offset( + note_name => 60, + note_format => $format, + offset => 1, +); +is $x->format($format), 63, 'get_offset'; + +$format = 'ISO'; +$x = $msn->get_offset( + note_name => 'D#4', + note_format => $format, + offset => -1, +); +is $x->format($format), 'C4', 'get_offset'; + +throws_ok { + $x = $msn->get_offset( + note_name => 'C0', + note_format => $format, + offset => -1, + ) +} qr/Octave: -1 out of bounds/, 'out of bounds'; + +throws_ok { + $x = $msn->get_offset( + note_name => 'A#127', + note_format => $format, + offset => 1, + ) +} qr/Octave: 128 out of bounds/, 'out of bounds'; + +done_testing();