Skip to content

Commit

Permalink
Enable option for disabling output generation (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanirvings authored and fushar committed Dec 6, 2016
1 parent 5f3b93f commit 4919ab6
Show file tree
Hide file tree
Showing 17 changed files with 287 additions and 17 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ set(SOURCES
include/tcframe/spec/core/Magic.hpp
include/tcframe/spec/core/MultipleTestCasesConfig.hpp
include/tcframe/spec/core/SeedSetter.hpp
include/tcframe/spec/core/StyleConfig.hpp
include/tcframe/spec/io.hpp
include/tcframe/spec/io/GridIOSegment.hpp
include/tcframe/spec/io/IOFormat.hpp
Expand Down
60 changes: 60 additions & 0 deletions ete-test/resources/multi-no-output/spec.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <tcframe/spec.hpp>

using namespace tcframe;

class ProblemSpec : public BaseProblemSpec {
protected:
int T;
int A, B;
int res;

void InputFormat() {
LINE(A, B);
}

void StyleConfig() {
NoOutput();
}

void GradingConfig() {
TimeLimit(2);
MemoryLimit(64);
}

void MultipleTestCasesConfig() {
Counter(T);
}

void MultipleTestCasesConstraints() {
CONS(1 <= T && T <= 5);
}

void Constraints() {
CONS(1 <= A && A <= 100);
CONS(1 <= B && B <= 100);
}
};

class TestSpec : public BaseTestSpec<ProblemSpec> {
protected:
void SampleTestCase1() {
Input({
"1 5"
});
}

void SampleTestCase2() {
Input({
"4 7"
});
}

void TestGroup1() {
CASE(A = 1, B = 3);
CASE(A = 2, B = 4);
}

void TestGroup2() {
CASE(A = 20, B = 30);
}
};
42 changes: 42 additions & 0 deletions ete-test/resources/normal-no-output/spec.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <tcframe/spec.hpp>

using namespace tcframe;

class ProblemSpec : public BaseProblemSpec {
protected:
int A, B;
int res;

void InputFormat() {
LINE(A, B);
}

void StyleConfig() {
NoOutput();
}

void GradingConfig() {
TimeLimit(2);
MemoryLimit(64);
}

void Constraints() {
CONS(1 <= A && A <= 10);
CONS(1 <= B && B <= 10);
}
};

class TestSpec : public BaseTestSpec<ProblemSpec> {
protected:
void SampleTestCase1() {
Input({
"1 5"
});
}

void TestCases() {
CASE(A = 1, B = 3);
CASE(A = 2, B = 4);
CASE(A = 5, B = 6);
}
};
9 changes: 9 additions & 0 deletions ete-test/resources/scripts/generate-without-solution.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -ex

export TCFRAME_HOME=../../tcframe

$TCFRAME_HOME/scripts/tcframe build
ls
./runner
26 changes: 26 additions & 0 deletions ete-test/tcframe/GenerationEteTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ TEST_F(GenerationEteTests, Normal) {
));
}

TEST_F(GenerationEteTests, Normal_NoOutput) {
ASSERT_THAT(execStatus("cd ete/normal-no-output && ../scripts/generate-without-solution.sh"), Eq(0));

EXPECT_THAT(ls("ete/normal-no-output/tc"), UnorderedElementsAre(
"normal-no-output_sample_1.in",
"normal-no-output_1.in",
"normal-no-output_2.in",
"normal-no-output_3.in"
));
}

TEST_F(GenerationEteTests, Normal_ComplexFormats) {
ASSERT_THAT(execStatus("cd ete/normal-complex-formats && ../scripts/generate.sh"), Eq(0));

Expand Down Expand Up @@ -65,6 +76,11 @@ TEST_F(GenerationEteTests, Multi) {
"multi_2.out"
));

EXPECT_THAT(readFile("ete/multi/tc/multi_1.in"), Eq(
"2\n"
"1 3\n"
"2 4\n"));

EXPECT_THAT(readFile("ete/multi/tc/multi_sample.out"), Eq(
"6\n"
"11\n"));
Expand All @@ -74,6 +90,16 @@ TEST_F(GenerationEteTests, Multi) {
"6\n"));
}

TEST_F(GenerationEteTests, Multi_NoOutput) {
ASSERT_THAT(execStatus("cd ete/multi-no-output && ../scripts/generate-without-solution.sh"), Eq(0));

EXPECT_THAT(ls("ete/multi-no-output/tc"), UnorderedElementsAre(
"multi-no-output_sample.in",
"multi-no-output_1.in",
"multi-no-output_2.in"
));
}

TEST_F(GenerationEteTests, Multi_WithOutputPrefix) {
ASSERT_THAT(execStatus("cd ete/multi-prefix && ../scripts/generate.sh"), Eq(0));

Expand Down
33 changes: 20 additions & 13 deletions include/tcframe/generator/Generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,15 @@ class Generator {
string baseId = TestCaseIdCreator::createBaseId(config.slug(), testGroup.id());
string baseIn = config.outputDir() + "/" + baseId + ".in";
string baseOut = config.outputDir() + "/" + baseId + ".out";
bool needsOutput = config.needsOutput();

ostringstream sout;

sout << "echo " << testCaseCount << " > " << baseId << ".in && ";
sout << "touch " << baseId << ".out";
sout << "echo " << testCaseCount << " > " << baseIn;

if (needsOutput) {
sout << " && touch " << baseOut;
}

os_->execute(ExecutionRequestBuilder().setCommand(sout.str()).build());

Expand All @@ -126,17 +130,20 @@ class Generator {
string out = config.outputDir() + "/" + id + ".out";

ostringstream sout2;
sout2 << "tail -n +2 " << in << " >> " << baseIn << " && ";

if (i > 1 && config.multipleTestCasesOutputPrefix()) {
string outputPrefix = config.multipleTestCasesOutputPrefix().value();
// Replace the prefix for the first tc, with the correct prefix for this tc
string firstPrefix = StringUtils::interpolate(outputPrefix, 1);
string correctPrefix = StringUtils::interpolate(outputPrefix, i);
sout2 << "printf \"%b\" \"" << escapeForBash(correctPrefix) << "\" >> " << baseOut << " && ";
sout2 << "tail -c +" << (firstPrefix.size() + 1) << " " << out << " >> " << baseOut;
} else {
sout2 << "cat " << out << " >> " << baseOut;
sout2 << "tail -n +2 " << in << " >> " << baseIn;

if (needsOutput) {
sout2 << " && ";
if (i > 1 && config.multipleTestCasesOutputPrefix()) {
string outputPrefix = config.multipleTestCasesOutputPrefix().value();
// Replace the prefix for the first tc, with the correct prefix for this tc
string firstPrefix = StringUtils::interpolate(outputPrefix, 1);
string correctPrefix = StringUtils::interpolate(outputPrefix, i);
sout2 << "printf \"%b\" \"" << escapeForBash(correctPrefix) << "\" >> " << baseOut << " && ";
sout2 << "tail -c +" << (firstPrefix.size() + 1) << " " << out << " >> " << baseOut;
} else {
sout2 << "cat " << out << " >> " << baseOut;
}
}

os_->execute(ExecutionRequestBuilder().setCommand(sout2.str()).build());
Expand Down
15 changes: 13 additions & 2 deletions include/tcframe/generator/GeneratorConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct GeneratorConfig {
unsigned seed_;
string solutionCommand_;
string outputDir_;
bool needsOutput_;

public:
const string& slug() const {
Expand Down Expand Up @@ -56,11 +57,15 @@ struct GeneratorConfig {
return outputDir_;
}

const bool needsOutput() const {
return needsOutput_;
}

bool operator==(const GeneratorConfig& o) const {
return tie(slug_, multipleTestCasesCounter_, multipleTestCasesOutputPrefix_,
seed_, solutionCommand_, outputDir_) ==
seed_, solutionCommand_, outputDir_, needsOutput_) ==
tie(o.slug_, o.multipleTestCasesCounter_, o.multipleTestCasesOutputPrefix_,
o.seed_, o.solutionCommand_, o.outputDir_);
o.seed_, o.solutionCommand_, o.outputDir_, o.needsOutput_);
}
};

Expand All @@ -78,6 +83,7 @@ class GeneratorConfigBuilder {
subject_.seed_ = CommonConfig::seed();
subject_.solutionCommand_ = CommonConfig::solutionCommand();
subject_.outputDir_ = CommonConfig::outputDir();
subject_.needsOutput_ = CommonConfig::needsOutput();
}

GeneratorConfigBuilder& setMultipleTestCasesCounter(optional<int*> counter) {
Expand Down Expand Up @@ -141,6 +147,11 @@ class GeneratorConfigBuilder {
return *this;
}

GeneratorConfigBuilder& setNeedsOutput(bool needsOutput) {
subject_.needsOutput_ = needsOutput;
return *this;
}

GeneratorConfig build() {
return move(subject_);
}
Expand Down
4 changes: 3 additions & 1 deletion include/tcframe/generator/TestCaseGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ class TestCaseGenerator {
applyInput(testCase);
verifyInput(testCase);
generateInput(testCase, inputFilename, config);
evaluateAndApplyOutput(testCase, inputFilename, outputFilename, config);
if (config.needsOutput()) {
evaluateAndApplyOutput(testCase, inputFilename, outputFilename, config);
}
} catch (GenerationException& e) {
logger_->logTestCaseFailedResult(testCase.description());
e.callback()();
Expand Down
1 change: 1 addition & 0 deletions include/tcframe/runner/Runner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class Runner {
.setSeed(args.seed())
.setSolutionCommand(args.solution())
.setOutputDir(args.output())
.setNeedsOutput(spec.styleConfig().needsOutput())
.build();

auto ioManipulator = new IOManipulator(spec.ioFormat());
Expand Down
7 changes: 7 additions & 0 deletions include/tcframe/spec/Spec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace tcframe {
struct Spec {
private:
SeedSetter* seedSetter_;
StyleConfig styleConfig_;
MultipleTestCasesConfig multipleTestCasesConfig_;
GradingConfig gradingConfig_;
IOFormat ioFormat_;
Expand All @@ -19,12 +20,14 @@ struct Spec {
public:
Spec(
SeedSetter* seedSetter,
const StyleConfig& styleConfig,
const MultipleTestCasesConfig& multipleTestCasesConfig,
const GradingConfig& gradingConfig,
const IOFormat& ioFormat,
const ConstraintSuite& constraintSuite,
const TestSuite& testSuite)
: seedSetter_(seedSetter)
, styleConfig_(styleConfig)
, multipleTestCasesConfig_(multipleTestCasesConfig)
, gradingConfig_(gradingConfig)
, ioFormat_(ioFormat)
Expand All @@ -35,6 +38,10 @@ struct Spec {
return seedSetter_;
}

const StyleConfig& styleConfig() const {
return styleConfig_;
}

const MultipleTestCasesConfig& multipleTestCasesConfig() const {
return multipleTestCasesConfig_;
}
Expand Down
1 change: 1 addition & 0 deletions include/tcframe/spec/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
#include "tcframe/spec/core/Magic.hpp"
#include "tcframe/spec/core/MultipleTestCasesConfig.hpp"
#include "tcframe/spec/core/SeedSetter.hpp"
#include "tcframe/spec/core/StyleConfig.hpp"
8 changes: 8 additions & 0 deletions include/tcframe/spec/core/BaseProblemSpec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "GradingConfig.hpp"
#include "MultipleTestCasesConfig.hpp"
#include "StyleConfig.hpp"
#include "tcframe/spec/constraint.hpp"
#include "tcframe/spec/io.hpp"
#include "tcframe/util.hpp"
Expand All @@ -15,6 +16,7 @@ namespace tcframe {
class BaseProblemSpec
: protected MultipleTestCasesConfigBuilder,
protected GradingConfigBuilder,
protected StyleConfigBuilder,
protected IOFormatBuilder,
protected ConstraintSuiteBuilder {
private:
Expand Down Expand Up @@ -48,6 +50,11 @@ class BaseProblemSpec
public:
virtual ~BaseProblemSpec() {}

tcframe::StyleConfig buildStyleConfig() {
StyleConfig();
return StyleConfigBuilder::build();
}

tcframe::MultipleTestCasesConfig buildMultipleTestCasesConfig() {
MultipleTestCasesConfig();
return MultipleTestCasesConfigBuilder::build();
Expand Down Expand Up @@ -85,6 +92,7 @@ class BaseProblemSpec
protected:
virtual void InputFormat() = 0;
virtual void OutputFormat() {}
virtual void StyleConfig() {}
virtual void GradingConfig() {}
virtual void MultipleTestCasesConfig() {}
virtual void MultipleTestCasesConstraints() {}
Expand Down
10 changes: 9 additions & 1 deletion include/tcframe/spec/core/BaseTestSpec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "GradingConfig.hpp"
#include "MultipleTestCasesConfig.hpp"
#include "SeedSetter.hpp"
#include "StyleConfig.hpp"
#include "tcframe/spec.hpp"
#include "tcframe/util.hpp"

Expand Down Expand Up @@ -110,12 +111,19 @@ class BaseTestSpec : public TProblemSpec, protected TestSuiteBuilder {

virtual Spec buildSpec(const string& slug) {
SeedSetter* seedSetter = new SeedSetter([=] (unsigned seed) {rnd.setSeed(seed);});
StyleConfig styleConfig = TProblemSpec::buildStyleConfig();
MultipleTestCasesConfig multipleTestCasesConfig = TProblemSpec::buildMultipleTestCasesConfig();
GradingConfig gradingConfig = TProblemSpec::buildGradingConfig();
IOFormat ioFormat = TProblemSpec::buildIOFormat();
ConstraintSuite constraintSuite = TProblemSpec::buildConstraintSuite();
TestSuite testSuite = buildTestSuite(slug);
return Spec(seedSetter, multipleTestCasesConfig, gradingConfig, ioFormat, constraintSuite, testSuite);
return Spec(seedSetter,
styleConfig,
multipleTestCasesConfig,
gradingConfig,
ioFormat,
constraintSuite,
testSuite);
}

protected:
Expand Down
4 changes: 4 additions & 0 deletions include/tcframe/spec/core/CommonConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class CommonConfig {
static string outputDir() {
return "tc";
}

static bool needsOutput() {
return true;
}
};

}

0 comments on commit 4919ab6

Please sign in to comment.