diff --git a/src/info.cpp b/src/info.cpp index 7a0bc509eb..fd9a8cf1ca 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -1070,6 +1070,12 @@ bool Info::has_exceptions() { return true; } + +/** Return true if a LAMMPS package is enabled in this binary + * + * \param pkg name of package + * \return true if yes, else false + */ bool Info::has_package(const std::string &package_name) { for (int i = 0; LAMMPS::installed_packages[i] != nullptr; ++i) { if (package_name == LAMMPS::installed_packages[i]) { diff --git a/src/input.h b/src/input.h index 28b8cf96ea..949a70defd 100644 --- a/src/input.h +++ b/src/input.h @@ -26,6 +26,7 @@ class Input : protected Pointers { friend class Error; friend class Deprecated; friend class SimpleCommandsTest_Echo_Test; + friend class ErrorTest_errorpointer_Test; friend std::string utils::point_to_error(Input *input, int failed); public: @@ -47,7 +48,7 @@ class Input : protected Pointers { int echo_screen; // 0 = no, 1 = yes int echo_log; // 0 = no, 1 = yes - private: + protected: int me; // proc ID int maxarg; // max # of args in arg char *line, *copy, *work; // input line & copy and work string @@ -66,7 +67,7 @@ class Input : protected Pointers { using CommandCreatorMap = std::map; CommandCreatorMap *command_map; - private: + protected: void parse(); // parse an input text line char *nextword(char *, char **); // find next word in string with quotes int numtriple(char *); // count number of triple quotes diff --git a/src/lammps.cpp b/src/lammps.cpp index 88c03e513a..2c3fbf0192 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -1142,19 +1142,6 @@ void _noopt LAMMPS::init_pkg_lists() #undef REGION_CLASS } -/** Return true if a LAMMPS package is enabled in this binary - * - * \param pkg name of package - * \return true if yes, else false - */ -bool LAMMPS::is_installed_pkg(const char *pkg) -{ - for (int i=0; installed_packages[i] != nullptr; ++i) - if (strcmp(installed_packages[i],pkg) == 0) return true; - - return false; -} - #define check_for_match(style,list,name) \ if (strcmp(list,#style) == 0) { \ std::map &styles(pkg_lists-> style ## _styles); \ diff --git a/src/lammps.h b/src/lammps.h index f155099ac2..78febe9bf8 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -79,7 +79,6 @@ class LAMMPS { const char *match_style(const char *style, const char *name); static const char *installed_packages[]; - static bool is_installed_pkg(const char *pkg); static bool has_git_info(); static const char *git_commit(); diff --git a/src/pair.cpp b/src/pair.cpp index 5de99fbeba..f511dd90d5 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -169,7 +169,7 @@ void Pair::modify_params(int narg, char **arg) if (strcmp(arg[iarg+1],"geometric") == 0) mix_flag = GEOMETRIC; else if (strcmp(arg[iarg+1],"arithmetic") == 0) mix_flag = ARITHMETIC; else if (strcmp(arg[iarg+1],"sixthpower") == 0) mix_flag = SIXTHPOWER; - else error->all(FLERR,"Unknown pair_modify mix argument: {}", arg[iarg+1]); + else error->all(FLERR, iarg + 1, "Unknown pair_modify mix argument: {}", arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"shift") == 0) { if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "pair_modify shift", error); @@ -179,13 +179,17 @@ void Pair::modify_params(int narg, char **arg) if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "pair_modify table", error); ncoultablebits = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (ncoultablebits > (int)sizeof(float)*CHAR_BIT) - error->all(FLERR,"Too many total bits for bitmapped lookup table"); + error->all(FLERR, iarg + 1, "Too many total bits for bitmapped Coulomb lookup table"); + if (ncoultablebits && (ncoultablebits < 8)) + error->all(FLERR, iarg + 1, "Too few total bits for bitmapped Coulomb lookup table"); iarg += 2; } else if (strcmp(arg[iarg],"table/disp") == 0) { if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "pair_modify table/disp", error); ndisptablebits = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (ndisptablebits > (int)sizeof(float)*CHAR_BIT) - error->all(FLERR,"Too many total bits for bitmapped lookup table"); + error->all(FLERR, iarg + 1, "Too many total bits for bitmapped Dispersion lookup table"); + if (ndisptablebits && (ndisptablebits < 8)) + error->all(FLERR, iarg + 1, "Too few total bits for bitmapped Dispersion lookup table"); iarg += 2; } else if (strcmp(arg[iarg],"tabinner") == 0) { if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "pair_modify tabinner", error); @@ -210,7 +214,7 @@ void Pair::modify_params(int narg, char **arg) if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "pair_modify neigh/trim", error); trim_flag = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; - } else error->all(FLERR,"Unknown pair_modify keyword: {}", arg[iarg]); + } else error->all(FLERR, iarg, "Unknown pair_modify keyword: {}", arg[iarg]); } } @@ -221,9 +225,9 @@ void Pair::init() int i,j; if (offset_flag && tail_flag) - error->all(FLERR,"Cannot have both pair_modify shift and tail set to yes"); + error->all(FLERR, Error::NOLASTLINE, "Cannot have both pair_modify shift and tail set to yes"); if (tail_flag && domain->dimension == 2) - error->all(FLERR,"Cannot use pair tail corrections with 2d simulations"); + error->all(FLERR, Error::NOLASTLINE, "Cannot use pair tail corrections with 2d simulations"); if (tail_flag && domain->nonperiodic && comm->me == 0) error->warning(FLERR,"Using pair tail corrections with non-periodic system"); if (!compute_flag && tail_flag && comm->me == 0) @@ -319,7 +323,8 @@ void Pair::reinit() // generalize this error message if reinit() is used by more than fix adapt if (!reinitflag) - error->all(FLERR,"Fix adapt interface to this pair style not supported"); + error->all(FLERR, Error::NOLASTLINE, + "Fix adapt interface to pair style {} is not supported", force->pair_style); etail = ptail = 0.0; @@ -371,7 +376,8 @@ void Pair::init_tables(double cut_coul, double *cut_respa) double qqrd2e = force->qqrd2e; if (force->kspace == nullptr) - error->all(FLERR,"Pair style requires a KSpace style"); + error->all(FLERR, Error::NOLASTLINE, + "Pair style {} requires a KSpace style", force->pair_style); double g_ewald = force->kspace->g_ewald; double cut_coulsq = cut_coul * cut_coul; @@ -773,7 +779,7 @@ void Pair::write_restart(FILE *) void Pair::add_tally_callback(Compute *ptr) { if (lmp->kokkos) - error->all(FLERR,"Cannot yet use compute tally with Kokkos"); + error->all(FLERR, Error::NOLASTLINE, "Cannot yet use compute tally with Kokkos"); int i,found=-1; @@ -831,7 +837,8 @@ void Pair::map_element2type(int narg, char **arg, bool update_setflag) // elements = list of element names if (narg != ntypes) - error->all(FLERR, "Number of element to type mappings does not match number of atom types"); + error->all(FLERR, Error::NOLASTLINE, + "Number of element to type mappings does not match number of atom types"); if (elements) { for (i = 0; i < nelements; i++) delete[] elements[i]; @@ -873,7 +880,8 @@ void Pair::map_element2type(int narg, char **arg, bool update_setflag) } } - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients" + utils::errorurl(21)); + if (count == 0) + error->all(FLERR,"Incorrect args for pair coefficients" + utils::errorurl(21)); } } @@ -1797,16 +1805,18 @@ void Pair::virial_fdotr_compute() void Pair::write_file(int narg, char **arg) { - if (narg != 8 && narg != 10) error->all(FLERR,"Illegal pair_write command"); + if (narg != 8 && narg != 10) + error->all(FLERR,"Illegal pair_write command"); if (single_enable == 0) - error->all(FLERR,"Pair style does not support pair_write"); + error->all(FLERR, Error::NOLASTLINE, + "Pair style {} does not support pair_write", force->pair_style); // parse arguments int itype = utils::expand_type_int(FLERR, arg[0], Atom::ATOM, lmp); int jtype = utils::expand_type_int(FLERR, arg[1], Atom::ATOM, lmp); if (itype < 1 || itype > atom->ntypes || jtype < 1 || jtype > atom->ntypes) - error->all(FLERR,"Invalid atom types in pair_write command"); + error->all(FLERR, "Invalid atom types in pair_write command"); int n = utils::inumeric(FLERR,arg[2],false,lmp); @@ -1814,14 +1824,14 @@ void Pair::write_file(int narg, char **arg) if (strcmp(arg[3],"r") == 0) style = RLINEAR; else if (strcmp(arg[3],"rsq") == 0) style = RSQ; else if (strcmp(arg[3],"bitmap") == 0) style = BMP; - else error->all(FLERR,"Invalid style in pair_write command"); + else error->all(FLERR, 3, "Invalid style {} in pair_write command", arg[3]); if (n < 2) error->all(FLERR, "Must have at least 2 table values"); double inner = utils::numeric(FLERR, arg[4], false, lmp); double outer = utils::numeric(FLERR, arg[5], false, lmp); if (inner <= 0.0 || inner >= outer) - error->all(FLERR,"Invalid cutoffs in pair_write command"); + error->all(FLERR,"Invalid cutoffs ({} - {}) in pair_write command", inner, outer); // open file in append mode if exists // add line with DATE: and UNITS: tag when creating new file @@ -1860,7 +1870,7 @@ void Pair::write_file(int narg, char **arg) if (style == RSQ) fprintf(fp, "\n%s\nN %d RSQ %.15g %.15g\n\n", arg[7], n, inner, outer); } else { - error->one(FLERR,"Cannot open pair_write file {}: {}",table_file, utils::getsyserror()); + error->one(FLERR, 6, "Cannot open pair_write file {}: {}",table_file, utils::getsyserror()); } } diff --git a/src/run.cpp b/src/run.cpp index 5444297e5d..4a6a971e01 100644 --- a/src/run.cpp +++ b/src/run.cpp @@ -39,7 +39,7 @@ void Run::command(int narg, char **arg) if (narg < 1) utils::missing_cmd_args(FLERR, "run", error); if (domain->box_exist == 0) - error->all(FLERR,"Run command before simulation box is defined" + utils::errorurl(33)); + error->all(FLERR, -1, "Run command before simulation box is defined" + utils::errorurl(33)); // ignore run command, if walltime limit was already reached @@ -62,7 +62,6 @@ void Run::command(int narg, char **arg) int iarg = 1; while (iarg < narg) { if (strcmp(arg[iarg],"upto") == 0) { - if (iarg+1 > narg) utils::missing_cmd_args(FLERR, "run upto", error); uptoflag = 1; iarg += 1; } else if (strcmp(arg[iarg],"start") == 0) { @@ -91,13 +90,13 @@ void Run::command(int narg, char **arg) } else if (strcmp(arg[iarg],"every") == 0) { if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "run every", error); nevery = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - if (nevery <= 0) error->all(FLERR, "Invalid run every argument: {}", nevery); + if (nevery <= 0) error->all(FLERR, iarg + 1, "Invalid run every argument: {}", nevery); first = iarg+2; last = narg-1; ncommands = last-first + 1; if (ncommands == 1 && strcmp(arg[first],"NULL") == 0) ncommands = 0; iarg = narg; - } else error->all(FLERR,"Unknown run keyword: {}", arg[iarg]); + } else error->all(FLERR, iarg, "Unknown run keyword: {}", arg[iarg]); } // set nsteps as integer, using upto value if specified @@ -105,12 +104,12 @@ void Run::command(int narg, char **arg) int nsteps; if (!uptoflag) { if (nsteps_input < 0 || nsteps_input > MAXSMALLINT) - error->all(FLERR,"Invalid run command N value: {}", nsteps_input); + error->all(FLERR, Error::ARGZERO, "Invalid run command N value: {}", nsteps_input); nsteps = static_cast (nsteps_input); } else { bigint delta = nsteps_input - update->ntimestep; if (delta < 0 || delta > MAXSMALLINT) - error->all(FLERR,"Invalid run command upto value: {}", delta); + error->all(FLERR, Error::ARGZERO, "Invalid run command upto value: {}. Must be >= {}", nsteps_input, update->ntimestep); nsteps = static_cast (delta); } @@ -118,15 +117,15 @@ void Run::command(int narg, char **arg) if (startflag) { if (start < 0) - error->all(FLERR,"Invalid run command start value: {}", start); + error->all(FLERR, "Invalid run command start value: {}", start); if (start > update->ntimestep) - error->all(FLERR,"Run command start value is after start of run"); + error->all(FLERR, "Run command start value {} is after start of run at step {}", start, update->ntimestep); } if (stopflag) { if (stop < 0) error->all(FLERR,"Invalid run command stop value: {}", stop); if (stop < update->ntimestep + nsteps) - error->all(FLERR,"Run command stop value is before end of run"); + error->all(FLERR,"Run command stop value {} is before end of run at step {}", stop, update->ntimestep + nsteps); } if (!preflag && utils::strmatch(update->integrate_style,"^respa")) diff --git a/src/utils.cpp b/src/utils.cpp index c2c6846c35..e376afc282 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -23,6 +23,7 @@ #ifndef FMT_STATIC_THOUSANDS_SEPARATOR #include "fmt/chrono.h" #endif +#include "info.h" #include "input.h" #include "label_map.h" #include "memory.h" @@ -449,7 +450,7 @@ std::string utils::check_packages_for_style(const std::string &style, const std: if (pkg) { errmsg += fmt::format(" is part of the {} package", pkg); - if (LAMMPS::is_installed_pkg(pkg)) + if (Info::has_package(pkg)) errmsg += ", but seems to be missing because of a dependency"; else errmsg += " which is not enabled in this LAMMPS binary." + utils::errorurl(10); diff --git a/unittest/c-library/test_library_open.cpp b/unittest/c-library/test_library_open.cpp index 61ef080b9a..b3103371bf 100644 --- a/unittest/c-library/test_library_open.cpp +++ b/unittest/c-library/test_library_open.cpp @@ -79,7 +79,7 @@ TEST(lammps_open, with_args) TEST(lammps_open, with_kokkos) { - if (!LAMMPS_NS::LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!LAMMPS_NS::Info::has_package("KOKKOS")) GTEST_SKIP(); std::vector args = {(char *)"lammps", (char *)"-log", (char *)"none", (char *)"-echo", (char *)"screen", (char *)"-sf", (char *)"kk"}; @@ -168,7 +168,7 @@ TEST(lammps_open_no_mpi, no_screen) TEST(lammps_open_no_mpi, with_omp) { - if (!LAMMPS_NS::LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); + if (!LAMMPS_NS::Info::has_package("OPENMP")) GTEST_SKIP(); const char *args[] = {"liblammps", "-pk", "omp", "2", "neigh", "no", "-sf", "omp", "-log", "none", "-nocite", nullptr}; char **argv = (char **)args; diff --git a/unittest/commands/test_kim_commands.cpp b/unittest/commands/test_kim_commands.cpp index 2e43faf96e..270b53ffb7 100644 --- a/unittest/commands/test_kim_commands.cpp +++ b/unittest/commands/test_kim_commands.cpp @@ -49,7 +49,7 @@ protected: TEST_F(KimCommandsTest, kim) { - if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP(); + if (!Info::has_package("KIM")) GTEST_SKIP(); TEST_FAILURE(".*ERROR: Illegal kim command.*", command("kim");); TEST_FAILURE(".*ERROR: Unknown kim subcommand.*", command("kim unknown");); @@ -62,7 +62,7 @@ TEST_F(KimCommandsTest, kim) TEST_F(KimCommandsTest, kim_init) { - if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP(); + if (!Info::has_package("KIM")) GTEST_SKIP(); TEST_FAILURE(".*ERROR: Illegal 'kim init' command.*", command("kim init");); TEST_FAILURE(".*ERROR: Illegal 'kim init' command.*", @@ -90,7 +90,7 @@ TEST_F(KimCommandsTest, kim_init) TEST_F(KimCommandsTest, kim_interactions) { - if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP(); + if (!Info::has_package("KIM")) GTEST_SKIP(); TEST_FAILURE(".*ERROR: Illegal kim interactions command: missing argument.*", command("kim interactions");); @@ -213,7 +213,7 @@ TEST_F(KimCommandsTest, kim_interactions) TEST_F(KimCommandsTest, kim_param) { - if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP(); + if (!Info::has_package("KIM")) GTEST_SKIP(); TEST_FAILURE(".*ERROR: Illegal 'kim param' command.*", command("kim param");); TEST_FAILURE(".*ERROR: Incorrect arguments in 'kim param' command.\n" @@ -401,8 +401,8 @@ TEST_F(KimCommandsTest, kim_param) TEST_F(KimCommandsTest, kim_property) { - if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP(); - if (!LAMMPS::is_installed_pkg("PYTHON")) GTEST_SKIP(); + if (!Info::has_package("KIM")) GTEST_SKIP(); + if (!Info::has_package("PYTHON")) GTEST_SKIP(); if (!lmp->python->has_minimum_version(3, 6)) { TEST_FAILURE(".*ERROR: Invalid Python version.\n" @@ -444,7 +444,7 @@ TEST_F(KimCommandsTest, kim_property) TEST_F(KimCommandsTest, kim_query) { - if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP(); + if (!Info::has_package("KIM")) GTEST_SKIP(); TEST_FAILURE(".*ERROR: Illegal 'kim query' command.*", command("kim query");); TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe keyword 'split' " diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index ad8b1634c6..cb52990350 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -106,6 +106,50 @@ TEST_F(SetTest, NoBoxNoAtoms) command("compute 1 all property/atom mol");); } +TEST_F(SetTest, velocity) +{ + atomic_system("atomic", "real"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("velocity all create 200 123513 loop geom"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + auto *temp = lmp->modify->get_compute_by_id("thermo_temp"); + EXPECT_DOUBLE_EQ(temp->compute_scalar(), 200.0); + BEGIN_HIDE_OUTPUT(); + command("velocity all scale 300.0"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + EXPECT_DOUBLE_EQ(temp->compute_scalar(), 300.0); + BEGIN_HIDE_OUTPUT(); + command("velocity all set 0.0 0.0 0.0"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + EXPECT_DOUBLE_EQ(temp->compute_scalar(), 0.0); + BEGIN_HIDE_OUTPUT(); + command("velocity all ramp vx 0.01 0.2 x 0.0 2.0"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + EXPECT_DOUBLE_EQ(temp->compute_scalar(), 3238.9377014185811); + BEGIN_HIDE_OUTPUT(); + command("velocity all zero linear"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + EXPECT_DOUBLE_EQ(temp->compute_scalar(), 1033.7682579098041); + BEGIN_HIDE_OUTPUT(); + command("velocity top set -0.01 0.0 0.0 sum yes"); + command("velocity bottom set 0.01 0.0 0.0 sum yes"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + EXPECT_DOUBLE_EQ(temp->compute_scalar(), 1079.5862416398786); + BEGIN_HIDE_OUTPUT(); + command("velocity all zero angular"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + EXPECT_DOUBLE_EQ(temp->compute_scalar(), 1056.6772497748414); +} + TEST_F(SetTest, StylesTypes) { if (!Info::has_package("MOLECULE")) GTEST_SKIP(); @@ -247,6 +291,36 @@ TEST_F(SetTest, StylesTypes) TEST_FAILURE(".*ERROR: Numeric index 9 is out of bounds .1-8.*", command("set type 9 x 0.0");); TEST_FAILURE(".*ERROR: Invalid range string: 3:10.*", command("set type 3:10 x 0.0");); TEST_FAILURE(".*ERROR: Could not find set group ID nope.*", command("set group nope x 0.0");); + + BEGIN_HIDE_OUTPUT(); + command("variable stephalf atom step*0.5+1"); + command("variable stepquart atom step*0.25+1"); + command("fix one all set 2 0 group all type v_stephalf"); + command("fix two all set 2 0 group top type v_stepquart"); + command("run 4 post no"); + END_HIDE_OUTPUT(); + EXPECT_EQ(atom->type[0], 2); + EXPECT_EQ(atom->type[1], 2); + EXPECT_EQ(atom->type[2], 3); + EXPECT_EQ(atom->type[3], 3); + EXPECT_EQ(atom->type[4], 2); + EXPECT_EQ(atom->type[5], 2); + EXPECT_EQ(atom->type[6], 3); + EXPECT_EQ(atom->type[7], 3); + BEGIN_HIDE_OUTPUT(); + command("run 4 pre no post no"); + END_HIDE_OUTPUT(); + EXPECT_EQ(atom->type[0], 3); + EXPECT_EQ(atom->type[1], 3); + EXPECT_EQ(atom->type[2], 5); + EXPECT_EQ(atom->type[3], 5); + EXPECT_EQ(atom->type[4], 3); + EXPECT_EQ(atom->type[5], 3); + EXPECT_EQ(atom->type[6], 5); + EXPECT_EQ(atom->type[7], 5); + + TEST_FAILURE(".*ERROR: Fix set command keyword type does not invoke a per-atom variable*", + command("fix three all set 1 0 group all type 1");); } TEST_F(SetTest, PosVelCharge) @@ -350,6 +424,60 @@ TEST_F(SetTest, PosVelCharge) ASSERT_EQ(atom->v[7][0], 1.125); ASSERT_EQ(atom->v[7][1], 0.28125); ASSERT_EQ(atom->v[7][2], 0.5); + + // trigger generation of ghost atoms + BEGIN_HIDE_OUTPUT(); + command("pair_style zero 0.2"); + command("pair_coeff * *"); + command("mass * 1.0"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + + // clear charges on local and ghost atoms + int nlocal = atom->nlocal; + int nall = atom->nlocal + atom->nghost; + for (int i = 0; i < nall; ++i) + atom->q[i] = 0.0; + + // use fix set without updating ghosts + BEGIN_HIDE_OUTPUT(); + command("variable stephalf atom -0.5*step"); + command("variable stepquart atom 0.25*step"); + command("fix one all set 2 0 group all charge v_stephalf"); + command("fix two all set 2 0 group top charge v_stepquart"); + command("run 4 post no"); + END_HIDE_OUTPUT(); + EXPECT_DOUBLE_EQ(atom->q[0], 1.0); + EXPECT_DOUBLE_EQ(atom->q[1], 1.0); + EXPECT_DOUBLE_EQ(atom->q[2], -2.0); + EXPECT_DOUBLE_EQ(atom->q[3], -2.0); + EXPECT_DOUBLE_EQ(atom->q[4], 1.0); + EXPECT_DOUBLE_EQ(atom->q[5], 1.0); + EXPECT_DOUBLE_EQ(atom->q[6], -2.0); + EXPECT_DOUBLE_EQ(atom->q[7], -2.0); + + // confirm that ghost atom charges are unchanged + for (int i = nlocal; i < nall; ++i) + ASSERT_DOUBLE_EQ(atom->q[i], 0.0); + + // replace fix set command to variant with updating ghosts + BEGIN_HIDE_OUTPUT(); + command("fix one all set 2 1 group all charge v_stephalf"); + command("fix two all set 2 1 group top charge v_stepquart"); + command("run 4 post no"); + END_HIDE_OUTPUT(); + EXPECT_DOUBLE_EQ(atom->q[0], 2.0); + EXPECT_DOUBLE_EQ(atom->q[1], 2.0); + EXPECT_DOUBLE_EQ(atom->q[2], -4.0); + EXPECT_DOUBLE_EQ(atom->q[3], -4.0); + EXPECT_DOUBLE_EQ(atom->q[4], 2.0); + EXPECT_DOUBLE_EQ(atom->q[5], 2.0); + EXPECT_DOUBLE_EQ(atom->q[6], -4.0); + EXPECT_DOUBLE_EQ(atom->q[7], -4.0); + + // confirm that ghost atom charges are non-zero + for (int i = nlocal; i < nall; ++i) + EXPECT_NE((int)atom->q[i], 0); } TEST_F(SetTest, SpinPackage) diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index 66faae2f8b..206f1ee4ad 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -13,6 +13,7 @@ #include "lammps.h" +#include "atom.h" #include "citeme.h" #include "comm.h" #include "force.h" @@ -556,7 +557,7 @@ TEST_F(SimpleCommandsTest, CiteMe) TEST_F(SimpleCommandsTest, Geturl) { - if (!LAMMPS::is_installed_pkg("EXTRA-COMMAND")) GTEST_SKIP(); + if (!Info::has_package("EXTRA-COMMAND")) GTEST_SKIP(); platform::unlink("index.html"); platform::unlink("myindex.html"); if (Info::has_curl_support()) { @@ -597,6 +598,63 @@ TEST_F(SimpleCommandsTest, Geturl) platform::unlink("myindex.html"); } +TEST_F(SimpleCommandsTest, run) +{ + bool caught = false; + try { + BEGIN_HIDE_OUTPUT(); + command("run 0"); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR: Run command before simulation box is defined")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Invalid exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + BEGIN_HIDE_OUTPUT(); + command("region box block 0 1 0 1 0 1"); + command("create_box 1 box"); + command("mass 1 1.0"); + command("run 10 post no"); + END_HIDE_OUTPUT(); + EXPECT_EQ(lmp->update->ntimestep, 10); + BEGIN_HIDE_OUTPUT(); + command("run 15 upto post yes"); + END_HIDE_OUTPUT(); + EXPECT_EQ(lmp->update->ntimestep, 15); + + TEST_FAILURE(".*ERROR: Illegal run start command: missing arg.*", command("run 10 start");); + TEST_FAILURE(".*ERROR: Illegal run stop command: missing arg.*", command("run 10 stop");); + TEST_FAILURE(".*ERROR: Illegal run every command: missing arg.*", command("run 10 every");); + TEST_FAILURE(".*ERROR: Unknown run keyword: xxx", command("run 10 xxx");); + TEST_FAILURE(".*ERROR: Invalid run command upto value: 10.*", command("run 10 upto");); + TEST_FAILURE(".*ERROR: Invalid run command start value: -10.*", command("run 10 start -10");); + TEST_FAILURE(".*ERROR: Run command start value 20 is after start of run at step 15.*", + command("run 10 start 20");); + TEST_FAILURE(".*ERROR: Invalid run command stop value: -10.*", command("run 10 stop -10");); + TEST_FAILURE(".*ERROR: Run command stop value 20 is before end of run at step 25.*", + command("run 10 stop 20");); + + BEGIN_HIDE_OUTPUT(); + command("run 15 post no start 0 stop 100"); + END_HIDE_OUTPUT(); + EXPECT_EQ(lmp->update->ntimestep, 30); + + EXPECT_DOUBLE_EQ(lmp->atom->mass[1], 1.0); + BEGIN_HIDE_OUTPUT(); + command("run 10 post no every 5 \"mass 1 2.0\""); + END_HIDE_OUTPUT(); + EXPECT_EQ(lmp->update->ntimestep, 40); + EXPECT_DOUBLE_EQ(lmp->atom->mass[1], 2.0); + + BEGIN_HIDE_OUTPUT(); + command("run 20 post no every 5 NULL"); + END_HIDE_OUTPUT(); + EXPECT_EQ(lmp->update->ntimestep, 60); +} } // namespace LAMMPS_NS int main(int argc, char **argv) diff --git a/unittest/cplusplus/test_advanced_utils.cpp b/unittest/cplusplus/test_advanced_utils.cpp index e863296e3e..3a4983d250 100644 --- a/unittest/cplusplus/test_advanced_utils.cpp +++ b/unittest/cplusplus/test_advanced_utils.cpp @@ -1,6 +1,7 @@ -// unit tests for utils:: functions requiring a LAMMPS +// unit tests for utils:: functions requiring a LAMMPS instance #include "error.h" +#include "info.h" #include "input.h" #include "lammps.h" #include "memory.h" @@ -10,13 +11,16 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include #include +using ::testing::StrEq; + // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; namespace LAMMPS_NS { -class Advanced_utils : public LAMMPSTest { +class AdvancedUtils : public LAMMPSTest { protected: Error *error; @@ -47,7 +51,7 @@ protected: } }; -TEST_F(Advanced_utils, missing_cmd_args) +TEST_F(AdvancedUtils, missing_cmd_args) { auto output = CAPTURE_OUTPUT([&] { utils::missing_cmd_args(FLERR, "dummy", nullptr); @@ -58,7 +62,7 @@ TEST_F(Advanced_utils, missing_cmd_args) utils::missing_cmd_args(FLERR, "dummy", error);); }; -TEST_F(Advanced_utils, logmesg) +TEST_F(AdvancedUtils, logmesg) { auto output = CAPTURE_OUTPUT([&] { utils::logmesg(lmp, "test message"); @@ -72,7 +76,7 @@ TEST_F(Advanced_utils, logmesg) }; // death tests only. the other cases are tested in the basic utils unit tester -TEST_F(Advanced_utils, bounds_int_fail) +TEST_F(AdvancedUtils, bounds_int_fail) { int nlo, nhi; TEST_FAILURE("ERROR: Invalid range string: 1x ", @@ -87,9 +91,13 @@ TEST_F(Advanced_utils, bounds_int_fail) utils::bounds(FLERR, "?", -10, 5, nlo, nhi, error);); TEST_FAILURE("ERROR: Invalid range string: 3\\*:2 ", utils::bounds(FLERR, "3*:2", -10, 5, nlo, nhi, error);); + TEST_FAILURE("ERROR: Numeric index 1 is out of bounds \\(5-6\\).*", + utils::bounds(FLERR, "1*4", 5, 6, nlo, nhi, error);); + TEST_FAILURE("ERROR: Numeric index 4 is out of bounds \\(1-3\\).*", + utils::bounds(FLERR, "1*4", 1, 3, nlo, nhi, error);); } -TEST_F(Advanced_utils, bounds_bigint_fail) +TEST_F(AdvancedUtils, bounds_bigint_fail) { bigint nlo, nhi; TEST_FAILURE("ERROR: Invalid range string: 1x ", @@ -104,9 +112,13 @@ TEST_F(Advanced_utils, bounds_bigint_fail) utils::bounds(FLERR, "?", -10, 5, nlo, nhi, error);); TEST_FAILURE("ERROR: Invalid range string: 3\\*:2 ", utils::bounds(FLERR, "3*:2", -10, 5, nlo, nhi, error);); + TEST_FAILURE("ERROR: Numeric index 1 is out of bounds \\(5-6\\).*", + utils::bounds(FLERR, "1*4", 5, 6, nlo, nhi, error);); + TEST_FAILURE("ERROR: Numeric index 4 is out of bounds \\(1-3\\).*", + utils::bounds(FLERR, "1*4", 1, 3, nlo, nhi, error);); } -TEST_F(Advanced_utils, expand_args) +TEST_F(AdvancedUtils, expand_args) { atomic_system(); BEGIN_CAPTURE_OUTPUT(); @@ -243,6 +255,383 @@ TEST_F(Advanced_utils, expand_args) delete[] args[i]; delete[] args; } + +TEST_F(AdvancedUtils, check_packages_for_style) +{ + auto mesg = utils::check_packages_for_style("pair", "unknown", lmp); + EXPECT_THAT(mesg, StrEq("Unrecognized pair style 'unknown'")); + + // try styles from multiple packages that are rarely installed in + // the hope that one of them triggers the error message about the missing package + if (!Info::has_package("ADIOS")) { + auto mesg = utils::check_packages_for_style("dump", "atom/adios", lmp); + EXPECT_THAT(mesg, StrEq("Unrecognized dump style 'atom/adios' is part of the ADIOS " + "package which is not enabled in this LAMMPS binary.\n" + "For more information see https://docs.lammps.org/err0010")); + } + + if (!Info::has_package("SCAFACOS")) { + auto mesg = utils::check_packages_for_style("kspace", "scafacos", lmp); + EXPECT_THAT(mesg, StrEq("Unrecognized kspace style 'scafacos' is part of the SCAFACOS " + "package which is not enabled in this LAMMPS binary.\n" + "For more information see https://docs.lammps.org/err0010")); + } + + // try styles from multiple packages that are commonly installed in + // the hope that one of them triggers the error message about the dependency + if (Info::has_package("MANYBODY")) { + auto mesg = utils::check_packages_for_style("pair", "tersoff", lmp); + EXPECT_THAT(mesg, StrEq("Unrecognized pair style 'tersoff' is part of the MANYBODY " + "package, but seems to be missing because of a dependency")); + } + if (Info::has_package("MOLECULE")) { + auto mesg = utils::check_packages_for_style("bond", "harmonic", lmp); + EXPECT_THAT(mesg, StrEq("Unrecognized bond style 'harmonic' is part of the MOLECULE " + "package, but seems to be missing because of a dependency")); + } +} + +TEST_F(AdvancedUtils, logical) +{ + bool caught = false; + EXPECT_EQ(utils::logical(FLERR, "yes", false, lmp), true); + EXPECT_EQ(utils::logical(FLERR, "no", false, lmp), false); + EXPECT_EQ(utils::logical(FLERR, "on", false, lmp), true); + EXPECT_EQ(utils::logical(FLERR, "off", false, lmp), false); + EXPECT_EQ(utils::logical(FLERR, "1", false, lmp), true); + EXPECT_EQ(utils::logical(FLERR, "0", false, lmp), false); + EXPECT_EQ(utils::logical(FLERR, "true", false, lmp), true); + EXPECT_EQ(utils::logical(FLERR, "false", false, lmp), false); + + try { + BEGIN_HIDE_OUTPUT(); + utils::logical(FLERR, "YES", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Expected boolean parameter " + "instead of 'YES' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::logical(FLERR, "1.0e-2", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR: Expected boolean parameter instead " + "of '1.0e-2' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); +}; + +TEST_F(AdvancedUtils, numeric) +{ + bool caught = false; + EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "0.0", false, lmp), 0.0); + EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "-1", false, lmp), -1.0); + EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "2.1e-1", false, lmp), 0.21); + EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "2.23e-308", false, lmp), 2.23e-308); + EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "1.79e308", false, lmp), 1.79e308); + + try { + BEGIN_HIDE_OUTPUT(); + utils::numeric(FLERR, "text", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Expected floating point parameter " + "instead of 'text' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::numeric(FLERR, "1.0d-2", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR: Expected floating point parameter instead " + "of '1.0d-2' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); +}; + +TEST_F(AdvancedUtils, inumeric) +{ + bool caught = false; + EXPECT_EQ(utils::inumeric(FLERR, "0", false, lmp), 0); + EXPECT_EQ(utils::inumeric(FLERR, "-1", false, lmp), -1); + EXPECT_EQ(utils::inumeric(FLERR, "+11", false, lmp), 11); + EXPECT_EQ(utils::inumeric(FLERR, "2147483647", false, lmp), 2147483647); + EXPECT_EQ(utils::inumeric(FLERR, "-2147483648", false, lmp), -2147483648); + + try { + BEGIN_HIDE_OUTPUT(); + utils::inumeric(FLERR, "2147483648", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Integer 2147483648 in input " + "script or data file is out of range")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::inumeric(FLERR, "-2147483649", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("Integer -2147483649 in input script " + "or data file is out of range")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + try { + BEGIN_HIDE_OUTPUT(); + utils::inumeric(FLERR, "--10", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Expected integer parameter " + "instead of '--10' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::inumeric(FLERR, "1.0", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR: Expected integer parameter instead " + "of '1.0' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); +}; + +// bigint is *always* 64-bit + +TEST_F(AdvancedUtils, bnumeric) +{ + bool caught = false; + EXPECT_EQ(utils::bnumeric(FLERR, "0", false, lmp), 0); + EXPECT_EQ(utils::bnumeric(FLERR, "-1", false, lmp), -1); + EXPECT_EQ(utils::bnumeric(FLERR, "+11", false, lmp), 11); + EXPECT_EQ(utils::bnumeric(FLERR, "2147483647000", false, lmp), 2147483647000); + EXPECT_EQ(utils::bnumeric(FLERR, "-2147483648000", false, lmp), -2147483648000); + + try { + BEGIN_HIDE_OUTPUT(); + utils::bnumeric(FLERR, "9223372036854775808", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Integer 9223372036854775808 in " + "input script or data file is out of range")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::bnumeric(FLERR, "-9223372036854775809", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("Integer -9223372036854775809 in input script " + "or data file is out of range")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + try { + BEGIN_HIDE_OUTPUT(); + utils::bnumeric(FLERR, "text", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Expected integer parameter " + "instead of 'text' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::bnumeric(FLERR, "1.0", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR: Expected integer parameter instead " + "of '1.0' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); +}; + +TEST_F(AdvancedUtils, tnumeric) +{ + if (sizeof(tagint) == 4) { + + bool caught = false; + EXPECT_EQ(utils::tnumeric(FLERR, "0", false, lmp), 0); + EXPECT_EQ(utils::tnumeric(FLERR, "-1", false, lmp), -1); + EXPECT_EQ(utils::tnumeric(FLERR, "+11", false, lmp), 11); + EXPECT_EQ(utils::tnumeric(FLERR, "2147483647", false, lmp), 2147483647); + EXPECT_EQ(utils::tnumeric(FLERR, "-2147483648", false, lmp), -2147483648); + + try { + BEGIN_HIDE_OUTPUT(); + utils::tnumeric(FLERR, "2147483648", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Integer 2147483648 in input " + "script or data file is out of range")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::tnumeric(FLERR, "-2147483649", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("Integer -2147483649 in input script " + "or data file is out of range")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + try { + BEGIN_HIDE_OUTPUT(); + utils::tnumeric(FLERR, "--10", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Expected integer parameter " + "instead of '--10' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::tnumeric(FLERR, "1.0", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR: Expected integer parameter instead " + "of '1.0' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + } else if (sizeof(tagint) == 8) { + bool caught = false; + EXPECT_EQ(utils::tnumeric(FLERR, "0", false, lmp), 0); + EXPECT_EQ(utils::tnumeric(FLERR, "-1", false, lmp), -1); + EXPECT_EQ(utils::tnumeric(FLERR, "+11", false, lmp), 11); + EXPECT_EQ(utils::tnumeric(FLERR, "2147483647000", false, lmp), 2147483647000); + EXPECT_EQ(utils::tnumeric(FLERR, "-2147483648000", false, lmp), -2147483648000); + + try { + BEGIN_HIDE_OUTPUT(); + utils::tnumeric(FLERR, "9223372036854775808", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Integer 9223372036854775808 in " + "input script or data file is out of range")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::tnumeric(FLERR, "-9223372036854775809", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("Integer -9223372036854775809 in input script " + "or data file is out of range")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + try { + BEGIN_HIDE_OUTPUT(); + utils::tnumeric(FLERR, "text", true, lmp); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: Expected integer parameter " + "instead of 'text' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n"; + } + ASSERT_TRUE(caught); + + try { + BEGIN_HIDE_OUTPUT(); + utils::tnumeric(FLERR, "1.0", false, lmp); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR: Expected integer parameter instead " + "of '1.0' in input script or data file ")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception: " << e.what() << "\n";; + } + ASSERT_TRUE(caught); + } +}; + } // namespace LAMMPS_NS int main(int argc, char **argv) diff --git a/unittest/cplusplus/test_error_class.cpp b/unittest/cplusplus/test_error_class.cpp index d7d6d7eab6..31d6252c4c 100644 --- a/unittest/cplusplus/test_error_class.cpp +++ b/unittest/cplusplus/test_error_class.cpp @@ -17,8 +17,9 @@ bool verbose = false; namespace LAMMPS_NS { using ::testing::ContainsRegex; +using ::testing::StrEq; -class Error_class : public LAMMPSTest { +class ErrorTest : public LAMMPSTest { protected: Error *error; Thermo *thermo; @@ -32,7 +33,7 @@ protected: } }; -TEST_F(Error_class, warning) +TEST_F(ErrorTest, warning) { // standard warning auto output = CAPTURE_OUTPUT([&] { @@ -100,16 +101,91 @@ TEST_F(Error_class, warning) ASSERT_THAT(error->get_numwarn(), 2); }; -TEST_F(Error_class, one) +TEST_F(ErrorTest, one) { - TEST_FAILURE("ERROR on proc 0: one error.*test_error_class.cpp:.*", - error->one(FLERR, "one error");); + bool caught = false; + try { + BEGIN_HIDE_OUTPUT(); + error->one(FLERR, "one error"); + } catch (LAMMPSAbortException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR on proc 0: one error.*test_error_class.cpp")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception\n"; + } + ASSERT_TRUE(caught); }; -TEST_F(Error_class, all) +TEST_F(ErrorTest, all) { - TEST_FAILURE("ERROR: one error.*test_error_class.cpp:.*", error->all(FLERR, "one error");); + bool caught = false; + try { + BEGIN_HIDE_OUTPUT(); + error->all(FLERR, "one error"); + } catch (LAMMPSException &e) { + END_HIDE_OUTPUT(); + EXPECT_THAT(e.what(), ContainsRegex("ERROR: one error.*test_error_class.cpp")); + caught = true; + } catch (std::exception &e) { + END_HIDE_OUTPUT(); + GTEST_FAIL() << "Incorrect exception\n"; + } + ASSERT_TRUE(caught); }; + +TEST_F(ErrorTest, errorpointer) +{ + lmp->input->line = utils::strdup("some command line with no blanks"); + lmp->input->parse(); + EXPECT_THAT(utils::point_to_error(lmp->input, Error::NOPOINTER), + StrEq("Last input line: some command line with no blanks\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, -1), + StrEq("Last input line: some command line with no blanks \n" + " ^^^^\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, 0), + StrEq("Last input line: some command line with no blanks \n" + " ^^^^^^^\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, 1), + StrEq("Last input line: some command line with no blanks \n" + " ^^^^\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, 2), + StrEq("Last input line: some command line with no blanks \n" + " ^^^^\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, 3), + StrEq("Last input line: some command line with no blanks \n" + " ^^\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, 4), + StrEq("Last input line: some command line with no blanks \n" + " ^^^^^^\n")); + + delete[] lmp->input->line; + lmp->input->line = utils::strdup("some command line 'with some blanks'"); + lmp->input->parse(); + EXPECT_THAT(utils::point_to_error(nullptr,0), StrEq("")); + EXPECT_THAT(utils::point_to_error(lmp->input, Error::NOPOINTER), + StrEq("Last input line: some command line 'with some blanks'\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, -1), + StrEq("Last input line: some command line 'with some blanks'\n" + "--> parsed line: some command line \"with some blanks\" \n" + " ^^^^\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, 0), + StrEq("Last input line: some command line 'with some blanks'\n" + "--> parsed line: some command line \"with some blanks\" \n" + " ^^^^^^^\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, 1), + StrEq("Last input line: some command line 'with some blanks'\n" + "--> parsed line: some command line \"with some blanks\" \n" + " ^^^^\n")); + EXPECT_THAT(utils::point_to_error(lmp->input, 2), + StrEq("Last input line: some command line 'with some blanks'\n" + "--> parsed line: some command line \"with some blanks\" \n" + " ^^^^^^^^^^^^^^^^^^\n")); + delete[] lmp->input->line; + lmp->input->line = nullptr; +}; + } // namespace LAMMPS_NS int main(int argc, char **argv) diff --git a/unittest/cplusplus/test_lammps_class.cpp b/unittest/cplusplus/test_lammps_class.cpp index 464ecca925..876a55b30d 100644 --- a/unittest/cplusplus/test_lammps_class.cpp +++ b/unittest/cplusplus/test_lammps_class.cpp @@ -175,7 +175,7 @@ protected: // only run this test fixture with omp suffix if OPENMP package is installed - if (LAMMPS::is_installed_pkg("OPENMP")) + if (Info::has_package("OPENMP")) lmp = new LAMMPS(args, MPI_COMM_WORLD); else GTEST_SKIP(); @@ -264,7 +264,7 @@ protected: if (Info::has_accelerator_feature("KOKKOS", "api", "openmp")) args[10] = "2"; - if (LAMMPS::is_installed_pkg("KOKKOS")) { + if (Info::has_package("KOKKOS")) { ::testing::internal::CaptureStdout(); lmp = new LAMMPS(args, MPI_COMM_WORLD); ::testing::internal::GetCapturedStdout(); @@ -329,7 +329,7 @@ TEST_F(LAMMPS_kokkos, InitMembers) TEST(LAMMPS_init, OpenMP) { - if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); + if (!Info::has_package("OPENMP")) GTEST_SKIP(); if (platform::openmp_standard() == "OpenMP not enabled") GTEST_SKIP(); FILE *fp = fopen("in.lammps_empty", "w"); diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index b76a542172..dd7daf4c4a 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -435,7 +435,7 @@ TEST(AngleStyle, plain) TEST(AngleStyle, omp) { - if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); + if (!Info::has_package("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", @@ -548,7 +548,7 @@ TEST(AngleStyle, omp) TEST(AngleStyle, kokkos_omp) { - if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); // test either OpenMP or Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial") && @@ -689,7 +689,7 @@ TEST(AngleStyle, kokkos_omp) TEST(AngleStyle, numdiff) { - if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP(); + if (!Info::has_package("EXTRA-FIX")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index 731aac9ef1..45a29ee83b 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -438,7 +438,7 @@ TEST(BondStyle, plain) TEST(BondStyle, omp) { - if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); + if (!Info::has_package("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", @@ -551,7 +551,7 @@ TEST(BondStyle, omp) TEST(BondStyle, kokkos_omp) { - if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); // test either OpenMP or Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial") && @@ -678,7 +678,7 @@ TEST(BondStyle, kokkos_omp) TEST(BondStyle, numdiff) { - if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP(); + if (!Info::has_package("EXTRA-FIX")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index 31d89ba9e5..3b3af41883 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -453,7 +453,7 @@ TEST(DihedralStyle, plain) TEST(DihedralStyle, omp) { - if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); + if (!Info::has_package("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", @@ -567,7 +567,7 @@ TEST(DihedralStyle, omp) TEST(DihedralStyle, kokkos_omp) { - if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); // test either OpenMP or Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial") && @@ -695,7 +695,7 @@ TEST(DihedralStyle, kokkos_omp) TEST(DihedralStyle, numdiff) { - if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP(); + if (!Info::has_package("EXTRA-FIX")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"}; diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index 133397ccdf..c01326da15 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -269,7 +269,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config) TEST(FixTimestep, plain) { - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); #if defined(USING_STATIC_LIBS) if (test_config.skip_tests.count("static")) GTEST_SKIP(); @@ -580,8 +580,8 @@ TEST(FixTimestep, plain) TEST(FixTimestep, omp) { - if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("OPENMP")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); #if defined(USING_STATIC_LIBS) if (test_config.skip_tests.count("static")) GTEST_SKIP(); @@ -892,7 +892,7 @@ TEST(FixTimestep, omp) TEST(FixTimestep, kokkos_omp) { - if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); // test either OpenMP or Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial") && diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index b9534fabe3..e5845f9cb9 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -431,7 +431,7 @@ TEST(ImproperStyle, plain) TEST(ImproperStyle, omp) { - if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); + if (!Info::has_package("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", @@ -545,7 +545,7 @@ TEST(ImproperStyle, omp) TEST(ImproperStyle, kokkos_omp) { - if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); // test either OpenMP or Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial") && @@ -670,7 +670,7 @@ TEST(ImproperStyle, kokkos_omp) TEST(ImproperStyle, numdiff) { - if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP(); + if (!Info::has_package("EXTRA-FIX")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"}; diff --git a/unittest/force-styles/test_mliappy_unified.cpp b/unittest/force-styles/test_mliappy_unified.cpp index c9e78b0cd4..15303fefbd 100644 --- a/unittest/force-styles/test_mliappy_unified.cpp +++ b/unittest/force-styles/test_mliappy_unified.cpp @@ -117,7 +117,7 @@ TEST(MliapUnified, VersusLJMeltGhost) TEST(MliapUnified, VersusLJMeltKokkos) { - if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); // test either OpenMP or Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial") && !Info::has_accelerator_feature("KOKKOS", "api", "openmp")) @@ -168,7 +168,7 @@ TEST(MliapUnified, VersusLJMeltKokkos) TEST(MliapUnified, VersusLJMeltGhostKokkos) { - if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); // test either OpenMP or Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp") && !Info::has_accelerator_feature("KOKKOS", "api", "serial")) diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index 5484a5add6..393a15762c 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -516,7 +516,7 @@ TEST(PairStyle, plain) TEST(PairStyle, omp) { - if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); + if (!Info::has_package("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", @@ -648,7 +648,7 @@ TEST(PairStyle, omp) TEST(PairStyle, kokkos_omp) { - if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); + if (!Info::has_package("KOKKOS")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); // test either OpenMP or Serial if (!Info::has_accelerator_feature("KOKKOS", "api", "serial") && @@ -801,7 +801,7 @@ TEST(PairStyle, kokkos_omp) TEST(PairStyle, gpu) { - if (!LAMMPS::is_installed_pkg("GPU")) GTEST_SKIP(); + if (!Info::has_package("GPU")) GTEST_SKIP(); if (!Info::has_gpu_device()) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); @@ -899,7 +899,7 @@ TEST(PairStyle, gpu) TEST(PairStyle, intel) { - if (!LAMMPS::is_installed_pkg("INTEL")) GTEST_SKIP(); + if (!Info::has_package("INTEL")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", @@ -990,7 +990,7 @@ TEST(PairStyle, intel) TEST(PairStyle, opt) { - if (!LAMMPS::is_installed_pkg("OPT")) GTEST_SKIP(); + if (!Info::has_package("OPT")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", "opt"}; diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp index f41584876b..7f802a37ac 100644 --- a/unittest/formats/test_atom_styles.cpp +++ b/unittest/formats/test_atom_styles.cpp @@ -19,6 +19,7 @@ #include "atom_vec_line.h" #include "atom_vec_tri.h" #include "body.h" +#include "info.h" #include "input.h" #include "lammps.h" #include "math_const.h" @@ -1146,7 +1147,7 @@ TEST_F(AtomStyleTest, sphere) TEST_F(AtomStyleTest, ellipsoid) { - if (!LAMMPS::is_installed_pkg("ASPHERE")) GTEST_SKIP(); + if (!Info::has_package("ASPHERE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("atom_style ellipsoid"); @@ -1483,7 +1484,7 @@ TEST_F(AtomStyleTest, ellipsoid) TEST_F(AtomStyleTest, line) { - if (!LAMMPS::is_installed_pkg("ASPHERE")) GTEST_SKIP(); + if (!Info::has_package("ASPHERE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("dimension 2"); @@ -1753,7 +1754,7 @@ TEST_F(AtomStyleTest, line) TEST_F(AtomStyleTest, tri) { - if (!LAMMPS::is_installed_pkg("ASPHERE")) GTEST_SKIP(); + if (!Info::has_package("ASPHERE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("atom_style tri"); @@ -2156,7 +2157,7 @@ TEST_F(AtomStyleTest, tri) TEST_F(AtomStyleTest, body_nparticle) { - if (!LAMMPS::is_installed_pkg("BODY")) GTEST_SKIP(); + if (!Info::has_package("BODY")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("atom_style body nparticle 2 4"); @@ -2724,7 +2725,7 @@ TEST_F(AtomStyleTest, body_nparticle) TEST_F(AtomStyleTest, template) { - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("molecule twomols h2o.mol co2.mol offset 2 1 1 0 0"); command("atom_style template twomols"); @@ -3119,7 +3120,7 @@ TEST_F(AtomStyleTest, template) TEST_F(AtomStyleTest, template_charge) { - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("molecule twomols h2o.mol co2.mol offset 2 1 1 0 0"); command("atom_style hybrid template twomols charge"); @@ -3547,7 +3548,7 @@ TEST_F(AtomStyleTest, template_charge) TEST_F(AtomStyleTest, bond) { - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("atom_style bond"); @@ -3895,7 +3896,7 @@ TEST_F(AtomStyleTest, bond) TEST_F(AtomStyleTest, angle) { - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("atom_style angle"); @@ -4255,8 +4256,8 @@ TEST_F(AtomStyleTest, angle) TEST_F(AtomStyleTest, full_ellipsoid) { - if (!LAMMPS::is_installed_pkg("ASPHERE")) GTEST_SKIP(); - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("ASPHERE")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("atom_style hybrid full ellipsoid"); @@ -4909,9 +4910,9 @@ TEST_F(AtomStyleTest, property_atom) TEST_F(AtomStyleTest, oxdna) { - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); - if (!LAMMPS::is_installed_pkg("ASPHERE")) GTEST_SKIP(); - if (!LAMMPS::is_installed_pkg("CG-DNA")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("ASPHERE")) GTEST_SKIP(); + if (!Info::has_package("CG-DNA")) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); command("atom_style hybrid bond ellipsoid oxdna"); diff --git a/unittest/formats/test_molecule_file.cpp b/unittest/formats/test_molecule_file.cpp index 98a9a23e40..e06cc59dc8 100644 --- a/unittest/formats/test_molecule_file.cpp +++ b/unittest/formats/test_molecule_file.cpp @@ -676,7 +676,7 @@ TEST_F(MoleculeFileTest, labelmap) TEST_F(MoleculeFileTest, bonds) { - if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); + if (!Info::has_package("MOLECULE")) GTEST_SKIP(); BEGIN_CAPTURE_OUTPUT(); command("atom_style bond"); command("region box block 0 1 0 1 0 1"); @@ -727,7 +727,7 @@ TEST_F(MoleculeFileTest, bonds) TEST_F(MoleculeFileTest, dipoles) { - if (!LAMMPS::is_installed_pkg("DIPOLE")) GTEST_SKIP(); + if (!Info::has_package("DIPOLE")) GTEST_SKIP(); BEGIN_CAPTURE_OUTPUT(); command("atom_style dipole"); command("region box block 0 1 0 1 0 1"); diff --git a/unittest/utils/test_utils.cpp b/unittest/utils/test_utils.cpp index 27fcca2061..3581a72b7a 100644 --- a/unittest/utils/test_utils.cpp +++ b/unittest/utils/test_utils.cpp @@ -11,6 +11,7 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include "atom.h" #include "lmptype.h" #include "pointers.h" #include "tokenizer.h" @@ -989,6 +990,16 @@ TEST(Utils, boundsbig_case3) ASSERT_EQ(nhi, -1); } +TEST(Utils, bounds_typelabel_forward) +{ + int nlo, nhi; + + nlo = nhi = -1; + utils::bounds_typelabel(FLERR, "2*9", 0, 10, nlo, nhi, nullptr, Atom::ATOM); + ASSERT_EQ(nlo, 2); + ASSERT_EQ(nhi, 9); +} + TEST(Utils, parse_grid_id) { auto words = utils::parse_grid_id(FLERR, "c_1:full:density", nullptr); @@ -1044,6 +1055,40 @@ TEST(Utils, getsyserror) #endif } +static void BEGIN_CAPTURE_OUTPUT() +{ + ::testing::internal::CaptureStdout(); +} + +static std::string END_CAPTURE_OUTPUT() +{ + return ::testing::internal::GetCapturedStdout(); +} + +TEST(Utils, print) +{ + BEGIN_CAPTURE_OUTPUT(); + utils::print("hello, world!\n"); + auto text = END_CAPTURE_OUTPUT(); + EXPECT_THAT(text, StrEq("hello, world!\n")); + + BEGIN_CAPTURE_OUTPUT(); + utils::print(stdout, "hello, world!\n"); + text = END_CAPTURE_OUTPUT(); + EXPECT_THAT(text, StrEq("hello, world!\n")); + + const auto world = "world"; + BEGIN_CAPTURE_OUTPUT(); + utils::print("hello, {:>20}!\n", world); + text = END_CAPTURE_OUTPUT(); + EXPECT_THAT(text, StrEq("hello, world!\n")); + + BEGIN_CAPTURE_OUTPUT(); + utils::print(stdout, "hello, {:<20}!\n", world); + text = END_CAPTURE_OUTPUT(); + EXPECT_THAT(text, StrEq("hello, world !\n")); +} + TEST(Utils, potential_file) { FILE *fp;