<commit_before>// ball_scopedattribute.t.cpp                                         -*-C++-*-

// ----------------------------------------------------------------------------
//                                   NOTICE
//
// This component is not up to date with current BDE coding standards, and
// should not be used as an example for new development.
// ----------------------------------------------------------------------------

#include <ball_scopedattribute.h>

#include <ball_categorymanager.h>
#include <ball_attributecontext.h>
#include <ball_rule.h>
#include <ball_predicate.h>
#include <ball_severity.h>
#include <ball_thresholdaggregate.h>

#include <bdlf_bind.h>
#include <bdlf_placeholder.h>

#include <bslim_testutil.h>

#include <bslma_testallocator.h>
#include <bslma_defaultallocatorguard.h>

#include <bsls_types.h>

#include <bsltf_templatetestfacility.h>
#include <bsltf_simpletesttype.h>

#include <bsl_cstdlib.h>
#include <bsl_iostream.h>
#include <bsl_sstream.h>
#include <bsl_vector.h>

using namespace BloombergLP;

using bsl::cout;
using bsl::cerr;
using bsl::endl;
using bsl::flush;

// ============================================================================
//                     STANDARD BDE ASSERT TEST FUNCTION
// ----------------------------------------------------------------------------

namespace {

int testStatus = 0;

void aSsErT(bool condition, const char *message, int line)
{
    if (condition) {
        cout << "Error " __FILE__ "(" << line << "): " << message
             << "    (failed)" << endl;

        if (0 <= testStatus && testStatus <= 100) {
            ++testStatus;
        }
    }
}

}  // close unnamed namespace

// ============================================================================
//               STANDARD BDE TEST DRIVER MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT       BSLIM_TESTUTIL_ASSERT
#define ASSERTV      BSLIM_TESTUTIL_ASSERTV

#define LOOP_ASSERT  BSLIM_TESTUTIL_LOOP_ASSERT
#define LOOP0_ASSERT BSLIM_TESTUTIL_LOOP0_ASSERT
#define LOOP1_ASSERT BSLIM_TESTUTIL_LOOP1_ASSERT
#define LOOP2_ASSERT BSLIM_TESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLIM_TESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLIM_TESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLIM_TESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLIM_TESTUTIL_LOOP6_ASSERT

#define Q            BSLIM_TESTUTIL_Q   // Quote identifier literally.
#define P            BSLIM_TESTUTIL_P   // Print identifier and value.
#define P_           BSLIM_TESTUTIL_P_  // P(X) without '\n'.
#define T_           BSLIM_TESTUTIL_T_  // Print a tab (w/o newline).
#define L_           BSLIM_TESTUTIL_L_  // current Line number

// ============================================================================
//                  NEGATIVE-TEST MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR)
#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR)
#define ASSERT_PASS(EXPR)      BSLS_ASSERTTEST_ASSERT_PASS(EXPR)
#define ASSERT_FAIL(EXPR)      BSLS_ASSERTTEST_ASSERT_FAIL(EXPR)
#define ASSERT_OPT_PASS(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR)
#define ASSERT_OPT_FAIL(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR)


//=============================================================================
//          GLOBAL TYPEDEFS/CONSTANTS/VARIABLES/FUNCTIONS FOR TESTING
//-----------------------------------------------------------------------------
typedef ball::ScopedAttribute           Obj;
typedef ball::ScopedAttribute_Container Obj_Container;

void testVisitor(bsl::vector<ball::Attribute>  *result,
                 const ball::Attribute&         attribute)
    // Append the value of the specified 'attribute' to the specified 'result'.
{
    result->push_back(attribute);
}

template <class TYPE>
struct TestCase5 {
    template <class VARIANT_TYPE>
    static void testIntegralType()
    {
        TYPE            value(42);
        Obj             mX("name", value);
        ball::Attribute attribute("name", VARIANT_TYPE(42));

        ASSERTV(true == ball::AttributeContext::getContext()->hasAttribute(
                                                                   attribute));
    }

    static void testPointerType()
    {
        TYPE             value;
        Obj              mX("name", &value);
        ball::Attribute  attribute("name", &value);

        ASSERTV(true == ball::AttributeContext::getContext()->hasAttribute(
                                                                   attribute));
    }
};

//=============================================================================
//                               MAIN PROGRAM
//-----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    int test = argc > 1 ? bsl::atoi(argv[1]) : 0;
    int verbose = argc > 2;
    int veryVerbose = argc > 3;
    int veryVeryVerbose = argc > 4;
    int veryVeryVeryVerbose = argc > 5;

    (void) veryVerbose;
    (void) veryVeryVerbose;

    cout << "TEST " << __FILE__ << " CASE " << test << endl;

    bslma::TestAllocator         da("da", veryVeryVeryVerbose);
    bslma::DefaultAllocatorGuard guard(&da);

    switch (test) { case 0:  // Zero is always the leading case.
      case 5: {
        if (verbose) cout << "\nTESTING ATTRIBUTE CREATION"
                          << "\n--------------------------" << endl;

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                   testIntegralType<int>,
                                                   char,
                                                   unsigned char,
                                                   short,
                                                   short int,
                                                   signed short,
                                                   signed short int,
                                                   unsigned short,
                                                   unsigned short int,
                                                   int,
                                                   signed,
                                                   signed int);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                testIntegralType<unsigned int>,
                                                unsigned int);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                testIntegralType<long>,
                                                long);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                testIntegralType<unsigned long>,
                                                unsigned long);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                   testIntegralType<long long>,
                                                   long long,
                                                   long long int,
                                                   signed long long,
                                                   signed long long int,
                                                   bsls::Types::Int64);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                          testIntegralType<unsigned long long>,
                                          unsigned long long,
                                          unsigned long long int,
                                          bsls::Types::Uint64
                                          );

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                   testPointerType,
                                                   char,
                                                   bsltf::SimpleTestType
                                                   );
      } break;
      case 4: {
        // ------------------------------------------------------------------
        // TESTING ATTRIBUTE CONTEXT VISITATION
        //
        // Concerns:
        //: 1 'ball::ScopedAttribute' adds an attribute to the local thread's
        //:    'ball::AttributeContext'.
        //:
        //: 2 Calling local thread's
        //:   'ball::AttributeContext::visitAttributes()' visits all attributes
        //:   in the current scope.
        //
        // Plan:
        //: 1 Create a set of scoped attributes and verify that they can be
        //:   collected by visiting attribute context.
        //
        // Testing
        //   ATTRIBUTE CONTEXT VISITATION
        // ------------------------------------------------------------------

        if (verbose) cout << "\nTESTING ATTRIBUTE CONTEXT VISITATION"
                          << "\n------------------------------------" << endl;

        {
            bsl::vector<ball::Attribute> result;<commit_msg>Fix SA test case for char* (#3391)<commit_after>// ball_scopedattribute.t.cpp                                         -*-C++-*-

// ----------------------------------------------------------------------------
//                                   NOTICE
//
// This component is not up to date with current BDE coding standards, and
// should not be used as an example for new development.
// ----------------------------------------------------------------------------

#include <ball_scopedattribute.h>

#include <ball_categorymanager.h>
#include <ball_attributecontext.h>
#include <ball_rule.h>
#include <ball_predicate.h>
#include <ball_severity.h>
#include <ball_thresholdaggregate.h>

#include <bdlf_bind.h>
#include <bdlf_placeholder.h>

#include <bslim_testutil.h>

#include <bslma_testallocator.h>
#include <bslma_defaultallocatorguard.h>

#include <bsls_nameof.h>
#include <bsls_types.h>

#include <bsltf_templatetestfacility.h>
#include <bsltf_simpletesttype.h>

#include <bsl_cstdlib.h>
#include <bsl_iostream.h>
#include <bsl_sstream.h>
#include <bsl_vector.h>

using namespace BloombergLP;

using bsl::cout;
using bsl::cerr;
using bsl::endl;
using bsl::flush;

// ============================================================================
//                     STANDARD BDE ASSERT TEST FUNCTION
// ----------------------------------------------------------------------------

namespace {

int testStatus = 0;

void aSsErT(bool condition, const char *message, int line)
{
    if (condition) {
        cout << "Error " __FILE__ "(" << line << "): " << message
             << "    (failed)" << endl;

        if (0 <= testStatus && testStatus <= 100) {
            ++testStatus;
        }
    }
}

}  // close unnamed namespace

// ============================================================================
//               STANDARD BDE TEST DRIVER MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT       BSLIM_TESTUTIL_ASSERT
#define ASSERTV      BSLIM_TESTUTIL_ASSERTV

#define LOOP_ASSERT  BSLIM_TESTUTIL_LOOP_ASSERT
#define LOOP0_ASSERT BSLIM_TESTUTIL_LOOP0_ASSERT
#define LOOP1_ASSERT BSLIM_TESTUTIL_LOOP1_ASSERT
#define LOOP2_ASSERT BSLIM_TESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLIM_TESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLIM_TESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLIM_TESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLIM_TESTUTIL_LOOP6_ASSERT

#define Q            BSLIM_TESTUTIL_Q   // Quote identifier literally.
#define P            BSLIM_TESTUTIL_P   // Print identifier and value.
#define P_           BSLIM_TESTUTIL_P_  // P(X) without '\n'.
#define T_           BSLIM_TESTUTIL_T_  // Print a tab (w/o newline).
#define L_           BSLIM_TESTUTIL_L_  // current Line number

// ============================================================================
//                  NEGATIVE-TEST MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR)
#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR)
#define ASSERT_PASS(EXPR)      BSLS_ASSERTTEST_ASSERT_PASS(EXPR)
#define ASSERT_FAIL(EXPR)      BSLS_ASSERTTEST_ASSERT_FAIL(EXPR)
#define ASSERT_OPT_PASS(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR)
#define ASSERT_OPT_FAIL(EXPR)  BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR)


//=============================================================================
//          GLOBAL TYPEDEFS/CONSTANTS/VARIABLES/FUNCTIONS FOR TESTING
//-----------------------------------------------------------------------------
typedef ball::ScopedAttribute           Obj;
typedef ball::ScopedAttribute_Container Obj_Container;

void testVisitor(bsl::vector<ball::Attribute>  *result,
                 const ball::Attribute&         attribute)
    // Append the value of the specified 'attribute' to the specified 'result'.
{
    result->push_back(attribute);
}

template <class TYPE>
struct TestCase5 {
    template <class VARIANT_TYPE>
    static void testIntegralType()
    {
        TYPE            value(42);
        Obj             mX("name", value);
        ball::Attribute attribute("name", VARIANT_TYPE(42));

        ASSERTV(true == ball::AttributeContext::getContext()->hasAttribute(
                                                                   attribute));
    }

    static void testPointerType()
    {
        TYPE             value;
        Obj              mX("name", &value);
        ball::Attribute  attribute("name", &value);

        ASSERTV(true == ball::AttributeContext::getContext()->hasAttribute(
                                                                   attribute));
    }
};

//=============================================================================
//                               MAIN PROGRAM
//-----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    int test = argc > 1 ? bsl::atoi(argv[1]) : 0;
    int verbose = argc > 2;
    int veryVerbose = argc > 3;
    int veryVeryVerbose = argc > 4;
    int veryVeryVeryVerbose = argc > 5;

    (void) veryVerbose;
    (void) veryVeryVerbose;

    cout << "TEST " << __FILE__ << " CASE " << test << endl;

    bslma::TestAllocator         da("da", veryVeryVeryVerbose);
    bslma::DefaultAllocatorGuard guard(&da);

    switch (test) { case 0:  // Zero is always the leading case.
      case 5: {
        if (verbose) cout << "\nTESTING ATTRIBUTE CREATION"
                          << "\n--------------------------" << endl;

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                   testIntegralType<int>,
                                                   char,
                                                   unsigned char,
                                                   short,
                                                   short int,
                                                   signed short,
                                                   signed short int,
                                                   unsigned short,
                                                   unsigned short int,
                                                   int,
                                                   signed,
                                                   signed int);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                testIntegralType<unsigned int>,
                                                unsigned int);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                testIntegralType<long>,
                                                long);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                testIntegralType<unsigned long>,
                                                unsigned long);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                   testIntegralType<long long>,
                                                   long long,
                                                   long long int,
                                                   signed long long,
                                                   signed long long int,
                                                   bsls::Types::Int64);

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                          testIntegralType<unsigned long long>,
                                          unsigned long long,
                                          unsigned long long int,
                                          bsls::Types::Uint64
                                          );

          BSLTF_TEMPLATETESTFACILITY_RUN_EACH_TYPE(TestCase5,
                                                   testPointerType,
                                                   bsltf::SimpleTestType
                                                   );

          // Testing const char* separately
          {
              const char      *value = "Hello";
              Obj              mX("name", value);
              ball::Attribute  attribute("name", value);

              ASSERTV(true ==
                      ball::AttributeContext::getContext()->hasAttribute(
                          attribute));
          }

      } break;
      case 4: {
        // ------------------------------------------------------------------
        // TESTING ATTRIBUTE CONTEXT VISITATION
        //
        // Concerns:
        //: 1 'ball::ScopedAttribute' adds an attribute to the local thread's
        //:    'ball::AttributeContext'.
        //:
        //: 2 Calling local thread's
        //:   'ball::AttributeContext::visitAttributes()' visits all attributes
        //:   in the current scope.
        //
        // Plan:
        //: 1 Create a set of scoped attributes and verify that they can be
        //:   collected by visiting attribute context.
        //
        // Testing
        //   ATTRIBUTE CONTEXT VISITATION
        // ------------------------------------------------------------------

        if (verbose) cout << "\nTESTING ATTRIBUTE CONTEXT VISITATION"
                          << "\n------------------------------------" << endl;

        {
            bsl::vector<ball::Attribute> result;
{'fraction_non_alphanumeric': 0.19071612349914235, 'fraction_numerical': 0.005360205831903945, 'mean_word_length': 1.2213358733182522, 'pattern_counts': {'":': 0, '<': 134, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 142, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '357907', 'n_tokens_mistral': 4463, 'n_tokens_neox': 4278, 'n_words': 943}