blob: de529118cb0acdbfed7a7acfade3cc9a5edbbcec [file] [log] [blame]
/*
* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: morlovich@google.com (Maksim Orlovich)
// Unit-test the srcset slot.
#include "net/instaweb/rewriter/public/srcset_slot.h"
#include "net/instaweb/rewriter/public/resource.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_filter.h"
#include "net/instaweb/rewriter/public/rewrite_test_base.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/html/html_element.h"
#include "pagespeed/kernel/html/html_name.h"
#include "pagespeed/kernel/html/html_writer_filter.h"
#include "pagespeed/kernel/http/content_type.h"
namespace {
static const char kHtmlUrl[] = "http://www.example.com/dir/a.html";
} // namespace
namespace net_instaweb {
TEST(SrcSetSlotParseTest, ParseAndSerialize) {
std::vector<SrcSetSlotCollection::ImageCandidate> out;
SrcSetSlotCollection::ParseSrcSet(
" ,a.jpg, b.jpg 100w,, c.jpg 10h, d.jpg (very, fancy) , e,f.jpg 10w",
&out);
ASSERT_EQ(5, out.size());
EXPECT_EQ("a.jpg", out[0].url);
EXPECT_EQ("", out[0].descriptor);
EXPECT_EQ("b.jpg", out[1].url);
EXPECT_EQ("100w", out[1].descriptor);
EXPECT_EQ("c.jpg", out[2].url);
EXPECT_EQ("10h", out[2].descriptor);
EXPECT_EQ("d.jpg", out[3].url);
EXPECT_EQ("(very, fancy)", out[3].descriptor);
EXPECT_EQ("e,f.jpg", out[4].url);
EXPECT_EQ("10w", out[4].descriptor);
EXPECT_EQ("a.jpg, b.jpg 100w, c.jpg 10h, d.jpg (very, fancy), e,f.jpg 10w",
SrcSetSlotCollection::Serialize(out));
std::vector<SrcSetSlotCollection::ImageCandidate> out2;
SrcSetSlotCollection::ParseSrcSet(
"a.jpg ,b.jpg 100w , c.jpg 200w, d.jpg",
&out2);
ASSERT_EQ(4, out2.size());
EXPECT_EQ("a.jpg", out2[0].url);
EXPECT_EQ("", out2[0].descriptor);
EXPECT_EQ("b.jpg", out2[1].url);
EXPECT_EQ("100w", out2[1].descriptor);
EXPECT_EQ("c.jpg", out2[2].url);
EXPECT_EQ("200w", out2[2].descriptor);
EXPECT_EQ("d.jpg", out2[3].url);
EXPECT_EQ("", out2[3].descriptor);
EXPECT_EQ("a.jpg, b.jpg 100w, c.jpg 200w, d.jpg",
SrcSetSlotCollection::Serialize(out2));
}
class SrcSetSlotTest : public RewriteTestBase {
protected:
bool AddBody() const override { return false; }
void SetUp() override {
RewriteTestBase::SetUp();
RewriteDriver* driver = rewrite_driver();
driver->AddFilters();
ASSERT_TRUE(driver->StartParseId(kHtmlUrl, "srcset_slot_test",
kContentTypeHtml));
element_ = driver->NewElement(nullptr, HtmlName::kImg);
driver->AddAttribute(element_, HtmlName::kSrcset,
"a.jpg, b.jpg 100w, c.png 1000w");
attribute_ = element_->FindAttribute(HtmlName::kSrcset);
driver->AddElement(element_, 42 /* line number */);
driver->CloseElement(element_, HtmlElement::BRIEF_CLOSE, 43 /* line # */);
}
void TearDown() override {
rewrite_driver()->FinishParse();
RewriteTestBase::TearDown();
}
GoogleString GetHtmlDomAsString() {
output_buffer_.clear();
html_parse()->ApplyFilter(html_writer_filter_.get());
return output_buffer_;
}
HtmlElement* element_;
HtmlElement::Attribute* attribute_;
};
TEST_F(SrcSetSlotTest, BasicOperation) {
SetupWriter();
RefCountedPtr<SrcSetSlotCollection> collection(new SrcSetSlotCollection(
rewrite_driver(),
element_,
attribute_));
collection->Initialize(rewrite_driver()->FindFilter("ic"));
ASSERT_EQ(3, collection->num_image_candidates());
EXPECT_EQ("a.jpg", collection->url(0));
EXPECT_EQ("", collection->descriptor(0));
EXPECT_EQ("b.jpg", collection->url(1));
EXPECT_EQ("100w", collection->descriptor(1));
EXPECT_EQ("c.png", collection->url(2));
EXPECT_EQ("1000w", collection->descriptor(2));
ResourceSlotPtr slot0(collection->slot(0));
EXPECT_EQ("http://www.example.com/dir/a.jpg", slot0->resource()->url());
ResourceSlotPtr slot1(collection->slot(1));
EXPECT_EQ("http://www.example.com/dir/b.jpg", slot1->resource()->url());
ResourceSlotPtr slot2(collection->slot(2));
EXPECT_EQ("http://www.example.com/dir/c.png", slot2->resource()->url());
// Now rewrite the 3 slots, but only render 2, with 1 prevented
// from rendering.
bool unused;
GoogleUrl optimized_a("http://www.example.com/dir/a.pagespeed.webp");
slot0->SetResource(
rewrite_driver()->CreateInputResource(
optimized_a, RewriteDriver::InputRole::kImg, &unused));
GoogleUrl optimized_b("http://www.example.com/dir/b.pagespeed.webp");
slot1->SetResource(
rewrite_driver()->CreateInputResource(
optimized_b, RewriteDriver::InputRole::kImg, &unused));
GoogleUrl optimized_c("http://www.example.com/dir/c.pagespeed.png");
slot2->SetResource(
rewrite_driver()->CreateInputResource(
optimized_c, RewriteDriver::InputRole::kImg, &unused));
slot0->set_disable_rendering(true);
slot0->Render();
slot1->Render();
// Empty descriptor output a bit silly... not expected in real life, though.
EXPECT_EQ("srcset_slot_test:42-43 srcset entry for ",
slot0->LocationString());
EXPECT_EQ("srcset_slot_test:42-43 srcset entry for 100w",
slot1->LocationString());
EXPECT_EQ("srcset_slot_test:42-43 srcset entry for 1000w",
slot2->LocationString());
EXPECT_EQ("<img srcset=\"a.jpg, b.pagespeed.webp 100w, c.png 1000w\"/>",
GetHtmlDomAsString());
collection->Detach();
}
} // namespace net_instaweb