<commit_before>require 'spec_helper'
describe "HttpRouter#recognize" do
  before(:each) do
    @router = HttpRouter.new
  end

  context("with static paths") do
    ['/', '/test', '/test/time', '/one/more/what', '/test.html', '/.html'].each do |path|
      it "should recognize #{path.inspect}" do
        route = @router.add(path).to(path)
        @router.recognize(Rack::MockRequest.env_for(path)).route.should == route
      end
    end

    context("with optional parts") do
      it "work either way" do
        route = @router.add("/test(/optional)").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test')).route.should == route
        @router.recognize(Rack::MockRequest.env_for('/test/optional')).route.should == route
      end
    end

    context("with escaped ()'s") do
      it "should recognize ()" do
        route = @router.add('/test\(:variable\)').to(:test)
        response = @router.recognize(Rack::MockRequest.env_for('/test(hello)'))
        response.route.should == route
        response.params.first.should == 'hello'
      end
    end

    context("with partial matching") do
      it "should match partially or completely" do
        route = @router.add("/test*").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test')).route.should == route
        response = @router.recognize(Rack::MockRequest.env_for('/test/optional'))
        response.route.should == route
        response.remaining_path.should == '/optional'
      end

    end

    context("with proc acceptance") do
      it "should match" do
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'hellodooly' }).to(:test1)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 80}.to(:test2)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 8080}.to(:test3)
        response = @router.recognize(Rack::MockRequest.env_for('http://lovelove:8080/test'))
        response.dest.should == :test3
      end

      it "should still use an existing less specific node if possible" do
        @router.add("/test").to(:test4)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'hellodooly' }).to(:test1)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 80}.to(:test2)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 8080}.to(:test3)
        response = @router.recognize(Rack::MockRequest.env_for('http://lovelove:8081/test'))
        response.dest.should == :test4
      end

      it "should match with request conditions" do
        @router.add("/test").get.arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 80}.to(:test1)
        @router.add("/test").get.arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 8080}.to(:test2)
        response = @router.recognize(Rack::MockRequest.env_for('http://lovelove:8080/test'))
        response.dest.should == :test2
      end

      it "should still use an existing less specific node if possible with request conditions" do
        @router.add("/test").get.arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 80}.to(:test1)
        @router.add("/test").get.arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 8080}.to(:test2)
        @router.add("/test").get.to(:test3)
        response = @router.recognize(Rack::MockRequest.env_for('http://lovelove:8081/test'))
        response.dest.should == :test3
      end

    end

    context("with trailing slashes") do
      it "should ignore" do
        route = @router.add("/test").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test/')).route.should == route
      end

      it "should not recognize when used with the /? syntax and ignore_trailing_slash disabled" do
        @router = HttpRouter.new(:ignore_trailing_slash => false)
        route = @router.add("/test/?").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test/')).route.should == route
      end

      it "should recognize when used with the /? syntax and ignore_trailing_slash enabled" do
        @router = HttpRouter.new(:ignore_trailing_slash => false)
        route = @router.add("/test").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test/')).should be_nil
      end
      it "should not capture normally" do
        route = @router.add("/:test").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test/')).params.first.should == 'test'
      end
    end
  end

  context "with missing leading /" do
    it "should recognize" do
      @router.add("foo").to(:test1)
      @router.add("foo.html").to(:test2)
      @router.recognize(Rack::MockRequest.env_for('/foo')).dest.should == :test1
      @router.recognize(Rack::MockRequest.env_for('/foo.html')).dest.should == :test2
    end
  end

  context "with request methods" do
    it "should recognize" do
      route = @router.post("/test").to(:test)
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'POST')).route.should == route
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'GET')).status.should == 405
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'GET')).headers['Allow'].should == "POST"
    end

    it "should recognize with optional parts and correctly return a 405 when the method isn't found" do
      @router.get("/test(.:format)").to(:get)
      @router.post("/test(.:format)").to(:post)
      @router.delete("/test(.:format)").to(:delete)
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'POST')).destination.should == :post
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'GET')).destination.should == :get
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'DELETE')).destination.should == :delete
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'PUT')).status.should == 405
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'PUT')).headers['Allow'].should == "DELETE, GET, POST"
      @router.recognize(Rack::MockRequest.env_for('/test.html', :method => 'POST')).destination.should == :post
      @router.recognize(Rack::MockRequest.env_for('/test.html', :method => 'GET')).destination.should == :get<commit_msg>better 405 test that is order invariant. (Thanks Cored!)<commit_after>require 'spec_helper'
describe "HttpRouter#recognize" do
  before(:each) do
    @router = HttpRouter.new
  end

  context("with static paths") do
    ['/', '/test', '/test/time', '/one/more/what', '/test.html', '/.html'].each do |path|
      it "should recognize #{path.inspect}" do
        route = @router.add(path).to(path)
        @router.recognize(Rack::MockRequest.env_for(path)).route.should == route
      end
    end

    context("with optional parts") do
      it "work either way" do
        route = @router.add("/test(/optional)").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test')).route.should == route
        @router.recognize(Rack::MockRequest.env_for('/test/optional')).route.should == route
      end
    end

    context("with escaped ()'s") do
      it "should recognize ()" do
        route = @router.add('/test\(:variable\)').to(:test)
        response = @router.recognize(Rack::MockRequest.env_for('/test(hello)'))
        response.route.should == route
        response.params.first.should == 'hello'
      end
    end

    context("with partial matching") do
      it "should match partially or completely" do
        route = @router.add("/test*").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test')).route.should == route
        response = @router.recognize(Rack::MockRequest.env_for('/test/optional'))
        response.route.should == route
        response.remaining_path.should == '/optional'
      end

    end

    context("with proc acceptance") do
      it "should match" do
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'hellodooly' }).to(:test1)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 80}.to(:test2)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 8080}.to(:test3)
        response = @router.recognize(Rack::MockRequest.env_for('http://lovelove:8080/test'))
        response.dest.should == :test3
      end

      it "should still use an existing less specific node if possible" do
        @router.add("/test").to(:test4)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'hellodooly' }).to(:test1)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 80}.to(:test2)
        @router.add("/test").arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 8080}.to(:test3)
        response = @router.recognize(Rack::MockRequest.env_for('http://lovelove:8081/test'))
        response.dest.should == :test4
      end

      it "should match with request conditions" do
        @router.add("/test").get.arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 80}.to(:test1)
        @router.add("/test").get.arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 8080}.to(:test2)
        response = @router.recognize(Rack::MockRequest.env_for('http://lovelove:8080/test'))
        response.dest.should == :test2
      end

      it "should still use an existing less specific node if possible with request conditions" do
        @router.add("/test").get.arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 80}.to(:test1)
        @router.add("/test").get.arbitrary(Proc.new{|req| req.host == 'lovelove' }).arbitrary{|req| req.port == 8080}.to(:test2)
        @router.add("/test").get.to(:test3)
        response = @router.recognize(Rack::MockRequest.env_for('http://lovelove:8081/test'))
        response.dest.should == :test3
      end

    end

    context("with trailing slashes") do
      it "should ignore" do
        route = @router.add("/test").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test/')).route.should == route
      end

      it "should not recognize when used with the /? syntax and ignore_trailing_slash disabled" do
        @router = HttpRouter.new(:ignore_trailing_slash => false)
        route = @router.add("/test/?").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test/')).route.should == route
      end

      it "should recognize when used with the /? syntax and ignore_trailing_slash enabled" do
        @router = HttpRouter.new(:ignore_trailing_slash => false)
        route = @router.add("/test").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test/')).should be_nil
      end
      it "should not capture normally" do
        route = @router.add("/:test").to(:test)
        @router.recognize(Rack::MockRequest.env_for('/test/')).params.first.should == 'test'
      end
    end
  end

  context "with missing leading /" do
    it "should recognize" do
      @router.add("foo").to(:test1)
      @router.add("foo.html").to(:test2)
      @router.recognize(Rack::MockRequest.env_for('/foo')).dest.should == :test1
      @router.recognize(Rack::MockRequest.env_for('/foo.html')).dest.should == :test2
    end
  end

  context "with request methods" do
    it "should recognize" do
      route = @router.post("/test").to(:test)
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'POST')).route.should == route
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'GET')).status.should == 405
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'GET')).headers['Allow'].should == "POST"
    end

    it "should recognize with optional parts and correctly return a 405 when the method isn't found" do
      @router.get("/test(.:format)").to(:get)
      @router.post("/test(.:format)").to(:post)
      @router.delete("/test(.:format)").to(:delete)
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'POST')).destination.should == :post
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'GET')).destination.should == :get
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'DELETE')).destination.should == :delete
      @router.recognize(Rack::MockRequest.env_for('/test', :method => 'PUT')).status.should == 405
      methods = @router.recognize(Rack::MockRequest.env_for('/test', :method => 'PUT')).headers['Allow'].split(/,\s+/)
      methods.should include('DELETE')
      methods.should include('GET')
      methods.should include('POST')
      methods.size.should == 3
      @router.recognize(Rack::MockRequest.env_for('/test.html', :method => 'POST')).destination.should == :post
      @router.recognize(Rack::MockRequest.env_for('/test.html', :method => 'GET')).destination.should == :get
{'fraction_non_alphanumeric': 0.18431102963641918, 'fraction_numerical': 0.010846318362358692, 'mean_word_length': 3.4128749578699025, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2722013', 'n_tokens_mistral': 4244, 'n_tokens_neox': 4087, 'n_words': 751}