#
# test/unit/bio/util/restriction_enzyme/test_analysis.rb - Unit test for Bio::RestrictionEnzyme::Analysis
#
# Author::    Trevor Wennblom  <mailto:trevor@corevx.com>
# Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com)
# License::   The Ruby License
#
#  $Id:$
#

# loading helper routine for testing bioruby
require 'pathname'
load Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4,
                            'bioruby_test_helper.rb')).cleanpath.to_s

# libraries needed for the tests
require 'test/unit'
require 'bio/util/restriction_enzyme/analysis'
require 'bio/sequence'

# :nodoc:
module Bio
  module TestRestrictionEnzyme
    class TestAnalysis < Test::Unit::TestCase # :nodoc:
      def setup
        @enz = Bio::RestrictionEnzyme
        @t = Bio::RestrictionEnzyme::Analysis

        @obj_1 = @t.cut('cagagag', 'ag^ag')
        @obj_2 = @t.cut('agagag', 'ag^ag')
        @obj_3 = @t.cut('cagagagt', 'ag^ag')

        e1 = @enz.new('atgcatgc', [3, 3])
        @obj_4 = @t.cut('atgcatgcatgc', e1)

        @obj_4bd = @t.cut('atgcatgcatgccc', e1, 'cc^c') # mix of always cut and sometimes cut

        e2 = @enz.new('atgcatgc', [3, 5])
        @obj_5 = @t.cut('atgcatgcatgc', e2)

        e3 = @enz.new('anna', [1, 1], [3, 3])
        e4 = @enz.new('gg', [1, 1])
        @obj_6 = @t.cut('agga', e3, e4)

        @obj_7 = @t.cut('gaccaggaaaaagaccaggaaagcctggaaaagttaac', 'EcoRII')
        @obj_7b = @t.cut('gaccaggaaaaagaccaggaaagcctggaaaagttaaccc', 'EcoRII', 'HincII', 'cc^c')
        @obj_7bd = @t.cut_without_permutations('gaccaggaaaaagaccaggaaagcctggaaaagttaaccc', 'EcoRII',
                                               'HincII', 'cc^c')

        @obj_8 = @t.cut('gaccaggaaaaagaccaggaaagcctggaaaagttaac', 'EcoRII', 'HincII')

        @obj_9 = @t.cut('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'EcoRII')
        @obj_9 = @t.cut('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'EcoRII', 'HincII')

        @obj_1d = @t.cut_without_permutations('cagagag', 'ag^ag')
        @obj_2d = @t.cut_without_permutations('agagag', 'ag^ag')
        @obj_3d = @t.cut_without_permutations('cagagagt', 'ag^ag')

        e1 = @enz.new('atgcatgc', [3, 3])
        @obj_4d = @t.cut_without_permutations('atgcatgcatgc', e1)

        e2 = @enz.new('atgcatgc', [3, 5])
        @obj_5d = @t.cut_without_permutations('atgcatgcatgc', e2)

        e3 = @enz.new('anna', [1, 1], [3, 3])
        e4 = @enz.new('gg', [1, 1])
        @obj_6d = @t.cut_without_permutations('agga', e3, e4)

        @obj_7d = @t.cut_without_permutations('gaccaggaaaaagaccaggaaagcctggaaaagttaac', 'EcoRII')
        @obj_8d = @t.cut_without_permutations('gaccaggaaaaagaccaggaaagcctggaaaagttaac', 'EcoRII', 'HincII')

        @obj_98 = @t.cut('', 'EcoRII', 'HincII')
        @obj_99 = @t.cut_without_permutations('', 'EcoRII', 'HincII')

        @obj_vr1 = @t.cut('gaccaggaaaaagaccaggaaagcctggaaaagttaac', 'EcoRII', { view_ranges: true })
        @obj_vr2 = @t.cut('cagagag', { view_ranges: true }, 'ag^ag')
      end

      def test_cut
        assert_equal(%w[ag cag], @obj_1.primary)
        assert_equal(%w[gtc tc], @obj_1.complement)
        assert_equal(2, @obj_1.size)
        assert_equal(Bio::RestrictionEnzyme::Fragments, @obj_1.class)
        assert_equal(Bio::RestrictionEnzyme::Fragment, @obj_1[0].class)

        assert_equal(['ag'], @obj_2.primary)
        assert_equal(%w[ag agt cag], @obj_3.primary)
        assert_equal(%w[atg atgcatg catg catgc], @obj_4.primary)

        #     A T G^C A T G C
        #
        #     A T G C A T G C A T G C
        #
        #     A T G^C A T G^C A T G C
        #
        #     A T G C A T G^C A T G C

        assert_equal(%w[atg atgcatg catgc catgcatgc], @obj_5.primary)
        assert_equal(%w[a ag g ga], @obj_6.primary)
        assert_equal(%w[ccaggaaaaaga ccaggaaag cctggaaaagttaac ga], @obj_7.primary)
        assert_equal(%w[aac ccaggaaaaaga ccaggaaag cctggaaaagtt ga], @obj_8.primary)

        #     e1 = @enz.new('atgcatgc', [3,3])
        #     @obj_4bd = @t.cut('atgcatgcatgccc', e1, 'cc^c') # mix of sometimes cut and always cut
        #
        #     [#<struct Bio::RestrictionEnzyme::Analysis::UniqueFragment
        #       primary="atgcatg",
        #       complement="tacgtac">,
        #      #<struct Bio::RestrictionEnzyme::Analysis::UniqueFragment
        #       primary="catgcc",
        #       complement="gtacg ">,
        #      #<struct Bio::RestrictionEnzyme::Analysis::UniqueFragment
        #       primary=" c",
        #       complement="gg">,
        #      #<struct Bio::RestrictionEnzyme::Analysis::UniqueFragment
        #       primary="atg",
        #       complement="tac">,
        #      #<struct Bio::RestrictionEnzyme::Analysis::UniqueFragment
        #       primary="catg",
        #       complement="gtac">]
        assert_equal(%w[atg atgcatg c catg catgcc], @obj_4bd.primary)
        assert_equal(%w[gg gtac gtacg tac tacgtac], @obj_4bd.complement)
      end

      def test_cut_without_permutations
        assert_equal(%w[ag cag], @obj_1d.primary)
        assert_equal(['ag'], @obj_2d.primary)
        assert_equal(%w[ag agt cag], @obj_3d.primary)
        assert_equal(%w[atg catg catgc], @obj_4d.primary)
        assert_equal(%w[atg catg catgc], @obj_5d.primary)
        assert_equal(%w[a g], @obj_6d.primary)
        assert_equal(%w[ccaggaaaaaga ccaggaaag cctggaaaagttaac ga], @obj_7d.primary)
        assert_equal(%w[aac ccaggaaaaaga ccaggaaag cctggaaaagtt ga], @obj_8d.primary)
      end

      def test_cut_from_bio_sequence_na
        assert_equal(%w[ag cag], Bio::Sequence::NA.new('cagagag').cut_with_enzyme('ag^ag').primary)
        assert_equal(%w[ag cag], Bio::Sequence::NA.new('cagagag').cut_with_enzymes('ag^ag').primary)
        assert_equal(%w[ag cag], Bio::Sequence::NA.new('cagagag').cut_with_enzymes('ag^ag', 'EcoRII').primary)

        # Note how EcoRII needs extra padding on the beginning and ending of the
        # sequence 'ccagg' to make the match since the cut must occur between
        # two nucleotides and can not occur on the very end of the sequence.
        #
        #   EcoRII:
        #     :blunt: "0"
        #     :c2: "5"
        #     :c4: "0"
        #     :c1: "-1"
        #     :pattern: CCWGG
        #     :len: "5"
        #     :name: EcoRII
        #     :c3: "0"
        #     :ncuts: "2"
        #
        #        -1 1 2 3 4 5
        #   5' - n^c c w g g n - 3'
        #   3' - n g g w c c^n - 5'
        #
        #   (w == [at])

        assert_equal(%w[ag agccagg cag],
                     Bio::Sequence::NA.new('cagagagccagg').cut_with_enzymes('ag^ag', 'EcoRII').primary)
        assert_equal(%w[ag agccagg cag], Bio::Sequence::NA.new('cagagagccagg').cut_with_enzymes('ag^ag').primary)
        assert_equal(:no_cuts_found, Bio::Sequence::NA.new('cagagagccagg').cut_with_enzymes('EcoRII'))

        assert_equal(%w[ag ag cag ccaggt],
                     Bio::Sequence::NA.new('cagagagccaggt').cut_with_enzymes('ag^ag', 'EcoRII').primary)
        assert_equal(%w[ag agccaggt cag], Bio::Sequence::NA.new('cagagagccaggt').cut_with_enzymes('ag^ag').primary)
        assert_equal(%w[cagagag ccaggt], Bio::Sequence::NA.new('cagagagccaggt').cut_with_enzymes('EcoRII').primary)
        assert_equal(%w[a gtctctcggtcc], Bio::Sequence::NA.new('cagagagccaggt').cut_with_enzymes('EcoRII').complement)
      end

      def test_view_ranges
        assert_equal(%w[ccaggaaaaaga ccaggaaag cctggaaaagttaac ga], @obj_vr1.primary)
        assert_equal(%w[ctggtcc tttcggacc ttttcaattg tttttctggtcc], @obj_vr1.complement)

        a0 = @obj_vr1[0]
        assert_equal('ga     ', a0.primary)
        assert_equal('ctggtcc', a0.complement)
        assert_equal(0, a0.p_left)
        assert_equal(1, a0.p_right)
        assert_equal(0, a0.c_left)
        assert_equal(6, a0.c_right)

        a1 = @obj_vr1[1]
        assert_equal('ccaggaaaaaga     ', a1.primary)
        assert_equal('     tttttctggtcc', a1.complement)
        assert_equal(2,  a1.p_left)
        assert_equal(13, a1.p_right)
        assert_equal(7,  a1.c_left)
        assert_equal(18, a1.c_right)

        a2 = @obj_vr1[2]
        assert_equal('ccaggaaag     ', a2.primary)
        assert_equal('     tttcggacc', a2.complement)
        assert_equal(14, a2.p_left)
        assert_equal(22, a2.p_right)
        assert_equal(19, a2.c_left)
        assert_equal(27, a2.c_right)

        a3 = @obj_vr1[3]
        assert_equal('cctggaaaagttaac', a3.primary)
        assert_equal('     ttttcaattg', a3.complement)
        assert_equal(23, a3.p_left)
        assert_equal(37, a3.p_right)
        assert_equal(28, a3.c_left)
        assert_equal(37, a3.c_right)

        a4 = @obj_vr1[4]
        assert_equal(nil, a4)

        assert_equal(%w[ag ag cag], @obj_vr2.primary)
        assert_equal(%w[gtc tc tc], @obj_vr2.complement)

        a0 = @obj_vr2[0]
        assert_equal('cag', a0.primary)
        assert_equal('gtc', a0.complement)
        assert_equal(0, a0.p_left)
        assert_equal(2, a0.p_right)
        assert_equal(0, a0.c_left)
        assert_equal(2, a0.c_right)

        a1 = @obj_vr2[1]
        assert_equal('ag', a1.primary)
        assert_equal('tc', a1.complement)
        assert_equal(3, a1.p_left)
        assert_equal(4, a1.p_right)
        assert_equal(3, a1.c_left)
        assert_equal(4, a1.c_right)

        a2 = @obj_vr2[2]
        assert_equal('ag', a2.primary)
        assert_equal('tc', a2.complement)
        assert_equal(5, a2.p_left)
        assert_equal(6, a2.p_right)
        assert_equal(5, a2.c_left)
        assert_equal(6, a2.c_right)

        a3 = @obj_vr2[3]
        assert_equal(nil, a3)
      end
    end
  end
end
