text:
using content::BrowserThread;
using history::ShortcutsBackend;

namespace {

struct TestShortcutInfo {
  std::string guid;
  std::string url;
  std::string title;  // The text that orginally was searched for.
  std::string contents;
  std::string contents_class;
  std::string description;
  std::string description_class;
  int typed_count;
  int days_from_now;
} shortcut_test_db[] = {
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E0",
    "http://www.google.com/", "goog",
    "Google", "0,1,4,0", "Google", "0,3,4,1", 100, 1 },
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E1",
    "http://slashdot.org/", "slash",
    "slashdot.org", "0,3,5,1",
    "Slashdot - News for nerds, stuff that matters", "0,2,5,0", 100, 0},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E2",
    "http://slashdot.org/", "news",
    "slashdot.org", "0,1",
    "Slashdot - News for nerds, stuff that matters", "0,0,11,2,15,0", 5, 0},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E3",
    "http://sports.yahoo.com/", "news",
    "sports.yahoo.com", "0,1",
    "Yahoo! Sports - Sports News, Scores, Rumors, Fantasy Games, and more",
    "0,0,23,2,27,0", 5, 2},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E4",
    "http://www.cnn.com/index.html", "news weather",
    "www.cnn.com/index.html", "0,1",
    "CNN.com - Breaking News, U.S., World, Weather, Entertainment & Video",
    "0,0,19,2,23,0,38,2,45,0", 10, 1},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E5",
    "http://sports.yahoo.com/", "nhl scores",
    "sports.yahoo.com", "0,1",
    "Yahoo! Sports - Sports News, Scores, Rumors, Fantasy Games, and more",
    "0,0,29,2,35,0", 10, 1},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E6",
    "http://www.nhl.com/scores/index.html", "nhl scores",
    "www.nhl.com/scores/index.html", "0,1,4,3,7,1",
    "January 13, 2010 - NHL.com - Scores", "0,0,19,2,22,0,29,2,35,0", 1, 5},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E7",
    "http://www.testsite.com/a.html", "just",
    "www.testsite.com/a.html", "0,1",
    "Test - site - just a test", "0,0,14,2,18,0", 1, 5},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E8",
    "http://www.testsite.com/b.html", "just",
    "www.testsite.com/b.html", "0,1",
    "Test - site - just a test", "0,0,14,2,18,0", 2, 5},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880E9",
    "http://www.testsite.com/c.html", "just",
    "www.testsite.com/c.html", "0,1",
    "Test - site - just a test", "0,0,14,2,18,0", 1, 8},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880EA",
    "http://www.testsite.com/d.html", "just a",
    "www.testsite.com/d.html", "0,1",
    "Test - site - just a test", "0,0,14,2,18,0", 1, 12},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880EB",
    "http://www.testsite.com/e.html", "just a t",
    "www.testsite.com/e.html", "0,1",
    "Test - site - just a test", "0,0,14,2,18,0", 1, 12},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880EC",
    "http://www.testsite.com/f.html", "just a te",
    "www.testsite.com/f.html", "0,1",
    "Test - site - just a test", "0,0,14,2,18,0", 1, 12},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880ED",
    "http://www.daysagotest.com/a.html", "ago",
    "www.daysagotest.com/a.html", "0,1,8,3,11,1",
    "Test - site", "0,0", 1, 1},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880EE",
    "http://www.daysagotest.com/b.html", "ago",
    "www.daysagotest.com/b.html", "0,1,8,3,11,1",
    "Test - site", "0,0", 1, 2},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880EF",
    "http://www.daysagotest.com/c.html", "ago",
    "www.daysagotest.com/c.html", "0,1,8,3,11,1",
    "Test - site", "0,0", 1, 3},
  { "BD85DBA2-8C29-49F9-84AE-48E1E90880F0",
    "http://www.daysagotest.com/d.html", "ago",
    "www.daysagotest.com/d.html", "0,1,8,3,11,1",
    "Test - site", "0,0", 1, 4},
};

}  // namespace

class ShortcutsProviderTest : public testing::Test,
                              public AutocompleteProviderListener {
 public:
  ShortcutsProviderTest();

  // AutocompleteProviderListener:
  virtual void OnProviderUpdate(bool updated_matches) OVERRIDE;

 protected:
  class SetShouldContain
      : public std::unary_function<const std::string&, std::set<std::string> > {
   public:
    explicit SetShouldContain(const ACMatches& matched_urls);

    void operator()(const std::string& expected);
    std::set<std::string> Leftovers() const { return matches_; }

   private:
    std::set<std::string> matches_;
  };

  void SetUp();
  void TearDown();

  // Fills test data into the provider.
  void FillData(TestShortcutInfo* db, size_t db_size);

  // Runs an autocomplete query on |text| and checks to see that the returned
  // results' destination URLs match those provided. |expected_urls| does not
  // need to be in sorted order.
  void RunTest(const string16 text,
               std::vector<std::string> expected_urls,
               std::string expected_top_result);

  MessageLoopForUI message_loop_;
  content::TestBrowserThread ui_thread_;
  content::TestBrowserThread file_thread_;

  TestingProfile profile_;

  ACMatches ac_matches_;  // The resulting matches after running RunTest.

  scoped_refptr<ShortcutsBackend> backend_;
  scoped_refptr<ShortcutsProvider> provider_;
};

ShortcutsProviderTest::ShortcutsProviderTest()
    : ui_thread_(BrowserThread::UI, &message_loop_),
      file_thread_(BrowserThread::FILE, &message_loop_) {
}

void ShortcutsProviderTest::OnProviderUpdate(bool updated_matches) {}

void ShortcutsProviderTest::SetUp() {
  ShortcutsBackendFactory::GetInstance()->SetTestingFactoryAndUse(
      &profile_, &ShortcutsBackendFactory::BuildProfileNoDatabaseForTesting);
  backend_ = ShortcutsBackendFactory::GetForProfile(&profile_);
  ASSERT_TRUE(backend_.get());
  profile_.CreateHistoryService(true, false);
  provider_ = new ShortcutsProvider(this, &profile_);
  FillData(shortcut_test_db, arraysize(shortcut_test_db));
}

void ShortcutsProviderTest::TearDown() {
  // Run all pending tasks or else some threads hold on to the message loop
  // and prevent it from being deleted.
  message_loop_.RunAllPending();
  provider_ = NULL;
}

void ShortcutsProviderTest::FillData(TestShortcutInfo* db, size_t db_size) {
  DCHECK(provider_.get());
  size_t expected_size = backend_->shortcuts_map().size() + db_size;
  for (size_t i = 0; i < db_size; ++i) {
    const TestShortcutInfo& cur = db[i];
    ShortcutsBackend::Shortcut shortcut(cur.guid,
        ASCIIToUTF16(cur.title), GURL(cur.url), ASCIIToUTF16(cur.contents),
        AutocompleteMatch::ClassificationsFromString(cur.contents_class),
        ASCIIToUTF16(cur.description),
        AutocompleteMatch::ClassificationsFromString(cur.description_class),
        base::Time::Now() - base::TimeDelta::FromDays(cur.days_from_now),
        cur.typed_count);
    backend_->AddShortcut(shortcut);
  }
  EXPECT_EQ(expected_size, backend_->shortcuts_map().size());
}

ShortcutsProviderTest::SetShouldContain::SetShouldContain(
    const ACMatches& matched_urls) {
  for (ACMatches::const_iterator iter = matched_urls.begin();
       iter != matched_urls.end(); ++iter)
    matches_.insert(iter->destination_url.spec());
}

void ShortcutsProviderTest::SetShouldContain::operator()(
    const std::string& expected) {
  EXPECT_EQ(1U, matches_.erase(expected));
}

void ShortcutsProviderTest::RunTest(const string16 text,
                                   std::vector<std::string> expected_urls,
                                   std::string expected_top_result) {
  std::sort(expected_urls.begin(), expected_urls.end());

  MessageLoop::current()->RunAllPending();
  AutocompleteInput input(text, string16(), false, false, true,
                          AutocompleteInput::ALL_MATCHES);
  provider_->Start(input, false);
  EXPECT_TRUE(provider_->done());

  ac_matches_ = provider_->matches();

  // We should have gotten back at most AutocompleteProvider::kMaxMatches.
  EXPECT_LE(ac_matches_.size(), AutocompleteProvider::kMaxMatches);

  // If the number of expected and actual matches aren't equal then we need
  // test no further, but let's do anyway so that we know which URLs failed.
  EXPECT_EQ(expected_urls.size(), ac_matches_.size());

  // Verify that all expected URLs were found and that all found URLs
  // were expected.
  std::set<std::string> Leftovers =
      for_each(expected_urls.begin(), expected_urls.end(),
               SetShouldContain(ac_matches_)).Leftovers();
  EXPECT_EQ(0U, Leftovers.size());

  // See if we got the expected top scorer.
  if (!ac_matches_.empty()) {
    std::partial_sort(ac_matches_.begin(), ac_matches_.begin() + 1,
                      ac_matches_.end(), AutocompleteMatch::MoreRelevant);
    EXPECT_EQ(expected_top_result, ac_matches_[0].destination_url.spec());
  }
}

TEST_F(ShortcutsProviderTest, SimpleSingleMatch) {
  string16 text(ASCIIToUTF16("go"));
  std::string expected_url("http://www.google.com/");
  std::vector<std::string> expected_urls;
  expected_urls.push_back(expected_url);
  RunTest(text, expected_urls, expected_url);
}

TEST_F(ShortcutsProviderTest, MultiMatch) {
  string16 text(ASCIIToUTF16("NEWS"));
  std::vector<std::string> expected_urls;
  // Scores high because of completion length.
  expected_urls.push_back("http://slashdot.org/");
  // Scores high because of visit count.
  expected_urls.push_back("http://sports.yahoo.com/");
  // Scores high because of visit count but less match span,
  // which is more important.
  expected_urls.push_back("http://www.cnn.com/index.html");
  RunTest(text, expected_urls, "http://slashdot.org/");
}

TEST_F(ShortcutsProviderTest, TypedCountMatches) {
  string16 text(ASCIIToUTF16("just"));
  std::vector<std::string> expected_urls;
  expected_urls.push_back("http://www.testsite.com/b.html");
  expected_urls.push_back("http://www.testsite.com/a.html");
  expected_urls.push_back("http://www.testsite.com/c.html");
  RunTest(text, expected_urls, "http://www.testsite.com/b.html");
}

TEST_F(ShortcutsProviderTest, FragmentLengthMatches) {
  string16 text(ASCIIToUTF16("just a"));
  std::vector<std::string> expected_urls;
  expected_urls.push_back("http://www.testsite.com/d.html");
  expected_urls.push_back("http://www.testsite.com/e.html");
  expected_urls.push_back("http://www.testsite.com/f.html");
  RunTest(text, expected_urls, "http://www.testsite.com/d.html");
}

TEST_F(ShortcutsProviderTest, DaysAgoMatches) {
  string16 text(ASCIIToUTF16("ago"));
  std::vector<std::string> expected_urls;
  expected_urls.push_back("http://www.daysagotest.com/a.html");
  expected_urls.push_back("http://www.daysagotest.com/b.html");
  expected_urls.push_back("http://www.daysagotest.com/c.html");
  RunTest(text, expected_urls, "http://www.daysagotest.com/a.html");
}

// Helper class to make running tests of ClassifyAllMatchesInString() more
// convenient.
class ClassifyTest {
 public:
  ClassifyTest(const string16& text, ACMatchClassifications matches);
  ~ClassifyTest();

  ACMatchClassifications RunTest(const string16& find_text);

 private:
  const string16 text_;
  const ACMatchClassifications matches_;
};

