お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
ライブラリ::Jinja言語::Python

substring

確認環境

Env Ver
Jinja 2.11.0
Python 3.8.5

サンプルコード

  • 変数名[begin:end]で指定する
    • {% set some_variable = string_variable[0:100] %}

ループ処理で変数代入を行う

確認環境

Env Ver
Jinja 2.11.0
Python 3.8.5
  • Jinja2でループ処理の中で変数の足しこみとかをするやつ
    • 代入先の変数宣言は{% set ns = namespace(title = "") %}のようにしてやる必要がある
    • 後はループの中でsetしてやれば上手くいく
    • 変数は宣言したブロックがスコープになるので、スコープを広げたいときは適当にブロックを上げてやると良い

サンプルコード

  • MkDocsのテンプレートでパンくずリストを生成するコード
    • [A] [B] [C]みたいな感じ
{% set ns = namespace(title = "") %}
{% for doc in page.ancestors %}
    {% set ns.title = "[" + doc.title + "] " + ns.title %}
{% endfor %}

テンプレートファイルを読み込む

確認環境

Env Ver
Jinja 2.11.0
Python 3.8.5

サンプルコード

  • フォルダ構成
─src
    ├─app
    │   ├─configs
    │   │    └config.yaml
    │   ├─templates
    │   │         └─main.html
    │   └─__init__.py
    └─main.py
  • コード
from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
    # appはフォルダ構成のappフォルダを指す
    loader=PackageLoader('app', 'templates'),
    autoescape=select_autoescape(['html', 'xml'])
)
template = env.get_template('main.html')
# `render()` の引数は埋め込み変数を KeyValue 形式で指定
print(template.render(the='variables', go='here'))

yamlファイルから設定をロードする

確認環境

Env Ver
Jinja 2.11.0
Python 3.8.5

サンプルコード

  • フォルダ構成
─src
    ├─app
    │   ├─configs
    │   │    └config.yaml
    │   ├─templates
    │   │         └─main.html
    │   └─__init__.py
    └─main.py
  • コード
from yaml import safe_load as yamlLoad
from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
    loader=PackageLoader('app', 'templates'),
    autoescape=select_autoescape(['html', 'xml'])
)

template = env.get_template('main.html')
with open('app/configs/config.yaml') as fYaml:
    print(template.render(yamlLoad(fYaml)))

概要

  • Jinja2で作られている
    • Python向けのテンプレートエンジン
    • これを理解することで自在にカスタマイズできる。たぶん
  • テンプレート変数について、まともなリファレンスはないので、mkdocsのGitHubリポジトリを眺めて知るのが早い
    • www.mkdocs.org にも一応書いてあるが、網羅されていない

カスタマイズ方法

  • まずはMaterial for MkDocsを読んでリファレンスを理解する
    • 設定で解決する内容ならここで終わり
  • テンプレートのカスタマイズが必要な場合、overrides/main.htmlを生やしてブロック単位でいじる
投稿日:
Node.js::Jest開発::テスト言語::TypeScript

スプレッド演算子で引き渡した内容の内、一部だけを利用するケースを想定

サンプルコード

検査対象

type FooBar = {
  foo: string;
  bar: number;
};

/**
 * `foo` と `bar` しか使われない関数
 * @param arg
 */
export const spreadExample = (arg: FooBar) => {
  return new Promise((resolve) => {
    resolve([arg.foo, arg.bar]);
  });
};

テストコード

import * as spex from '../spreadExample';

const spiedSpreadExample = jest.spyOn(spex, 'spreadExample');

describe('spreadExample', () => {
  it('example', async () => {
    const test = {
      foo: 'hoge',
      bar: 123,
      baz: true, // 今回の課題となる項目
    };
    // 余計な `baz` が流し込まれているため、
    // 普通に検査しようとすると `baz` が邪魔で上手く行かないケース
    await spex.spreadExample({ ...test });

    expect(spiedSpreadExample).toBeCalled();
    // コールバックで `expect.objectContaining()` を呼ぶことにより
    // 見たい項目だけを検査することが可能(`baz` を見なくて済む
    expect(spiedSpreadExample).toHaveBeenCalledWith(
      expect.objectContaining({
        foo: 'hoge',
        bar: 123,
      })
    );
  });
});
投稿日:
言語::TypeScript開発::テストNode.js::Jest

単体テストの観点でいうとprocess.argvそのものはモックしないほうが良いと思っているので、本記事ではprocess.argv自体をモックする方法と、それを回避する方法を紹介する

サンプルコード

正攻法

describe('example', () => {
  afterEach(() => {
    // 元に戻しておく
    process.argv.length = 2;
  });
  it('got first param', () => {
    process.argv.push('param1');
    expect(process.argv.length).toBe(3);
    expect(process.argv[2]).toBe('param1');
  });
});

そもそもモックせずに済むように設計する

process.argvを利用している関数でprocess.argvを引数に取ればモック不要となる

const getArgv = (argv: string[]) => {
    // some procedure
}

describe('getArgv', () => {
  it('got first param', () => {
    const argv = [,, 'param1'];
    expect(argv.length).toBe(3);
    expect(argv[2]).toBe('param1');
  });
});