Compare commits

...

7 Commits

Author SHA1 Message Date
Michael Richters ab7e4187d1
Update Redial testcase to use default keymap
4 years ago
Michael Richters f50af857aa
Update Qukeys test suite to use the keymap definition stuff
4 years ago
Michael Richters 1c559260fd
Add basic OneShot testcase
4 years ago
Michael Richters 7ef7b4ba57
Add common keymap files to simplify test sketches
4 years ago
Michael Richters 9ee4c931f3
Use new testing infrastructure in Qukeys test cases
4 years ago
Michael Richters 278bea785b
Use new testing infrastructure in Redial test cases
4 years ago
Michael Richters c4139e48f7
Add Millis and Cycles types to enable polymorphic Run, PressKey, ReleaseKey, etc.
4 years ago

@ -0,0 +1,98 @@
// -*- c++ -*-
#pragma once
#define LAYER_0 \
[0] = KEYMAP_STACKED( \
key_0AA, key_0AB, key_0AC, key_0AD, key_0AE, key_0AF, key_0AG, \
key_0BA, key_0BB, key_0BC, key_0BD, key_0BE, key_0BF, key_0BG, \
key_0CA, key_0CB, key_0CC, key_0CD, key_0CE, key_0CF, \
key_0DA, key_0DB, key_0DC, key_0DD, key_0DE, key_0DF, key_0CG, \
key_0AH, key_0BH, key_0CH, key_0DH, \
key_0DG, \
\
key_0AJ, key_0AK, key_0AL, key_0AM, key_0AN, key_0AO, key_0AP, \
key_0BJ, key_0BK, key_0BL, key_0BM, key_0BN, key_0BO, key_0BP, \
key_0CK, key_0CL, key_0CM, key_0CN, key_0CO, key_0CP, \
key_0CJ, key_0DK, key_0DL, key_0DM, key_0DN, key_0DO, key_0DP, \
key_0DI, key_0CI, key_0BI, key_0AI, \
key_0DJ)
#define LAYER_1 \
[1] = KEYMAP_STACKED( \
key_1AA, key_1AB, key_1AC, key_1AD, key_1AE, key_1AF, key_1AG, \
key_1BA, key_1BB, key_1BC, key_1BD, key_1BE, key_1BF, key_1BG, \
key_1CA, key_1CB, key_1CC, key_1CD, key_1CE, key_1CF, \
key_1DA, key_1DB, key_1DC, key_1DD, key_1DE, key_1DF, key_1CG, \
key_1AH, key_1BH, key_1CH, key_1DH, \
key_1DG, \
\
key_1AJ, key_1AK, key_1AL, key_1AM, key_1AN, key_1AO, key_1AP, \
key_1BJ, key_1BK, key_1BL, key_1BM, key_1BN, key_1BO, key_1BP, \
key_1CK, key_1CL, key_1CM, key_1CN, key_1CO, key_1CP, \
key_1CJ, key_1DK, key_1DL, key_1DM, key_1DN, key_1DO, key_1DP, \
key_1DI, key_1CI, key_1BI, key_1AI, \
key_1DJ)
#define LAYER_2 \
[2] = KEYMAP_STACKED( \
key_2AA, key_2AB, key_2AC, key_2AD, key_2AE, key_2AF, key_2AG, \
key_2BA, key_2BB, key_2BC, key_2BD, key_2BE, key_2BF, key_2BG, \
key_2CA, key_2CB, key_2CC, key_2CD, key_2CE, key_2CF, \
key_2DA, key_2DB, key_2DC, key_2DD, key_2DE, key_2DF, key_2CG, \
key_2AH, key_2BH, key_2CH, key_2DH, \
key_2DG, \
\
key_2AJ, key_2AK, key_2AL, key_2AM, key_2AN, key_2AO, key_2AP, \
key_2BJ, key_2BK, key_2BL, key_2BM, key_2BN, key_2BO, key_2BP, \
key_2CK, key_2CL, key_2CM, key_2CN, key_2CO, key_2CP, \
key_2CJ, key_2DK, key_2DL, key_2DM, key_2DN, key_2DO, key_2DP, \
key_2DI, key_2CI, key_2BI, key_2AI, \
key_2DJ)
#define LAYER_3 \
[3] = KEYMAP_STACKED( \
key_3AA, key_3AB, key_3AC, key_3AD, key_3AE, key_3AF, key_3AG, \
key_3BA, key_3BB, key_3BC, key_3BD, key_3BE, key_3BF, key_3BG, \
key_3CA, key_3CB, key_3CC, key_3CD, key_3CE, key_3CF, \
key_3DA, key_3DB, key_3DC, key_3DD, key_3DE, key_3DF, key_3CG, \
key_3AH, key_3BH, key_3CH, key_3DH, \
key_3DG, \
\
key_3AJ, key_3AK, key_3AL, key_3AM, key_3AN, key_3AO, key_3AP, \
key_3BJ, key_3BK, key_3BL, key_3BM, key_3BN, key_3BO, key_3BP, \
key_3CK, key_3CL, key_3CM, key_3CN, key_3CO, key_3CP, \
key_3CJ, key_3DK, key_3DL, key_3DM, key_3DN, key_3DO, key_3DP, \
key_3DI, key_3CI, key_3BI, key_3AI, \
key_3DJ)
#define LAYER_4 \
[4] = KEYMAP_STACKED( \
key_4AA, key_4AB, key_4AC, key_4AD, key_4AE, key_4AF, key_4AG, \
key_4BA, key_4BB, key_4BC, key_4BD, key_4BE, key_4BF, key_4BG, \
key_4CA, key_4CB, key_4CC, key_4CD, key_4CE, key_4CF, \
key_4DA, key_4DB, key_4DC, key_4DD, key_4DE, key_4DF, key_4CG, \
key_4AH, key_4BH, key_4CH, key_4DH, \
key_4DG, \
\
key_4AJ, key_4AK, key_4AL, key_4AM, key_4AN, key_4AO, key_4AP, \
key_4BJ, key_4BK, key_4BL, key_4BM, key_4BN, key_4BO, key_4BP, \
key_4CK, key_4CL, key_4CM, key_4CN, key_4CO, key_4CP, \
key_4CJ, key_4DK, key_4DL, key_4DM, key_4DN, key_4DO, key_4DP, \
key_4DI, key_4CI, key_4BI, key_4AI, \
key_4DJ)
#define LAYER_5 \
[5] = KEYMAP_STACKED( \
key_5AA, key_5AB, key_5AC, key_5AD, key_5AE, key_5AF, key_5AG, \
key_5BA, key_5BB, key_5BC, key_5BD, key_5BE, key_5BF, key_5BG, \
key_5CA, key_5CB, key_5CC, key_5CD, key_5CE, key_5CF, \
key_5DA, key_5DB, key_5DC, key_5DD, key_5DE, key_5DF, key_5CG, \
key_5AH, key_5BH, key_5CH, key_5DH, \
key_5DG, \
\
key_5AJ, key_5AK, key_5AL, key_5AM, key_5AN, key_5AO, key_5AP, \
key_5BJ, key_5BK, key_5BL, key_5BM, key_5BN, key_5BO, key_5BP, \
key_5CK, key_5CL, key_5CM, key_5CN, key_5CO, key_5CP, \
key_5CJ, key_5DK, key_5DL, key_5DM, key_5DN, key_5DO, key_5DP, \
key_5DI, key_5CI, key_5BI, key_5AI, \
key_5DJ)

@ -0,0 +1,270 @@
// -*- c++ -*-
namespace kaleidoscope {
namespace testing {
namespace keymap {
// Layer 0
constexpr Key key_0AA = Keymap::key_0AA;
constexpr Key key_0AB = Keymap::key_0AB;
constexpr Key key_0AC = Keymap::key_0AC;
constexpr Key key_0AD = Keymap::key_0AD;
constexpr Key key_0AE = Keymap::key_0AE;
constexpr Key key_0AF = Keymap::key_0AF;
constexpr Key key_0AG = Keymap::key_0AG;
constexpr Key key_0AH = Keymap::key_0AH;
constexpr Key key_0AI = Keymap::key_0AI;
constexpr Key key_0AJ = Keymap::key_0AJ;
constexpr Key key_0AK = Keymap::key_0AK;
constexpr Key key_0AL = Keymap::key_0AL;
constexpr Key key_0AM = Keymap::key_0AM;
constexpr Key key_0AN = Keymap::key_0AN;
constexpr Key key_0AO = Keymap::key_0AO;
constexpr Key key_0AP = Keymap::key_0AP;
constexpr Key key_0BA = Keymap::key_0BA;
constexpr Key key_0BB = Keymap::key_0BB;
constexpr Key key_0BC = Keymap::key_0BC;
constexpr Key key_0BD = Keymap::key_0BD;
constexpr Key key_0BE = Keymap::key_0BE;
constexpr Key key_0BF = Keymap::key_0BF;
constexpr Key key_0BG = Keymap::key_0BG;
constexpr Key key_0BH = Keymap::key_0BH;
constexpr Key key_0BI = Keymap::key_0BI;
constexpr Key key_0BJ = Keymap::key_0BJ;
constexpr Key key_0BK = Keymap::key_0BK;
constexpr Key key_0BL = Keymap::key_0BL;
constexpr Key key_0BM = Keymap::key_0BM;
constexpr Key key_0BN = Keymap::key_0BN;
constexpr Key key_0BO = Keymap::key_0BO;
constexpr Key key_0BP = Keymap::key_0BP;
constexpr Key key_0CA = Keymap::key_0CA;
constexpr Key key_0CB = Keymap::key_0CB;
constexpr Key key_0CC = Keymap::key_0CC;
constexpr Key key_0CD = Keymap::key_0CD;
constexpr Key key_0CE = Keymap::key_0CE;
constexpr Key key_0CF = Keymap::key_0CF;
constexpr Key key_0CG = Keymap::key_0CG;
constexpr Key key_0CH = Keymap::key_0CH;
constexpr Key key_0CI = Keymap::key_0CI;
constexpr Key key_0CJ = Keymap::key_0CJ;
constexpr Key key_0CK = Keymap::key_0CK;
constexpr Key key_0CL = Keymap::key_0CL;
constexpr Key key_0CM = Keymap::key_0CM;
constexpr Key key_0CN = Keymap::key_0CN;
constexpr Key key_0CO = Keymap::key_0CO;
constexpr Key key_0CP = Keymap::key_0CP;
constexpr Key key_0DA = Keymap::key_0DA;
constexpr Key key_0DB = Keymap::key_0DB;
constexpr Key key_0DC = Keymap::key_0DC;
constexpr Key key_0DD = Keymap::key_0DD;
constexpr Key key_0DE = Keymap::key_0DE;
constexpr Key key_0DF = Keymap::key_0DF;
constexpr Key key_0DG = Keymap::key_0DG;
constexpr Key key_0DH = Keymap::key_0DH;
constexpr Key key_0DI = Keymap::key_0DI;
constexpr Key key_0DJ = Keymap::key_0DJ;
constexpr Key key_0DK = Keymap::key_0DK;
constexpr Key key_0DL = Keymap::key_0DL;
constexpr Key key_0DM = Keymap::key_0DM;
constexpr Key key_0DN = Keymap::key_0DN;
constexpr Key key_0DO = Keymap::key_0DO;
constexpr Key key_0DP = Keymap::key_0DP;
// Layer 1
constexpr Key key_1AA = Keymap::key_1AA;
constexpr Key key_1AB = Keymap::key_1AB;
constexpr Key key_1AC = Keymap::key_1AC;
constexpr Key key_1AD = Keymap::key_1AD;
constexpr Key key_1AE = Keymap::key_1AE;
constexpr Key key_1AF = Keymap::key_1AF;
constexpr Key key_1AG = Keymap::key_1AG;
constexpr Key key_1AH = Keymap::key_1AH;
constexpr Key key_1AI = Keymap::key_1AI;
constexpr Key key_1AJ = Keymap::key_1AJ;
constexpr Key key_1AK = Keymap::key_1AK;
constexpr Key key_1AL = Keymap::key_1AL;
constexpr Key key_1AM = Keymap::key_1AM;
constexpr Key key_1AN = Keymap::key_1AN;
constexpr Key key_1AO = Keymap::key_1AO;
constexpr Key key_1AP = Keymap::key_1AP;
constexpr Key key_1BA = Keymap::key_1BA;
constexpr Key key_1BB = Keymap::key_1BB;
constexpr Key key_1BC = Keymap::key_1BC;
constexpr Key key_1BD = Keymap::key_1BD;
constexpr Key key_1BE = Keymap::key_1BE;
constexpr Key key_1BF = Keymap::key_1BF;
constexpr Key key_1BG = Keymap::key_1BG;
constexpr Key key_1BH = Keymap::key_1BH;
constexpr Key key_1BI = Keymap::key_1BI;
constexpr Key key_1BJ = Keymap::key_1BJ;
constexpr Key key_1BK = Keymap::key_1BK;
constexpr Key key_1BL = Keymap::key_1BL;
constexpr Key key_1BM = Keymap::key_1BM;
constexpr Key key_1BN = Keymap::key_1BN;
constexpr Key key_1BO = Keymap::key_1BO;
constexpr Key key_1BP = Keymap::key_1BP;
constexpr Key key_1CA = Keymap::key_1CA;
constexpr Key key_1CB = Keymap::key_1CB;
constexpr Key key_1CC = Keymap::key_1CC;
constexpr Key key_1CD = Keymap::key_1CD;
constexpr Key key_1CE = Keymap::key_1CE;
constexpr Key key_1CF = Keymap::key_1CF;
constexpr Key key_1CG = Keymap::key_1CG;
constexpr Key key_1CH = Keymap::key_1CH;
constexpr Key key_1CI = Keymap::key_1CI;
constexpr Key key_1CJ = Keymap::key_1CJ;
constexpr Key key_1CK = Keymap::key_1CK;
constexpr Key key_1CL = Keymap::key_1CL;
constexpr Key key_1CM = Keymap::key_1CM;
constexpr Key key_1CN = Keymap::key_1CN;
constexpr Key key_1CO = Keymap::key_1CO;
constexpr Key key_1CP = Keymap::key_1CP;
constexpr Key key_1DA = Keymap::key_1DA;
constexpr Key key_1DB = Keymap::key_1DB;
constexpr Key key_1DC = Keymap::key_1DC;
constexpr Key key_1DD = Keymap::key_1DD;
constexpr Key key_1DE = Keymap::key_1DE;
constexpr Key key_1DF = Keymap::key_1DF;
constexpr Key key_1DG = Keymap::key_1DG;
constexpr Key key_1DH = Keymap::key_1DH;
constexpr Key key_1DI = Keymap::key_1DI;
constexpr Key key_1DJ = Keymap::key_1DJ;
constexpr Key key_1DK = Keymap::key_1DK;
constexpr Key key_1DL = Keymap::key_1DL;
constexpr Key key_1DM = Keymap::key_1DM;
constexpr Key key_1DN = Keymap::key_1DN;
constexpr Key key_1DO = Keymap::key_1DO;
constexpr Key key_1DP = Keymap::key_1DP;
// Layer 2
constexpr Key key_2AA = Keymap::key_2AA;
constexpr Key key_2AB = Keymap::key_2AB;
constexpr Key key_2AC = Keymap::key_2AC;
constexpr Key key_2AD = Keymap::key_2AD;
constexpr Key key_2AE = Keymap::key_2AE;
constexpr Key key_2AF = Keymap::key_2AF;
constexpr Key key_2AG = Keymap::key_2AG;
constexpr Key key_2AH = Keymap::key_2AH;
constexpr Key key_2AI = Keymap::key_2AI;
constexpr Key key_2AJ = Keymap::key_2AJ;
constexpr Key key_2AK = Keymap::key_2AK;
constexpr Key key_2AL = Keymap::key_2AL;
constexpr Key key_2AM = Keymap::key_2AM;
constexpr Key key_2AN = Keymap::key_2AN;
constexpr Key key_2AO = Keymap::key_2AO;
constexpr Key key_2AP = Keymap::key_2AP;
constexpr Key key_2BA = Keymap::key_2BA;
constexpr Key key_2BB = Keymap::key_2BB;
constexpr Key key_2BC = Keymap::key_2BC;
constexpr Key key_2BD = Keymap::key_2BD;
constexpr Key key_2BE = Keymap::key_2BE;
constexpr Key key_2BF = Keymap::key_2BF;
constexpr Key key_2BG = Keymap::key_2BG;
constexpr Key key_2BH = Keymap::key_2BH;
constexpr Key key_2BI = Keymap::key_2BI;
constexpr Key key_2BJ = Keymap::key_2BJ;
constexpr Key key_2BK = Keymap::key_2BK;
constexpr Key key_2BL = Keymap::key_2BL;
constexpr Key key_2BM = Keymap::key_2BM;
constexpr Key key_2BN = Keymap::key_2BN;
constexpr Key key_2BO = Keymap::key_2BO;
constexpr Key key_2BP = Keymap::key_2BP;
constexpr Key key_2CA = Keymap::key_2CA;
constexpr Key key_2CB = Keymap::key_2CB;
constexpr Key key_2CC = Keymap::key_2CC;
constexpr Key key_2CD = Keymap::key_2CD;
constexpr Key key_2CE = Keymap::key_2CE;
constexpr Key key_2CF = Keymap::key_2CF;
constexpr Key key_2CG = Keymap::key_2CG;
constexpr Key key_2CH = Keymap::key_2CH;
constexpr Key key_2CI = Keymap::key_2CI;
constexpr Key key_2CJ = Keymap::key_2CJ;
constexpr Key key_2CK = Keymap::key_2CK;
constexpr Key key_2CL = Keymap::key_2CL;
constexpr Key key_2CM = Keymap::key_2CM;
constexpr Key key_2CN = Keymap::key_2CN;
constexpr Key key_2CO = Keymap::key_2CO;
constexpr Key key_2CP = Keymap::key_2CP;
constexpr Key key_2DA = Keymap::key_2DA;
constexpr Key key_2DB = Keymap::key_2DB;
constexpr Key key_2DC = Keymap::key_2DC;
constexpr Key key_2DD = Keymap::key_2DD;
constexpr Key key_2DE = Keymap::key_2DE;
constexpr Key key_2DF = Keymap::key_2DF;
constexpr Key key_2DG = Keymap::key_2DG;
constexpr Key key_2DH = Keymap::key_2DH;
constexpr Key key_2DI = Keymap::key_2DI;
constexpr Key key_2DJ = Keymap::key_2DJ;
constexpr Key key_2DK = Keymap::key_2DK;
constexpr Key key_2DL = Keymap::key_2DL;
constexpr Key key_2DM = Keymap::key_2DM;
constexpr Key key_2DN = Keymap::key_2DN;
constexpr Key key_2DO = Keymap::key_2DO;
constexpr Key key_2DP = Keymap::key_2DP;
// Layer 3
constexpr Key key_3AA = Keymap::key_3AA;
constexpr Key key_3AB = Keymap::key_3AB;
constexpr Key key_3AC = Keymap::key_3AC;
constexpr Key key_3AD = Keymap::key_3AD;
constexpr Key key_3AE = Keymap::key_3AE;
constexpr Key key_3AF = Keymap::key_3AF;
constexpr Key key_3AG = Keymap::key_3AG;
constexpr Key key_3AH = Keymap::key_3AH;
constexpr Key key_3AI = Keymap::key_3AI;
constexpr Key key_3AJ = Keymap::key_3AJ;
constexpr Key key_3AK = Keymap::key_3AK;
constexpr Key key_3AL = Keymap::key_3AL;
constexpr Key key_3AM = Keymap::key_3AM;
constexpr Key key_3AN = Keymap::key_3AN;
constexpr Key key_3AO = Keymap::key_3AO;
constexpr Key key_3AP = Keymap::key_3AP;
constexpr Key key_3BA = Keymap::key_3BA;
constexpr Key key_3BB = Keymap::key_3BB;
constexpr Key key_3BC = Keymap::key_3BC;
constexpr Key key_3BD = Keymap::key_3BD;
constexpr Key key_3BE = Keymap::key_3BE;
constexpr Key key_3BF = Keymap::key_3BF;
constexpr Key key_3BG = Keymap::key_3BG;
constexpr Key key_3BH = Keymap::key_3BH;
constexpr Key key_3BI = Keymap::key_3BI;
constexpr Key key_3BJ = Keymap::key_3BJ;
constexpr Key key_3BK = Keymap::key_3BK;
constexpr Key key_3BL = Keymap::key_3BL;
constexpr Key key_3BM = Keymap::key_3BM;
constexpr Key key_3BN = Keymap::key_3BN;
constexpr Key key_3BO = Keymap::key_3BO;
constexpr Key key_3BP = Keymap::key_3BP;
constexpr Key key_3CA = Keymap::key_3CA;
constexpr Key key_3CB = Keymap::key_3CB;
constexpr Key key_3CC = Keymap::key_3CC;
constexpr Key key_3CD = Keymap::key_3CD;
constexpr Key key_3CE = Keymap::key_3CE;
constexpr Key key_3CF = Keymap::key_3CF;
constexpr Key key_3CG = Keymap::key_3CG;
constexpr Key key_3CH = Keymap::key_3CH;
constexpr Key key_3CI = Keymap::key_3CI;
constexpr Key key_3CJ = Keymap::key_3CJ;
constexpr Key key_3CK = Keymap::key_3CK;
constexpr Key key_3CL = Keymap::key_3CL;
constexpr Key key_3CM = Keymap::key_3CM;
constexpr Key key_3CN = Keymap::key_3CN;
constexpr Key key_3CO = Keymap::key_3CO;
constexpr Key key_3CP = Keymap::key_3CP;
constexpr Key key_3DA = Keymap::key_3DA;
constexpr Key key_3DB = Keymap::key_3DB;
constexpr Key key_3DC = Keymap::key_3DC;
constexpr Key key_3DD = Keymap::key_3DD;
constexpr Key key_3DE = Keymap::key_3DE;
constexpr Key key_3DF = Keymap::key_3DF;
constexpr Key key_3DG = Keymap::key_3DG;
constexpr Key key_3DH = Keymap::key_3DH;
constexpr Key key_3DI = Keymap::key_3DI;
constexpr Key key_3DJ = Keymap::key_3DJ;
constexpr Key key_3DK = Keymap::key_3DK;
constexpr Key key_3DL = Keymap::key_3DL;
constexpr Key key_3DM = Keymap::key_3DM;
constexpr Key key_3DN = Keymap::key_3DN;
constexpr Key key_3DO = Keymap::key_3DO;
constexpr Key key_3DP = Keymap::key_3DP;
} // namespace keymap
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,344 @@
// -*- c++ -*-
#pragma once
#include <kaleidoscope/key_defs.h>
#include <kaleidoscope/KeyAddr.h>
namespace kaleidoscope {
namespace testing {
constexpr KeyAddr addr_AA{0, 0};
constexpr KeyAddr addr_AB{0, 1};
constexpr KeyAddr addr_AC{0, 2};
constexpr KeyAddr addr_AD{0, 3};
constexpr KeyAddr addr_AE{0, 4};
constexpr KeyAddr addr_AF{0, 5};
constexpr KeyAddr addr_AG{0, 6};
constexpr KeyAddr addr_AH{0, 7};
constexpr KeyAddr addr_AI{0, 8};
constexpr KeyAddr addr_AJ{0, 9};
constexpr KeyAddr addr_AK{0, 10};
constexpr KeyAddr addr_AL{0, 11};
constexpr KeyAddr addr_AM{0, 12};
constexpr KeyAddr addr_AN{0, 13};
constexpr KeyAddr addr_AO{0, 14};
constexpr KeyAddr addr_AP{0, 15};
constexpr KeyAddr addr_BA{1, 0};
constexpr KeyAddr addr_BB{1, 1};
constexpr KeyAddr addr_BC{1, 2};
constexpr KeyAddr addr_BD{1, 3};
constexpr KeyAddr addr_BE{1, 4};
constexpr KeyAddr addr_BF{1, 5};
constexpr KeyAddr addr_BG{1, 6};
constexpr KeyAddr addr_BH{1, 7};
constexpr KeyAddr addr_BI{1, 8};
constexpr KeyAddr addr_BJ{1, 9};
constexpr KeyAddr addr_BK{1, 10};
constexpr KeyAddr addr_BL{1, 11};
constexpr KeyAddr addr_BM{1, 12};
constexpr KeyAddr addr_BN{1, 13};
constexpr KeyAddr addr_BO{1, 14};
constexpr KeyAddr addr_BP{1, 15};
constexpr KeyAddr addr_CA{2, 0};
constexpr KeyAddr addr_CB{2, 1};
constexpr KeyAddr addr_CC{2, 2};
constexpr KeyAddr addr_CD{2, 3};
constexpr KeyAddr addr_CE{2, 4};
constexpr KeyAddr addr_CF{2, 5};
constexpr KeyAddr addr_CG{2, 6};
constexpr KeyAddr addr_CH{2, 7};
constexpr KeyAddr addr_CI{2, 8};
constexpr KeyAddr addr_CJ{2, 9};
constexpr KeyAddr addr_CK{2, 10};
constexpr KeyAddr addr_CL{2, 11};
constexpr KeyAddr addr_CM{2, 12};
constexpr KeyAddr addr_CN{2, 13};
constexpr KeyAddr addr_CO{2, 14};
constexpr KeyAddr addr_CP{2, 15};
constexpr KeyAddr addr_DA{3, 0};
constexpr KeyAddr addr_DB{3, 1};
constexpr KeyAddr addr_DC{3, 2};
constexpr KeyAddr addr_DD{3, 3};
constexpr KeyAddr addr_DE{3, 4};
constexpr KeyAddr addr_DF{3, 5};
constexpr KeyAddr addr_DG{3, 6};
constexpr KeyAddr addr_DH{3, 7};
constexpr KeyAddr addr_DI{3, 8};
constexpr KeyAddr addr_DJ{3, 9};
constexpr KeyAddr addr_DK{3, 10};
constexpr KeyAddr addr_DL{3, 11};
constexpr KeyAddr addr_DM{3, 12};
constexpr KeyAddr addr_DN{3, 13};
constexpr KeyAddr addr_DO{3, 14};
constexpr KeyAddr addr_DP{3, 15};
namespace keymap {
class KeymapDefaults {
public:
// Layer 0
static constexpr Key key_0AA = ___;
static constexpr Key key_0AB = ___;
static constexpr Key key_0AC = ___;
static constexpr Key key_0AD = ___;
static constexpr Key key_0AE = ___;
static constexpr Key key_0AF = ___;
static constexpr Key key_0AG = ___;
static constexpr Key key_0AH = ___;
static constexpr Key key_0AI = ___;
static constexpr Key key_0AJ = ___;
static constexpr Key key_0AK = ___;
static constexpr Key key_0AL = ___;
static constexpr Key key_0AM = ___;
static constexpr Key key_0AN = ___;
static constexpr Key key_0AO = ___;
static constexpr Key key_0AP = ___;
static constexpr Key key_0BA = ___;
static constexpr Key key_0BB = ___;
static constexpr Key key_0BC = ___;
static constexpr Key key_0BD = ___;
static constexpr Key key_0BE = ___;
static constexpr Key key_0BF = ___;
static constexpr Key key_0BG = ___;
static constexpr Key key_0BH = ___;
static constexpr Key key_0BI = ___;
static constexpr Key key_0BJ = ___;
static constexpr Key key_0BK = ___;
static constexpr Key key_0BL = ___;
static constexpr Key key_0BM = ___;
static constexpr Key key_0BN = ___;
static constexpr Key key_0BO = ___;
static constexpr Key key_0BP = ___;
static constexpr Key key_0CA = ___;
static constexpr Key key_0CB = ___;
static constexpr Key key_0CC = ___;
static constexpr Key key_0CD = ___;
static constexpr Key key_0CE = ___;
static constexpr Key key_0CF = ___;
static constexpr Key key_0CG = ___;
static constexpr Key key_0CH = ___;
static constexpr Key key_0CI = ___;
static constexpr Key key_0CJ = ___;
static constexpr Key key_0CK = ___;
static constexpr Key key_0CL = ___;
static constexpr Key key_0CM = ___;
static constexpr Key key_0CN = ___;
static constexpr Key key_0CO = ___;
static constexpr Key key_0CP = ___;
static constexpr Key key_0DA = ___;
static constexpr Key key_0DB = ___;
static constexpr Key key_0DC = ___;
static constexpr Key key_0DD = ___;
static constexpr Key key_0DE = ___;
static constexpr Key key_0DF = ___;
static constexpr Key key_0DG = ___;
static constexpr Key key_0DH = ___;
static constexpr Key key_0DI = ___;
static constexpr Key key_0DJ = ___;
static constexpr Key key_0DK = ___;
static constexpr Key key_0DL = ___;
static constexpr Key key_0DM = ___;
static constexpr Key key_0DN = ___;
static constexpr Key key_0DO = ___;
static constexpr Key key_0DP = ___;
// Layer 1
static constexpr Key key_1AA = ___;
static constexpr Key key_1AB = ___;
static constexpr Key key_1AC = ___;
static constexpr Key key_1AD = ___;
static constexpr Key key_1AE = ___;
static constexpr Key key_1AF = ___;
static constexpr Key key_1AG = ___;
static constexpr Key key_1AH = ___;
static constexpr Key key_1AI = ___;
static constexpr Key key_1AJ = ___;
static constexpr Key key_1AK = ___;
static constexpr Key key_1AL = ___;
static constexpr Key key_1AM = ___;
static constexpr Key key_1AN = ___;
static constexpr Key key_1AO = ___;
static constexpr Key key_1AP = ___;
static constexpr Key key_1BA = ___;
static constexpr Key key_1BB = ___;
static constexpr Key key_1BC = ___;
static constexpr Key key_1BD = ___;
static constexpr Key key_1BE = ___;
static constexpr Key key_1BF = ___;
static constexpr Key key_1BG = ___;
static constexpr Key key_1BH = ___;
static constexpr Key key_1BI = ___;
static constexpr Key key_1BJ = ___;
static constexpr Key key_1BK = ___;
static constexpr Key key_1BL = ___;
static constexpr Key key_1BM = ___;
static constexpr Key key_1BN = ___;
static constexpr Key key_1BO = ___;
static constexpr Key key_1BP = ___;
static constexpr Key key_1CA = ___;
static constexpr Key key_1CB = ___;
static constexpr Key key_1CC = ___;
static constexpr Key key_1CD = ___;
static constexpr Key key_1CE = ___;
static constexpr Key key_1CF = ___;
static constexpr Key key_1CG = ___;
static constexpr Key key_1CH = ___;
static constexpr Key key_1CI = ___;
static constexpr Key key_1CJ = ___;
static constexpr Key key_1CK = ___;
static constexpr Key key_1CL = ___;
static constexpr Key key_1CM = ___;
static constexpr Key key_1CN = ___;
static constexpr Key key_1CO = ___;
static constexpr Key key_1CP = ___;
static constexpr Key key_1DA = ___;
static constexpr Key key_1DB = ___;
static constexpr Key key_1DC = ___;
static constexpr Key key_1DD = ___;
static constexpr Key key_1DE = ___;
static constexpr Key key_1DF = ___;
static constexpr Key key_1DG = ___;
static constexpr Key key_1DH = ___;
static constexpr Key key_1DI = ___;
static constexpr Key key_1DJ = ___;
static constexpr Key key_1DK = ___;
static constexpr Key key_1DL = ___;
static constexpr Key key_1DM = ___;
static constexpr Key key_1DN = ___;
static constexpr Key key_1DO = ___;
static constexpr Key key_1DP = ___;
// Layer 2
static constexpr Key key_2AA = ___;
static constexpr Key key_2AB = ___;
static constexpr Key key_2AC = ___;
static constexpr Key key_2AD = ___;
static constexpr Key key_2AE = ___;
static constexpr Key key_2AF = ___;
static constexpr Key key_2AG = ___;
static constexpr Key key_2AH = ___;
static constexpr Key key_2AI = ___;
static constexpr Key key_2AJ = ___;
static constexpr Key key_2AK = ___;
static constexpr Key key_2AL = ___;
static constexpr Key key_2AM = ___;
static constexpr Key key_2AN = ___;
static constexpr Key key_2AO = ___;
static constexpr Key key_2AP = ___;
static constexpr Key key_2BA = ___;
static constexpr Key key_2BB = ___;
static constexpr Key key_2BC = ___;
static constexpr Key key_2BD = ___;
static constexpr Key key_2BE = ___;
static constexpr Key key_2BF = ___;
static constexpr Key key_2BG = ___;
static constexpr Key key_2BH = ___;
static constexpr Key key_2BI = ___;
static constexpr Key key_2BJ = ___;
static constexpr Key key_2BK = ___;
static constexpr Key key_2BL = ___;
static constexpr Key key_2BM = ___;
static constexpr Key key_2BN = ___;
static constexpr Key key_2BO = ___;
static constexpr Key key_2BP = ___;
static constexpr Key key_2CA = ___;
static constexpr Key key_2CB = ___;
static constexpr Key key_2CC = ___;
static constexpr Key key_2CD = ___;
static constexpr Key key_2CE = ___;
static constexpr Key key_2CF = ___;
static constexpr Key key_2CG = ___;
static constexpr Key key_2CH = ___;
static constexpr Key key_2CI = ___;
static constexpr Key key_2CJ = ___;
static constexpr Key key_2CK = ___;
static constexpr Key key_2CL = ___;
static constexpr Key key_2CM = ___;
static constexpr Key key_2CN = ___;
static constexpr Key key_2CO = ___;
static constexpr Key key_2CP = ___;
static constexpr Key key_2DA = ___;
static constexpr Key key_2DB = ___;
static constexpr Key key_2DC = ___;
static constexpr Key key_2DD = ___;
static constexpr Key key_2DE = ___;
static constexpr Key key_2DF = ___;
static constexpr Key key_2DG = ___;
static constexpr Key key_2DH = ___;
static constexpr Key key_2DI = ___;
static constexpr Key key_2DJ = ___;
static constexpr Key key_2DK = ___;
static constexpr Key key_2DL = ___;
static constexpr Key key_2DM = ___;
static constexpr Key key_2DN = ___;
static constexpr Key key_2DO = ___;
static constexpr Key key_2DP = ___;
// Layer 3
static constexpr Key key_3AA = ___;
static constexpr Key key_3AB = ___;
static constexpr Key key_3AC = ___;
static constexpr Key key_3AD = ___;
static constexpr Key key_3AE = ___;
static constexpr Key key_3AF = ___;
static constexpr Key key_3AG = ___;
static constexpr Key key_3AH = ___;
static constexpr Key key_3AI = ___;
static constexpr Key key_3AJ = ___;
static constexpr Key key_3AK = ___;
static constexpr Key key_3AL = ___;
static constexpr Key key_3AM = ___;
static constexpr Key key_3AN = ___;
static constexpr Key key_3AO = ___;
static constexpr Key key_3AP = ___;
static constexpr Key key_3BA = ___;
static constexpr Key key_3BB = ___;
static constexpr Key key_3BC = ___;
static constexpr Key key_3BD = ___;
static constexpr Key key_3BE = ___;
static constexpr Key key_3BF = ___;
static constexpr Key key_3BG = ___;
static constexpr Key key_3BH = ___;
static constexpr Key key_3BI = ___;
static constexpr Key key_3BJ = ___;
static constexpr Key key_3BK = ___;
static constexpr Key key_3BL = ___;
static constexpr Key key_3BM = ___;
static constexpr Key key_3BN = ___;
static constexpr Key key_3BO = ___;
static constexpr Key key_3BP = ___;
static constexpr Key key_3CA = ___;
static constexpr Key key_3CB = ___;
static constexpr Key key_3CC = ___;
static constexpr Key key_3CD = ___;
static constexpr Key key_3CE = ___;
static constexpr Key key_3CF = ___;
static constexpr Key key_3CG = ___;
static constexpr Key key_3CH = ___;
static constexpr Key key_3CI = ___;
static constexpr Key key_3CJ = ___;
static constexpr Key key_3CK = ___;
static constexpr Key key_3CL = ___;
static constexpr Key key_3CM = ___;
static constexpr Key key_3CN = ___;
static constexpr Key key_3CO = ___;
static constexpr Key key_3CP = ___;
static constexpr Key key_3DA = ___;
static constexpr Key key_3DB = ___;
static constexpr Key key_3DC = ___;
static constexpr Key key_3DD = ___;
static constexpr Key key_3DE = ___;
static constexpr Key key_3DF = ___;
static constexpr Key key_3DG = ___;
static constexpr Key key_3DH = ___;
static constexpr Key key_3DI = ___;
static constexpr Key key_3DJ = ___;
static constexpr Key key_3DK = ___;
static constexpr Key key_3DL = ___;
static constexpr Key key_3DM = ___;
static constexpr Key key_3DN = ___;
static constexpr Key key_3DO = ___;
static constexpr Key key_3DP = ___;
};
} // namespace keymap
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,29 @@
/* -*- mode: c++ -*-
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
namespace kaleidoscope {
namespace testing {
struct Cycles {
uint32_t value;
};
} // namespace testing
} // namespace kaleidoscope

@ -31,7 +31,7 @@ const std::set<uint8_t> & ExpectedKeyboardReport::Keycodes() const {
return keycodes_;
}
uint32_t ExpectedKeyboardReport::Timestamp() const {
Millis ExpectedKeyboardReport::Timestamp() const {
return timestamp_;
}

@ -21,23 +21,25 @@
#include <set>
#include <string>
#include "testing/Millis.h"
namespace kaleidoscope {
namespace testing {
class ExpectedKeyboardReport {
public:
ExpectedKeyboardReport(uint32_t timestamp,
ExpectedKeyboardReport(Millis timestamp,
const std::set<uint8_t> & keycodes,
std::string message = "");
const std::set<uint8_t> & Keycodes() const;
uint32_t Timestamp() const;
Millis Timestamp() const;
const std::string & Message() const;
private:
uint32_t timestamp_;
Millis timestamp_;
std::set<uint8_t> keycodes_;
std::string failure_message_;
};

@ -0,0 +1,111 @@
/* -*- mode: c++ -*-
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
namespace kaleidoscope {
namespace testing {
struct Millis {
uint32_t value;
constexpr bool operator==(const Millis& other) const {
return this->value == other.value;
}
constexpr bool operator!=(const Millis& other) const {
return !(*this == other);
}
constexpr bool operator<(const Millis& other) const {
return this->value < other.value;
}
constexpr bool operator>(const Millis& other) const {
return this->value > other.value;
}
constexpr bool operator<=(const Millis& other) const {
return this->value <= other.value;
}
constexpr bool operator>=(const Millis& other) const {
return this->value >= other.value;
}
Millis operator+(const Millis& other) {
return Millis{this->value + other.value};
}
Millis operator-(const Millis& other) {
return Millis{this->value - other.value};
}
Millis operator+(const uint32_t raw) {
return Millis{this->value + raw};
}
Millis operator-(const uint32_t raw) {
return Millis{this->value - raw};
}
Millis& operator=(const uint32_t raw) {
this->value = raw;
return *this;
}
Millis& operator+=(const uint32_t raw) {
this->value += raw;
return *this;
}
Millis& operator-=(const uint32_t raw) {
this->value -= raw;
return *this;
}
constexpr bool operator<(uint32_t raw) const {
return this->value < raw;
}
constexpr bool operator>(uint32_t raw) const {
return this->value > raw;
}
constexpr bool operator<=(uint32_t raw) const {
return this->value <= raw;
}
constexpr bool operator>=(uint32_t raw) const {
return this->value >= raw;
}
operator size_t() {
return value;
}
};
constexpr bool operator<(uint32_t x, const Millis& y) {
return x < y.value;
}
constexpr bool operator>(uint32_t x, const Millis& y) {
return x > y.value;
}
constexpr bool operator<=(uint32_t x, const Millis& y) {
return x <= y.value;
}
constexpr bool operator>=(uint32_t x, const Millis& y) {
return x >= y.value;
}
constexpr Millis operator+(uint32_t x, const Millis& y) {
return Millis{x + y.value};
}
constexpr Millis operator-(uint32_t x, const Millis& y) {
return Millis{x - y.value};
}
} // namespace testing
} // namespace kaleidoscope

@ -31,6 +31,24 @@ std::unique_ptr<State> VirtualDeviceTest::RunCycle() {
return State::Snapshot();
}
// =============================================================================
void VirtualDeviceTest::Run(Cycles n) {
sim_.RunCycles(n.value);
}
void VirtualDeviceTest::Run(Millis t) {
sim_.RunForMillis(t);
}
void VirtualDeviceTest::RunUntil(Millis end) {
uint32_t t0 = Runtime.millisAtCycleStart();
Run(Millis{end - t0});
}
void VirtualDeviceTest::RunFrom(Millis start, Millis t) {
RunUntil(Millis{start + t});
}
// =============================================================================
void VirtualDeviceTest::LoadState() {
output_state_ = State::Snapshot();
@ -47,24 +65,44 @@ const HIDState* VirtualDeviceTest::HIDReports() const {
return output_state_->HIDReports();
}
uint32_t VirtualDeviceTest::ReportTimestamp(size_t index) const {
Millis VirtualDeviceTest::ReportTimestamp(size_t index) const {
uint32_t t = output_state_->HIDReports()->Keyboard(index).Timestamp();
return t;
return Millis{t};
}
// -----------------------------------------------------------------------------
uint32_t VirtualDeviceTest::EventTimestamp(size_t index) const {
return input_timestamps_[index];
Millis VirtualDeviceTest::EventTimestamp(size_t index) const {
return Millis{input_timestamps_[index]};
}
// =============================================================================
void VirtualDeviceTest::PressKey(KeyAddr addr) {
sim_.Press(addr);
input_timestamps_.push_back(Runtime.millisAtCycleStart());
input_timestamps_.push_back(Millis{Runtime.millisAtCycleStart()});
}
void VirtualDeviceTest::ReleaseKey(KeyAddr addr) {
sim_.Release(addr);
input_timestamps_.push_back(Runtime.millisAtCycleStart());
input_timestamps_.push_back(Millis{Runtime.millisAtCycleStart()});
}
// -----------------------------------------------------------------------------
void VirtualDeviceTest::PressKey(Cycles n, KeyAddr addr) {
sim_.RunCycles(n.value);
PressKey(addr);
}
void VirtualDeviceTest::ReleaseKey(Cycles n, KeyAddr addr) {
sim_.RunCycles(n.value);
ReleaseKey(addr);
}
// -----------------------------------------------------------------------------
void VirtualDeviceTest::PressKey(Millis t, KeyAddr addr) {
sim_.RunForMillis(t);
PressKey(addr);
}
void VirtualDeviceTest::ReleaseKey(Millis t, KeyAddr addr) {
sim_.RunForMillis(t);
ReleaseKey(addr);
}
@ -86,7 +124,7 @@ void VirtualDeviceTest::ExpectReport(Keycodes keys,
void VirtualDeviceTest::ExpectReport(AddKeycodes added_keys,
RemoveKeycodes removed_keys,
std::string description) {
uint32_t report_timestamp = Runtime.millisAtCycleStart();
Millis report_timestamp{Runtime.millisAtCycleStart()};
for (Key key : added_keys) {
AddToReport(key);
}
@ -109,6 +147,34 @@ void VirtualDeviceTest::ExpectReport(RemoveKeycodes removed_keys,
ExpectReport(AddKeycodes{}, removed_keys, description);
}
// -----------------------------------------------------------------------------
void VirtualDeviceTest::ExpectReport(Cycles n,
AddKeycodes added_keys,
std::string description) {
sim_.RunCycles(n.value);
ExpectReport(added_keys, description);
}
void VirtualDeviceTest::ExpectReport(Cycles n,
RemoveKeycodes removed_keys,
std::string description) {
sim_.RunCycles(n.value);
ExpectReport(removed_keys, description);
}
// -----------------------------------------------------------------------------
void VirtualDeviceTest::ExpectReport(Millis t,
AddKeycodes added_keys,
std::string description) {
sim_.RunForMillis(t);
ExpectReport(added_keys, description);
}
void VirtualDeviceTest::ExpectReport(Millis t,
RemoveKeycodes removed_keys,
std::string description) {
sim_.RunForMillis(t);
ExpectReport(removed_keys, description);
}
// =============================================================================
void VirtualDeviceTest::ClearReport() {
current_keyboard_keycodes_.clear();

@ -18,6 +18,8 @@
#include <cstddef>
#include "testing/Cycles.h"
#include "testing/Millis.h"
#include "testing/ExpectedKeyboardReport.h"
#include "testing/SimHarness.h"
#include "testing/State.h"
@ -59,6 +61,24 @@ class VirtualDeviceTest : public ::testing::Test {
SimHarness sim_;
// ---------------------------------------------------------------------------
// Utility functions to advance time in the simulator.
// Run the simulator `n` cycles
void Run(Cycles n);
// Run the simulator `t` (virtual) milliseconds
void Run(Millis t);
// Run the simulator until the (virtual) clock reaches `end` milliseconds
void RunUntil(Millis end);
// Run the simulator until the (virtual) clock advances `t` milliseconds past
// `start`. This is most useful when testing timeouts based on an input event
// that is not the most recent one (e.g. a timeout following a keypress, but
// with a key release in between).
void RunFrom(Millis start, Millis t);
// ---------------------------------------------------------------------------
// A representation of the set of observed HID reports accumulated by the
// simulator as a testcase executes. It starts out empty, and a call to
@ -79,21 +99,28 @@ class VirtualDeviceTest : public ::testing::Test {
const HIDState* HIDReports() const;
// Get the timestamp of a logged Keyboard HID report
uint32_t ReportTimestamp(size_t index) const;
Millis ReportTimestamp(size_t index) const;
// ---------------------------------------------------------------------------
// A vector of timestamps for input events. Calls to `PressKey()` &
// `ReleaseKey()` append timestamps to it when called.
std::vector<uint32_t> input_timestamps_ = {};
std::vector<Millis> input_timestamps_ = {};
// Get the timestamp of a logged input event from `output_state_`
uint32_t EventTimestamp(size_t index) const;
Millis EventTimestamp(size_t index) const;
// ---------------------------------------------------------------------------
// Press/release a keyswitch & log the input event timestamp
void PressKey(KeyAddr addr);
void ReleaseKey(KeyAddr addr);
// Run for `n` cycles, then press/release a keyswitch
void PressKey(Cycles n, KeyAddr addr);
void ReleaseKey(Cycles n, KeyAddr addr);
// Run for `t` milliseconds, then press/release a keyswitch
void PressKey(Millis t, KeyAddr addr);
void ReleaseKey(Millis t, KeyAddr addr);
// ---------------------------------------------------------------------------
// The following functions all add an expected value of HID report to the
@ -112,6 +139,12 @@ class VirtualDeviceTest : public ::testing::Test {
void ExpectReport(AddKeycodes added_keys, std::string description);
void ExpectReport(RemoveKeycodes removed_keys, std::string description);
void ExpectReport(Cycles n, AddKeycodes added_keys, std::string description);
void ExpectReport(Cycles n, RemoveKeycodes removed_keys, std::string description);
void ExpectReport(Millis t, AddKeycodes added_keys, std::string description);
void ExpectReport(Millis t, RemoveKeycodes removed_keys, std::string description);
// ---------------------------------------------------------------------------
std::set<uint8_t> current_keyboard_keycodes_ = {};
// Manage the set of keycodes expected in the next report

@ -0,0 +1,33 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
#include <kaleidoscope/key_defs.h>
#include <kaleidoscope/KeyAddr.h>
#include "keymap.h"
namespace kaleidoscope {
namespace testing {
constexpr uint16_t ONESHOT_TIMEOUT = 200;
constexpr uint16_t ONESHOT_HOLD_TIMEOUT = 50;
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,45 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/key_defs.h>
#include <kaleidoscope/KeyAddr.h>
#include "testing/keymap-defaults.h"
#include <Kaleidoscope-OneShot.h>
namespace kaleidoscope {
namespace testing {
namespace keymap {
class Keymap : public KeymapDefaults {
public:
// Layer 0
static constexpr Key key_0AA = Key_S;
static constexpr Key key_0AB = Key_D;
static constexpr Key key_0BA = OSM(LeftShift);
static constexpr Key key_0BB = OSM(LeftGui);
static constexpr Key key_0BC = OSM(LeftControl);
static constexpr Key key_0CA = OSL(1);
};
} // namespace keymap
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,31 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Default key values to be used in sketches are defined from the
// `keymap-defaults.h` file, provided by Kaleidoscope.
#include "testing/keymap-defaults.h"
// For keys of interest, the values can be overridden by defining them in the
// `keymap-overrides.h` file, in this directory.
#include "keymap-overrides.h"
// Finally, we include this file so we can refer to key values in the keymap
// more briefly (`key_0AA` vs `Keymap::key_0AA`, both in the
// `kaleidoscope::testing::keymap` namespace).
#include "testing/keymap-aliases.inc"

@ -0,0 +1,39 @@
/* -*- mode: c++ -*-
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-OneShot.h>
#include "./common.h"
#include "testing/default-layers.h"
using namespace kaleidoscope::testing::keymap;
KEYMAPS(LAYER_0, LAYER_1);
// Use Qukeys
KALEIDOSCOPE_INIT_PLUGINS(OneShot);
void setup() {
Kaleidoscope.setup();
OneShot.time_out = kaleidoscope::testing::ONESHOT_TIMEOUT;
OneShot.hold_time_out = kaleidoscope::testing::ONESHOT_HOLD_TIMEOUT;
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,81 @@
/* -*- mode: c++ -*-
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "testing/setup-googletest.h"
#include "../common.h"
SETUP_GOOGLETEST();
namespace kaleidoscope {
namespace testing {
namespace {
using namespace kaleidoscope::testing::keymap;
constexpr KeyAddr key_addr_OSM_LeftControl = addr_BC;
constexpr KeyAddr key_addr_OSM_LeftGui = addr_BB;
constexpr KeyAddr key_addr_OSM_LeftShift = addr_BA;
constexpr KeyAddr key_addr_OSL_1 = addr_CA;
constexpr KeyAddr key_addr_S = addr_AA;
constexpr KeyAddr key_addr_D = addr_AB;
class OneShotBasic : public VirtualDeviceTest {};
TEST_F(OneShotBasic, OneShotModifier) {
// Tap `OSM(LeftShift)`
PressKey(Millis{10}, key_addr_OSM_LeftShift);
ExpectReport(Cycles{1}, AddKeycodes{Key_LeftShift},
"Report should contain only `LeftShift`");
ReleaseKey(Millis{20}, key_addr_OSM_LeftShift);
// Tap `Key_S`
PressKey(Millis{10}, key_addr_S);
ExpectReport(Cycles{1}, AddKeycodes{Key_S},
"Report should contain `LeftShift` & `S`");
ExpectReport(Cycles{1}, RemoveKeycodes{Key_LeftShift},
"Report should be contain only `S`");
ReleaseKey(Millis{10}, key_addr_S);
ExpectReport(Cycles{1}, RemoveKeycodes{Key_S},
"Report should be empty");
sim_.RunForMillis(10);
CHECK_EXPECTED_REPORTS()
}
TEST_F(OneShotBasic, OsmTimeout) {
ClearState();
// Tap `OSM(LeftShift)`
PressKey(Millis{10}, key_addr_OSM_LeftShift);
ExpectReport(Cycles{1}, AddKeycodes{Key_LeftShift},
"Report should contain only `LeftShift`");
ReleaseKey(Millis{20}, key_addr_OSM_LeftShift);
RunFrom(EventTimestamp(0), Millis{ONESHOT_TIMEOUT});
ExpectReport(Cycles{3}, RemoveKeycodes{Key_LeftShift},
"Report should be empty");
CHECK_EXPECTED_REPORTS()
}
} // namespace
} // namespace testing
} // namespace kaleidoscope

@ -1,5 +1,4 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2020 Keyboard.io, Inc.
*
@ -19,6 +18,10 @@
#pragma once
#include <cstdint>
#include <kaleidoscope/key_defs.h>
#include <kaleidoscope/KeyAddr.h>
#include "keymap.h"
namespace kaleidoscope {
namespace testing {
@ -27,5 +30,5 @@ constexpr uint16_t QUKEYS_HOLD_TIMEOUT = 200;
constexpr uint8_t QUKEYS_OVERLAP_THRESHOLD = 90;
constexpr uint8_t QUKEYS_MINIMUM_HOLD_TIME = 10;
}
}
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,44 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/key_defs.h>
#include <kaleidoscope/KeyAddr.h>
#include "testing/keymap-defaults.h"
#include <Kaleidoscope-Qukeys.h>
namespace kaleidoscope {
namespace testing {
namespace keymap {
class Keymap : public KeymapDefaults {
public:
// Layer 0
static constexpr Key key_0AA = Key_A;
static constexpr Key key_0AB = Key_F;
static constexpr Key key_0AC = Key_X;
};
constexpr KeyAddr key_addr_A = addr_AA;
constexpr KeyAddr key_addr_F = addr_AB;
constexpr KeyAddr key_addr_X = addr_AC;
} // namespace keymap
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,31 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Default key values to be used in sketches are defined from the
// `keymap-defaults.h` file, provided by Kaleidoscope.
#include "testing/keymap-defaults.h"
// For keys of interest, the values can be overridden by defining them in the
// `keymap-overrides.h` file, in this directory.
#include "keymap-overrides.h"
// Finally, we include this file so we can refer to key values in the keymap
// more briefly (`key_0AA` vs `Keymap::key_0AA`, both in the
// `kaleidoscope::testing::keymap` namespace).
#include "testing/keymap-aliases.inc"

@ -19,72 +19,18 @@
#include <Kaleidoscope-Macros.h>
#include "./common.h"
#include "testing/default-layers.h"
enum { MACRO_TOGGLE_QUKEYS };
using namespace kaleidoscope::testing::keymap;
// *INDENT-OFF*
KEYMAPS(
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
KEYMAPS(LAYER_0);
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_Q,
M(MACRO_TOGGLE_QUKEYS), Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, SFT_T(J), CTL_T(K), ALT_T(L), GUI_T(Semicolon), Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
LT(1,E)
),
[1] = KEYMAP_STACKED
(
___, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_1, Key_2, Key_3, Key_4,
___,
___, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_1, Key_2, Key_3, Key_4,
___
),
)
// *INDENT-ON*
// Defining a macro (on the "any" key: see above) to toggle Qukeys on and off
const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) {
switch (macro_index) {
case MACRO_TOGGLE_QUKEYS:
if (keyToggledOn(key_state))
Qukeys.toggle();
break;
}
return MACRO_NONE;
}
// Use Qukeys
KALEIDOSCOPE_INIT_PLUGINS(Qukeys, Macros);
KALEIDOSCOPE_INIT_PLUGINS(Qukeys);
void setup() {
QUKEYS(
kaleidoscope::plugin::Qukey(0, KeyAddr(2, 1), Key_LeftGui), // A/cmd
kaleidoscope::plugin::Qukey(0, KeyAddr(2, 2), Key_LeftAlt), // S/alt
kaleidoscope::plugin::Qukey(0, KeyAddr(2, 3), Key_LeftControl), // D/ctrl
kaleidoscope::plugin::Qukey(0, KeyAddr(2, 4), Key_LeftShift), // F/shift
kaleidoscope::plugin::Qukey(0, KeyAddr(3, 6), ShiftToLayer(1)) // Q/layer-shift (on `fn`)
kaleidoscope::plugin::Qukey(0, key_addr_A, Key_LeftGui), // A/cmd
kaleidoscope::plugin::Qukey(0, key_addr_F, Key_LeftShift), // F/shift
)
Qukeys.setHoldTimeout(kaleidoscope::testing::QUKEYS_HOLD_TIMEOUT);
Qukeys.setOverlapThreshold(kaleidoscope::testing::QUKEYS_OVERLAP_THRESHOLD);

@ -24,190 +24,80 @@ namespace kaleidoscope {
namespace testing {
namespace {
constexpr KeyAddr key_addr_A{2, 1};
constexpr KeyAddr key_addr_S{2, 2};
constexpr KeyAddr key_addr_D{2, 3};
constexpr KeyAddr key_addr_F{2, 4};
constexpr KeyAddr key_addr_X{3, 2};
using namespace kaleidoscope::testing::keymap;
using ::testing::IsEmpty;
class QukeysBasic : public VirtualDeviceTest {
protected:
std::set<uint8_t> expected_keycodes_ = {};
std::unique_ptr<State> state_ = nullptr;
};
class QukeysBasic : public VirtualDeviceTest {};
TEST_F(QukeysBasic, TapQukeyAlone) {
// Press `A`
sim_.Press(key_addr_A);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0)
<< "There should be no HID report after the qukey is pressed";
sim_.RunForMillis(20);
// Release `A`
sim_.Release(key_addr_A);
sim_.RunCycles(2);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 2)
<< "There should be two HID reports after the release of a tapped qukey";
expected_keycodes_.insert(Key_A.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The first report should include only `A`";
expected_keycodes_.erase(Key_A.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(1).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The second report should be empty";
PressKey(Millis{10}, key_addr_A);
ReleaseKey(Millis{50}, key_addr_A);
ExpectReport(Cycles{1}, AddKeycodes{Key_A}, "Report should contain only `A`");
ExpectReport(Cycles{1}, RemoveKeycodes{Key_A}, "Report should be empty");
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0);
Run(Cycles{3});
CHECK_EXPECTED_REPORTS();
}
TEST_F(QukeysBasic, HoldQukeyAlone) {
constexpr uint32_t hold_time = 400;
// Press `A`
sim_.Press(key_addr_A);
PressKey(Millis{10}, key_addr_A);
ExpectReport(Millis{QUKEYS_HOLD_TIMEOUT}, AddKeycodes{Key_LeftGui},
"The first report should include only `LeftGui`");
ReleaseKey(Millis{hold_time}, key_addr_A);
ExpectReport(Cycles{1}, RemoveKeycodes{Key_LeftGui},
"The second report should be empty");
state_ = RunCycle();
Run(Cycles{3});
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0);
CHECK_EXPECTED_REPORTS();
uint32_t t0 = Kaleidoscope.millisAtCycleStart();
// To test the hold timeout, we check after every cycle to see if there's new
// HID report. We can't just call `RunForMillis()` because we care about when
// that report was sent.
do {
state_ = RunCycle();
} while (state_->HIDReports()->Keyboard().size() == 0 &&
(Kaleidoscope.millisAtCycleStart() - t0 < QUKEYS_HOLD_TIMEOUT + 1));
uint32_t t1 = Kaleidoscope.millisAtCycleStart();
EXPECT_THAT(t1 - t0, ::testing::Ge(QUKEYS_HOLD_TIMEOUT))
Millis measured_delay = ReportTimestamp(0) - input_timestamps_[0];
EXPECT_THAT(measured_delay, ::testing::Ge(QUKEYS_HOLD_TIMEOUT))
<< "The HID report should be sent after the hold timeout has elapsed";
expected_keycodes_.insert(Key_LeftGui.getKeyCode());
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should be only one HID report";
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The HID report should contain just `Key_LeftGui`";
sim_.RunForMillis(100);
sim_.Release(key_addr_A);
sim_.RunCycles(2);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should be a HID report immediately after the key is released";
expected_keycodes_.erase(Key_LeftGui.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The HID report should be empty at this point";
EXPECT_THAT(ReportTimestamp(1), ::testing::Ge(EventTimestamp(1)))
<< "The key should stay active until release";
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0);
}
TEST_F(QukeysBasic, FullOverlap) {
sim_.Press(key_addr_F);
sim_.RunForMillis(20);
sim_.Press(key_addr_X);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0)
<< "After both keys are pressed, there should still be no reports";
sim_.RunForMillis(50);
sim_.Release(key_addr_X);
sim_.RunCycles(3);
state_ = RunCycle();
expected_keycodes_.insert(Key_LeftShift.getKeyCode());
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 3)
<< "After the subsequent key is released, we should get 3 reports";
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The first report should contain the qukey's altername keycode";
expected_keycodes_.insert(Key_X.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(1).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The second report should add the subsequent key";
expected_keycodes_.erase(Key_X.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(2).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The third report should be the release of the subsequent key";
sim_.Release(key_addr_F);
sim_.RunCycles(3);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "After the qukey is release, we should get one report";
expected_keycodes_.erase(Key_LeftShift.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The HID report should now be empty";
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0);
PressKey(Millis{10}, key_addr_F);
PressKey(Millis{20}, key_addr_X);
ReleaseKey(Millis{50}, key_addr_X);
ExpectReport(Cycles{1}, AddKeycodes{Key_LeftShift},
"The first report should contain only `LeftShift`");
ExpectReport(Cycles{1}, AddKeycodes{Key_X},
"The second report should add `X`");
ExpectReport(Cycles{1}, RemoveKeycodes{Key_X},
"The third report should remove `X`");
ReleaseKey(Millis{10}, key_addr_F);
ExpectReport(Cycles{1}, RemoveKeycodes{Key_LeftShift},
"The fourth report should remove `LeftShift`");
Run(Cycles{3});
CHECK_EXPECTED_REPORTS();
}
TEST_F(QukeysBasic, RolloverPrimary) {
sim_.Press(key_addr_F);
sim_.RunForMillis(20);
sim_.Press(key_addr_X);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0)
<< "After both keys are pressed, there should still be no reports";
sim_.RunForMillis(50);
sim_.Release(key_addr_F);
sim_.RunForMillis(50);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 3)
<< "After the qukey is released, and the overlap threshold is exceeded, there should be 3 reports";
expected_keycodes_.insert(Key_F.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The first report should contain the qukey's primary value";
expected_keycodes_.insert(Key_X.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(1).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The second report should contain the subsequent (normal) key";
expected_keycodes_.erase(Key_F.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(2).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The third report should contain the release of the qukey";
sim_.Release(key_addr_X);
sim_.RunCycles(3);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "After the normal key is released, we should get one report";
expected_keycodes_.erase(Key_X.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The HID report should now be empty";
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0);
PressKey(Millis{10}, key_addr_F);
PressKey(Millis{40}, key_addr_X);
ReleaseKey(Millis{20}, key_addr_F);
ExpectReport(Millis{30}, AddKeycodes{Key_F},
"The first report should add `F`");
ExpectReport(Cycles{1}, AddKeycodes{Key_X},
"The second report should add `X`");
ExpectReport(Cycles{1}, RemoveKeycodes{Key_F},
"The third report should remove `F`");
ReleaseKey(Millis{40}, key_addr_X);
ExpectReport(Cycles{1}, RemoveKeycodes{Key_X},
"The fourth report should remove `X`");
Run(Cycles{3});
CHECK_EXPECTED_REPORTS();
}
} // namespace

@ -0,0 +1,32 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
#include <kaleidoscope/key_defs.h>
#include <kaleidoscope/KeyAddr.h>
#include "keymap.h"
namespace kaleidoscope {
namespace testing {
// Constants shared by both the sketch and the testcase should be defined here.
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,39 @@
/* -*- mode: c++ -*-
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/key_defs.h>
#include <kaleidoscope/KeyAddr.h>
#include "testing/keymap-defaults.h"
#include <Kaleidoscope-Redial.h>
namespace kaleidoscope {
namespace testing {
namespace keymap {
class Keymap : public KeymapDefaults {
public:
// Layer 0
static constexpr Key key_0AA = Key_Redial;
static constexpr Key key_0AB = Key_A;
static constexpr Key key_0AC = Key_X;
};
} // namespace keymap
} // namespace testing
} // namespace kaleidoscope

@ -0,0 +1,31 @@
// -*- mode: c++ -*-
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2020 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Default key values to be used in sketches are defined from the
// `keymap-defaults.h` file, provided by Kaleidoscope.
#include "testing/keymap-defaults.h"
// For keys of interest, the values can be overridden by defining them in the
// `keymap-overrides.h` file, in this directory.
#include "keymap-overrides.h"
// Finally, we include this file so we can refer to key values in the keymap
// more briefly (`key_0AA` vs `Keymap::key_0AA`, both in the
// `kaleidoscope::testing::keymap` namespace).
#include "testing/keymap-aliases.inc"

@ -17,30 +17,13 @@
#include <Kaleidoscope.h>
#include <Kaleidoscope-Redial.h>
// *INDENT-OFF*
KEYMAPS(
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
#include "./common.h"
#include "testing/default-layers.h"
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
XXX,
using namespace kaleidoscope::testing::keymap;
Key_Redial, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
KEYMAPS(LAYER_0);
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
XXX
),
)
// *INDENT-ON*
// Use Redial
KALEIDOSCOPE_INIT_PLUGINS(Redial);
void setup() {

@ -16,153 +16,65 @@
#include "testing/setup-googletest.h"
#include "../common.h"
SETUP_GOOGLETEST();
namespace kaleidoscope {
namespace testing {
namespace {
constexpr KeyAddr key_addr_Redial{0, 9};
constexpr KeyAddr key_addr_A{2, 1};
constexpr KeyAddr key_addr_X{3, 2};
constexpr KeyAddr key_addr_Redial = addr_AA;
constexpr KeyAddr key_addr_A = addr_AB;
constexpr KeyAddr key_addr_X = addr_AC;
class RedialBasic : public VirtualDeviceTest {
protected:
std::set<uint8_t> expected_keycodes_ = {};
std::unique_ptr<State> state_ = nullptr;
};
TEST_F(RedialBasic, RedialFirst) {
// Press redial key
sim_.Press(key_addr_Redial);
TEST_F(RedialBasic, RedialWithoutPriorKey) {
state_ = RunCycle();
PressKey(Millis{10}, key_addr_Redial);
ReleaseKey(Millis{25}, key_addr_Redial);
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0)
<< "There should be no HID report for a redial key without anything pressed first";
sim_.RunForMillis(10);
LoadState();
// Release redial key
sim_.Release(key_addr_Redial);
sim_.RunCycle();
ASSERT_EQ(HIDReports()->Keyboard().size(), 0)
<< "There should be no HID report without a prior keypress";
}
TEST_F(RedialBasic, RedialFirstKey) {
// Press `A`
sim_.Press(key_addr_A);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should be one report after letter key press";
expected_keycodes_.insert(Key_A.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The report should include only `A`";
// Release `A`
sim_.Release(key_addr_A);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should be one report after letter key release";
expected_keycodes_.erase(Key_A.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The report should be empty";
sim_.RunCycle();
// Press redial key
sim_.Press(key_addr_Redial);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should now be a redial-key report";
expected_keycodes_.insert(Key_A.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The report should include only `A`";
// Release redial key
sim_.Release(key_addr_Redial);
state_ = RunCycle();
PressKey(Millis{10}, key_addr_A);
ExpectReport(Cycles{1}, AddKeycodes{Key_A}, "Report should contain only `A`");
ReleaseKey(Millis{25}, key_addr_A);
ExpectReport(Cycles{1}, RemoveKeycodes{Key_A}, "Report should be empty");
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should be one report after redial-key release";
PressKey(Millis{10}, key_addr_Redial);
ExpectReport(Cycles{1}, AddKeycodes{Key_A}, "Report should contain only `A`");
ReleaseKey(Millis{25}, key_addr_Redial);
ExpectReport(Cycles{1}, RemoveKeycodes{Key_A}, "Report should be empty");
expected_keycodes_.erase(Key_A.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The report should be empty";
sim_.RunForMillis(10);
sim_.RunCycle();
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0);
CHECK_EXPECTED_REPORTS();
}
TEST_F(RedialBasic, RedialNextKey) {
// Press `X`
sim_.Press(key_addr_X);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should be one report after letter key press";
expected_keycodes_.insert(Key_X.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The report should include only `X`";
// Release `X`
sim_.Release(key_addr_X);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should be one report after letter key release";
expected_keycodes_.erase(Key_X.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The report should be empty";
sim_.RunCycle();
// Press redial key
sim_.Press(key_addr_Redial);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should now be a redial-key report";
expected_keycodes_.insert(Key_X.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The report should include only `X`";
// Release redial key
sim_.Release(key_addr_Redial);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 1)
<< "There should be one report after redial-key release";
PressKey(Millis{10}, key_addr_X);
ExpectReport(Cycles{1}, AddKeycodes{Key_X}, "Report should contain only `X`");
ReleaseKey(Millis{25}, key_addr_X);
ExpectReport(Cycles{1}, RemoveKeycodes{Key_X}, "Report should be empty");
expected_keycodes_.erase(Key_X.getKeyCode());
EXPECT_THAT(state_->HIDReports()->Keyboard(0).ActiveKeycodes(),
::testing::ElementsAreArray(expected_keycodes_))
<< "The report should be empty";
PressKey(Millis{10}, key_addr_Redial);
ExpectReport(Cycles{1}, AddKeycodes{Key_X}, "Report should contain only `X`");
ReleaseKey(Millis{25}, key_addr_Redial);
ExpectReport(Cycles{1}, RemoveKeycodes{Key_X}, "Report should be empty");
sim_.RunCycle();
sim_.RunForMillis(10);
state_ = RunCycle();
ASSERT_EQ(state_->HIDReports()->Keyboard().size(), 0);
CHECK_EXPECTED_REPORTS();
}
} // namespace

Loading…
Cancel
Save