ClassifyTest::ClassifyTest(const string16& text, ACMatchClassifications matches)
    : text_(text),
      matches_(matches) {
}

ClassifyTest::~ClassifyTest() {
}

ACMatchClassifications ClassifyTest::RunTest(const string16& find_text) {
  return ShortcutsProvider::ClassifyAllMatchesInString(find_text,
      ShortcutsProvider::CreateWordMapForString(find_text), text_, matches_);
}

TEST_F(ShortcutsProviderTest, ClassifyAllMatchesInString) {
  ACMatchClassifications matches;
  matches.push_back(ACMatchClassification(0, ACMatchClassification::NONE));
  ClassifyTest classify_test(ASCIIToUTF16("A man, a plan, a canal Panama"),
                             matches);

  ACMatchClassifications spans_a = classify_test.RunTest(ASCIIToUTF16("man"));
  // ACMatch spans should be: '--MMM------------------------'
  ASSERT_EQ(3U, spans_a.size());
  EXPECT_EQ(0U, spans_a[0].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_a[0].style);
  EXPECT_EQ(2U, spans_a[1].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_a[1].style);
  EXPECT_EQ(5U, spans_a[2].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_a[2].style);

  ACMatchClassifications spans_b = classify_test.RunTest(ASCIIToUTF16("man p"));
  // ACMatch spans should be: '--MMM----M-------------M-----'
  ASSERT_EQ(7U, spans_b.size());
  EXPECT_EQ(0U, spans_b[0].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_b[0].style);
  EXPECT_EQ(2U, spans_b[1].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_b[1].style);
  EXPECT_EQ(5U, spans_b[2].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_b[2].style);
  EXPECT_EQ(9U, spans_b[3].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_b[3].style);
  EXPECT_EQ(10U, spans_b[4].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_b[4].style);
  EXPECT_EQ(23U, spans_b[5].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_b[5].style);
  EXPECT_EQ(24U, spans_b[6].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_b[6].style);

  ACMatchClassifications spans_c =
      classify_test.RunTest(ASCIIToUTF16("man plan panama"));
  // ACMatch spans should be:'--MMM----MMMM----------MMMMMM'
  ASSERT_EQ(6U, spans_c.size());
  EXPECT_EQ(0U, spans_c[0].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_c[0].style);
  EXPECT_EQ(2U, spans_c[1].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_c[1].style);
  EXPECT_EQ(5U, spans_c[2].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_c[2].style);
  EXPECT_EQ(9U, spans_c[3].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_c[3].style);
  EXPECT_EQ(13U, spans_c[4].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_c[4].style);
  EXPECT_EQ(23U, spans_c[5].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_c[5].style);

  ClassifyTest classify_test2(ASCIIToUTF16("Yahoo! Sports - Sports News, "
      "Scores, Rumors, Fantasy Games, and more"), matches);

  ACMatchClassifications spans_d = classify_test2.RunTest(ASCIIToUTF16("ne"));
  // ACMatch spans should match first two letters of the "news".
  ASSERT_EQ(3U, spans_d.size());
  EXPECT_EQ(0U, spans_d[0].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_d[0].style);
  EXPECT_EQ(23U, spans_d[1].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_d[1].style);
  EXPECT_EQ(25U, spans_d[2].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_d[2].style);

  ACMatchClassifications spans_e =
      classify_test2.RunTest(ASCIIToUTF16("news r"));
  // ACMatch spans should be the same as original matches.
  ASSERT_EQ(15U, spans_e.size());
  EXPECT_EQ(0U, spans_e[0].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_e[0].style);
  // "r" in "Sports".
  EXPECT_EQ(10U, spans_e[1].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_e[1].style);
  EXPECT_EQ(11U, spans_e[2].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_e[2].style);
  // "r" in second "Sports".
  EXPECT_EQ(19U, spans_e[3].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_e[3].style);
  EXPECT_EQ(20U, spans_e[4].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_e[4].style);
  // "News".
  EXPECT_EQ(23U, spans_e[5].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_e[5].style);
  EXPECT_EQ(27U, spans_e[6].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_e[6].style);
  // "r" in "Scores".
  EXPECT_EQ(32U, spans_e[7].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_e[7].style);
  EXPECT_EQ(33U, spans_e[8].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_e[8].style);
  // First "r" in "Rumors".
  EXPECT_EQ(37U, spans_e[9].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_e[9].style);
  EXPECT_EQ(38U, spans_e[10].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_e[10].style);
  // Second "r" in "Rumors".
  EXPECT_EQ(41U, spans_e[11].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_e[11].style);
  EXPECT_EQ(42U, spans_e[12].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_e[12].style);
  // "r" in "more".
  EXPECT_EQ(66U, spans_e[13].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_e[13].style);
  EXPECT_EQ(67U, spans_e[14].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_e[14].style);

  matches.clear();
  matches.push_back(ACMatchClassification(0, ACMatchClassification::URL));
  ClassifyTest classify_test3(ASCIIToUTF16("livescore.goal.com"), matches);

  ACMatchClassifications spans_f = classify_test3.RunTest(ASCIIToUTF16("go"));
  // ACMatch spans should match first two letters of the "goal".
  ASSERT_EQ(3U, spans_f.size());
  EXPECT_EQ(0U, spans_f[0].offset);
  EXPECT_EQ(ACMatchClassification::URL, spans_f[0].style);
  EXPECT_EQ(10U, spans_f[1].offset);
  EXPECT_EQ(ACMatchClassification::URL | ACMatchClassification::MATCH,
            spans_f[1].style);
  EXPECT_EQ(12U, spans_f[2].offset);
  EXPECT_EQ(ACMatchClassification::URL, spans_f[2].style);

  matches.clear();
  matches.push_back(ACMatchClassification(0, ACMatchClassification::NONE));
  matches.push_back(ACMatchClassification(13, ACMatchClassification::URL));
  ClassifyTest classify_test4(ASCIIToUTF16("Email login: mail.somecorp.com"),
                              matches);

  ACMatchClassifications spans_g = classify_test4.RunTest(ASCIIToUTF16("ail"));
  ASSERT_EQ(6U, spans_g.size());
  EXPECT_EQ(0U, spans_g[0].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_g[0].style);
  EXPECT_EQ(2U, spans_g[1].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_g[1].style);
  EXPECT_EQ(5U, spans_g[2].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_g[2].style);
  EXPECT_EQ(13U, spans_g[3].offset);
  EXPECT_EQ(ACMatchClassification::URL, spans_g[3].style);
  EXPECT_EQ(14U, spans_g[4].offset);
  EXPECT_EQ(ACMatchClassification::URL | ACMatchClassification::MATCH,
            spans_g[4].style);
  EXPECT_EQ(17U, spans_g[5].offset);
  EXPECT_EQ(ACMatchClassification::URL, spans_g[5].style);

  ACMatchClassifications spans_h =
      classify_test4.RunTest(ASCIIToUTF16("lo log"));
  ASSERT_EQ(4U, spans_h.size());
  EXPECT_EQ(0U, spans_h[0].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_h[0].style);
  EXPECT_EQ(6U, spans_h[1].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_h[1].style);
  EXPECT_EQ(9U, spans_h[2].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_h[2].style);
  EXPECT_EQ(13U, spans_h[3].offset);
  EXPECT_EQ(ACMatchClassification::URL, spans_h[3].style);

  ACMatchClassifications spans_i =
      classify_test4.RunTest(ASCIIToUTF16("ail em"));
  // 'Email' and 'ail' should be matched.
  ASSERT_EQ(5U, spans_i.size());
  EXPECT_EQ(0U, spans_i[0].offset);
  EXPECT_EQ(ACMatchClassification::MATCH, spans_i[0].style);
  EXPECT_EQ(5U, spans_i[1].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_i[1].style);
  EXPECT_EQ(13U, spans_i[2].offset);
  EXPECT_EQ(ACMatchClassification::URL, spans_i[2].style);
  EXPECT_EQ(14U, spans_i[3].offset);
  EXPECT_EQ(ACMatchClassification::URL | ACMatchClassification::MATCH,
            spans_i[3].style);
  EXPECT_EQ(17U, spans_i[4].offset);
  EXPECT_EQ(ACMatchClassification::URL, spans_i[4].style);

  // Some web sites do not have a description, so second and third parameters in
  // ClassifyAllMatchesInString could be empty.
  // Extra parens in the next line hack around C++03's "most vexing parse".
  class ClassifyTest classify_test5((string16()), ACMatchClassifications());
  ACMatchClassifications spans_j = classify_test5.RunTest(ASCIIToUTF16("man"));
  ASSERT_EQ(0U, spans_j.size());

  // Matches which end at beginning of classification merge properly.
  matches.clear();
  matches.push_back(ACMatchClassification(0, ACMatchClassification::DIM));
  matches.push_back(ACMatchClassification(9, ACMatchClassification::NONE));
  ClassifyTest classify_test6(ASCIIToUTF16("html password example"), matches);

  // Extra space in the next string avoids having the string be a prefix of the
  // text above, which would allow for two different valid classification sets,
  // one of which uses two spans (the first of which would mark all of "html
  // pass" as a match) and one which uses four (which marks the individual words
  // as matches but not the space between them).  This way only the latter is
  // valid.
  ACMatchClassifications spans_k =
      classify_test6.RunTest(ASCIIToUTF16("html  pass"));
  ASSERT_EQ(4U, spans_k.size());
  EXPECT_EQ(0U, spans_k[0].offset);
  EXPECT_EQ(ACMatchClassification::DIM | ACMatchClassification::MATCH,
            spans_k[0].style);
  EXPECT_EQ(4U, spans_k[1].offset);
  EXPECT_EQ(ACMatchClassification::DIM, spans_k[1].style);
  EXPECT_EQ(5U, spans_k[2].offset);
  EXPECT_EQ(ACMatchClassification::DIM | ACMatchClassification::MATCH,
            spans_k[2].style);
  EXPECT_EQ(9U, spans_k[3].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_k[3].style);

  // Multiple matches with both beginning and end at beginning of
  // classifications merge properly.
  matches.clear();
  matches.push_back(ACMatchClassification(0, ACMatchClassification::URL));
  matches.push_back(ACMatchClassification(11, ACMatchClassification::NONE));
  ClassifyTest classify_test7(ASCIIToUTF16("http://a.co is great"), matches);

  ACMatchClassifications spans_l =
      classify_test7.RunTest(ASCIIToUTF16("ht co"));
  ASSERT_EQ(4U, spans_l.size());
  EXPECT_EQ(0U, spans_l[0].offset);
  EXPECT_EQ(ACMatchClassification::URL | ACMatchClassification::MATCH,
            spans_l[0].style);
  EXPECT_EQ(2U, spans_l[1].offset);
  EXPECT_EQ(ACMatchClassification::URL, spans_l[1].style);
  EXPECT_EQ(9U, spans_l[2].offset);
  EXPECT_EQ(ACMatchClassification::URL | ACMatchClassification::MATCH,
            spans_l[2].style);
  EXPECT_EQ(11U, spans_l[3].offset);
  EXPECT_EQ(ACMatchClassification::NONE, spans_l[3].style);

}

