ホームページ ウェブフロントエンド jsチュートリアル 実行可能な JavaScript 仕様を構築する方法の詳細な説明

実行可能な JavaScript 仕様を構築する方法の詳細な説明

Oct 23, 2020 pm 05:57 PM
javascript 仕様

実行可能な JavaScript 仕様を構築する方法の詳細な説明

プログラミングは、単にタスクを完了する方法をコンピュータに指示するだけではなく、他の人、さらには将来の自分にアイデアを正確に伝えることでもあります。このようなコミュニケーションには、情報を共有することや、単に改訂を容易にすることなど、複数の目的がある場合があります。これは、昔に行われた内容を理解していないか覚えていない場合は困難です。

ソフトウェアを作成するときは、コードが意図した機能を備えていることを確認する必要もあります。セマンティクスを定義する正式な方法はありますが、最も単純かつ最速の (ただし厳密さはそれほど厳しくない) アプローチは、機能を使用して、期待どおりの結果が得られるかどうかを確認することです。

ほとんどの開発者は、コード ブロックの目標を明確にするためのコメントとしてのコード ドキュメントと、関数が目的の出力を与えることを確認するための一連のテストという実践に慣れています。

しかし、通常、文書化とテストは別の手順で行われます。これらのプラクティスを統合することで、プロジェクト開発に携わるすべての人に、より良いエクスペリエンスを提供できます。この記事では、ドキュメントとテストの両方に適した JavaScript 仕様を実行できる単純なプログラムの実装について説明します。

ディレクトリ内のすべての仕様ファイルを検索し、各仕様で見つかったすべてのアサーションを抽出し、その結果を計算し、最後にどのアサーションが失敗し、どのアサーションが失敗したかを表示するコマンド ライン インターフェイスを構築します。

仕様の形式

各仕様ファイルは、テンプレート テキストから文字列をエクスポートします。最初の行は仕様のタイトルとして機能します。テンプレート リテラルを使用すると、文字列の間に JS 式を埋め込むことができ、各式はアサーションを表します。各アサーションを識別するために、行を一意の文字で始めることができます。

この例では、バー文字 (|) とダッシュ (-) の組み合わせを使用できます。ダッシュは回転ドアの記号に似ており、論理アサーションの記号として表すこともできます。 。

これは、その使用法を説明した例です:

const dependency = require('./dependency')module.exports = `
  Example of a Specification File
  
  This project allows to test JavaScript programs using specification files.
  Every *.spec.js file exports a single template literal that includes a general
  explanation of the file being specified. Each file represents a logical
  component of a bigger system. Each logical component is composed of several
  units of functionality that can be tested for certain properties.
  Each one of this units of functionality may have one or more
  assertions. Each assertion is denoted by a line as the following:

  |- ${dependency} The dependency has been loaded and the first assert has
  been evaluated.

  Multiple assertions can be made for each file:

  |- ${false} This assertion will fail.

  |- ${2 + 2 === 4} This assertion will succeed.

  The combination of | and - will form a Turnstile ligature (|-) using the appropriate
  font. Fira Code is recommended. A Turnstile symbol was used by Gottlob Frege
  at the start of sentenses being asserted as true.

  The intended usage is for specification-first software. Where the programmer
  defines the high level structure of a program in terms of a specification,
  then progressively builds the parts conforming that specification until all
  the tests are passed. A desired side-effect is having a simple way to generate
  up-to-date documentation outside the code for API consumers.
`
ログイン後にコピー

次に、プログラムの高レベルの構造に移りましょう。

プログラムの構造

プログラムの構造全体は、2 つの Node.js ライブラリを使用して処理することに加えて、数行のコードで定義できます。ファイル システム (fs ) とディレクトリ パス (path) には依存関係はありません。このセクションではプログラムの構造のみを定義します。関数の定義は次のセクションで説明します。

#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const specRegExp = /\.spec\.js$/
const target = path.join(process.cwd(), process.argv[2])
// Get all the specification file paths
// If a specification file is provided then just test that file
// Otherwise find all the specification files in the target directory
const paths = specRegExp.test(target)
  ? [ target ]
  : findSpecifications(target, specRegExp).filter(x => x)
// Get the content of each specification file
// Get the assertions of each specification file
const assertionGroups = getAssertions(getSpecifications(paths))
// Log all the assertions
logAssertions(assertionGroups)
 
// Check for any failed assertions and return an appropriate exit code
process.exitCode = checkAssertions(assertionGroups)
ログイン後にコピー

これは CLI (コマンド ライン インターフェイス) のエントリ ポイントでもあるため、このファイルがノード プログラムによって実行される必要があることを示すシバンの最初の行を追加する必要があります。単一のパラメータのみを対象としているため、コマンド オプションを処理するために特定のライブラリを追加する必要はありません。ただし、このプログラムを大幅に拡張する予定がある場合は、他のオプションを検討することもできます。

ターゲットのテスト ファイルまたはディレクトリを取得するには、実行されたコマンドへのパス (process.cwd() を使用) と、コマンドの実行時にユーザーが最初のパラメーターとして指定したパラメーター (process を使用) を組み合わせる必要があります。 .argv[2 ])それらを接続します。

これらの値への参照は、プロセス オブジェクトの Node.js ドキュメントで見つけることができます。この方法により、ターゲットのディレクトリ/ファイルの絶対パスが取得されます。

ここで、最初に行う必要があるのは、すべての JavaScript 仕様ファイルを見つけることです。 12 行目に示すように、条件演算子を使用して柔軟性を高めることができます。ユーザーが正規ファイルをターゲットとして指定した場合は、ファイル パスを直接使用するだけです。

それ以外の場合、ユーザーがディレクトリ パスを指定した場合は、specRegExp で定義されたパターンに一致するすべてのファイルを検索する必要があります。このパターンは、後で findSpecific 関数を使用して定義します。この関数は、ターゲット ディレクトリ内の各仕様ファイルへのパスの配列を返します。

18 行目では、getspecation() と getassertion() の 2 つの関数を組み合わせて、assertionGroups 定数を定義します。まず各仕様ファイルの内容を取得し、そこからアサーションを抽出します。

これら 2 つの関数は後で定義します。ここでは、最初の関数の出力を 2 番目の関数のパラメーターとして使用することに注意してください。これにより、プロセスが簡略化され、2 つの関数間で直接接続が確立されました。

関数を 1 つだけ持つこともでき、関数を分割することで実際のプロセスが何であるかをよりよく理解できるようになりますが、プログラムは明確で理解しやすいものである必要があり、それだけでは十分ではないことに注意してください。

assertationsGroup 定数は次のように構成されています。

assertionGroup[specification][assertion]
ログイン後にコピー

次に、logassertion() 関数を使用して結果をレポートできるように、これらすべてのアサーションをユーザー ログに記録します。各アサーションには結果 (true または false) と簡単な説明が含まれており、この情報を使用して各タイプの結果に特別な色を付けることができます。

最後に、アサーションの結果に基づいて終了コードを定義します。これにより、プログラムがどのように終了したかに関する情報がプロセスに提供されます: プロセスは成功しましたか、それとも失敗しましたか? 終了コード 0 はプロセスが正常に終了したことを意味し、失敗した場合は 1 を意味し、この例では少なくとも 1 つのアサーションが失敗した場合は 1 を意味します。

すべての仕様ファイルを検索

要找到所有的JavaScript规范文件,我们可以使用一个递归函数,该函数遍历用户作为CLI参数指定的目录。在搜索时,应该使用程序开始时定义的正则表达式(/\.spec\.js$/)检查每个文件,该表达式将匹配以.spec.js结尾的所有文件路径。

function findSpecifications (dir, matchPattern) {
  return fs.readdirSync(dir)
    .map(filePath => path.join(dir, filePath))
    .filter(filePath => matchPattern.test(filePath) && fs.statSync(filePath).isFile())
}
ログイン後にコピー

我们的findspecification函数接受一个目标目录(dir)和一个正则表达式,该正则表达式标识规范文件(matchPattern)。

获取每个规范的内容

由于我们导出的是模板文本,因此获取内容和计算后的断言非常简单,因此我们必须导入每个文件,当它被导入时,所有的断言都将自动进行计算。

function getSpecifications (paths) {
  return paths.map(path => require(path))
}
ログイン後にコピー

使用map()函数,我们使用节点的require函数将数组的路径替换为文件的内容。

从文本中提取断言

此时,我们有一个数组,其中包含每个规范文件的内容,并且已经计算了它们的断言。我们使用旋转门指示器(|-)来查找所有这些断言并提取它们。

function getAssertions (specifications) {
  return specifications.map(specification => ({
    title: specification.split('\n\n', 1)[0].trim(),
    assertions: specification.match(/^( |\t)*(\|-)(.|\n)*?\./gm).map(assertion => {
      const assertionFragments = /(?:\|-) (\w*) ((?:.|\n)*)/.exec(assertion)
 
      return {
        value: assertionFragments[1],
        description: assertionFragments[2].replace(/\n /, '')
      }
    })
  }))
}
ログイン後にコピー

这个函数将返回一个类似的数组,但是用一个如下结构的对象替换每个规范的内容:

title: <String: Name of this particular specification>,
  assertions: [
    {
      value: <Boolean: The result of the assertion>,
      description: <String: The short description for the assertion>
    }
  ]
}
ログイン後にコピー

标题是用规范字符串的第一行设置的。然后,每个断言都作为数组存储在断言键中。该值将断言的结果表示为布尔值。我们将使用这个值来知道断言是否成功。

此外,描述将显示给用户,作为识别哪些断言成功和哪些断言失败的方法。我们在每种情况下都使用正则表达式。

记录结果

我们沿着程序构建的数组现在有一系列JavaScript规范文件,其中包含一列找到的断言及其结果和描述,因此除了向用户报告结果之外,没有什么可做的。

{
  function logAssertions(assertionGroups) {
  // Methods to log text with colors
  const ansiColor = {
    blue: text => console.log(`\x1b[1m\x1b[34m${text}\x1b[39m\x1b[22m`),
    green: text => console.log(`\x1b[32m    ${text}\x1b[39m`),
    red: text => console.log(`\x1b[31m    ${text}\x1b[39m`)
  }
  // Log the results
  assertionGroups.forEach(group => {
    ansiColor.blue(group.title)
    group.assertions.forEach(assertion => {
      assertion.value === &#39;true&#39;
        ? ansiColor.green(assertion.description)
        : ansiColor.red(assertion.description)
    })
  })
 
  console.log(&#39;\n&#39;)
}
ログイン後にコピー

我们可以根据结果使用颜色来格式化输入。为了在终端上显示颜色,我们需要添加ANSI转义码。为了在下一个块中简化它们的用法,我们将每种颜色保存为ansiColor对象的方法。

首先,我们要显示规范的标题,请记住,我们为每个规范使用数组的第一个维度,并将其命名为一组(断言)。然后,我们使用它们各自的颜色根据它们的值记录所有断言:绿色表示计算为true的断言,红色表示具有其他值的断言。

注意比较,我们检查true是否为字符串,因为我们从每个文件接收字符串。

检查结果

最后,最后一步是检查所有测试是否成功。

function checkAssertions (assertionGroups) {
  return assertionGroups.some(
    group => group.assertions.some(assertion => assertion.value === &#39;false&#39;)
  ) ? 1 : 0
}
ログイン後にコピー

我们使用数组的some()方法检查每个断言组(规范),看看是否至少有一个值是' ' ' false ' ' '。我们嵌套了其中的两个因为我们有一个二维数组。

运行我们的程序

此时,我们的CLI应准备好运行一些JavaScript规范,并查看是否拾取并评估了断言。在test目录中,您可以从本文开头复制规范示例,并将以下命令粘贴到您的文件中:package.json

"scripts": {
  "test": "node index.js test"
  }
ログイン後にコピー

其中test是包含示例规范文件的目录的名称。

当运行npm test命令时,您应该看到使用它们各自颜色的结果。

相关免费学习推荐:js视频教程

更多编程相关知识,请访问:编程入门!!

以上が実行可能な JavaScript 仕様を構築する方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

Python学習に必要な変数の命名規則 Python学習に必要な変数の命名規則 Jan 20, 2024 am 09:03 AM

Python を学習するときに知っておく必要がある変数の命名規則 Python プログラミング言語を学習するときに重要な点は、変数に正しく名前を付けて使用する方法を学ぶことです。変数は、データを保存および表現するために使用される識別子です。適切な変数命名規則は、コードの読みやすさを向上させるだけでなく、エラーの可能性も減らします。この記事では、一般的に使用される変数の命名規則をいくつか紹介し、対応するコード例を示します。意味のある名前を使用する 変数名には明確な意味があり、変数に格納されているデータを説明できる必要があります。意味のある名前を使用すると、

See all articles