<commit_before>// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "TestFixtures/SimpleObject.hpp"
#include "HasForwardOnlyType.hpp"
#include <autowiring/autowiring.h>
#include <autowiring/ContextMember.h>
#include THREAD_HEADER

class PostConstructTest:
  public testing::Test
{};

using namespace std;

// Two classes to make up the cyclic dependency:
class A:
  public ContextMember
{
public:
  int m_value = 2;

  int GetValue(void) const {return m_value;}
};

// For testing NotifyWhenAutowired with heirarchies
class Interface
{
public:
  virtual int GetValue() = 0;
};

class Implementation :
  public ContextMember,
  public Interface
{
public:
  virtual int GetValue() override { return 2; }
};

class Naive:
  public ContextMember
{
public:
  Naive(void) {
    if(!m_a)
      throw exception();
  }

  Autowired<A> m_a;
};

class Smarter:
  public ContextMember
{
public:
  Smarter(void)
  {
    m_a.NotifyWhenAutowired([this] () {
      this->value = m_a->GetValue();
    });
  }

  int value = 1;
  Autowired<A> m_a;
};

class SmarterInterface
{
public:
  SmarterInterface(void)
  {
    m_interface.NotifyWhenAutowired([this] () {
      this->value = m_interface->GetValue();
    });
  }

  int value = 1;
  Autowired<Interface> m_interface;
};

class FailedAutowiringInstance {
};

TEST_F(PostConstructTest, VerifyNaiveBehavior) {
  // Create a context and add just the naive class, to verify the problematic behavior:
  AutoCurrentContext ctxt;
  ASSERT_THROW(ctxt->Inject<Naive>(), std::exception) << "Naive class didn't throw an exception as expected";
}

TEST_F(PostConstructTest, VerifySmartBehavior) {
  AutoCurrentContext ctxt;

  // Add the smart class, which has a member that autowired type A
  ctxt->Inject<Smarter>();

  // Check that we can get the item we just injected
  Autowired<Smarter> smarter;
  ASSERT_TRUE(smarter.IsAutowired()) << "Slot was not satisfied as expected";
  ASSERT_EQ(1, smarter->value) << "Unexpected initial value of SmarterA instance";

  // Now inject A, and see if delayed autowiring has taken place:
  ctxt->Inject<A>();
  ASSERT_FALSE(!smarter->m_a.get()) << "Autowired member was not wired as expected";

  // Verify the value was updated by the notification routine
  ASSERT_EQ(2, smarter->value) << "Post-construction notification routine wasn't invoked as expected";
}

TEST_F(PostConstructTest, VerifySmartBehaviorWithInheritance) {
  AutoCurrentContext ctxt;

  // Add the smart classes, which should succeed
  ctxt->Inject<SmarterInterface>();

  //Initially value should be one, which is the default
  Autowired<SmarterInterface> smarterI;
  ASSERT_EQ(1, smarterI->value) << "Unexpected initial value of SmarterA instance";

  //Now add Implementation and check the wiring
  ctxt->Inject<Implementation>();
  ASSERT_FALSE(!smarterI->m_interface.get()) << "Autowired subclass was not wired as expected";

  ASSERT_EQ(2, smarterI->value) << "Post-construction notification routine wasn't invoked on subclass";
}

TEST_F(PostConstructTest, VerifyLoopingFailedAutowiring) {
  for(size_t i = 10; i--;) {
    Autowired<FailedAutowiringInstance> ignored;
    ASSERT_FALSE(ignored.IsAutowired()) << "Successfully autowired an instance that should not have been autowirable";
  }
}

TEST_F(PostConstructTest, VerifyTrivialNotifyWhenAutowired) {
  // Inject a type first:
  AutoRequired<SimpleObject>();

  // Now autowire, and add a registration:
  bool called = false;
  Autowired<SimpleObject> so;
  so.NotifyWhenAutowired([&called] { called = true; });

  ASSERT_TRUE(called) << "An autowiring notification was not invoked on an already-satisfied field as expected";
}

TEST_F(PostConstructTest, MultiNotifyWhenAutowired) {
  // Add multiple notifications on the same space:
  int field = 0;
  Autowired<SimpleObject> so;
  for(size_t i = 10; i--;)
    so.NotifyWhenAutowired([&field] { field++; });

  // Inject the type to trigger the autowiring
  AutoRequired<SimpleObject>();

  // Verify that the notification got hit ten times:
  ASSERT_EQ(10, field) << "Autowiring lambdas did not run the expected number of times";
}

TEST_F(PostConstructTest, NotificationTeardownRace) {
  std::shared_ptr<CoreContext> pContext;

  auto quit = false;
  auto shouldQuit = MakeAtExit([&quit] { quit = true; });
  std::atomic<size_t> counter{0};

  // This thread sets up the race pathology:
  std::thread t([&] {
    while(!quit) {<commit_msg>Add tests for failure of NotifyWhenAutowired when dealing with inheritance.<commit_after>// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "TestFixtures/SimpleObject.hpp"
#include "HasForwardOnlyType.hpp"
#include <autowiring/autowiring.h>
#include <autowiring/ContextMember.h>
#include THREAD_HEADER

class PostConstructTest:
  public testing::Test
{};

using namespace std;

// Two classes to make up the cyclic dependency:
class A:
  public ContextMember
{
public:
  int m_value = 2;

  int GetValue(void) const {return m_value;}
};

// For testing NotifyWhenAutowired with heirarchies
class Interface
{
public:
  virtual int GetValue() = 0;
};

class Implementation :
  public ContextMember,
  public Interface
{
public:
  virtual int GetValue() override { return 2; }
};

class Naive:
  public ContextMember
{
public:
  Naive(void) {
    if(!m_a)
      throw exception();
  }

  Autowired<A> m_a;
};

class Smarter:
  public ContextMember
{
public:
  Smarter(void)
  {
    m_a.NotifyWhenAutowired([this] () {
      this->value = m_a->GetValue();
    });
  }

  int value = 1;
  Autowired<A> m_a;
};

class SmarterInterface
{
public:
  SmarterInterface(void)
  {
    m_interface.NotifyWhenAutowired([this] () {
      this->value = m_interface->GetValue();
    });
  }

  int value = 1;
  Autowired<Interface> m_interface;
};

class FailedAutowiringInstance {
};

TEST_F(PostConstructTest, VerifyNaiveBehavior) {
  // Create a context and add just the naive class, to verify the problematic behavior:
  AutoCurrentContext ctxt;
  ASSERT_THROW(ctxt->Inject<Naive>(), std::exception) << "Naive class didn't throw an exception as expected";
}

TEST_F(PostConstructTest, VerifySmartBehavior) {
  AutoCurrentContext ctxt;

  // Add the smart class, which has a member that autowired type A
  ctxt->Inject<Smarter>();

  // Check that we can get the item we just injected
  Autowired<Smarter> smarter;
  ASSERT_TRUE(smarter.IsAutowired()) << "Slot was not satisfied as expected";
  ASSERT_EQ(1, smarter->value) << "Unexpected initial value of SmarterA instance";

  // Now inject A, and see if delayed autowiring has taken place:
  ctxt->Inject<A>();
  ASSERT_FALSE(!smarter->m_a.get()) << "Autowired member was not wired as expected";

  // Verify the value was updated by the notification routine
  ASSERT_EQ(2, smarter->value) << "Post-construction notification routine wasn't invoked as expected";
}

TEST_F(PostConstructTest, VerifySmartBehaviorWithInheritance) {
  AutoCurrentContext ctxt;

  // Add the smart classes, which should succeed
  ctxt->Inject<SmarterInterface>();

  //Initially value should be one, which is the default
  Autowired<SmarterInterface> smarterI;
  ASSERT_EQ(1, smarterI->value) << "Unexpected initial value of SmarterA instance";

  //Now add Implementation and check the wiring
  ctxt->Inject<Implementation>();
  ASSERT_FALSE(!smarterI->m_interface.get()) << "Autowired subclass was not wired as expected";

  ASSERT_EQ(2, smarterI->value) << "Post-construction notification routine wasn't invoked on subclass";
}

TEST_F(PostConstructTest, VerifyLoopingFailedAutowiring) {
  for(size_t i = 10; i--;) {
    Autowired<FailedAutowiringInstance> ignored;
    ASSERT_FALSE(ignored.IsAutowired()) << "Successfully autowired an instance that should not have been autowirable";
  }
}

TEST_F(PostConstructTest, VerifyTrivialNotifyWhenAutowired) {
  // Inject a type first:
  AutoRequired<SimpleObject>();

  // Now autowire, and add a registration:
  bool called = false;
  Autowired<SimpleObject> so;
  so.NotifyWhenAutowired([&called] { called = true; });

  ASSERT_TRUE(called) << "An autowiring notification was not invoked on an already-satisfied field as expected";
}

TEST_F(PostConstructTest, DelayedNotifyWhenAutowired) {
  // Autorequire, and add a registration:
  bool called = false;
  Autowired<SimpleObject> so;
  so.NotifyWhenAutowired([&called] { called = true; });

  // Inject a type after:
  AutoRequired<SimpleObject>();
  ASSERT_TRUE(called) << "An autowiring notification was not invoked on an already-satisfied field as expected";
}

struct Interface2 : ContextMember {};
struct Implementation2 : Interface2 {
};

TEST_F(PostConstructTest, DeriveNotifyWhenAutowired) {

  // Autorequire, and add a registration:
  bool called = false;
  Autowired<Interface2> interface;
  interface.NotifyWhenAutowired([&called] { called = true; });

  // Inject a type after:
  AutoRequired<Implementation2>();
  ASSERT_TRUE(called) << "An autowiring notification was not invoked on an already-satisfied field as expected";
}

struct Interface3 : ContextMember {};
struct Implementation3 : Interface3 {
};

TEST_F(PostConstructTest, InjectNotifyWhenAutowired) {
  // Autorequire, and add a registration:
  bool called = false;
  Autowired<Interface3> interface;
  interface.NotifyWhenAutowired([&called] { called = true; });

  // Inject a type after:
  AutoCurrentContext()->Inject<Implementation3>();
  ASSERT_TRUE(called) << "An autowiring notification was not invoked on an already-satisfied field as expected";
}

TEST_F(PostConstructTest, MultiNotifyWhenAutowired) {
  // Add multiple notifications on the same space:
  int field = 0;
  Autowired<SimpleObject> so;
  for(size_t i = 10; i--;)
    so.NotifyWhenAutowired([&field] { field++; });

  // Inject the type to trigger the autowiring
  AutoRequired<SimpleObject>();

  // Verify that the notification got hit ten times:
  ASSERT_EQ(10, field) << "Autowiring lambdas did not run the expected number of times";
}


TEST_F(PostConstructTest, NotificationTeardownRace) {
  std::shared_ptr<CoreContext> pContext;

  auto quit = false;
  auto shouldQuit = MakeAtExit([&quit] { quit = true; });
  std::atomic<size_t> counter{0};

  // This thread sets up the race pathology:
  std::thread t([&] {
    while(!quit) {
{'fraction_non_alphanumeric': 0.11028982688192959, 'fraction_numerical': 0.00583544057576347, 'mean_word_length': 4.612991266375546, 'pattern_counts': {'":': 0, '<': 97, '<?xml version=': 0, '>': 78, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1776373', 'n_tokens_mistral': 3259, 'n_tokens_neox': 3183, 'n_words': 930}