TEST_F(ShortcutsProviderTest, CalculateScore) {
  ACMatchClassifications spans_content;
  spans_content.push_back(ACMatchClassification(0, ACMatchClassification::URL));
  spans_content.push_back(ACMatchClassification(
      4, ACMatchClassification::MATCH | ACMatchClassification::URL));
  spans_content.push_back(ACMatchClassification(8, ACMatchClassification::URL));
  ACMatchClassifications spans_description;
  spans_description.push_back(
      ACMatchClassification(0, ACMatchClassification::NONE));
  spans_description.push_back(
      ACMatchClassification(2, ACMatchClassification::MATCH));
  ShortcutsBackend::Shortcut shortcut(std::string(),
      ASCIIToUTF16("test"), GURL("http://www.test.com"),
      ASCIIToUTF16("www.test.com"), spans_content, ASCIIToUTF16("A test"),
      spans_description, base::Time::Now(), 1);

  // Maximal score.
  const int kMaxScore = ShortcutsProvider::CalculateScore(
      ASCIIToUTF16("test"), shortcut);

  // Score decreases as percent of the match is decreased.
  int score_three_quarters =
      ShortcutsProvider::CalculateScore(ASCIIToUTF16("tes"), shortcut);
  EXPECT_LT(score_three_quarters, kMaxScore);
  int score_one_half =
      ShortcutsProvider::CalculateScore(ASCIIToUTF16("te"), shortcut);
  EXPECT_LT(score_one_half, score_three_quarters);
  int score_one_quarter =
      ShortcutsProvider::CalculateScore(ASCIIToUTF16("t"), shortcut);
  EXPECT_LT(score_one_quarter, score_one_half);

  // Should decay with time - one week.
  shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(7);
  int score_week_old =
      ShortcutsProvider::CalculateScore(ASCIIToUTF16("test"), shortcut);
  EXPECT_LT(score_week_old, kMaxScore);

  // Should decay more in two weeks.
  shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14);
  int score_two_weeks_old =
      ShortcutsProvider::CalculateScore(ASCIIToUTF16("test"), shortcut);
  EXPECT_LT(score_two_weeks_old, score_week_old);

  // But not if it was activly clicked on. 2 hits slow decaying power.
  shortcut.number_of_hits = 2;
  shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14);
  int score_popular_two_weeks_old =
      ShortcutsProvider::CalculateScore(ASCIIToUTF16("test"), shortcut);
  EXPECT_LT(score_two_weeks_old, score_popular_two_weeks_old);
  // But still decayed.
  EXPECT_LT(score_popular_two_weeks_old, kMaxScore);

  // 3 hits slow decaying power even more.
  shortcut.number_of_hits = 3;
  shortcut.last_access_time = base::Time::Now() - base::TimeDelta::FromDays(14);
  int score_more_popular_two_weeks_old =
      ShortcutsProvider::CalculateScore(ASCIIToUTF16("test"), shortcut);
  EXPECT_LT(score_two_weeks_old, score_more_popular_two_weeks_old);
  EXPECT_LT(score_popular_two_weeks_old, score_more_popular_two_weeks_old);
  // But still decayed.
  EXPECT_LT(score_more_popular_two_weeks_old, kMaxScore);
}

TEST_F(ShortcutsProviderTest, DeleteMatch) {
  TestShortcutInfo shortcuts_to_test_delete[3] = {
    { "BD85DBA2-8C29-49F9-84AE-48E1E90880F1",
      "http://www.deletetest.com/1.html", "delete",
      "http://www.deletetest.com/1.html", "0,2",
      "Erase this shortcut!", "0,0", 1, 1},
    { "BD85DBA2-8C29-49F9-84AE-48E1E90880F2",
      "http://www.deletetest.com/1.html", "erase",
      "http://www.deletetest.com/1.html", "0,2",
      "Erase this shortcut!", "0,0", 1, 1},
    { "BD85DBA2-8C29-49F9-84AE-48E1E90880F3",
      "http://www.deletetest.com/2.html", "delete",
      "http://www.deletetest.com/2.html", "0,2",
      "Erase this shortcut!", "0,0", 1, 1},
  };

  size_t original_shortcuts_count = backend_->shortcuts_map().size();

  FillData(shortcuts_to_test_delete, arraysize(shortcuts_to_test_delete));

  EXPECT_EQ(original_shortcuts_count + 3, backend_->shortcuts_map().size());
  EXPECT_FALSE(backend_->shortcuts_map().end() ==
               backend_->shortcuts_map().find(ASCIIToUTF16("delete")));
  EXPECT_FALSE(backend_->shortcuts_map().end() ==
               backend_->shortcuts_map().find(ASCIIToUTF16("erase")));

  AutocompleteMatch match(provider_, 1200, true,
                          AutocompleteMatch::HISTORY_TITLE);

  match.destination_url = GURL(shortcuts_to_test_delete[0].url);
  match.contents = ASCIIToUTF16(shortcuts_to_test_delete[0].contents);
  match.description = ASCIIToUTF16(shortcuts_to_test_delete[0].description);

  provider_->DeleteMatch(match);

  // |shortcuts_to_test_delete[0]| and |shortcuts_to_test_delete[1]| should be
  // deleted, but not |shortcuts_to_test_delete[2]| as it has different url.
  EXPECT_EQ(original_shortcuts_count + 1, backend_->shortcuts_map().size());
  EXPECT_FALSE(backend_->shortcuts_map().end() ==
               backend_->shortcuts_map().find(ASCIIToUTF16("delete")));
  EXPECT_TRUE(backend_->shortcuts_map().end() ==
              backend_->shortcuts_map().find(ASCIIToUTF16("erase")));

  match.destination_url = GURL(shortcuts_to_test_delete[2].url);
  match.contents = ASCIIToUTF16(shortcuts_to_test_delete[2].contents);
  match.description = ASCIIToUTF16(shortcuts_to_test_delete[2].description);

  provider_->DeleteMatch(match);
  EXPECT_EQ(original_shortcuts_count, backend_->shortcuts_map().size());
  EXPECT_TRUE(backend_->shortcuts_map().end() ==
              backend_->shortcuts_map().find(ASCIIToUTF16("delete")));
}


text:
#region Copyright (c) 2014 Orcomp development team.
// -------------------------------------------------------------------------------------------------------------------
// <copyright file="FileSystemHelperTest.cs" company="Orcomp development team">
//   Copyright (c) 2014 Orcomp development team. All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
#endregion

namespace SolutionValidator.Tests.Validator.FolderStructure
{
	#region using...
	using System.Linq;
	using System.Text.RegularExpressions;
	using NUnit.Framework;
	using SolutionValidator.Configuration;
	using SolutionValidator.FolderStructure;

	#endregion

	[TestFixture]
	public class FileSystemHelperTest
	{
		private string root;
		private FileSystemHelper fileSystemHelper;

		[TestFixtureSetUp]
		public void TestFixtureSetUp()
		{
			root = TestUtils.CreateFoldersAndFiles(TestUtils.MockFileSystemDefinition);
			fileSystemHelper = new FileSystemHelper();
		}

		[TestFixtureTearDown]
		public void TestFixtureTearDown()
		{
			TestUtils.DeleteFolder(root);
		}

		[Test]
		[TestCase(@"", @"", 15)]

		[TestCase(@"^fileFolder\\.*", @"", 3)]
		[TestCase(@"^fileFolder\\.*;^folderWithFile100\\.*", @";", 10)]
		[TestCase(@"^fileFolder\\.*;^folderWithFile200\\.*", @";", 4)]
		[TestCase(@"^fileFolder\\.*;^folderWithFile200\\.*;^folderWithFile300\\.*", @";;", 5)]
		[TestCase(@"^fileFolder\\.*;^folderWithFile100\\.*;^folderWithFile200\\.*;^folderWithFile300\\.*", @";;;", 12)]

		[TestCase(@"", @"^fileFolder\\.*", 12)]
		[TestCase(@";", @"^fileFolder\\.*;^folderWithFile100\\.*", 5)]
		[TestCase(@";", @"^fileFolder\\.*;^folderWithFile200\\.*", 11)]
		[TestCase(@";;", @"^fileFolder\\.*;^folderWithFile200\\.*;^folderWithFile300\\.*", 10)]
		[TestCase(@";;;", @"^fileFolder\\.*;^folderWithFile100\\.*;^folderWithFile200\\.*;^folderWithFile300\\.*", 3)]

		[TestCase(@"^fileFolder\\.*", @"^fileFolder\\.*", 0)]
		[TestCase(@"^fileFolder\\.*;^folderWithFile100\\.*", @"^fileFolder\\.*;^folderWithFile100\\.*", 0)]
		[TestCase(@"^fileFolder\\.*;^folderWithFile200\\.*", @"^fileFolder\\.*;^folderWithFile200\\.*", 0)]
		[TestCase(@"^fileFolder\\.*;^folderWithFile200\\.*;^folderWithFile300\\.*", @"^fileFolder\\.*;^folderWithFile200\\.*;^folderWithFile300\\.*", 0)]
		[TestCase(@"^fileFolder\\.*;^folderWithFile100\\.*;^folderWithFile200\\.*;^folderWithFile300\\.*", @"^fileFolder\\.*;^folderWithFile100\\.*;^folderWithFile200\\.*;^folderWithFile300\\.*", 0)]

		[TestCase(@"", @".*", 0)]
		[TestCase(@".*", @"", 15)]
		[TestCase(@".*", @".*", 0)]

		[TestCase(@"^fileFolder\\.*", @".*002.*", 2)]
		[TestCase(@"^fileFolder\\.*;", @";.*002.*", 2)]
		[TestCase(@"^fileFolder\\.*;", @".*001.*;.*002.*", 1)]
		public void TestGetFiles(string includes, string excludes, int expectedCount)
		{
			var includeSplit = includes.Split(';');
			var excludeSplit = excludes.Split(';');
			var includeExcludeCollection = new IncludeExcludeCollection();

			Assert.AreEqual(includeSplit.Count(), excludeSplit.Count());
			for (int index = 0; index < includeSplit.Length; index++)
			{
				includeExcludeCollection.Add(new IncludeExcludeElement {Include = includeSplit[index], Exclude = excludeSplit[index]});
			}

			string tempRoot = null;
			try
			{
				tempRoot = TestUtils.CreateFoldersAndFiles(TestUtils.MockFileSystemDefinition, "cs");
				var files = new FileSystemHelper().GetFiles(tempRoot, "*.cs", includeExcludeCollection);
				Assert.AreEqual(expectedCount, files.Count());
			}
			finally
			{
				if (tempRoot != null)
				{
					TestUtils.DeleteFolder(tempRoot);
				}
			}
		}

		[Test]
		[TestCase("**/", 19)]
		[TestCase("**/**/", 12)]
		[TestCase("**/**/**/", 6)]
		[TestCase("folder100/", 1)]
		[TestCase("folder100/**/", 6)]
		[TestCase("folder100/**/**/", 3)]
		[TestCase("**/folder010/", 1)]
		[TestCase("**/folder010/**/", 3)]
		public void TestGetFolders(string folderPattern, int expectedCount)
		{
			var folders = fileSystemHelper.GetFolders(root, folderPattern);
			Assert.AreEqual(expectedCount, folders.Count());
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
<?php

class Controller extends Kohana_Controller {

	protected $conventions;

	/**
	 * Loads conventions by directory's, controller's and action's names.
	 */
	protected function load_conventions() {

		$this->conventions = array();

		if ($this->request->directory()) {

			$this->conventions[] = $this->request->directory();

		}

		$this->conventions[] = $this->request->controller();
		$this->conventions[] = $this->request->action();

	}

	function before() {

		parent::before();

		$this->load_conventions();

		/**
		 * Loads permissions if they're found by conventions.
		 */

		$permissions = Kohana::$config->load('permissions');
		$permissions = $permissions->as_array();

		$found_permissions = array();

		// Loads directory's or controller's permissions.

		if (isset($permissions[$this->conventions[0]])) {

			$found_permissions = array_merge($found_permissions, Arr::get_non_assoc_elements($permissions[$this->conventions[0]]));

		}

		// Loads controller's or action's permissions.

		if (isset($permissions[$this->conventions[0]][$this->conventions[1]])) {

			$found_permissions = array_merge($found_permissions, Arr::get_non_assoc_elements($permissions[$this->conventions[0]][$this->conventions[1]]));

		}

		// Loads action's permissions when directory is not empty.

		if ($this->request->directory() && isset($permissions[$this->conventions[0]][$this->conventions[1]][$this->conventions[2]])) {

			$found_permissions = array_merge($found_permissions, Arr::get_non_assoc_elements($permissions[$this->conventions[0]][$this->conventions[1]][$this->conventions[2]]));

		}

		/**
		 * Executes all found permissions.
		 */

		if (!empty($found_permissions)) {

			foreach ($found_permissions as $permission) {

				if (!is_callable($permission)) {

					throw new HTTP_Exception_500("Permission must be callable!");

				}

				$response = call_user_func_array($permission, array());

				if (!$response) {

					throw new HTTP_Exception_401("You are not allowed to do that!");

				}

			}

		}

	}

}


text:
package org.elasticsearch.action.admin.indices.diskusage;

import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.xcontent.ToXContentFragment;
import org.elasticsearch.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * The result of analyzing disk usage of each field in a shard/index
 */
public final class IndexDiskUsageStats implements ToXContentFragment, Writeable {
    public static final String TOTAL = "total";
    public static final String TOTAL_IN_BYTES = "total_in_bytes";
    public static final String INVERTED_INDEX = "inverted_index";
    public static final String STORED_FIELDS = "stored_fields";
    public static final String STORED_FIELDS_IN_BYTES = "stored_fields_in_bytes";
    public static final String DOC_VALUES = "doc_values";
    public static final String DOC_VALUES_IN_BYTES = "doc_values_in_bytes";
    public static final String POINTS = "points";
    public static final String POINTS_IN_BYTES = "points_in_bytes";
    public static final String NORMS = "norms";
    public static final String NORMS_IN_BYTES = "norms_in_bytes";
    public static final String TERM_VECTORS = "term_vectors";
    public static final String TERM_VECTORS_IN_BYTES = "term_vectors_in_bytes";

    public static final String STORE_SIZE = "store_size";
    public static final String STORE_SIZE_IN_BYTES = "store_size_in_bytes";

    private final Map<String, PerFieldDiskUsage> fields;
    private long indexSizeInBytes;

    public IndexDiskUsageStats(long indexSizeInBytes) {
        fields = new HashMap<>();
        this.indexSizeInBytes = indexSizeInBytes;
    }

    public IndexDiskUsageStats(StreamInput in) throws IOException {
        this.fields = new HashMap<>(in.readMap(StreamInput::readString, PerFieldDiskUsage::new));
        this.indexSizeInBytes = in.readVLong();
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        out.writeMap(fields, StreamOutput::writeString, (o, v) -> v.writeTo(o));
        out.writeVLong(indexSizeInBytes);
    }

    PerFieldDiskUsage total() {
        final PerFieldDiskUsage total = new PerFieldDiskUsage();
        for (PerFieldDiskUsage value : fields.values()) {
            total.add(value);
        }
        return total;
    }

    Map<String, PerFieldDiskUsage> getFields() {
        return fields;
    }

    long getIndexSizeInBytes() {
        return indexSizeInBytes;
    }

    private void checkByteSize(long bytes) {
        if (bytes < 0) {
            throw new IllegalArgumentException("Bytes must be non-negative; got " + bytes);
        }
    }

    private PerFieldDiskUsage getOrAdd(String fieldName) {
        Objects.requireNonNull(fieldName, "fieldName must be non-null");
        return fields.computeIfAbsent(fieldName, k -> new PerFieldDiskUsage());
    }

    public void addInvertedIndex(String fieldName, long bytes) {
        checkByteSize(bytes);
        getOrAdd(fieldName).invertedIndexBytes += bytes;
    }

    public void addStoredField(String fieldName, long bytes) {
        checkByteSize(bytes);
        getOrAdd(fieldName).storedFieldBytes += bytes;
    }

    public void addDocValues(String fieldName, long bytes) {
        checkByteSize(bytes);
        getOrAdd(fieldName).docValuesBytes += bytes;
    }

    public void addPoints(String fieldName, long bytes) {
        checkByteSize(bytes);
        getOrAdd(fieldName).pointsBytes += bytes;
    }

    public void addNorms(String fieldName, long bytes) {
        checkByteSize(bytes);
        getOrAdd(fieldName).normsBytes += bytes;
    }

    public void addTermVectors(String fieldName, long bytes) {
        checkByteSize(bytes);
        getOrAdd(fieldName).termVectorsBytes += bytes;
    }

    public IndexDiskUsageStats add(IndexDiskUsageStats other) {
        other.fields.forEach((k, v) -> getOrAdd(k).add(v));
        this.indexSizeInBytes += other.indexSizeInBytes;
        return this;
    }

    @Override
    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
        final PerFieldDiskUsage total = total();
        builder.field(STORE_SIZE, new ByteSizeValue(indexSizeInBytes));
        builder.field(STORE_SIZE_IN_BYTES, indexSizeInBytes);

        // all fields
        builder.startObject("all_fields");
        total.toXContent(builder, params);
        builder.endObject();

        // per field
        builder.startObject("fields");
        {
            final List<Map.Entry<String, PerFieldDiskUsage>> entries = fields.entrySet()
                .stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toList());
            for (Map.Entry<String, PerFieldDiskUsage> entry : entries) {
                builder.startObject(entry.getKey());
                entry.getValue().toXContent(builder, params);
                builder.endObject();
            }
        }
        builder.endObject();
        return builder;
    }

    @Override
    public String toString() {
        return Strings.toString(this);
    }

    /**
     * Disk usage stats for a single field
     */
    public static final class PerFieldDiskUsage implements ToXContentFragment, Writeable {
        private long invertedIndexBytes;
        private long storedFieldBytes;
        private long docValuesBytes;
        private long pointsBytes;
        private long normsBytes;
        private long termVectorsBytes;

        private PerFieldDiskUsage() {

        }

        private PerFieldDiskUsage(StreamInput in) throws IOException {
            invertedIndexBytes = in.readVLong();
            storedFieldBytes = in.readVLong();
            docValuesBytes = in.readVLong();
            pointsBytes = in.readVLong();
            normsBytes = in.readVLong();
            termVectorsBytes = in.readVLong();
        }

        @Override
        public void writeTo(StreamOutput out) throws IOException {
            out.writeVLong(invertedIndexBytes);
            out.writeVLong(storedFieldBytes);
            out.writeVLong(docValuesBytes);
            out.writeVLong(pointsBytes);
            out.writeVLong(normsBytes);
            out.writeVLong(termVectorsBytes);
        }

        private void add(PerFieldDiskUsage other) {
            invertedIndexBytes += other.invertedIndexBytes;
            storedFieldBytes += other.storedFieldBytes;
            docValuesBytes += other.docValuesBytes;
            pointsBytes += other.pointsBytes;
            normsBytes += other.normsBytes;
            termVectorsBytes += other.termVectorsBytes;
        }

        public long getInvertedIndexBytes() {
            return invertedIndexBytes;
        }

        public long getStoredFieldBytes() {
            return storedFieldBytes;
        }

        public long getDocValuesBytes() {
            return docValuesBytes;
        }

        public long getPointsBytes() {
            return pointsBytes;
        }

        public long getNormsBytes() {
            return normsBytes;
        }

        public long getTermVectorsBytes() {
            return termVectorsBytes;
        }

        long totalBytes() {
            return invertedIndexBytes + storedFieldBytes + docValuesBytes + pointsBytes + normsBytes + termVectorsBytes;
        }

        @Override
        public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
            final long totalBytes = totalBytes();
            builder.field(TOTAL, new ByteSizeValue(totalBytes));
            builder.field(TOTAL_IN_BYTES, totalBytes);

            builder.startObject(INVERTED_INDEX);
            builder.field(TOTAL, new ByteSizeValue(invertedIndexBytes));
            builder.field(TOTAL_IN_BYTES, invertedIndexBytes);
            builder.endObject();

            builder.field(STORED_FIELDS, new ByteSizeValue(storedFieldBytes));
            builder.field(STORED_FIELDS_IN_BYTES, storedFieldBytes);

            builder.field(DOC_VALUES, new ByteSizeValue(docValuesBytes));
            builder.field(DOC_VALUES_IN_BYTES, docValuesBytes);

            builder.field(POINTS, new ByteSizeValue(pointsBytes));
            builder.field(POINTS_IN_BYTES, pointsBytes);

            builder.field(NORMS, new ByteSizeValue(normsBytes));
            builder.field(NORMS_IN_BYTES, normsBytes);

            builder.field(TERM_VECTORS, new ByteSizeValue(termVectorsBytes));
            builder.field(TERM_VECTORS_IN_BYTES, termVectorsBytes);
            return builder;
        }

        @Override
        public String toString() {
            return Strings.toString(this);
        }
    }
}


text:
package com.jayway.jsonpath.internal.filter;

import com.jayway.jsonpath.BaseTest;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;

@RunWith(Parameterized.class)
public class PatternFlagTest extends BaseTest {

    private final int flags;
    private final String expectedFlags;

    public PatternFlagTest(int flags, String expectedFlags) {
        this.flags = flags;
        this.expectedFlags = expectedFlags;
    }

    @Test
    public void testParseFlags() {
        Assert.assertEquals(expectedFlags, PatternFlag.parseFlags(flags));
    }

    @Parameterized.Parameters
    public static Iterable data() {
        return Arrays.asList(
            new Object[][]{
                { 1,   "d"       },
                { 2,   "i"       },
                { 4,   "x"       },
                { 8,   "m"       },
                { 32,  "s"       },
                { 64,  "u"       },
                { 256, "U"       },
                { 300, "xmsU"    },
                { 13,  "dxm"     },
                { 7,   "dix"     },
                { 100, "xsu"     },
                { 367, "dixmsuU" }
            }
        );
    }
}


text:
<!doctype html>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Draggable Demo</title>
  <link rel="stylesheet" href="../../../docs/demo.css" />
  <link rel="stylesheet" href="styles/demo.css" />
  <link rel="stylesheet" href="../css/odo-draggable.css">

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1/themes/prism.css">

Odo Draggable

A class for versatile, performant draggability.

Support

IE9+.

Dependencies

Odo Pointer, Odo Device, Odo Helpers, Tiny Emitter.

Odo Pointer also expects Object.assign from ES6 to be available.

X Axis

          <button onclick="x.setPosition(50, 50);">Set to 50%</button>
          <button onclick="x.setPosition(0, 0);">Set to 0</button>

          <button id="limit-toggle" class="limitless">
            Remove limits
            Set limits on draggable
          </button>

Setup

var x = new OdoDraggable(document.getElementById('draggable-x'), {
  axis: 'x'
});

Position

Set the position of the draggable element. The parameters are percentages, so 50 equates to 50%.

// Set to 50%
x.setPosition(50, 50);

// Set to 0
x.setPosition(0, 0);

The position of the draggable element can be retrieved with getPosition. Optionally specify the first parameter as true to get the percentage coordinates instead of pixels.

x.setPosition(50, 50);
// Get pixels
x.getPosition(); // Coordinate {x: 480, y: 0}
// Get percentages
x.getPosition(true);// Coordinate {x: 50, y: 0}

Limits

You can also sets limits on the draggable instance, which restricts it to given boundaries. The only parameter is a Rect. Rects have a left, top, width, and height and can be accessed from the math property of OdoHelpers.

In this example, the draggable stops at the edges of the .container element. Since the draggable is centered within the container and the draggable starts at 0, 0, the left limit needs to be negative half the leftover space. The minimum x position is the left value. The maximum x is the left + width. The width in this case, is the leftover space (20% because draggable is 80%). The y axis works the same way, but in this example, the top and height parameters don't matter because this draggable is restricted to the x axis.

var math = OdoHelpers.math;
var draggableWidth = x.element.offsetWidth;
var containerWidth = container.offsetWidth;

var left = (containerWidth - draggableWidth) / -2;
var top = 0;
var width = containerWidth - draggableWidth;
var height = 0;
var rect = new OdoHelpers.Rect(left, top, width, height);
x.setLimits(rect);

Y Axis

Heads up! Any draggable element on the Y axis requires its parent to have a height to work with the fallback left and top positioning.

          <button onclick="y.isEnabled = false;">Disable</button>
          <button onclick="y.isEnabled = true;">Enable</button>

Setup

var y = new OdoDraggable(document.getElementById('draggable-y'), {
  axis: 'y'
});

Disabling

The draggable instance can be disabled (and re-enabled). The carousel, for example, disables dragging while its animating.

// Disable draggable
y.isEnabled = false;

// Enable draggable.
y.isEnabled = true;

Both Axis

Just like the Y axis note above, the element which contains the draggable element must have a height, otherwise the top percentage value is not relative to anything and is calculated as zero.

          <button onclick="xy.friction = 0.4;">Set friction to 0.4</button>
          <button onclick="xy.friction = 1;">Set friction to 1</button>

Setup

var xy = new OdoDraggable(document.getElementById('draggable-xy'), {
  axis: 'xy'
});

Friction

You can make a draggable instance act like it is resisting the user's touch by setting a friction value. A value of 1 represents no friction; 100% of the user's movements are translated into movement of the draggable instance. Use a value less than 1, like 0.4, and the draggable element does not move completely in sync with your pointing device.

// Give it friction, like the edge slide of a carousel.
xy.friction = 0.4;

// Remove friction.
xy.friction = 1;

Throwable

Give it a toss.

By default, draggable instances are not throwable. Use the isThrowable option to enable it. You must also set a boundary for the throwable element, otherwise you can throw it off the screen!

// Create new draggable
var throwable = new OdoDraggable(document.getElementById('draggable-throw-me'), {
  axis: 'xy',
  isThrowable: true
});

var element = throwable.element;
var parent = element.parentNode;
var draggableWidth = element.offsetWidth;
var draggableHeight = element.offsetHeight;
var containerWidth = parent.offsetWidth;
var containerHeight = parent.offsetHeight;

var left = 0;
var top = 0;
var width = containerWidth - draggableWidth;
var height = containerHeight - draggableHeight;
var rect = new OdoHelpers.Rect(left, top, width, height);

// Set a boundary for the draggable so that it won't be thrown outside of its parent.
throwable.setLimits(rect);

More like a carousel

This example uses the same markup and css as the Odo Carousel, except the .carousel-element's width is set to fit the exact amount of slides (width is 500% instead of 2000%).

                    1

                    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

                    2

                    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

                    3

                    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

                    4

                    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

                    5

                    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

            Throw Friction
            <input id="throw-friction" type="number" step="0.01" value="0.94" min="0" max="0.99"/>

            Amplifier
            <input id="amplifier" type="number" step="4" value="24" min="0" max="100"/>

            Velocity Stop
            <input id="velocity-stop" type="number" step="0.01" value="0.08" min="0" max="0.5"/>

          <button id="back-to-defaults">Reset</button>

Here we follow the same steps. Set the isThrowable option and then set limits.

var freescroll = new OdoDraggable(document.getElementById('draggable-carousel'), {
  axis: 'x',
  isThrowable: true
});

var element = freescroll.element;
var parent = element.parentNode;
var draggableWidth = element.offsetWidth;
var containerWidth = parent.offsetWidth;

var left = -draggableWidth + containerWidth;
var top = 0;
var width = -left;
var height = 0;
var rect = new OdoHelpers.Rect(left, top, width, height);

freescroll.setLimits(rect);

Events

Draggable emits three events: START, MOVE, and END.

instance.on(OdoDraggable.EventType.START, function(pointerEvent) {
  console.log('drag started', pointerEvent);
});

instance.on(OdoDraggable.EventType.MOVE, function (pointerEvent) {
  console.log('drag move:', pointerEvent);
});

instance.on(OdoDraggable.EventType.END, function (pointerEvent) {
  console.log('drag ended:', pointerEvent);
});

PointerEvent

Here is the data contained within a drag end event from the first draggable on this page. There are a few simple properties here that have already determined the drag movement compared to its axis.

{
  axisDirection: "left",
  currentVelocity: {
    x: 1.88,
    y: 0.14
  }
  delta: {
    x: -32,
    y: 0
  },
  deltaTime: 203,
  didMoveOnAxis: true,
  direction: "left", // OdoPointer.Direction.LEFT
  distance: 32,
  end: {
    x: -32,
    y: 0
  },
  isDirectionOnAxis: true,
  position: {
    percent: {
      x: -3.2160804020100504,
      y: 0
    },
    pixel: {
      x: -32,
      y: 0
    },
  },
  start: {
    x: 0,
    y: 0
  },
  target: div,
  type: "ododraggable:end", // OdoDraggable.EventType.END
  velocity: {
    x: 0.15763546798029557,
    y: 0
  }
}

Disposal

To properly destroy a draggable instance, you must call the dispose method. This removes event listeners, nullifies DOM references, and performs other clean up.

xy.dispose();

Options

OdoDraggable.Defaults = {
  // Draggable axis.
  axis: OdoPointer.Axis.X,

  // Amplifies throw velocity by this value. Higher values make the throwable
  // travel farther and faster.
  amplifier: 24,

  // Once the velocity has gone below this threshold, throwing stops.
  velocityStop: 0.08,

  // On each throw frame, the velocity is multiplied by this friction value.
  // It must be less than 1. Higher values let the throwable slide farther and longer.
  throwFriction: 0.94,

  // Whether the draggable will keep its movement momentum after the user releases.
  isThrowable: false
}


text:
module Linguistics
  module Latin
    module Verb
      class LatinVerb
        class Querent
          module ActiveVoiceSubjunctiveMoodImperfectTenseMethods
            def active_voice_subjunctive_mood_imperfect_tense
              elements = [ 'm', *AP_FIRST_AND_SECOND_CONJUG_PERS_ENDINGS ].flat_map do |ending|
                present_active_infinitive.sub(/e$/,'ē') + ending
              end
              meaning = { :meaning => MEANINGS[:active_voice_subjunctive_mood_imperfect_tense] }
              TenseBlock.new(elements, meaning)
            end

            def active_voice_subjunctive_mood_imperfect_tense_first_person_singular_number
              active_voice_subjunctive_mood_imperfect_tense.first_person_singular_number
            end

            def active_voice_subjunctive_mood_imperfect_tense_singular_number_first_person
              active_voice_subjunctive_mood_imperfect_tense.singular_number_first_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_second_person_singular_number
              active_voice_subjunctive_mood_imperfect_tense.second_person_singular_number
            end

            def active_voice_subjunctive_mood_imperfect_tense_singular_number_second_person
              active_voice_subjunctive_mood_imperfect_tense.singular_number_second_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_third_person_singular_number
              active_voice_subjunctive_mood_imperfect_tense.third_person_singular_number
            end

            def active_voice_subjunctive_mood_imperfect_tense_singular_number_third_person
              active_voice_subjunctive_mood_imperfect_tense.singular_number_third_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_first_person_plural_number
              active_voice_subjunctive_mood_imperfect_tense.first_person_plural_number
            end

            def active_voice_subjunctive_mood_imperfect_tense_plural_number_first_person
              active_voice_subjunctive_mood_imperfect_tense.plural_number_first_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_second_person_plural_number
              active_voice_subjunctive_mood_imperfect_tense.second_person_plural_number
            end

            def active_voice_subjunctive_mood_imperfect_tense_plural_number_second_person
              active_voice_subjunctive_mood_imperfect_tense.plural_number_second_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_third_person_plural_number
              active_voice_subjunctive_mood_imperfect_tense.third_person_plural_number
            end

            def active_voice_subjunctive_mood_imperfect_tense_plural_number_third_person
              active_voice_subjunctive_mood_imperfect_tense.plural_number_third_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_first_person
              active_voice_subjunctive_mood_imperfect_tense.first_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_second_person
              active_voice_subjunctive_mood_imperfect_tense.second_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_third_person
              active_voice_subjunctive_mood_imperfect_tense.third_person
            end

            def active_voice_subjunctive_mood_imperfect_tense_singular_number
              active_voice_subjunctive_mood_imperfect_tense.singular_number
            end

            def active_voice_subjunctive_mood_imperfect_tense_plural_number
              active_voice_subjunctive_mood_imperfect_tense.plural_number
            end
          end
        end
      end
    end
  end
end


text:
declare class AuthConfig {
    static TOKEN_SECRET: string;
    static MONGO_URI: string;
    static FACEBOOK_SECRET: string;
    static FOURSQUARE_SECRET: string;
    static GOOGLE_SECRET: string;
    static GITHUB_SECRET: string;
    static LINKEDIN_SECRET: string;
    static TWITCH_SECRET: string;
    static WINDOWS_LIVE_SECRET: string;
    static YAHOO_SECRET: string;
    static TWITTER_KEY: string;
    static TWITTER_SECRET: string;
}
export = AuthConfig;


text:
This sample Android app demonstrates
integrating a `SearchView` backport into the `appcompat-v7` action bar.

This app is covered in
[the chapter on `appcompat-v7`](https://commonsware.com/Android/previews/appcompat-the-official-action-bar-backport)
in [*The Busy Coder's Guide to Android Development*](https://commonsware.com/Android/).


text:
<?php

use CodeMommy\WebPHP\Environment;

return array(
    'debug' => Environment::get('application.debug', false),
    'title' => 'CacheDream - an open source project that provide cache service for developers',
    'domain' => array('staticfile.net', 'www.staticfile.net', 'mirrors.mom', 'www.mirrors.mom', 'www.cachedream.com'),
    'static' => '//cache.shareany.com/?v=3&f=http://www.cachedream.com/static',
);


text:
/*
	NounTemplate.cpp

	This class provides the hook for the game to enumerate the available ship types
	(c)1999 PaleStar Development, Richard Lyle
*/

#include "Debug/Assert.h"
#include "NounTemplate.h"
#include "Noun.h"
#include "WorldContext.h"

//----------------------------------------------------------------------------

IMPLEMENT_FACTORY( NounTemplate, Resource );
REGISTER_FACTORY_KEY( NounTemplate, 4040652215298323130LL );

BEGIN_PROPERTY_LIST( NounTemplate, Resource )
	ADD_PROPERTY( m_nFlags );
	ADD_PROPERTY( m_nRank );
	ADD_PROPERTY( m_pScene );
END_PROPERTY_LIST();

NounTemplate::NounTemplate()
{
	m_nFlags = 0;
	m_nRank = 0;
}

//----------------------------------------------------------------------------

bool NounTemplate::read( const InStream & input )
{
	if (! Resource::read( input ) )
		return false;
	// force the Resource to be loaded
	m_pScene.load();
	return true;
}

//----------------------------------------------------------------------------

Noun * NounTemplate::noun()
{
	if ( m_pScene.valid() && m_pScene->node() && m_pScene->node()->childCount() > 0 )
		return WidgetCast<Noun>( m_pScene->node()->child( 0 ) );

	return NULL;
}

Noun * NounTemplate::spawn()
{
	Noun * pTemplate = noun();
	if ( pTemplate != NULL )
	{
		// cloning automatically generates a new key
		Noun * pCopy = WidgetCast<Noun>( pTemplate->copy() );
		ASSERT( pCopy );

		return( pCopy );
	}

	return( NULL );
}

//----------------------------------------------------------------------------
// EOF


text:
Date

12 January 2016 @ 17:00 GMT / 09:00 PST

|Attendees|
|---------|
|kitsonk|
|dylanks|
|pdfernhout|
|gavinr_|

## Agenda

* *Apologies, none...*

### Status Details

[See Status Table](https://github.com/dojo/meta#status)

## Notes

[Transcript](https://botbot.me/freenode/dojo-meeting/2016-01-26/?msg=58711894&page=1)

* *Dylan* - Trying to wrap up the final 1.11 issues
* *Dylan* - Lots of risks because automated tests are failing
* *Kit* - How does it compare to 1.10
* *Dylan* - No Intern suites for 1.10, but seems to be better than 1.10
* *Kit* - I think Dylan's e-mail was clear on the Dojo 1.11 plan
* *Kit* - dgrid team feeding back on dojo/compose, need to revisit part of the API (see [dojo/compose#22](https://github.com/dojo/compose/issues/22))
* *Kit* - alphas for [dojo/loader](https://www.npmjs.com/package/dojo-loader) and [dojo/core](https://www.npmjs.com/package/dojo-core) are on npm, focusing on trying to get them to beta release quality.
* *Kit* - progress on enhancements being supported with TypeScript team, will make a list for tracking
* *Kit* - AOB?
* *Paul F* - We should look at mithril for vdom
* *Kit* - Yes Paul Buchoun was looking at that in relationship to [dojo/meta#11](https://github.com/dojo/meta/issues/11)


text:
import { Element } from 'slate'

export const input = {
  type: 'heading-large',
  children: [{ text: '' }],
}
export const test = value => Element.isElementType(value, 'paragraph', 'source')

export const output = false


text:
<?php

namespace OAuth\OAuth2\Service;

use OAuth\OAuth2\Token\StdOAuth2Token;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Consumer\CredentialsInterface;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Http\Uri\UriInterface;

class GitHub extends AbstractService
{
    /**
     * Defined scopes, see http://developer.github.com/v3/oauth/ for definitions.
     */

    /**
     * Public read-only access (includes public user profile info, public repo info, and gists)
     */
    const SCOPE_READONLY = '';

    /**
     * Read/write access to profile info only.
     *
     * Includes SCOPE_USER_EMAIL and SCOPE_USER_FOLLOW.
     */
    const SCOPE_USER = 'user';

    /**
     * Read access to a user's email addresses.
     */
    const SCOPE_USER_EMAIL = 'user:email';

    /**
     * Access to follow or unfollow other users.
     */
    const SCOPE_USER_FOLLOW = 'user:follow';

    /**
     * Read/write access to public repos and organizations.
     */
    const SCOPE_PUBLIC_REPO = 'public_repo';

    /**
     * Read/write access to public and private repos and organizations.
     *
     * Includes SCOPE_REPO_STATUS.
     */
    const SCOPE_REPO = 'repo';

    /**
     * Grants access to deployment statuses for public and private repositories.
     * This scope is only necessary to grant other users or services access to deployment statuses,
     * without granting access to the code.
     */
    const SCOPE_REPO_DEPLOYMENT = 'repo_deployment';

    /**
     * Read/write access to public and private repository commit statuses. This scope is only necessary to grant other
     * users or services access to private repository commit statuses without granting access to the code. The repo and
     * public_repo scopes already include access to commit status for private and public repositories, respectively.
     */
    const SCOPE_REPO_STATUS = 'repo:status';

    /**
     * Delete access to adminable repositories.
     */
    const SCOPE_DELETE_REPO = 'delete_repo';

    /**
     * Read access to a user's notifications. repo is accepted too.
     */
    const SCOPE_NOTIFICATIONS = 'notifications';

    /**
     * Write access to gists.
     */
    const SCOPE_GIST = 'gist';

    /**
     * Grants read and ping access to hooks in public or private repositories.
     */
    const SCOPE_HOOKS_READ = 'read:repo_hook';

    /**
     * Grants read, write, and ping access to hooks in public or private repositories.
     */
    const SCOPE_HOOKS_WRITE = 'write:repo_hook';

    /**
     * Grants read, write, ping, and delete access to hooks in public or private repositories.
     */
    const SCOPE_HOOKS_ADMIN = 'admin:repo_hook';

    /**
     * Read-only access to organization, teams, and membership.
     */
    const SCOPE_ORG_READ = 'read:org';

    /**
     * Publicize and unpublicize organization membership.
     */
    const SCOPE_ORG_WRITE = 'write:org';

    /**
     * Fully manage organization, teams, and memberships.
     */
    const SCOPE_ORG_ADMIN = 'admin:org';

    /**
     * List and view details for public keys.
     */
    const SCOPE_PUBLIC_KEY_READ = 'read:public_key';

    /**
     * Create, list, and view details for public keys.
     */
    const SCOPE_PUBLIC_KEY_WRITE = 'write:public_key';

    /**
     * Fully manage public keys.
     */
    const SCOPE_PUBLIC_KEY_ADMIN = 'admin:public_key';

    public function __construct(
        CredentialsInterface $credentials,
        ClientInterface $httpClient,
        TokenStorageInterface $storage,
        $scopes = array(),
        UriInterface $baseApiUri = null
    ) {
        parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);

        if (null === $baseApiUri) {
            $this->baseApiUri = new Uri('https://api.github.com/');
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getAuthorizationEndpoint()
    {
        return new Uri('https://github.com/login/oauth/authorize');
    }

    /**
     * {@inheritdoc}
     */
    public function getAccessTokenEndpoint()
    {
        return new Uri('https://github.com/login/oauth/access_token');
    }

    /**
     * {@inheritdoc}
     */
    protected function getAuthorizationMethod()
    {
        return static::AUTHORIZATION_METHOD_QUERY_STRING;
    }

    /**
     * {@inheritdoc}
     */
    protected function parseAccessTokenResponse($responseBody)
    {
        $data = json_decode($responseBody, true);

        if (null === $data || !is_array($data)) {
            throw new TokenResponseException('Unable to parse response.');
        } elseif (isset($data['error'])) {
            throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
        }

        $token = new StdOAuth2Token();
        $token->setAccessToken($data['access_token']);
        // Github tokens evidently never expire...
        $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
        unset($data['access_token']);

        $token->setExtraParams($data);

        return $token;
    }

    /**
     * Used to configure response type -- we want JSON from github, default is query string format
     *
     * @return array
     */
    protected function getExtraOAuthHeaders()
    {
        return array('Accept' => 'application/json');
    }

    /**
     * Required for GitHub API calls.
     *
     * @return array
     */
    protected function getExtraApiHeaders()
    {
        return array('Accept' => 'application/vnd.github.beta+json');
    }
}


text:
exports.definition = {
	config: {
		columns: {
		    "IdAlumnoAsignatura": "integer",
		    "Alumno": "integer",
		    "Asignatura": "integer",
		    "Nombre": "string"
		},
		adapter: {
			type: "sql",
            collection_name: "VW_Alumno_Asignatura_Asignatura",
            db_file: "/AulaVirtual_v"+ require("Alloy").CFG.databaseversion +".sqlite",
            db_name: "AulaVirtual",
            idAttribute: "IdAlumnoAsignatura",
            remoteBackup:"false"
		}
	},
	extendModel: function(Model) {
		_.extend(Model.prototype, {
			// extended functions and properties go here
		});

		return Model;
	},
	extendCollection: function(Collection) {
		_.extend(Collection.prototype, {
			// extended functions and properties go here
		});

		return Collection;
	}
}


text:
package io.github.lijunguan.sample;

import android.app.Application;

import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;

import io.github.lijunguan.imgselector.utils.KLog;

/**
 * Created by lijunguan on 2016/4/28.
 * emial: lijunguan199210@gmail.com
 * blog: https://lijunguan.github.io
 */
public class App extends Application {

    private RefWatcher mRrefWatcher;

    public RefWatcher getRrefWatcher() {
        return mRrefWatcher;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mRrefWatcher = LeakCanary.install(this);
        KLog.d("Aplication========onCreate=========");
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        mRrefWatcher = LeakCanary.install(this);
        KLog.d("Aplication========onTerminate=========");

    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<!--

-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">

    <corners android:radius="@dimen/ui_widget_corner_radius"/>
    <solid android:color="#1F000000"/>
    <padding
            android:left="@dimen/ui_button_padding_horizontal"
            android:top="@dimen/ui_button_padding_vertical"
            android:right="@dimen/ui_button_padding_horizontal"
            android:bottom="@dimen/ui_button_padding_vertical"/>
</shape>


text:
package com.shocktrade.server.actors

import java.util.Date
import java.util.concurrent.atomic.AtomicInteger

import akka.actor.{Actor, ActorLogging, Props}
import akka.pattern.ask
import akka.util.Timeout
import com.shocktrade.models.quote.StockQuotes
import com.shocktrade.server.actors.YahooCsvQuoteUpdateActor._
import com.shocktrade.server.trading.TradingClock
import com.shocktrade.services.yahoofinance.YFStockQuoteService
import com.shocktrade.util.BSONHelper._
import play.libs.Akka
import reactivemongo.bson.{BSONDateTime, BSONDocument => BS}

import scala.concurrent.ExecutionContext

/**
 * Yahoo! Finance CSV Quote Update Actor
 * @author lawrence.daniels@gmail.com
 */
class YahooCsvQuoteUpdateActor() extends Actor with ActorLogging {
  implicit val ec = context.dispatcher
  private val counter = new AtomicInteger()

  override def receive = {
    case RefreshAllQuotes =>
      if (TradingClock.isTradingActive) {
        log.info("Loading symbols for CSV updates...")
        val mySender = sender()

        counter.set(0)
        var count = 0
        StockQuotes.getSymbolsForCsvUpdate foreach { docs =>
          docs.flatMap(_.getAs[String]("symbol")).sliding(32, 32) foreach { symbols =>
            count += symbols.length
            self ! RefreshQuotes(symbols)
          }
          mySender ! count
        }
      }

    case RefreshQuotes(symbols) =>
      YFStockQuoteService.getQuotesSync(symbols, Parameters) foreach { q =>
        StockQuotes.updateQuote(q.symbol, BS(
          "name" -> q.name,
          "exchange" -> q.exchange,
          "lastTrade" -> q.lastTrade,
          "tradeDate" -> q.tradeDate.map(t => BSONDateTime(t.getTime)).orNull,
          "tradeDateTime" -> q.tradeDateTime.map(t => BSONDateTime(t.getTime)).orNull,
          "tradeTime" -> q.tradeTime,
          "change" -> q.change,
          "changePct" -> q.changePct,
          "prevClose" -> q.prevClose,
          "open" -> q.open,
          "close" -> q.close,
          "high" -> q.high,
          "low" -> q.low,
          "high52Week" -> q.high52Week,
          "low52Week" -> q.low52Week,
          "volume" -> q.volume,
          "marketCap" -> q.marketCap,
          "ask" -> q.ask, "askSize" -> q.askSize,
          "bid" -> q.bid, "bidSize" -> q.bidSize,
          "yfDynLastUpdated" -> new Date(),
          "errorMessage" -> q.errorMessage
        ))

        // log the statistics
        if (counter.incrementAndGet() % 1000 == 0) {
          log.info(s"Processed ${counter.get} quotes")
        }
      }

    case message =>
      log.error(s"Unhandled message: $message (${Option(message).map(_.getClass.getName).orNull}})")
      unhandled(message)
  }

}

/**
 * Yahoo! Finance CSV Quote Update Actor Singleton
 * @author lawrence.daniels@gmail.com
 */
object YahooCsvQuoteUpdateActor {
  private val Parameters = YFStockQuoteService.getParams(
    "symbol", "exchange", "name", "lastTrade", "tradeDate", "tradeTime", "change", "changePct", "prevClose", "open", "close", "high", "low",
    "high52Week", "low52Week", "volume", "marketCap", "errorMessage", "ask", "askSize", "bid", "bidSize")

  private val myActor = Akka.system.actorOf(Props[YahooCsvQuoteUpdateActor], name = "CsvQuote")

  def !(message: Any) = myActor ! message

  def ?(message: Any)(implicit ec: ExecutionContext, timeout: Timeout) = myActor ? message

  case object RefreshAllQuotes

  case class RefreshQuotes(symbols: Seq[String])

}


text:
@interface MoreNavigationViewController ()

@end

@implementation MoreNavigationViewController

@end


text:
var test = require('./util'),
    tape = require('tape');

tape('vg2png generates PNG output', t => {
  const cmd = './bin/vg2png test/resources/bar.vg.json';
  test(t, cmd, 'vg2png-test.png', true);
});

tape('vg2png generates scaled PNG output', t => {
  const cmd = './bin/vg2png --scale 2 test/resources/bar.vg.json';
  test(t, cmd, 'vg2png-test-scaled.png', true);
});


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<title>管理员回复</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="__CSS__/adminStyle.css" rel="stylesheet" type="text/css" />

    管理员回复

用户:{$simpleuser.uname}

留言:{$ucontent}

  {foreach $allReply as $vo}

管理员编号{$vo.adminid}--时间:{$vo.replytime}

回复内容:{$vo.replycontent}

   {/foreach}

   <form action="{:url('adminWritereply')}">

		<input type="hidden" name="uid" value="{$simpleuser.uid}"/>
		<input type="hidden" name="umid" value="{$umid}"/>
	   <textarea class="textarea block" name="replycontent" style="padding:1em;"></textarea>
	   <input type="submit" value="回复 " class="tdBtn" style="margin:8px 0;"/>

   </form>


text:
<?php namespace Seek\Exceptions;

class NotFoundException extends SeekException
{
}


text:
package com.eaw1805.www.client.gui.scroll;

import com.eaw1805.www.client.widgets.ScrollVerticalBarEAW;

public interface ScrollChild {
    public void setScroller(final ScrollVerticalBarEAW scroller, final boolean autoResize);
    public void resizeScrollBar();
}


text:
ActiveRecord::Schema.define(version: 20150914204557) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "arrivals", force: :cascade do |t|
    t.integer "trip_id"
    t.integer "station_id"
  end

  add_index "arrivals", ["station_id"], name: "index_arrivals_on_station_id", using: :btree
  add_index "arrivals", ["trip_id"], name: "index_arrivals_on_trip_id", using: :btree

  create_table "departures", force: :cascade do |t|
    t.integer "trip_id"
    t.integer "station_id"
  end

  add_index "departures", ["station_id"], name: "index_departures_on_station_id", using: :btree
  add_index "departures", ["trip_id"], name: "index_departures_on_trip_id", using: :btree

  create_table "stations", force: :cascade do |t|
    t.integer "cabi_id"
    t.string  "station_name"
    t.decimal "latitude"
    t.decimal "longitude"
  end

  create_table "trips", force: :cascade do |t|
    t.integer  "duration"
    t.datetime "start_date"
    t.datetime "end_date"
  end

  add_foreign_key "arrivals", "stations"
  add_foreign_key "arrivals", "trips"
  add_foreign_key "departures", "stations"
  add_foreign_key "departures", "trips"
end


text:
<?php

namespace Acme\PizzaBundle\Entity;

use Doctrine\ORM\Mapping as ORM,
    Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="pizza")
 */
class Pizza
{
    /**
     * @var integer
     *
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string")
     * @Assert\NotBlank()
     * @Assert\MinLength(5)
     */
    protected $name;

    /**
     * @var float
     *
     * @ORM\Column(type="decimal", precision=5, scale=2)
     * @Assert\NotBlank()
     * @Assert\Min(2)
     */
    protected $price;

    /**
     * Get the id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set the name
     *
     * @param string $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * Get the name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set the price
     *
     * @param float $price
     */
    public function setPrice($price)
    {
        $this->price = $price;
    }

    /**
     * Get the price
     *
     * @return float
     */
    public function getPrice()
    {
        return $this->price;
    }

    /**
     * Set a property
     *
     * @param string $name
     * @param mixed  $value
     *
     * @throws \InvalidArgumentException If the property does not exists
     */
    public function set($name, $value)
    {
        switch ($name) {
            case 'name':
                $this->setName($value);
                break;

            case 'price':
                $this->setPrice($value);
                break;

            case 'id':
                $this->setId($value);
                break;

            default:
                throw new \InvalidArgumentException(sprintf('Generic setter for "%s" is not defined', $name));
        }
    }

    /**
     * Get a property
     *
     * @param string $name
     *
     * @return mixed
     *
     * @throws \InvalidArgumentException If the property does not exists
     */
    public function get($name)
    {
        switch ($name) {
            case 'name':
                return $this->getName($value);

            case 'price':
                return $this->getPrice($value);

            case 'id':
                return $this->getId($value);

            default:
                throw new \InvalidArgumentException(sprintf('Generic getter for "%s" is not defined', $name));
        }
    }

    public function __toString()
    {
        return $this->name . "(". $this->price . ")";
    }
}


text:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    >

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        />

    <View
        android:layout_width="fill_parent"
        android:layout_height="1px"
        android:background="@color/gray"
        />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="@dimen/bottom_bar_height"
        android:gravity="center_vertical"
        android:padding="8dip"
        android:baselineAligned="false">

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical"
            android:paddingRight="8dp"
            >

            <TextView
                android:id="@+id/tv_song_title"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/black"
                android:singleLine="true"
                android:maxLines="1"
                android:ellipsize="end"
                android:text="未选歌曲"
                android:textSize="@dimen/listview_item_title_text_size"
                />

            <TextView
                android:id="@+id/tv_artist"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/gray"
                android:maxLines="1"
                android:ellipsize="end"
                android:text=""
                android:layout_below="@id/tv_song_title"
                />

            <TextView
                android:id="@+id/tv_song_progress"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/gray"
                android:maxLines="1"
                android:ellipsize="end"
                android:text="00:00"
                android:layout_below="@id/tv_artist"
                />

            <TextView
                android:id="@+id/tv_song_duration"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/gray"
                android:maxLines="1"
                android:ellipsize="end"
                android:text="/00:00"
                android:layout_below="@id/tv_artist"
                android:layout_toRightOf="@id/tv_song_progress"
                />
        </RelativeLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            >
            <ImageButton
                android:id="@+id/btn_play_prev_song"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/icon_prev_song_selector"
                android:background="@null"
                android:layout_marginRight="8dp"
                android:contentDescription=""/>

            <ImageButton
                android:id="@+id/btn_play_and_pause"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/icon_play_selector"
                android:background="@null"
                android:layout_marginRight="8dp"
                android:contentDescription=""/>

            <ImageButton
                android:id="@+id/btn_play_next_song"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/icon_next_song_selector"
                android:background="@null"
                android:layout_marginRight="4dp"
                android:contentDescription=""/>

        </LinearLayout>
    </LinearLayout>
</LinearLayout>


text:
using System.Security;
using Xunit;

namespace System.Security.Cryptography.X509Certificates.Tests
{
    public static class ImportTests
    {
        [Fact]
        public static void TestImportNotSupported_X509Certificate()
        {
            using (var c = new X509Certificate())
            {
                VerifyImportNotSupported(c);
            }
        }

        [Fact]
        public static void TestImportNotSupported_X509Certificate2()
        {
            using (var c = new X509Certificate2())
            {
                VerifyImportNotSupported(c);
            }
        }

        private static void VerifyImportNotSupported(X509Certificate c)
        {
            Assert.Throws<PlatformNotSupportedException>(() => c.Import(Array.Empty<byte>()));
            Assert.Throws<PlatformNotSupportedException>(() => c.Import(string.Empty));
            Assert.Throws<PlatformNotSupportedException>(() => c.Import(Array.Empty<byte>(), string.Empty, X509KeyStorageFlags.DefaultKeySet));
            Assert.Throws<PlatformNotSupportedException>(() => c.Import(Array.Empty<byte>(), new SecureString(), X509KeyStorageFlags.DefaultKeySet));
            Assert.Throws<PlatformNotSupportedException>(() => c.Import(string.Empty, string.Empty, X509KeyStorageFlags.DefaultKeySet));
            Assert.Throws<PlatformNotSupportedException>(() => c.Import(string.Empty, new SecureString(), X509KeyStorageFlags.DefaultKeySet));
        }
    }
}


text:
import { mount } from 'avoriaz';
import Notifications from '../../../src/Notifications.vue';
import CssGroup from '../../../src/CssGroup.vue';
import VelocityGroup from '../../../src/VelocityGroup.vue';

describe('Notifications', () => {
  describe('defaults', () => {
    it('has correct default props', () => {
      const wrapper = mount(Notifications);

      expect(wrapper.vm.$props.width).to.eq(300);
      expect(wrapper.vm.$props.reverse).to.eq(false);
      expect(wrapper.vm.$props.position).to.deep.eq(['top', 'right']);
      expect(wrapper.vm.$props.classes).to.eq('vue-notification');
      expect(wrapper.vm.$props.animationType).to.eq('css');
      expect(wrapper.vm.$props.animation.enter).to.exist;
      expect(wrapper.vm.$props.animation.leave).to.exist;
      expect(wrapper.vm.$props.speed).to.eq(300);
      expect(wrapper.vm.$props.duration).to.eq(3000);
      expect(wrapper.vm.$props.delay).to.eq(0);
      expect(wrapper.vm.$props.ignoreDuplicates).to.eq(false);
    });

    it('list is empty', () => {
      const wrapper = mount(Notifications);

      expect(wrapper.data().list).to.deep.eq([]);
    });
  });

  describe('methods', ()=> {
    describe('addItem', () => {
      describe('when no group', () => {
        it('adds item to list', () => {
          const wrapper = mount(Notifications);

          const event = {
            title: 'Title',
            text: 'Text',
            type: 'success',
          };

          const result = wrapper.vm.addItem(event);

          expect(wrapper.data().list.length).to.eq(1);
          expect(wrapper.data().list[0].id).to.exist;
          expect(wrapper.data().list[0].title).to.eq('Title');
          expect(wrapper.data().list[0].text).to.eq('Text');
          expect(wrapper.data().list[0].type).to.eq('success');
          expect(wrapper.data().list[0].state).to.eq(0);
          expect(wrapper.data().list[0].speed).to.eq(300);
          expect(wrapper.data().list[0].length).to.eq(3600);
          expect(wrapper.data().list[0].timer).to.exist;
        });
      });

      describe('when a group is defined and matches event group name', () => {
        it('adds item to list', () => {
          const propsData = {
            group: 'Group',
          };

          const wrapper = mount(Notifications, { propsData });

          const event = {
            group: 'Group',
            title: 'Title',
            text: 'Text',
            type: 'success',
          };

          const result = wrapper.vm.addItem(event);

          expect(wrapper.data().list.length).to.eq(1);
          expect(wrapper.data().list[0].id).to.exist;
          expect(wrapper.data().list[0].title).to.eq('Title');
          expect(wrapper.data().list[0].text).to.eq('Text');
          expect(wrapper.data().list[0].type).to.eq('success');
          expect(wrapper.data().list[0].state).to.eq(0);
          expect(wrapper.data().list[0].speed).to.eq(300);
          expect(wrapper.data().list[0].length).to.eq(3600);
          expect(wrapper.data().list[0].timer).to.exist;
        });
      });

      describe('when a group is defined and does not match event group name', () => {
        it('does not add item to list', () => {
          const propsData = {
            group: 'Does Not Match',
          };

          const wrapper = mount(Notifications, { propsData });

          const event = {
            group: 'Group',
            title: 'Title',
            text: 'Text',
            type: 'success',
          };

          const result = wrapper.vm.addItem(event);

          expect(wrapper.data().list.length).to.eq(0);
        });
      });

      describe('item property overrides', () => {
        it('item length calculated from duration and speed props', () => {
          const duration = 50;
          const speed = 25;
          const expectedLength = duration + 2 * speed;

          const propsData = {
            duration,
            speed,
          };

          const wrapper = mount(Notifications, { propsData });

          const event = {
            group: 'Group',
            title: 'Title',
            text: 'Text',
            type: 'success',
          };

          const result = wrapper.vm.addItem(event);

          expect(wrapper.data().list.length).to.eq(1);
          expect(wrapper.data().list[0].speed).to.eq(speed);
          expect(wrapper.data().list[0].length).to.eq(expectedLength);
        });
      });

      describe('order of inserted items', () => {
        it('by default inserts items in reverse order', () => {
          const wrapper = mount(Notifications);

          const event1 = {
            title: 'First',
          };

          const event2 = {
            title: 'Second',
          };

          wrapper.vm.addItem(event1);
          wrapper.vm.addItem(event2);

          expect(wrapper.data().list.length).to.eq(2);
          expect(wrapper.data().list[0].title).to.eq('Second');
          expect(wrapper.data().list[1].title).to.eq('First');
        });

        it('when position is top and reverse is false, inserts in reverse order', () => {
          const propsData = {
            position: 'top right',
            reverse: false,
          };

          const wrapper = mount(Notifications, { propsData });

          const event1 = {
            title: 'First',
          };

          const event2 = {
            title: 'Second',
          };

          wrapper.vm.addItem(event1);
          wrapper.vm.addItem(event2);

          expect(wrapper.data().list.length).to.eq(2);
          expect(wrapper.data().list[0].title).to.eq('Second');
          expect(wrapper.data().list[1].title).to.eq('First');
        });

        it('when position is top and reverse is true, inserts in sequential order', () => {
          const propsData = {
            position: 'top right',
            reverse: true,
          };

          const wrapper = mount(Notifications, { propsData });

          const event1 = {
            title: 'First',
          };

          const event2 = {
            title: 'Second',
          };

          wrapper.vm.addItem(event1);
          wrapper.vm.addItem(event2);

          expect(wrapper.data().list.length).to.eq(2);
          expect(wrapper.data().list[0].title).to.eq('First');
          expect(wrapper.data().list[1].title).to.eq('Second');
        });

        it('when position is bottom and reverse is false, inserts in sequential order', () => {
          const propsData = {
            position: 'bottom right',
            reverse: false,
          };

          const wrapper = mount(Notifications, { propsData });

          const event1 = {
            title: 'First',
          };

          const event2 = {
            title: 'Second',
          };

          wrapper.vm.addItem(event1);
          wrapper.vm.addItem(event2);

          expect(wrapper.data().list.length).to.eq(2);
          expect(wrapper.data().list[0].title).to.eq('First');
          expect(wrapper.data().list[1].title).to.eq('Second');
        });

        it('when position is bottom and reverse is true, inserts in reverse order', () => {
          const propsData = {
            position: 'bottom right',
            reverse: true,
          };

          const wrapper = mount(Notifications, { propsData });

          const event1 = {
            title: 'First',
          };

          const event2 = {
            title: 'Second',
          };

          wrapper.vm.addItem(event1);
          wrapper.vm.addItem(event2);

          expect(wrapper.data().list.length).to.eq(2);
          expect(wrapper.data().list[0].title).to.eq('Second');
          expect(wrapper.data().list[1].title).to.eq('First');
        });
      });

      describe('auto-destroy of items', () => {
        it('item is destroyed after certain duration', () => {
          const duration = 50;
          const speed = 25;
          const expectedLength = duration + 2 * speed;

          const propsData = {
            duration,
            speed,
          };

          const clock = sinon.useFakeTimers();

          const wrapper = mount(Notifications, { propsData });

          const event = {
            group: 'Group',
            title: 'Title',
            text: 'Text',
            type: 'success',
          };

          const result = wrapper.vm.addItem(event);

          expect(wrapper.data().list.length).to.eq(1);

          clock.tick(expectedLength);

          expect(wrapper.data().list.length).to.eq(0);

          clock.restore();
        });
      });

      describe('when ignoreDuplictes is on', () => {
        const wrapper = mount(Notifications, {
          propsData: {
            ignoreDuplicates: true
          }
        });

        it('adds unique item to list', () => {
          const event = {
            title: 'Title',
            text: 'Text',
            type: 'success',
          };

          const result = wrapper.vm.addItem(event);

          expect(wrapper.data().list.length).to.eq(1);
          expect(wrapper.data().list[0].id).to.exist;
          expect(wrapper.data().list[0].title).to.eq('Title');
          expect(wrapper.data().list[0].text).to.eq('Text');
          expect(wrapper.data().list[0].type).to.eq('success');
          expect(wrapper.data().list[0].state).to.eq(0);
          expect(wrapper.data().list[0].speed).to.eq(300);
          expect(wrapper.data().list[0].length).to.eq(3600);
          expect(wrapper.data().list[0].timer).to.exist;
        });
      });

      it('does not add item with same title and text to list', () => {
        const wrapper = mount(Notifications);

        const event = {
          title: 'Title',
          text: 'Text',
          type: 'success',
        };

        const result = wrapper.vm.addItem(event);

        expect(wrapper.data().list.length).to.eq(1);
        expect(wrapper.data().list[0].id).to.exist;
        expect(wrapper.data().list[0].title).to.eq('Title');
        expect(wrapper.data().list[0].text).to.eq('Text');
        expect(wrapper.data().list[0].type).to.eq('success');
        expect(wrapper.data().list[0].state).to.eq(0);
        expect(wrapper.data().list[0].speed).to.eq(300);
        expect(wrapper.data().list[0].length).to.eq(3600);
        expect(wrapper.data().list[0].timer).to.exist;
      });
    });
  });

  describe('rendering', () => {
    describe('notification wrapper', () => {
      it('adds notification item with correct title and text', (done) => {
        const wrapper = mount(Notifications);

        const event = {
          title: 'Title',
          text: 'Text',
          type: 'success',
        };

        wrapper.vm.addItem(event);

        wrapper.vm.$nextTick(() => {
          const notifications = wrapper.find('.notification-wrapper');

          expect(notifications.length).to.eq(1);

          const title = wrapper.first('.notification-title').text();
          expect(title).to.eq('Title');

          const text = wrapper.first('.notification-content').text();
          expect(text).to.eq('Text');

          done();
        });
      });

      it('adds notification with correct inline styling', (done) => {
        const wrapper = mount(Notifications);

        const event = {
          title: 'Title',
          text: 'Text',
          type: 'success',
        };

        wrapper.vm.addItem(event);

        wrapper.vm.$nextTick(() => {
          const notification = wrapper.first('.notification-wrapper');

          expect(notification).to.exist;
          expect(notification.element.style.transition).to.eq('all 300ms');

          done();
        });
      });

      it('adds the event type as css class body', (done) => {
        const wrapper = mount(Notifications);

        const event = {
          title: 'Title',
          text: 'Text',
          type: 'success',
        };

        wrapper.vm.addItem(event);

        wrapper.vm.$nextTick(() => {
          const notification = wrapper.first('.notification-wrapper > div');

          expect(notification).to.exist;
          expect(notification.element.className).includes('notification')
          expect(notification.element.className).includes('vue-notification')
          expect(notification.element.className).includes('success')

          done();
        });
      });

      it('has correct default body classes', (done) => {
        const wrapper = mount(Notifications);

        const event = {
          title: 'Title',
          text: 'Text',
          type: 'success',
        };

        wrapper.vm.addItem(event);

        wrapper.vm.$nextTick(() => {
          const notification = wrapper.first('.notification-wrapper > div');

          expect(notification).to.exist;
          expect(notification.element.className).includes('vue-notification')

          done();
        });
      });

      it('body classes can be customized via prop', (done) => {
        const propsData = {
          classes: 'pizza taco-sushi'
        };

        const wrapper = mount(Notifications, { propsData });

        const event = {
          title: 'Title',
          text: 'Text',
          type: 'success',
        };

        wrapper.vm.addItem(event);

        wrapper.vm.$nextTick(() => {
          const notification = wrapper.first('.notification-wrapper > div');

          expect(notification).to.exist;
          expect(notification.element.className).includes('pizza');
          expect(notification.element.className).includes('taco-sushi');

          done();
        });
      });
    });

    describe('transition wrapper', () => {
      it('default is css transition', () => {
        const wrapper = mount(Notifications);

        const event = {
          title: 'Title',
          text: 'Text',
          type: 'success',
        };

        expect(wrapper.find(CssGroup).length).to.eq(1);
        expect(wrapper.find(VelocityGroup).length).to.eq(0);
      });

      it('uses using velocity transition when enabled via prop', () => {
        const propsData = {
          animationType: 'velocity',
        };

        const wrapper = mount(Notifications, { propsData });

        const event = {
          title: 'Title',
          text: 'Text',
          type: 'success',
        };

        expect(wrapper.find(CssGroup).length).to.eq(0);
        expect(wrapper.find(VelocityGroup).length).to.eq(1);
      });
    });
  });

  describe('with velocity animation library', () => {
    const velocity = sinon.stub();
    Notifications.configure({ velocity });

    it('applies no additional inline styling to notification', (done) => {
      const propsData = {
        animationType: 'velocity',
      };

      const wrapper = mount(Notifications, { propsData });

      const event = {
        title: 'Title',
        text: 'Text',
        type: 'success',
      };

      wrapper.vm.addItem(event);

      wrapper.vm.$nextTick(() => {
        const notification = wrapper.first('.notification-wrapper');

        expect(notification).to.exist;
        expect(notification.element.style.transition).to.eq('');

        done();
      });
    });

    it('adds item to list', () => {
      const propsData = {
        animationType: 'velocity',
      };

      const wrapper = mount(Notifications, { propsData });

      const event = {
        title: 'Title',
        text: 'Text',
        type: 'success',
      };

      const result = wrapper.vm.addItem(event);

      expect(wrapper.data().list.length).to.eq(1);
      expect(wrapper.data().list[0].id).to.exist;
      expect(wrapper.data().list[0].title).to.eq('Title');
      expect(wrapper.data().list[0].text).to.eq('Text');
      expect(wrapper.data().list[0].type).to.eq('success');
      expect(wrapper.data().list[0].state).to.eq(0);
      expect(wrapper.data().list[0].speed).to.eq(300);
      expect(wrapper.data().list[0].length).to.eq(3600);
      expect(wrapper.data().list[0].timer).to.exist;
    });

    it('calls velocity service for animations', () => {
      const duration = 50;
      const speed = 25;
      const expectedLength = duration + 2 * speed;

      const propsData = {
        animationType: 'velocity',
        duration,
        speed,
      };

      const wrapper = mount(Notifications, { propsData });

      const event = {
        group: 'Group',
        title: 'Title',
        text: 'Text',
        type: 'success',
      };

      const result = wrapper.vm.addItem(event);

      expect(velocity.called).to.eq(true);
    });
  });
});