-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
テストコード #15
Comments
どうやるんだろうなぁ。 やってることが基本的に
で、unittest 書きづらいんだよなぁ。 vscode.window.activeTextEditor にモック差し込んだりとかできたりする? |
いや、普通に「VSCode ウィンドウ新たに立ち上げて、a.trita 開いて、所定の操作させて、最後にカーソル位置やテキストの内容をgetしてassertする」 ↑ これできる気がする |
テストコード実行するたびにいちいちウィンドウ新たに立ち上がる感じ(GUIテスト)になるけど、それでも手作業よりははるかに良い。 |
書くとしたら日付が変わると並び順が変わるので、テスト時に毎回ゼロからデータをつくるようにする
|
mocha 思い出すmocha における describe it before beforeEach after afterEach の実行順序 - Qiita テストコードは既に yo code のおかげで実行できるようになってる
少しおためしimport * as assert from 'assert';
import { describe, before, after, beforeEach, afterEach, it } from 'mocha';
import * as vscode from 'vscode';
// import * as myExtension from '../extension';
suite('Extension Test Suite', () => {
before(() => {
vscode.window.showInformationMessage('Start all tests.');
});
test('Sample test', () => {
assert.strictEqual(-1, [1, 2, 3].indexOf(5));
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
});
});
describe('describe1', () => {
before(() => {
console.log('before')
});
after(() => {
console.log('after')
});
beforeEach(() => {
console.log('before')
});
afterEach(() => {
console.log('after')
});
it('test1', () => {
assert.strictEqual(1, 100-98-1);
});
it('test2', () => {
assert.strictEqual(2, 100-98);
});
});
describe('describe2', () => {
it('test3', () => {
assert.strictEqual(1, 100-98-1);
});
});
|
suite と test って何?describe や it じゃダメなの? |
Testing Extensions | Visual Studio Code Extension API 記述なさそう。たぶん単に「suite がスイート表してて、テストケースは test が使えるよ(mochaデフォの describe と it はわかりづらいけどこれならわかりやすいやろ?)」ってことかな |
うん、suite は describe の、test は it のシンタックスシュガーっぽい |
chaiは?まあ assert あるし、いったんこれでいいか |
テストコードから test.trita(空ファイル) を開くには? |
VS Code API | Visual Studio Code Extension API vscode.window.openNewFile() ← こんなんがあるはず |
開いたかどうか見れないんだが。
pause でも setTimeout でも構わず終了しやがる |
あとかれんとでぃれくとりもわからん。
undefined だし。まず workspace folder を開く必要がある? |
https://code.visualstudio.com/api/references/vscode-api#TextDocument activeTextEditor.document.fileName で「untitled 1」まで取れた。 が、ディレクトリはないっぽいな。 今が src/test/suite/extension.test.ts なんだが、src を得るにはどうしたらいいんだ? |
その workspace folder のパスが知りたいんやが |
console.log(vscode.env.appRoot) ちゃう。 ……いや、実行時にここに各種ファイルがコピーされてくるから、ここ基点で進めればええってこと? |
いや、違うね |
これが欲しい。src/test/suite/test.trita を開きたいんですけども…… |
マジで正解どれなん……? |
javascript - VS Code extension - get full path - Stack Overflow ググってもこれしか出てこない。 その workspace folder が空なんですよ。 |
.../src/test/suite/extension.test.ts を実行してるんだから、.../src/test/suite/ を得る手段が絶対あるはずだと思うんだが |
path さんでしたか
|
だが out 側に test.trita などテスト用ファイルがない |
import * as path from 'path'
class Path {
static get _entrypoint(){
// __dirname には現在実行中のソースコードが格納されているディレクトリ.
// node.js の動作.
// src/test/suite/test.ts の場合, out/test/suite になる
return path.resolve(__dirname)
}
static get root(){
const defaultRoot = this._entrypoint
return path.resolve(defaultRoot, '..', '..', '..', 'src', 'test', 'suite')
}
} わりかししんどい。 Path.root にあたるパスを一発で取得できるシステム変数があってもばちあたらんと思うが |
// import * as myExtension from '../extension'; yo code のテンプレはこれを出してる |
😭 endTask 以降がマジで難しい戻り値何も考えずにつくってるから、thenable で返さないといけないようにするのがパッと見てできん |
Promise と Thenable は違うわけだが、Thenable はどうやって定義すればいいの? ……たぶん想定されてないんだよなぁ。 |
endTask export function endTask(){
// s e >DoEnd> s e
// -------------------
// x x x x Invalid. start してないので end しない.
// o x o o OK. 普通に end する.
// o o o x OK. トグルで end をやめる.
// x o - - Don't care.
//
// x x から x o に至れないので x o の時は想定していない.
// 今のコードだと end しない挙動になるが, 特に問題はないのでこのままで.
const editor = getEditor();
const doc = editor.document;
const currentLine = doc.lineAt(CursorPositioner.current()).text;
const currentStartTimeValue = currentLine.substr(POS_STARTTIME, LEN_TIME);
const isNotStarted = currentStartTimeValue == EMPTYTIME;
if(isNotStarted){
return;
}
const currentEndTimeValue = currentLine.substr(POS_ENDTIME, LEN_TIME);
const isDoneNewly = currentEndTimeValue == EMPTYTIME;
const shouldCopyBecauseRepeat = currentLine.indexOf("rep:") != -1;
let afterStringForEndTime = EMPTYTIME;
if(isDoneNewly){
afterStringForEndTime = DateTimeUtil.nowtimeString();
}
const endTimeRange = CursorPositioner.rangeBetweenEndTime()
const endTimeBuilder = function(editBuilder: vscode.TextEditorEdit): void{
editBuilder.replace(endTimeRange, afterStringForEndTime);
}
const endTimePromise = editor.edit(endTimeBuilder);
const functionAfterCopy = () => {
CursorMover.golineend();
doRepeatIfPossible();
}
endTimePromise.then(
(isSucceedEdit) => {
if(isSucceedEdit && isDoneNewly && shouldCopyBecauseRepeat){
copyTask(functionAfterCopy);
}
}
)
} |
ぐちゃぐちゃすぎる……w |
copyTask function copyTask(cursorMoverAfterCopy: any){ // eslint-disable-line @typescript-eslint/no-explicit-any
const editor = getEditor();
const doc = editor.document;
const currentLine = doc.lineAt(CursorPositioner.current()).text;
const inserteeString = `${currentLine}\n`;
const inserteePos = CursorPositioner.linetop();
// 挿入後は現在行位置に「挿入した行」が来るため
// 「挿入前における現在行位置」をそのまま使うだけで
// 挿入した行に対する操作を行える.
//
// line[x-1]
// aaaaaaaIaa line[x]
// line[x+1]
//
// line[x-1]
// aaaaaaaIaa line[x] <== 挿入された行. x行目で変わらずアクセスできる.
// aaaaaaaIaa line[x+1]
const startpos = CursorPositioner.startOfTimeFields();
const endpos = CursorPositioner.endOfTimeFields();
const replaceeRange = new vscode.Range(startpos, endpos);
const afterString = `${EMPTYTIME} ${EMPTYTIME}`;
// insert: 現在行を複製する.
// replace: 複製した行の開始/終了時刻をクリアする(複製後は todo task として扱いたいはず).
const f = function(editBuilder: vscode.TextEditorEdit): void{
editBuilder.insert(inserteePos, inserteeString);
editBuilder.replace(replaceeRange, afterString);
}
const promise = editor.edit(f);
promise.then(
(isSucceedEdit) => {
if(!isSucceedEdit){
return;
}
if(cursorMoverAfterCopy === undefined){
return;
}
cursorMoverAfterCopy();
}
)
} |
copyTask の呼び出し元は二つあって、 endTask さん const functionAfterCopy = () => {
CursorMover.golineend();
doRepeatIfPossible();
} copyTask のエントリポイント const task_copy = vscode.commands.registerCommand('tritask.task.copy', () => {
const callbackAfterCopy = CursorMover.golineend;
copyTask(callbackAfterCopy);
}); |
CursorMover.golineend class CursorMover {
static golineend() {
vscode.commands.executeCommand("cursorLineEnd");
return this;
} CursorMover 自体を return している(promise じゃない) |
dorepeat if possible function doRepeatIfPossible(){
const editor = getEditor();
const curPos = CursorPositioner.current();
const doc = editor.document;
const currentLine = doc.lineAt(curPos).text;
if(currentLine.indexOf("rep:") == -1){
return;
}
const curLineNumber = curPos.line;
const commandLine = `${getHelperCommandline()} -y ${curLineNumber} --repeat`;
console.log(`Repeat: "${commandLine}"`);
doSave();
exec(commandLine, (err) => {
if(err){
console.log(err);
}
});
}
do save function doSave(){
const editor = getEditor();
const doc = editor.document;
// 変更が無い状態(not dirty)で save() すると failed になるので防止.
if(!doc.isDirty){
return;
}
const promise = editor.document.save();
promise.then((result) =>{
if(!result){
abort("Failed to save()");
throw new Error();
}
});
}
|
😭 これはダメだ……ちょっと書き換えて済むレベルじゃない……一から書き直した方が良いかもしれん |
依存関係
|
どうすべきか?
|
endTask(){
// ……
// ★ここどう書けばいい? copyTask, golineend, do repeat 順に実行する
// ……
return thenable_boolean_object
} |
|
|
async function endTask(){ } で良い? activate() の const task_end = vscode.commands.registerCommand('tritask.task.end', () => {
endTask();
}); ここが async に対応してるか心配なんだが |
問題なさそう。 ならいけるね |
🏃 ガッと修正する感じになるぞ
ここまでいけばキレイな非同期コードになってるはず |
さあてと、やりますか 🏃 🏃 |
抜本的修正なのでブランチ切った方が良い? メモだけ: 48e1db5 |
1h でワンパス通します 2020/12/14 19:55:23 ready go! 2020/12/14 21:18:24 終わったの addTask だけ。まあそうスイスイとはいきませんよね |
くせものclass CursorMover {
static golinetop() {
return vscode.commands.executeCommand("cursorLineStart");
}
static golineend() {
return vscode.commands.executeCommand("cursorLineEnd");
}
static left() {
return vscode.commands.executeCommand("cursorLeft");
}
static up() {
return vscode.commands.executeCommand("cursorUp");
} こいつらが Thenable を返しやがるせいで、Thenable たちと共存できない(chain できない)…… かといって vscode.Selection で up や down を再現するのは地獄 |
いや、いけるか。 |
いや、ダメ。
えぐそう |
up はつかってなかったから消した |
add 後のカーソル位置は、
↓
つまり1行だけ下にずれる |
move は left() ではなく、「前の行の pos_description」が正しい。 つまり left() 要らん left() 実装マジエグかったので助かるンゴ…… static left(): vscode.Position {
const editor = getEditor();
const curPos = editor.selection.active;
let newY = curPos.line;
let newX = curPos.character;
const isLineTop = newX == 0
const isNotLineTop = !isLineTop
const isFirstLine = newY == 0
const isNotFirstLine = !isFirstLine
if(isLineTop && isNotFirstLine){
const prevLinePos = curPos.with(newY - 1, newX)
const doc = editor.document
const prevLine = doc.lineAt(prevLinePos).text;
const prevLineLength = prevLine.length
newY = newY - 1
newX = prevLineLength
}else if(isLineTop && isFirstLine){
// pass
}else if(isNotLineTop){
newX = newX - 1
}
return curPos.with(newY, newX);
} |
重くなってきたので移動する #20 へ |
lint にせよ refactoring にせよ、ガッと修正した後でも動くことをさっと確認したい。
サマリー
task
thenablePromise<boolean>
で return させる気の所為ならそれでいい(Thenableベースの途中でPromiseになるからテストコードダメかもという懸念Promise に統一する。then() の中で resolve することで変換するedit().then(){ この中で return false or true する場合}
The text was updated successfully, but these errors were encountered: