<commit_before>/****** Run RDataFrame tests both with and without IMT enabled *******/
#include <gtest/gtest.h>
#include <ROOT/RDataFrame.hxx>
#include <ROOT/TSeq.hxx>
#include <TFile.h>
#include <TGraph.h>
#include <TInterpreter.h>
#include <TRandom.h>
#include <TROOT.h>
#include <TSystem.h>
#include <TTree.h>

#include <algorithm> // std::sort
#include <chrono>
#include <thread>
#include <set>
#include <random>

using namespace ROOT;
using namespace ROOT::RDF;
using namespace ROOT::VecOps;

// Fixture for all tests in this file. If parameter is true, run with implicit MT, else run sequentially
class RDFSimpleTests : public ::testing::TestWithParam<bool> {
protected:
   RDFSimpleTests() : NSLOTS(GetParam() ? 4u : 1u)
   {
      if (GetParam())
         ROOT::EnableImplicitMT(NSLOTS);
   }
   ~RDFSimpleTests()
   {
      if (GetParam())
         ROOT::DisableImplicitMT();
   }
   const unsigned int NSLOTS;
};

// Create file `filename` containing a test tree `treeName` with `nevents` events
// TODO: create just one file at the beginning of the test execution, delete the file at test exit
void FillTree(const char *filename, const char *treeName, int nevents = 0)
{
   TFile f(filename, "RECREATE");
   TTree t(treeName, treeName);
   t.SetAutoFlush(1); // yes, one event per cluster: to make MT more meaningful
   double b1;
   int b2;
   double b3[2];
   unsigned int n;
   int b4[2] = {21, 42};
   t.Branch("b1", &b1);
   t.Branch("b2", &b2);
   t.Branch("b3", b3, "b3[2]/D");
   t.Branch("n", &n);
   t.Branch("b4", b4, "b4[n]/I");
   for (int i = 0; i < nevents; ++i) {
      b1 = i;
      b2 = i * i;
      b3[0] = b1;
      b3[1] = -b1;
      n = i % 2 + 1;
      t.Fill();
   }
   t.Write();
   f.Close();
}

TEST_P(RDFSimpleTests, CreateEmpty)
{
   RDataFrame tdf(10);
   auto c = tdf.Count();
   EXPECT_EQ(10U, *c);
}

TEST_P(RDFSimpleTests, CreateZeroEntries)
{
   RDataFrame tdf(0);
   auto c = tdf.Count();
   EXPECT_EQ(0U, *c);
}

TEST_P(RDFSimpleTests, CreateZeroEntriesWithBranches)
{
   auto filename = "dataframe_simple_0.root";
   auto treename = "t";
   // create input file (at most once per execution of the parametrized gtest)
   static bool hasFile = false;
   if (!hasFile) {
      FillTree(filename, treename);
      hasFile = true;
   }
   RDataFrame tdf(treename, filename);
   auto c = tdf.Count();
   auto m = tdf.Mean("b1");
   EXPECT_EQ(0U, *c);
   EXPECT_EQ(0., *m);
}

TEST_P(RDFSimpleTests, BuildWithTDirectory)
{
   auto filename = "dataframe_simple_1.root";
   auto treename = "t";
   // create input file (at most once per execution of the parametrized gtest)
   static bool hasFile = false;
   if (!hasFile) {
      FillTree(filename, treename, 50);
      hasFile = true;
   }
   TFile f(filename);
   RDataFrame tdf(treename, &f);
   auto c = tdf.Count();
   EXPECT_EQ(50U, *c);
}

// Jitting of column types
TEST_P(RDFSimpleTests, TypeGuessing)
{
   auto filename = "dataframe_simple_2.root";
   auto treename = "t";
   // create input file (at most once per execution of the parametrized gtest)
   static bool hasFile = false;
   if (!hasFile) {
      FillTree(filename, treename, 50);
      hasFile = true;
   }
   RDataFrame tdf(treename, filename, {"b1"});
   auto hcompiled = tdf.Histo1D<double>();
   auto hjitted = tdf.Histo1D();
   EXPECT_EQ(50, hcompiled->GetEntries());
   EXPECT_EQ(50, hjitted->GetEntries());
   EXPECT_DOUBLE_EQ(hcompiled->GetMean(), hjitted->GetMean());
}

// Define

TEST_P(RDFSimpleTests, Define_lambda)
{
   RDataFrame tdf(10);
   auto d = tdf.Define("i", []() { return 1; });
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

int DefineFunction()
{
   return 1;
}

TEST_P(RDFSimpleTests, Define_function)
{
   RDataFrame tdf(10);
   auto d = tdf.Define("i", DefineFunction);
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

struct DefineStruct {
   int operator()() { return 1; }
};

TEST_P(RDFSimpleTests, Define_functor)
{
   RDataFrame tdf(10);
   DefineStruct def;
   auto d = tdf.Define("i", def);
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST_P(RDFSimpleTests, Define_jitted)
{
   RDataFrame tdf(10);
   auto d = tdf.Define("i", "1");
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

struct RFoo {};

TEST_P(RDFSimpleTests, Define_jitted_type_unknown_to_interpreter)
{
   RDataFrame tdf(10);
   auto d = tdf.Define("foo", [](){return RFoo();});

   // We check that the if nothing is done with RFoo in jitted strings
   // everything works fine
   EXPECT_EQ(10U, *d.Count());
}
<commit_msg>[DF] Add test for Define'd variable of template type<commit_after>/****** Run RDataFrame tests both with and without IMT enabled *******/
#include <gtest/gtest.h>
#include <ROOT/RDataFrame.hxx>
#include <ROOT/TSeq.hxx>
#include <TFile.h>
#include <TGraph.h>
#include <TInterpreter.h>
#include <TRandom.h>
#include <TROOT.h>
#include <TSystem.h>
#include <TTree.h>

#include <algorithm> // std::sort
#include <array>
#include <chrono>
#include <thread>
#include <set>
#include <random>

using namespace ROOT;
using namespace ROOT::RDF;
using namespace ROOT::VecOps;

// Fixture for all tests in this file. If parameter is true, run with implicit MT, else run sequentially
class RDFSimpleTests : public ::testing::TestWithParam<bool> {
protected:
   RDFSimpleTests() : NSLOTS(GetParam() ? 4u : 1u)
   {
      if (GetParam())
         ROOT::EnableImplicitMT(NSLOTS);
   }
   ~RDFSimpleTests()
   {
      if (GetParam())
         ROOT::DisableImplicitMT();
   }
   const unsigned int NSLOTS;
};

// Create file `filename` containing a test tree `treeName` with `nevents` events
// TODO: create just one file at the beginning of the test execution, delete the file at test exit
void FillTree(const char *filename, const char *treeName, int nevents = 0)
{
   TFile f(filename, "RECREATE");
   TTree t(treeName, treeName);
   t.SetAutoFlush(1); // yes, one event per cluster: to make MT more meaningful
   double b1;
   int b2;
   double b3[2];
   unsigned int n;
   int b4[2] = {21, 42};
   t.Branch("b1", &b1);
   t.Branch("b2", &b2);
   t.Branch("b3", b3, "b3[2]/D");
   t.Branch("n", &n);
   t.Branch("b4", b4, "b4[n]/I");
   for (int i = 0; i < nevents; ++i) {
      b1 = i;
      b2 = i * i;
      b3[0] = b1;
      b3[1] = -b1;
      n = i % 2 + 1;
      t.Fill();
   }
   t.Write();
   f.Close();
}

TEST_P(RDFSimpleTests, CreateEmpty)
{
   RDataFrame tdf(10);
   auto c = tdf.Count();
   EXPECT_EQ(10U, *c);
}

TEST_P(RDFSimpleTests, CreateZeroEntries)
{
   RDataFrame tdf(0);
   auto c = tdf.Count();
   EXPECT_EQ(0U, *c);
}

TEST_P(RDFSimpleTests, CreateZeroEntriesWithBranches)
{
   auto filename = "dataframe_simple_0.root";
   auto treename = "t";
   // create input file (at most once per execution of the parametrized gtest)
   static bool hasFile = false;
   if (!hasFile) {
      FillTree(filename, treename);
      hasFile = true;
   }
   RDataFrame tdf(treename, filename);
   auto c = tdf.Count();
   auto m = tdf.Mean("b1");
   EXPECT_EQ(0U, *c);
   EXPECT_EQ(0., *m);
}

TEST_P(RDFSimpleTests, BuildWithTDirectory)
{
   auto filename = "dataframe_simple_1.root";
   auto treename = "t";
   // create input file (at most once per execution of the parametrized gtest)
   static bool hasFile = false;
   if (!hasFile) {
      FillTree(filename, treename, 50);
      hasFile = true;
   }
   TFile f(filename);
   RDataFrame tdf(treename, &f);
   auto c = tdf.Count();
   EXPECT_EQ(50U, *c);
}

// Jitting of column types
TEST_P(RDFSimpleTests, TypeGuessing)
{
   auto filename = "dataframe_simple_2.root";
   auto treename = "t";
   // create input file (at most once per execution of the parametrized gtest)
   static bool hasFile = false;
   if (!hasFile) {
      FillTree(filename, treename, 50);
      hasFile = true;
   }
   RDataFrame tdf(treename, filename, {"b1"});
   auto hcompiled = tdf.Histo1D<double>();
   auto hjitted = tdf.Histo1D();
   EXPECT_EQ(50, hcompiled->GetEntries());
   EXPECT_EQ(50, hjitted->GetEntries());
   EXPECT_DOUBLE_EQ(hcompiled->GetMean(), hjitted->GetMean());
}

// Define

TEST_P(RDFSimpleTests, Define_lambda)
{
   RDataFrame tdf(10);
   auto d = tdf.Define("i", []() { return 1; });
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

int DefineFunction()
{
   return 1;
}

TEST_P(RDFSimpleTests, Define_function)
{
   RDataFrame tdf(10);
   auto d = tdf.Define("i", DefineFunction);
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

struct DefineStruct {
   int operator()() { return 1; }
};

TEST_P(RDFSimpleTests, Define_functor)
{
   RDataFrame tdf(10);
   DefineStruct def;
   auto d = tdf.Define("i", def);
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

TEST_P(RDFSimpleTests, Define_jitted)
{
   RDataFrame tdf(10);
   auto d = tdf.Define("i", "1");
   auto m = d.Mean("i");
   EXPECT_DOUBLE_EQ(1., *m);
}

struct RFoo {};

TEST_P(RDFSimpleTests, Define_jitted_type_unknown_to_interpreter)
{
   RDataFrame tdf(10);
   auto d = tdf.Define("foo", [](){return RFoo();});
   auto d2 = tdf.Define("foo2", [](){return std::array<RFoo, 2>();});

   // We check that the if nothing is done with RFoo in jitted strings
   // everything works fine
   EXPECT_EQ(10U, *d.Count());
}

{'fraction_non_alphanumeric': 0.1534103290477228, 'fraction_numerical': 0.017977772935280016, 'mean_word_length': 3.5127826941986235, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 47, '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': '4999093', 'n_tokens_mistral': 3544, 'n_tokens_neox': 3488, 'n_words': 896}