Commit 64d0f9a3 authored by Hans Fugal's avatar Hans Fugal Committed by ptarjan

(wangle) codegen then() variant tests

Summary:
When all the variants I am dreaming of work, there's a little more than
100 tests generated.

Test Plan: fbmake runtests

Reviewed By: hannesr@fb.com

FB internal diff: D1258754
parent a71d861b
// This file is @generated by thens.rb
#include "Thens.h"
TEST(Future, thenVariants) {
SomeClass anObject;
Executor* anExecutor;
{Future<B> f = someFuture<A>().then(aFunction<Future<B>, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<Future<B>, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&anObject, &SomeClass::aMethod<Future<B>, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(aStdFunction<Future<B>, Try<A>&&>());}
{Future<B> f = someFuture<A>().then([&](Try<A>&&){return someFuture<B>();});}
{Future<B> f = someFuture<A>().then(aFunction<B, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<B, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&anObject, &SomeClass::aMethod<B, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(aStdFunction<B, Try<A>&&>());}
{Future<B> f = someFuture<A>().then([&](Try<A>&&){return B();});}
}
/*
* Copyright 2014 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <gtest/gtest.h>
#include <memory>
#include "folly/wangle/Future.h"
#include "folly/wangle/Executor.h"
using namespace folly::wangle;
using namespace std;
using namespace testing;
typedef unique_ptr<int> A;
struct B {};
template <class T>
using EnableIfFuture = typename std::enable_if<isFuture<T>::value>::type;
template <class T>
using EnableUnlessFuture = typename std::enable_if<!isFuture<T>::value>::type;
template <class T>
Future<T> someFuture() {
return makeFuture(T());
}
template <class Ret, class... Params, typename = void>
Ret aFunction(Params...);
template <class Ret, class... Params>
typename std::enable_if<isFuture<Ret>::value, Ret>::type
aFunction(Params...) {
typedef typename Ret::value_type T;
return makeFuture(T());
}
template <class Ret, class... Params>
typename std::enable_if<!isFuture<Ret>::value, Ret>::type
aFunction(Params...) {
return Ret();
}
template <class Ret, class... Params>
std::function<Ret(Params...)>
aStdFunction(typename std::enable_if<!isFuture<Ret>::value, bool>::type = false) {
return [](Params...) -> Ret { return Ret(); };
}
template <class Ret, class... Params>
std::function<Ret(Params...)>
aStdFunction(typename std::enable_if<isFuture<Ret>::value, bool>::type = true) {
typedef typename Ret::value_type T;
return [](Params...) -> Future<T> { return makeFuture(T()); };
}
class SomeClass {
B b;
public:
template <class Ret, class... Params>
static Ret aStaticMethod(Params...);
template <class Ret, class... Params>
static
typename std::enable_if<!isFuture<Ret>::value, Ret>::type
aStaticMethod(Params...) {
return Ret();
}
template <class Ret, class... Params>
static
typename std::enable_if<isFuture<Ret>::value, Ret>::type
aStaticMethod(Params...) {
typedef typename Ret::value_type T;
return makeFuture(T());
}
template <class Ret, class... Params>
Ret aMethod(Params...);
template <class Ret, class... Params>
typename std::enable_if<!isFuture<Ret>::value, Ret>::type
aMethod(Params...) {
return Ret();
}
template <class Ret, class... Params>
typename std::enable_if<isFuture<Ret>::value, Ret>::type
aMethod(Params...) {
typedef typename Ret::value_type T;
return makeFuture(T());
}
};
#!/usr/bin/env ruby
# An exercise in combinatorics.
# (ordinary/static function, member function, std::function, lambda)
# X
# returns (Future<R>, R)
# X
# accepts (Try<T>&&, Try<T> const&, Try<T>, T&&, T const&, T, nothing)
def test(*args)
args = args.join(", ")
[
"{Future<B> f = someFuture<A>().then(#{args});}",
#"{Future<B> f = makeFuture(A()).then(#{args}, anExecutor);}",
]
end
def retval(ret)
{
"Future<B>" => "someFuture<B>()",
"Try<B>" => "Try<B>(B())",
"B" => "B()"
}[ret]
end
return_types = [
"Future<B>",
"B",
#"Try<B>",
]
param_types = [
"Try<A>&&",
#"Try<A> const&",
#"Try<A>",
#"Try<A>&",
#"A&&",
#"A const&",
#"A",
#"A&",
#"",
]
tests = (
return_types.map { |ret|
param_types.map { |param|
both = "#{ret}, #{param}"
[
["aFunction<#{both}>"],
["&SomeClass::aStaticMethod<#{both}>"],
# TODO switch these around (std::bind-style)
["&anObject", "&SomeClass::aMethod<#{both}>"],
["aStdFunction<#{both}>()"],
["[&](#{param}){return #{retval(ret)};}"],
]
}
}.flatten(2) + [
#[""],
]
).map {|a| test(a)}.flatten
print <<EOF
// This file is #{"@"}generated by thens.rb
#include "Thens.h"
TEST(Future, thenVariants) {
SomeClass anObject;
Executor* anExecutor;
#{tests.join("\n ")}
}
EOF
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment