require_relative "spec_helper"

describe Gemnigma::ValidateFileArg do
  it "should be a module" do
    expect(Gemnigma::ValidateFileArg.class).to eql(Module)
  end

  it "should have a method set_msg" do
    expect(Gemnigma::ValidateFileArg.instance_methods.include? :set_msg).to be true
  end

  it "should have a message get_args" do
    expect(Gemnigma::ValidateFileArg.instance_methods.include? :get_args).to be true
  end

  it "should have a method user_choice" do
    expect(Gemnigma::ValidateFileArg.instance_methods.include? :user_choice).to be true
  end

  it "should have a method validate" do
    expect(Gemnigma::ValidateFileArg.instance_methods.include? :validate).to be true
  end

  describe "#set_msg" do
    it "should return a new instance of message" do
      res = Class.new.extend(Gemnigma::ValidateFileArg)
      expect(res.set_msg).to be_an_instance_of Gemnigma::Messages
    end
  end

  describe "#get_args" do

    subject(:validator) { Class.new.extend(Gemnigma::ValidateFileArg) }

    it "should assign and return strings" do
      validator.get_args

      validator.instance_variable_set("@input_file", "message.txt")
      validator.instance_variable_set("@output_file", "output.txt")

      expect(validator.instance_variable_get("@input_file")).to eql("message.txt")
      expect(validator.instance_variable_get("@output_file")).to eql("output.txt")
    end
  end

  describe "#user_choice" do
    subject(:validator) { Class.new.extend(Gemnigma::ValidateFileArg) }

    it "should assign and return a string" do
      allow(validator).to receive(:user_choice) { "y" }

      expect(validator.user_choice).to be_a String
    end
  end

  describe "#validate" do 

    subject(:validator) { Class.new.extend(Gemnigma::ValidateFileArg) }

    it "should return false if input file doesn't exist" do
      validator.instance_variable_set("@message", Gemnigma::Messages.new)
      validator.instance_variable_set("@input_file", "non-existent.txt")

      expect(validator.validate).to be false
    end

    it "should return true if input file exists" do
      validator.instance_variable_set("@message", Gemnigma::Messages.new)
      validator.instance_variable_set("@input_file", "message.txt")
      validator.instance_variable_set("@output_file", "output.txt")

      expect(validator.validate).to be true
    end

    it "should return false if user chooses no as option to overwrite file" do
      validator.instance_variable_set("@message", Gemnigma::Messages.new)
      validator.instance_variable_set("@input_file", "message.txt")
      validator.instance_variable_set("@output_file", "message.txt")
      allow(validator).to receive(:user_choice) { "n" }

      expect(validator.validate).to be false
    end

    it "should yield control if user chooses yes as option to overwrite file" do
      validator.instance_variable_set("@message", Gemnigma::Messages.new)
      validator.instance_variable_set("@input_file", "message.txt")
      validator.instance_variable_set("@output_file", "message.txt")
      allow(validator).to receive(:user_choice) { "y" }

      expect{ |arg| validator.validate(&arg) }.to yield_control
    end

    it "should return false if user chooses an invalid option to overwrite file" do
      validator.instance_variable_set("@message", Gemnigma::Messages.new)
      validator.instance_variable_set("@input_file", "message.txt")
      validator.instance_variable_set("@output_file", "message.txt")
      allow(validator).to receive(:user_choice) { "woot!" }

      expect(validator.validate).to be false
    end

    it "should display an error message if input file does not exist" do

      io = double("io", puts: nil)
      message = Gemnigma::Messages.new(io)
      message.file_not_in_existence("non-existent.txt")

      expect(io).to have_received(:puts).with("non-existent.txt: File does not exist\nExiting...")
    end

    it "should display a success message if file exists" do

      io = double("io", puts: nil)
      message = Gemnigma::Messages.new(io)
      message.file_in_existence("message.txt", "new_file.txt")

      expect(io).to have_received(:puts).with("message.txt exists... Checking new_file.txt")
    end

    it "should display a informing a user that a file is about to be created" do

      io = double("io", puts: nil)
      message = Gemnigma::Messages.new(io)
      message.creating_new_file("new_file.txt")

      expect(io).to have_received(:puts).with("new_file.txt will be created, proceeding...")
    end

    it "should display a message alerting a user that a file is already in existence" do

      io = double("io", puts: nil)
      message = Gemnigma::Messages.new(io)
      message.overwrite_warning("new_file.txt")

      expect(io).to have_received(:puts).with("new_file.txt exists already, do you want to overwrite it? (Y) or (N): ")
    end
  end
end