Skip to content

Commit

Permalink
Added proper tests for the rest of Operation
Browse files Browse the repository at this point in the history
  • Loading branch information
stex committed Jul 28, 2020
1 parent 6b9d4d4 commit 449be08
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 46 deletions.
4 changes: 3 additions & 1 deletion exe/plex_symlinker
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ opts = Slop.parse { |o|
}

fail ArgumentError, "Please provide at least source and target directory." if opts.arguments.size != 2
PlexSymlinker.logger = Logger.new(opts[:log]) if opts[:log]
if opts[:log]
PlexSymlinker.output = File.new(opts[:log], "w")
end

PlexSymlinker::Operation.new(*opts.arguments, symlink_target_dir: opts[:symlink_target_dir]).perform
12 changes: 8 additions & 4 deletions lib/plex_symlinker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
module PlexSymlinker
class Error < StandardError; end

def self.logger
@logger ||= Logger.new("/dev/null")
def self.output
@output ||= STDOUT
end

def self.output=(val)
@output = val
end

def self.logger=(logger)
@logger = logger
def self.logger
@logger ||= Logger.new(output)
end
end
12 changes: 6 additions & 6 deletions lib/plex_symlinker/operation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ def initialize(files_base_dir, symlinks_base_dir, symlink_target_dir: nil)
# @return [Array<String>] The paths to all files with matching extensions within the given directory
#
def files(dir, extensions = FileTypes::AudioFile.registered_types.keys)
extensions.flat_map do |extension|
Dir[File.join(dir, "**/*.#{extension}")]
end
Dir[File.join(dir, "**/*.{#{extensions.join(",")}}")]
end

def audio_files
Expand All @@ -68,15 +66,17 @@ def perform
def create_symlinks
PlexSymlinker.logger.info "Creating new symlinks..."

progress = ProgressBar.create(total: audio_files.size)
progress = ProgressBar.create(total: audio_files.size, output: PlexSymlinker.output)

audio_files.each do |file|
progress.title = "#{file.album_artist.truncate(20)}/#{file.album.truncate(20)}"
progress.log " --* #{file.album_artist}/#{file.album}..."

FileUtils.mkdir_p(File.join(symlinks_base_dir, file.relative_symlink_dir))

path = file.path.gsub(files_base_dir, virtual_files_base_dir)
path = file.path.gsub(files_base_dir, symlink_target_dir)
symlink_path = File.join(symlinks_base_dir, file.relative_symlink_path)

# If we already have a symlink, don't try to create it again.
next if File.symlink?(symlink_path)

File.symlink(path, symlink_path)
Expand Down
8 changes: 4 additions & 4 deletions spec/plex_symlinker/file_types/mp3_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
let(:file) { resource_file("example.mp3") }
subject { described_class.new(file.to_s) }

its(:album) { is_expected.to eql "book-album" }
its(:genre) { is_expected.to eql "book-genre" }
its(:title) { is_expected.to eql "book-title" }
its(:album) { is_expected.to eql "mp3-book-album" }
its(:genre) { is_expected.to eql "mp3-book-genre" }
its(:title) { is_expected.to eql "mp3-book-title" }
its(:year) { is_expected.to eql "2001" }
its(:artist) { is_expected.to eql "book-artist" }
its(:artist) { is_expected.to eql "mp3-book-artist" }
its(:track_number) { is_expected.to eql "42" }
end
16 changes: 8 additions & 8 deletions spec/plex_symlinker/file_types/mp4_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
let(:file) { resource_file("example.m4b") }
subject { described_class.new(file.to_s) }

its(:sort_album_artist) { is_expected.to eql "book-sort-album-artist" }
its(:sort_artist) { is_expected.to eql "book-sort-artist" }
its(:sort_album) { is_expected.to eql "book-sort-album" }
its(:album) { is_expected.to eql "book-album" }
its(:sort_album_artist) { is_expected.to eql "m4b-book-sort-album-artist" }
its(:sort_artist) { is_expected.to eql "m4b-book-sort-artist" }
its(:sort_album) { is_expected.to eql "m4b-book-sort-album" }
its(:album) { is_expected.to eql "m4b-book-album" }

its(:genre) { is_expected.to eql "book-genre" }
its(:title) { is_expected.to eql "book-title" }
its(:genre) { is_expected.to eql "m4b-book-genre" }
its(:title) { is_expected.to eql "m4b-book-title" }
its(:year) { is_expected.to eql "2001" }
its(:artist) { is_expected.to eql "book-artist" }
its(:performer) { is_expected.to eql "book-performer" }
its(:artist) { is_expected.to eql "m4b-book-artist" }
its(:performer) { is_expected.to eql "m4b-book-performer" }
end
106 changes: 84 additions & 22 deletions spec/plex_symlinker/operation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
FileUtils.rm_rf(spec_root.join("tmp"))
FileUtils.mkdir_p([tmp_source_dir, tmp_symlinks_dir])
FileUtils.cp(resource_files, tmp_source_dir)

PlexSymlinker.output = File.new("/dev/null", "w")
end

after(:all) do
Expand All @@ -14,16 +16,76 @@

subject { described_class.new(files_base_dir.to_s, symlinks_base_dir.to_s, symlink_target_dir: symlink_target_dir.to_s) }

#----------------------------------------------------------------
# #create_symlinks
#----------------------------------------------------------------

describe "#create_symlinks" do
shared_examples "symlink creation" do
let(:expected_symlinks) {
files_base_dir.children.map { |file|
af = PlexSymlinker::FileTypes::AudioFile.from_path(file.to_s)
["", af.album_artist, af.album, af.symlink_file_name].join("/")
}
}

it "generates the expected folder structure" do
expect { subject.create_symlinks }
.to change { Dir[symlinks_base_dir.join("**", "*.*")].map { |p| p.gsub(symlinks_base_dir.to_s, "") } }
.from([])
.to match_array(expected_symlinks)
end

it "points the generated symlinks to the actual files" do
subject.create_symlinks
expect(Dir[symlinks_base_dir.join("**", "*.*")].map(&File.method(:readlink)))
.to match_array(expected_symlink_targets)
end
end

context "with a custom symlink target dir" do
include_examples "symlink creation" do
# Would be /app/source in the base docker setup
let(:files_base_dir) { tmp_source_dir }

# Would be /app/target in the base docker setup
let(:symlinks_base_dir) { tmp_symlinks_dir }

# Would be the actual files directory on the host machine in the base docker setup
# As the directory wouldn't exist within the docker container either, we use a
# a non-existent path here as well. It's only important that the existing symlinks will
# point to this directory instead of +files_base_dir+
let(:symlink_target_dir) { Pathname.new("/tmp/audio_files") }

let(:expected_symlink_targets) {
files_base_dir.children(false).map { |f| symlink_target_dir.join(f.to_s).to_s }
}
end
end

context "with no custom symlink target dir" do
include_examples "symlink creation" do
let(:files_base_dir) { tmp_source_dir }
let(:symlinks_base_dir) { tmp_symlinks_dir }
let(:symlink_target_dir) { nil }

let(:expected_symlink_targets) {
files_base_dir.children.map(&:to_s)
}
end
end
end

#----------------------------------------------------------------
# #cleanup
#----------------------------------------------------------------

describe "#cleanup" do
shared_examples_for "cleanup" do
shared_examples "cleanup" do
let!(:valid_existing_symlink) { symlinks_base_dir.join("existing.mp3").tap { |path| File.symlink(existing_file, path) } }
let!(:invalid_existing_symlink) { symlinks_base_dir.join("deleted.mp3").tap { |path| File.symlink(deleted_file, path) } }

it "removes only the invalid symlink" do
it "removes invalid symlinks" do
expect { subject.cleanup }
.to change { symlinks_base_dir.children(false).map(&:to_s) }
.from(array_including(["existing.mp3", "deleted.mp3"]))
Expand All @@ -32,33 +94,33 @@
end

context "with a custom symlink target dir" do
# Would be /app/source in the base docker setup
let(:files_base_dir) { tmp_source_dir }

# Would be /app/target in the base docker setup
let(:symlinks_base_dir) { tmp_symlinks_dir }
include_examples "cleanup" do
# Would be /app/source in the base docker setup
let(:files_base_dir) { tmp_source_dir }

# Would be the actual files directory on the host machine in the base docker setup
# As the directory wouldn't exist within the docker container either, we use a
# a non-existent path here as well. It's only important that the existing symlinks will
# point to this directory instead of +files_base_dir+
let(:symlink_target_dir) { Pathname.new("/tmp/audio_files") }
# Would be /app/target in the base docker setup
let(:symlinks_base_dir) { tmp_symlinks_dir }

let(:existing_file) { symlink_target_dir.join("example.mp3") }
let(:deleted_file) { symlink_target_dir.join("deleted.mp3") }
# Would be the actual files directory on the host machine in the base docker setup
# As the directory wouldn't exist within the docker container either, we use a
# a non-existent path here as well. It's only important that the existing symlinks will
# point to this directory instead of +files_base_dir+
let(:symlink_target_dir) { Pathname.new("/tmp/audio_files") }

it_behaves_like "cleanup"
let(:existing_file) { symlink_target_dir.join("example.mp3") }
let(:deleted_file) { symlink_target_dir.join("deleted.mp3") }
end
end

context "with no custom symlink target dir" do
let(:files_base_dir) { tmp_source_dir }
let(:symlinks_base_dir) { tmp_symlinks_dir }
let(:symlink_target_dir) { nil }

let(:existing_file) { files_base_dir.join("example.mp3") }
let(:deleted_file) { files_base_dir.join("deleted.mp3") }
include_examples "cleanup" do
let(:files_base_dir) { tmp_source_dir }
let(:symlinks_base_dir) { tmp_symlinks_dir }
let(:symlink_target_dir) { nil }

it_behaves_like "cleanup"
let(:existing_file) { files_base_dir.join("example.mp3") }
let(:deleted_file) { files_base_dir.join("deleted.mp3") }
end
end
end
end
Binary file modified spec/resources/example.m4b
Binary file not shown.
Binary file modified spec/resources/example.mp3
Binary file not shown.
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def resource_file(filename)
end

def resource_files
spec_root.join("resources").children
Dir[spec_root.join("resources", "**", "*.{#{PlexSymlinker::FileTypes::AudioFile.registered_types.keys.join(",")}}")]
end
end

Expand Down

0 comments on commit 449be08

Please sign in to comment.