Add --no-emoji option to disable emoji characters in console output (#1635)
* Add --no-emoji option to disable emoji characters in console output
- Added emoji-util.js utility for conditional emoji formatting
- Updated args.js to include --no-emoji command line option
- Modified script-util.js to use formatMessage() for all emoji output
- Updated startup.js to use emoji utility
- Added documentation and demo scripts
- Resolves issues with stdout when piping to automation tools
- Python no longer chokes on emoji characters in output
- Maintains backward compatibility (emojis enabled by default)
* Fix env.formatMessage() for startup.test.js - add emoji utility wrapper to env.js
* Update src-script/script-util.js
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
* Fix license header corruption and standardize emoji usage
- Fixed corrupted license header in script-util.js
- Standardized to use emojiUtil.formatMessage() in script files
- Keep env.formatMessage() wrapper for startup.js compatibility
- Both approaches work correctly for their respective module systems
* Fix comprehensive emoji support across ZAP
- Fix broken emoji syntax in startup.js and gsdk-public-regen.js
- Add emoji support to gsdk-public-regen.js and zap-package-metadata.js
- Create fix-emojis.js utility script for systematic emoji conversion
- All emojis now respect --no-emoji flag and NO_EMOJI environment variable
* Complete emoji support implementation across all ZAP scripts
- Add emoji utility to zap-start.js and zap-uitest.js
- Fix remaining hardcoded emojis in zap-start.js, zap-uitest.js, and gsdk-public-regen.js
- All console output now respects --no-emoji flag and NO_EMOJI environment variable
- Comprehensive solution ensures automation-friendly output for CI/CD pipelines
* Make emoji utility stateful and testable
- Replace static constant with dynamic isEmojiDisabled() function
- Add setEmojiDisabled() and resetEmojiState() for testing
- Export testing functions through env.js wrapper
- Fix test to use CommonJS emoji-util directly
- Maintains environment variable and command line flag detection
- Enables proper unit testing of emoji functionality
* Restore accidentally deleted API documentation
- Restore docs/api.md from commit 48de0060 (before emoji changes)
- File was accidentally truncated in commit 5f8ef3e8 due to JSDoc generation failure
- JSDoc fails with Node.js v24 due to util.isRegExp compatibility issue
- Restores all 28,406 lines of API documentation
* Remove EMOJI_IMPLEMENTATION_SUMMARY.md
- Remove redundant summary file
- Documentation is already covered in docs/no-emoji-implementation.md
* Remove temporary development files
- Remove demo-no-emoji.js (was just a demonstration script)
- Remove fix-emojis.js (was a utility script for development)
- Keep only the production implementation files
* Refactor: Consolidate formatMessage function to follow DRY principle
- Remove duplicate formatMessage function from emoji-util.js
- Keep single formatMessage implementation in env.js for general message formatting
- Update all imports and function calls across codebase from emojiUtil.formatMessage to env.formatMessage
- Maintain emoji-util.js focus on emoji state management only
- Improve code organization by placing message formatting in general utilities module
Fixes code duplication and follows best practices for single responsibility principle.
* Fix module syntax in env.js: convert ES modules to CommonJS
- Convert 42 'export function' declarations to regular functions
- Convert 'export const environmentVariable' to regular const
- Add all exports to module.exports object for CommonJS compatibility
- Resolves CI failure caused by mixed ES/CommonJS module syntax
- Maintains all existing functionality while fixing Node.js module loading
* Fix formatMessage implementation in env.js
- Implement formatMessage logic directly instead of calling non-existent emojiUtil.formatMessage
- Use emojiUtil.isEmojiDisabled() to check state and format accordingly
- Resolves TypeError: emojiUtil.formatMessage is not a function
* Address PR review: Fix emoji corruption and rename formatMessage to formatEmojiMessage
- Fix corrupted emojis (� symbols) that appeared due to encoding issues during sed operations
- Rename formatMessage() to formatEmojiMessage() for better semantic clarity
- Restore proper Unicode emojis: 👈 for read operations, 👉 for write operations, 🔧 for processing
- Update all 94+ function call sites across startup.js, script utilities, and tests
- Verify emoji functionality works correctly with comprehensive test coverage
- Remove obsolete test files and documentation per cleanup requirements
Addresses feedback from PR review regarding function naming and emoji display issues.
* Clean up empty development files
Remove empty files that were created during development:
- EMOJI_IMPLEMENTATION_SUMMARY.md
- demo-no-emoji.js
- fix-emojis.js
These were temporary files that never got populated with content.
* update apack.json
* remove package-lock.json
* cleanup
* cleanup
* adding helper functions because they are needed for the tests
* add tests and cleanup
* more emojies
* bug fix
* fix ci
* fix to new format
* fix emoji
* fix tests
---------
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
diff --git a/apack.json b/apack.json
index 4a887c7..df08720 100644
--- a/apack.json
+++ b/apack.json
@@ -75,10 +75,10 @@
"cmd": "$(zap-cli) --version"
},
"uc_generate": {
- "cmd": "$(zap-cli) generate --noUi --noServer -o ${generationOutput} --packageMatch fuzzy [ --zcl ${zcl.zigbeeZclJsonFile} | --zcl ${sdkRoot}/app/zcl/zcl-zap.json ] [ --zcl ${zcl.matterZclJsonFile} | --zcl ${sdkRoot}/extension/matter_extension/src/app/zap-templates/zcl/zcl.json ] [ --generationTemplate ${zcl.zigbeeTemplateJsonFile} | --generationTemplate ${sdkRoot}/protocol/zigbee/app/framework/gen-template/gen-templates.json ] [ --generationTemplate ${zcl.matterTemplateJsonFile} | --generationTemplate ${sdkRoot}/extension/matter_extension/src/app/zap-templates/app-templates.json ] --in ${contentFolder} --noLoadingFailure --appendGenerationSubdirectory --upgradeZapFile"
+ "cmd": "$(zap-cli) generate --noUi --noServer -o ${generationOutput} --packageMatch fuzzy [ --zcl ${zcl.zigbeeZclJsonFile} | --zcl ${sdkRoot}/app/zcl/zcl-zap.json ] [ --zcl ${zcl.matterZclJsonFile} | --zcl ${sdkRoot}/extension/matter_extension/src/app/zap-templates/zcl/zcl.json ] [ --generationTemplate ${zcl.zigbeeTemplateJsonFile} | --generationTemplate ${sdkRoot}/protocol/zigbee/app/framework/gen-template/gen-templates.json ] [ --generationTemplate ${zcl.matterTemplateJsonFile} | --generationTemplate ${sdkRoot}/extension/matter_extension/src/app/zap-templates/app-templates.json ] --in ${contentFolder} --noLoadingFailure --appendGenerationSubdirectory --upgradeZapFile --no-emoji"
},
"uc_upgrade": {
- "cmd": "$(zap-cli) upgrade --results ${results} -d ${tempContentFolder} [ --zcl ${zcl.zigbeeZclJsonFile} | --zcl ${sdkRoot}/app/zcl/zcl-zap.json ] [ --zcl ${zcl.matterZclJsonFile} | --zcl ${sdkRoot}/extension/matter_extension/src/app/zap-templates/zcl/zcl.json ] [ --generationTemplate ${zcl.zigbeeTemplateJsonFile} | --generationTemplate ${sdkRoot}/protocol/zigbee/app/framework/gen-template/gen-templates.json ] [ --generationTemplate ${zcl.matterTemplateJsonFile} | --generationTemplate ${sdkRoot}/extension/matter_extension/src/app/zap-templates/app-templates.json ] --noLoadingFailure"
+ "cmd": "$(zap-cli) upgrade --results ${results} -d ${tempContentFolder} [ --zcl ${zcl.zigbeeZclJsonFile} | --zcl ${sdkRoot}/app/zcl/zcl-zap.json ] [ --zcl ${zcl.matterZclJsonFile} | --zcl ${sdkRoot}/extension/matter_extension/src/app/zap-templates/zcl/zcl.json ] [ --generationTemplate ${zcl.zigbeeTemplateJsonFile} | --generationTemplate ${sdkRoot}/protocol/zigbee/app/framework/gen-template/gen-templates.json ] [ --generationTemplate ${zcl.matterTemplateJsonFile} | --generationTemplate ${sdkRoot}/extension/matter_extension/src/app/zap-templates/app-templates.json ] --noLoadingFailure --no-emoji"
},
"zapHelp": {
"cmd": "$(zap) --help"
diff --git a/docs/api.md b/docs/api.md
index b7d54f4..8e4eeec 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -337,6 +337,20 @@
</dd>
</dl>
+## Functions
+
+<dl>
+<dt><a href="#setEmojiDisabled">setEmojiDisabled(value)</a></dt>
+<dd><p>Set emoji disabled state (for testing)</p>
+</dd>
+<dt><a href="#resetEmojiState">resetEmojiState()</a></dt>
+<dd><p>Reset emoji disabled state to environment/argv detection (for testing)</p>
+</dd>
+<dt><a href="#isEmojiDisabled">isEmojiDisabled()</a> ⇒ <code>boolean</code></dt>
+<dd><p>Check if emojis should be disabled</p>
+</dd>
+</dl>
+
<a name="module_DB API_ External URLs."></a>
## DB API: External URLs.
@@ -17955,379 +17969,380 @@
* [JS API: Environment utilities](#module_JS API_ Environment utilities)
- * [.setSaveFileFormat(n)](#module_JS API_ Environment utilities.setSaveFileFormat)
- * [.defaultFileFormat()](#module_JS API_ Environment utilities.defaultFileFormat) ⇒
- * [.builtinSilabsZclMetafile()](#module_JS API_ Environment utilities.builtinSilabsZclMetafile) ⇒
- * [.builtinSilabsTemplatesMetaFile()](#module_JS API_ Environment utilities.builtinSilabsTemplatesMetaFile) ⇒
- * [.builtinSilabsZclSpecialMetafile()](#module_JS API_ Environment utilities.builtinSilabsZclSpecialMetafile) ⇒
- * [.builtinSilabsZclGeneralXmlFile()](#module_JS API_ Environment utilities.builtinSilabsZclGeneralXmlFile) ⇒
- * [.builtinSilabsSpecialZclGeneralSpecialXmlFile()](#module_JS API_ Environment utilities.builtinSilabsSpecialZclGeneralSpecialXmlFile) ⇒
- * [.builtinMatterZclMetafile()](#module_JS API_ Environment utilities.builtinMatterZclMetafile) ⇒
- * [.builtinNewMatterZclMetafile()](#module_JS API_ Environment utilities.builtinNewMatterZclMetafile) ⇒
- * [.builtinMatterTemplatesMetaFile()](#module_JS API_ Environment utilities.builtinMatterTemplatesMetaFile) ⇒
- * [.builtinDotdotZclMetafile()](#module_JS API_ Environment utilities.builtinDotdotZclMetafile) ⇒
- * [.builtinMatterZclMetafile2()](#module_JS API_ Environment utilities.builtinMatterZclMetafile2) ⇒
- * [.builtinTemplateMetafile()](#module_JS API_ Environment utilities.builtinTemplateMetafile) ⇒
- * [.setDevelopmentEnv()](#module_JS API_ Environment utilities.setDevelopmentEnv)
- * [.setProductionEnv()](#module_JS API_ Environment utilities.setProductionEnv)
- * [.logInitStdout()](#module_JS API_ Environment utilities.logInitStdout)
- * [.logInitLogFile()](#module_JS API_ Environment utilities.logInitLogFile)
- * [.setAppDirectory(path)](#module_JS API_ Environment utilities.setAppDirectory)
- * [.appDirectory()](#module_JS API_ Environment utilities.appDirectory) ⇒
- * [.iconsDirectory()](#module_JS API_ Environment utilities.iconsDirectory) ⇒
- * [.schemaFile()](#module_JS API_ Environment utilities.schemaFile) ⇒
- * [.sqliteFile(filename)](#module_JS API_ Environment utilities.sqliteFile) ⇒
- * [.sqliteTestFile(id, deleteExistingFile)](#module_JS API_ Environment utilities.sqliteTestFile) ⇒
- * [.zapVersionAsString()](#module_JS API_ Environment utilities.zapVersionAsString)
- * [.locateProjectResource(filePath)](#module_JS API_ Environment utilities.locateProjectResource) ⇒
- * [.zapVersion()](#module_JS API_ Environment utilities.zapVersion) ⇒
- * [.baseUrl()](#module_JS API_ Environment utilities.baseUrl) ⇒
- * [.printToStderr(msg)](#module_JS API_ Environment utilities.printToStderr)
- * [.log(level, msg, err)](#module_JS API_ Environment utilities.log)
- * [.logInfo(msg, err)](#module_JS API_ Environment utilities.logInfo)
- * [.logError(msg, err)](#module_JS API_ Environment utilities.logError)
- * [.logWarning(msg, err)](#module_JS API_ Environment utilities.logWarning)
- * [.logSql(msg, err)](#module_JS API_ Environment utilities.logSql)
- * [.logBrowser(msg, err)](#module_JS API_ Environment utilities.logBrowser)
- * [.logIpc(msg, err)](#module_JS API_ Environment utilities.logIpc)
- * [.logDebug(msg, err)](#module_JS API_ Environment utilities.logDebug)
- * [.logWarningToFile(msg)](#module_JS API_ Environment utilities.logWarningToFile)
- * [.isMatchingVersion(versionsArray, providedVersion)](#module_JS API_ Environment utilities.isMatchingVersion) ⇒
- * [.versionsCheck()](#module_JS API_ Environment utilities.versionsCheck) ⇒
- * [.httpStaticContent()](#module_JS API_ Environment utilities.httpStaticContent) ⇒
+ * [~setSaveFileFormat(n)](#module_JS API_ Environment utilities..setSaveFileFormat)
+ * [~defaultFileFormat()](#module_JS API_ Environment utilities..defaultFileFormat) ⇒
+ * [~builtinSilabsZclMetafile()](#module_JS API_ Environment utilities..builtinSilabsZclMetafile) ⇒
+ * [~builtinSilabsTemplatesMetaFile()](#module_JS API_ Environment utilities..builtinSilabsTemplatesMetaFile) ⇒
+ * [~builtinSilabsZclSpecialMetafile()](#module_JS API_ Environment utilities..builtinSilabsZclSpecialMetafile) ⇒
+ * [~builtinSilabsZclGeneralXmlFile()](#module_JS API_ Environment utilities..builtinSilabsZclGeneralXmlFile) ⇒
+ * [~builtinSilabsSpecialZclGeneralSpecialXmlFile()](#module_JS API_ Environment utilities..builtinSilabsSpecialZclGeneralSpecialXmlFile) ⇒
+ * [~builtinMatterZclMetafile()](#module_JS API_ Environment utilities..builtinMatterZclMetafile) ⇒
+ * [~builtinNewMatterZclMetafile()](#module_JS API_ Environment utilities..builtinNewMatterZclMetafile) ⇒
+ * [~builtinMatterTemplatesMetaFile()](#module_JS API_ Environment utilities..builtinMatterTemplatesMetaFile) ⇒
+ * [~builtinDotdotZclMetafile()](#module_JS API_ Environment utilities..builtinDotdotZclMetafile) ⇒
+ * [~builtinMatterZclMetafile2()](#module_JS API_ Environment utilities..builtinMatterZclMetafile2) ⇒
+ * [~builtinTemplateMetafile()](#module_JS API_ Environment utilities..builtinTemplateMetafile) ⇒
+ * [~setDevelopmentEnv()](#module_JS API_ Environment utilities..setDevelopmentEnv)
+ * [~setProductionEnv()](#module_JS API_ Environment utilities..setProductionEnv)
+ * [~logInitStdout()](#module_JS API_ Environment utilities..logInitStdout)
+ * [~logInitLogFile()](#module_JS API_ Environment utilities..logInitLogFile)
+ * [~setAppDirectory(path)](#module_JS API_ Environment utilities..setAppDirectory)
+ * [~appDirectory()](#module_JS API_ Environment utilities..appDirectory) ⇒
+ * [~iconsDirectory()](#module_JS API_ Environment utilities..iconsDirectory) ⇒
+ * [~schemaFile()](#module_JS API_ Environment utilities..schemaFile) ⇒
+ * [~sqliteFile(filename)](#module_JS API_ Environment utilities..sqliteFile) ⇒
+ * [~sqliteTestFile(id, deleteExistingFile)](#module_JS API_ Environment utilities..sqliteTestFile) ⇒
+ * [~zapVersionAsString()](#module_JS API_ Environment utilities..zapVersionAsString)
+ * [~locateProjectResource(filePath)](#module_JS API_ Environment utilities..locateProjectResource) ⇒
+ * [~zapVersion()](#module_JS API_ Environment utilities..zapVersion) ⇒
+ * [~baseUrl()](#module_JS API_ Environment utilities..baseUrl) ⇒
+ * [~printToStderr(msg)](#module_JS API_ Environment utilities..printToStderr)
+ * [~log(level, msg, err)](#module_JS API_ Environment utilities..log)
+ * [~logInfo(msg, err)](#module_JS API_ Environment utilities..logInfo)
+ * [~logError(msg, err)](#module_JS API_ Environment utilities..logError)
+ * [~logWarning(msg, err)](#module_JS API_ Environment utilities..logWarning)
+ * [~logSql(msg, err)](#module_JS API_ Environment utilities..logSql)
+ * [~logBrowser(msg, err)](#module_JS API_ Environment utilities..logBrowser)
+ * [~logIpc(msg, err)](#module_JS API_ Environment utilities..logIpc)
+ * [~logDebug(msg, err)](#module_JS API_ Environment utilities..logDebug)
+ * [~logWarningToFile(msg)](#module_JS API_ Environment utilities..logWarningToFile)
+ * [~isMatchingVersion(versionsArray, providedVersion)](#module_JS API_ Environment utilities..isMatchingVersion) ⇒
+ * [~versionsCheck()](#module_JS API_ Environment utilities..versionsCheck) ⇒
+ * [~httpStaticContent()](#module_JS API_ Environment utilities..httpStaticContent) ⇒
+ * [~formatEmojiMessage(emoji, message)](#module_JS API_ Environment utilities..formatEmojiMessage) ⇒ <code>string</code>
-<a name="module_JS API_ Environment utilities.setSaveFileFormat"></a>
+<a name="module_JS API_ Environment utilities..setSaveFileFormat"></a>
-### JS API: Environment utilities.setSaveFileFormat(n)
+### JS API: Environment utilities~setSaveFileFormat(n)
Set save file format.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
| Param | Type |
| --- | --- |
| n | <code>\*</code> |
-<a name="module_JS API_ Environment utilities.defaultFileFormat"></a>
+<a name="module_JS API_ Environment utilities..defaultFileFormat"></a>
-### JS API: Environment utilities.defaultFileFormat() ⇒
+### JS API: Environment utilities~defaultFileFormat() ⇒
Get save file format.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: saveFileFormat
-<a name="module_JS API_ Environment utilities.builtinSilabsZclMetafile"></a>
+<a name="module_JS API_ Environment utilities..builtinSilabsZclMetafile"></a>
-### JS API: Environment utilities.builtinSilabsZclMetafile() ⇒
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+### JS API: Environment utilities~builtinSilabsZclMetafile() ⇒
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: path to zcl.json file
-<a name="module_JS API_ Environment utilities.builtinSilabsTemplatesMetaFile"></a>
+<a name="module_JS API_ Environment utilities..builtinSilabsTemplatesMetaFile"></a>
-### JS API: Environment utilities.builtinSilabsTemplatesMetaFile() ⇒
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+### JS API: Environment utilities~builtinSilabsTemplatesMetaFile() ⇒
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: path to gen-templates.json file
-<a name="module_JS API_ Environment utilities.builtinSilabsZclSpecialMetafile"></a>
+<a name="module_JS API_ Environment utilities..builtinSilabsZclSpecialMetafile"></a>
-### JS API: Environment utilities.builtinSilabsZclSpecialMetafile() ⇒
+### JS API: Environment utilities~builtinSilabsZclSpecialMetafile() ⇒
Used to retrieve zcl-special.json by zcl reload test in zcl-loader.test.js
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: path to zcl-special.json file used by zcl-loader.test.js
-<a name="module_JS API_ Environment utilities.builtinSilabsZclGeneralXmlFile"></a>
+<a name="module_JS API_ Environment utilities..builtinSilabsZclGeneralXmlFile"></a>
-### JS API: Environment utilities.builtinSilabsZclGeneralXmlFile() ⇒
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+### JS API: Environment utilities~builtinSilabsZclGeneralXmlFile() ⇒
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: path to general.xml file
-<a name="module_JS API_ Environment utilities.builtinSilabsSpecialZclGeneralSpecialXmlFile"></a>
+<a name="module_JS API_ Environment utilities..builtinSilabsSpecialZclGeneralSpecialXmlFile"></a>
-### JS API: Environment utilities.builtinSilabsSpecialZclGeneralSpecialXmlFile() ⇒
+### JS API: Environment utilities~builtinSilabsSpecialZclGeneralSpecialXmlFile() ⇒
Used to retrieve general-special.xml by zcl reload test in zcl-loader.test.js
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: path to general-special.xml file used by zcl-loader.test.js
-<a name="module_JS API_ Environment utilities.builtinMatterZclMetafile"></a>
+<a name="module_JS API_ Environment utilities..builtinMatterZclMetafile"></a>
-### JS API: Environment utilities.builtinMatterZclMetafile() ⇒
+### JS API: Environment utilities~builtinMatterZclMetafile() ⇒
Get builtin matter ZCL json file
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: matter ZCL json file
-<a name="module_JS API_ Environment utilities.builtinNewMatterZclMetafile"></a>
+<a name="module_JS API_ Environment utilities..builtinNewMatterZclMetafile"></a>
-### JS API: Environment utilities.builtinNewMatterZclMetafile() ⇒
+### JS API: Environment utilities~builtinNewMatterZclMetafile() ⇒
Get builtin matter ZCL json file
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: matter ZCL json file
-<a name="module_JS API_ Environment utilities.builtinMatterTemplatesMetaFile"></a>
+<a name="module_JS API_ Environment utilities..builtinMatterTemplatesMetaFile"></a>
-### JS API: Environment utilities.builtinMatterTemplatesMetaFile() ⇒
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+### JS API: Environment utilities~builtinMatterTemplatesMetaFile() ⇒
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: path to templates.json file
-<a name="module_JS API_ Environment utilities.builtinDotdotZclMetafile"></a>
+<a name="module_JS API_ Environment utilities..builtinDotdotZclMetafile"></a>
-### JS API: Environment utilities.builtinDotdotZclMetafile() ⇒
+### JS API: Environment utilities~builtinDotdotZclMetafile() ⇒
Get builtin dotdot ZCL json file
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: dotdot ZCL json file
-<a name="module_JS API_ Environment utilities.builtinMatterZclMetafile2"></a>
+<a name="module_JS API_ Environment utilities..builtinMatterZclMetafile2"></a>
-### JS API: Environment utilities.builtinMatterZclMetafile2() ⇒
+### JS API: Environment utilities~builtinMatterZclMetafile2() ⇒
Get builtin Matter ZCL json file
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: matter ZCL json file
-<a name="module_JS API_ Environment utilities.builtinTemplateMetafile"></a>
+<a name="module_JS API_ Environment utilities..builtinTemplateMetafile"></a>
-### JS API: Environment utilities.builtinTemplateMetafile() ⇒
+### JS API: Environment utilities~builtinTemplateMetafile() ⇒
No builtin meta template file.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: null
-<a name="module_JS API_ Environment utilities.setDevelopmentEnv"></a>
+<a name="module_JS API_ Environment utilities..setDevelopmentEnv"></a>
-### JS API: Environment utilities.setDevelopmentEnv()
+### JS API: Environment utilities~setDevelopmentEnv()
Set up the devlopment environment.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-<a name="module_JS API_ Environment utilities.setProductionEnv"></a>
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+<a name="module_JS API_ Environment utilities..setProductionEnv"></a>
-### JS API: Environment utilities.setProductionEnv()
+### JS API: Environment utilities~setProductionEnv()
Set up the production environment.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-<a name="module_JS API_ Environment utilities.logInitStdout"></a>
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+<a name="module_JS API_ Environment utilities..logInitStdout"></a>
-### JS API: Environment utilities.logInitStdout()
+### JS API: Environment utilities~logInitStdout()
set explicit_logger_set
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-<a name="module_JS API_ Environment utilities.logInitLogFile"></a>
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+<a name="module_JS API_ Environment utilities..logInitLogFile"></a>
-### JS API: Environment utilities.logInitLogFile()
+### JS API: Environment utilities~logInitLogFile()
Create zap.log file for logging.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-<a name="module_JS API_ Environment utilities.setAppDirectory"></a>
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+<a name="module_JS API_ Environment utilities..setAppDirectory"></a>
-### JS API: Environment utilities.setAppDirectory(path)
+### JS API: Environment utilities~setAppDirectory(path)
Set the state directory. This method is intended to be called
only at the application startup, when CLI args are being parsed.
This method honors '~/' being the first characters in its argument.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
| Param | Type | Description |
| --- | --- | --- |
| path | <code>\*</code> | Absolute path. Typically '~/.zap'. |
-<a name="module_JS API_ Environment utilities.appDirectory"></a>
+<a name="module_JS API_ Environment utilities..appDirectory"></a>
-### JS API: Environment utilities.appDirectory() ⇒
+### JS API: Environment utilities~appDirectory() ⇒
Returns an app directory. It creates it, if it doesn't exist
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: state directory, which is guaranteed to be already existing
-<a name="module_JS API_ Environment utilities.iconsDirectory"></a>
+<a name="module_JS API_ Environment utilities..iconsDirectory"></a>
-### JS API: Environment utilities.iconsDirectory() ⇒
+### JS API: Environment utilities~iconsDirectory() ⇒
Get path to icons directory.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: path to icons directory
-<a name="module_JS API_ Environment utilities.schemaFile"></a>
+<a name="module_JS API_ Environment utilities..schemaFile"></a>
-### JS API: Environment utilities.schemaFile() ⇒
+### JS API: Environment utilities~schemaFile() ⇒
Get path to sqlite schema file.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: path to sqlite schema file
-<a name="module_JS API_ Environment utilities.sqliteFile"></a>
+<a name="module_JS API_ Environment utilities..sqliteFile"></a>
-### JS API: Environment utilities.sqliteFile(filename) ⇒
+### JS API: Environment utilities~sqliteFile(filename) ⇒
Get sqlite file path relative to app directory.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: sqlite file path
-| Param | Type |
-| --- | --- |
-| filename | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| filename | <code>\*</code> | <code>zap</code> |
-<a name="module_JS API_ Environment utilities.sqliteTestFile"></a>
+<a name="module_JS API_ Environment utilities..sqliteTestFile"></a>
-### JS API: Environment utilities.sqliteTestFile(id, deleteExistingFile) ⇒
+### JS API: Environment utilities~sqliteTestFile(id, deleteExistingFile) ⇒
Get sqlite test file name.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: sqlite test file name
-| Param | Type |
-| --- | --- |
-| id | <code>\*</code> |
-| deleteExistingFile | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| id | <code>\*</code> | |
+| deleteExistingFile | <code>\*</code> | <code>true</code> |
-<a name="module_JS API_ Environment utilities.zapVersionAsString"></a>
+<a name="module_JS API_ Environment utilities..zapVersionAsString"></a>
-### JS API: Environment utilities.zapVersionAsString()
+### JS API: Environment utilities~zapVersionAsString()
Returns a version as a single on-line string.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-<a name="module_JS API_ Environment utilities.locateProjectResource"></a>
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+<a name="module_JS API_ Environment utilities..locateProjectResource"></a>
-### JS API: Environment utilities.locateProjectResource(filePath) ⇒
+### JS API: Environment utilities~locateProjectResource(filePath) ⇒
This function locates a resource in the project, such as various
JSON files and zcl-builtin stuff.
It needs to adapt to a change in path that can occur when
things are copied into the dist/ directory.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: located project resource
| Param |
| --- |
| filePath |
-<a name="module_JS API_ Environment utilities.zapVersion"></a>
+<a name="module_JS API_ Environment utilities..zapVersion"></a>
-### JS API: Environment utilities.zapVersion() ⇒
+### JS API: Environment utilities~zapVersion() ⇒
Returns the zap version.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: zap version, which is an object that
contains 'version', 'featureLevel', 'hash', 'timestamp' and 'date'
-<a name="module_JS API_ Environment utilities.baseUrl"></a>
+<a name="module_JS API_ Environment utilities..baseUrl"></a>
-### JS API: Environment utilities.baseUrl() ⇒
+### JS API: Environment utilities~baseUrl() ⇒
Get zapBaseUrl.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: zapBaseUrl
-<a name="module_JS API_ Environment utilities.printToStderr"></a>
+<a name="module_JS API_ Environment utilities..printToStderr"></a>
-### JS API: Environment utilities.printToStderr(msg)
+### JS API: Environment utilities~printToStderr(msg)
Prints the data to stderr, without much fuss.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
| Param |
| --- |
| msg |
-<a name="module_JS API_ Environment utilities.log"></a>
+<a name="module_JS API_ Environment utilities..log"></a>
-### JS API: Environment utilities.log(level, msg, err)
+### JS API: Environment utilities~log(level, msg, err)
Base level common logger.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-| Param | Type |
-| --- | --- |
-| level | <code>\*</code> |
-| msg | <code>\*</code> |
-| err | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| level | <code>\*</code> | |
+| msg | <code>\*</code> | |
+| err | <code>\*</code> | <code></code> |
-<a name="module_JS API_ Environment utilities.logInfo"></a>
+<a name="module_JS API_ Environment utilities..logInfo"></a>
-### JS API: Environment utilities.logInfo(msg, err)
+### JS API: Environment utilities~logInfo(msg, err)
Info level message.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-| Param | Type |
-| --- | --- |
-| msg | <code>\*</code> |
-| err | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| msg | <code>\*</code> | |
+| err | <code>\*</code> | <code></code> |
-<a name="module_JS API_ Environment utilities.logError"></a>
+<a name="module_JS API_ Environment utilities..logError"></a>
-### JS API: Environment utilities.logError(msg, err)
+### JS API: Environment utilities~logError(msg, err)
Error level message.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-| Param | Type |
-| --- | --- |
-| msg | <code>\*</code> |
-| err | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| msg | <code>\*</code> | |
+| err | <code>\*</code> | <code></code> |
-<a name="module_JS API_ Environment utilities.logWarning"></a>
+<a name="module_JS API_ Environment utilities..logWarning"></a>
-### JS API: Environment utilities.logWarning(msg, err)
+### JS API: Environment utilities~logWarning(msg, err)
Warning level message.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-| Param | Type |
-| --- | --- |
-| msg | <code>\*</code> |
-| err | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| msg | <code>\*</code> | |
+| err | <code>\*</code> | <code></code> |
-<a name="module_JS API_ Environment utilities.logSql"></a>
+<a name="module_JS API_ Environment utilities..logSql"></a>
-### JS API: Environment utilities.logSql(msg, err)
+### JS API: Environment utilities~logSql(msg, err)
Sql level message.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
| Param | Type |
| --- | --- |
| msg | <code>\*</code> |
| err | <code>\*</code> |
-<a name="module_JS API_ Environment utilities.logBrowser"></a>
+<a name="module_JS API_ Environment utilities..logBrowser"></a>
-### JS API: Environment utilities.logBrowser(msg, err)
+### JS API: Environment utilities~logBrowser(msg, err)
Browser level message.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-| Param | Type |
-| --- | --- |
-| msg | <code>\*</code> |
-| err | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| msg | <code>\*</code> | |
+| err | <code>\*</code> | <code></code> |
-<a name="module_JS API_ Environment utilities.logIpc"></a>
+<a name="module_JS API_ Environment utilities..logIpc"></a>
-### JS API: Environment utilities.logIpc(msg, err)
+### JS API: Environment utilities~logIpc(msg, err)
IPC level message.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-| Param | Type |
-| --- | --- |
-| msg | <code>\*</code> |
-| err | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| msg | <code>\*</code> | |
+| err | <code>\*</code> | <code></code> |
-<a name="module_JS API_ Environment utilities.logDebug"></a>
+<a name="module_JS API_ Environment utilities..logDebug"></a>
-### JS API: Environment utilities.logDebug(msg, err)
+### JS API: Environment utilities~logDebug(msg, err)
Debug level message.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
-| Param | Type |
-| --- | --- |
-| msg | <code>\*</code> |
-| err | <code>\*</code> |
+| Param | Type | Default |
+| --- | --- | --- |
+| msg | <code>\*</code> | |
+| err | <code>\*</code> | <code></code> |
-<a name="module_JS API_ Environment utilities.logWarningToFile"></a>
+<a name="module_JS API_ Environment utilities..logWarningToFile"></a>
-### JS API: Environment utilities.logWarningToFile(msg)
+### JS API: Environment utilities~logWarningToFile(msg)
Log Warning level message to zap.log file.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
| Param | Type |
| --- | --- |
| msg | <code>\*</code> |
-<a name="module_JS API_ Environment utilities.isMatchingVersion"></a>
+<a name="module_JS API_ Environment utilities..isMatchingVersion"></a>
-### JS API: Environment utilities.isMatchingVersion(versionsArray, providedVersion) ⇒
+### JS API: Environment utilities~isMatchingVersion(versionsArray, providedVersion) ⇒
Returns true if major or minor component of versions is different.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: boolean
| Param | Type |
@@ -18335,22 +18350,35 @@
| versionsArray | <code>\*</code> |
| providedVersion | <code>\*</code> |
-<a name="module_JS API_ Environment utilities.versionsCheck"></a>
+<a name="module_JS API_ Environment utilities..versionsCheck"></a>
-### JS API: Environment utilities.versionsCheck() ⇒
+### JS API: Environment utilities~versionsCheck() ⇒
Returns true if versions of node and electron are matching.
If versions are not matching, it prints out a warhing
and returns false.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: true or false, depending on match
-<a name="module_JS API_ Environment utilities.httpStaticContent"></a>
+<a name="module_JS API_ Environment utilities..httpStaticContent"></a>
-### JS API: Environment utilities.httpStaticContent() ⇒
+### JS API: Environment utilities~httpStaticContent() ⇒
Returns path to HTTP static content while taking into account DEV / PROD modes.
-**Kind**: static method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
**Returns**: full path to HTTP static content
+<a name="module_JS API_ Environment utilities..formatEmojiMessage"></a>
+
+### JS API: Environment utilities~formatEmojiMessage(emoji, message) ⇒ <code>string</code>
+Format a message with emoji if enabled, without if disabled.
+
+**Kind**: inner method of [<code>JS API: Environment utilities</code>](#module_JS API_ Environment utilities)
+**Returns**: <code>string</code> - formatted message
+
+| Param | Type | Description |
+| --- | --- | --- |
+| emoji | <code>string</code> | the emoji character |
+| message | <code>string</code> | the text message |
+
<a name="module_External API_ External API utilities"></a>
## External API: External API utilities
@@ -28398,3 +28426,27 @@
| db | <code>\*</code> |
| packageIds | <code>\*</code> |
+<a name="setEmojiDisabled"></a>
+
+## setEmojiDisabled(value)
+Set emoji disabled state (for testing)
+
+**Kind**: global function
+
+| Param | Type |
+| --- | --- |
+| value | <code>boolean</code> |
+
+<a name="resetEmojiState"></a>
+
+## resetEmojiState()
+Reset emoji disabled state to environment/argv detection (for testing)
+
+**Kind**: global function
+<a name="isEmojiDisabled"></a>
+
+## isEmojiDisabled() ⇒ <code>boolean</code>
+Check if emojis should be disabled
+
+**Kind**: global function
+**Returns**: <code>boolean</code> - true if emojis should be disabled
diff --git a/src-electron/db/zap-schema.sql b/src-electron/db/zap-schema.sql
index 528b363..859e177 100644
--- a/src-electron/db/zap-schema.sql
+++ b/src-electron/db/zap-schema.sql
@@ -1094,7 +1094,7 @@
ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_ID
),
"WARNING",
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -1196,7 +1196,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -1295,7 +1295,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -1583,7 +1583,7 @@
ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_ATTRIBUTE_ID = new.ENDPOINT_TYPE_ATTRIBUTE_ID
),
"WARNING",
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -1699,7 +1699,7 @@
ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_ATTRIBUTE_ID = new.ENDPOINT_TYPE_ATTRIBUTE_ID
),
"WARNING",
- "⚠ Check Cluster Compliance on endpoint: "
+ "⚠️ Check Cluster Compliance on endpoint: "
||
(
SELECT
@@ -1843,7 +1843,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -1954,7 +1954,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Cluster Compliance on endpoint: "
+ "%Check Cluster Compliance on endpoint: "
||
(
SELECT
@@ -2094,7 +2094,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -2207,7 +2207,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Cluster Compliance on endpoint: "
+ "%Check Cluster Compliance on endpoint: "
||
(
SELECT
@@ -2355,7 +2355,7 @@
ENDPOINT_TYPE_COMMAND.ENDPOINT_TYPE_COMMAND_ID = new.ENDPOINT_TYPE_COMMAND_ID
),
"WARNING",
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -2482,7 +2482,7 @@
ENDPOINT_TYPE_COMMAND.ENDPOINT_TYPE_COMMAND_ID = new.ENDPOINT_TYPE_COMMAND_ID
),
"WARNING",
- "⚠ Check Cluster Compliance on endpoint: "
+ "⚠️ Check Cluster Compliance on endpoint: "
||
(
SELECT
@@ -2615,7 +2615,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -2732,7 +2732,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Cluster Compliance on endpoint: "
+ "%Check Cluster Compliance on endpoint: "
||
(
SELECT
@@ -2862,7 +2862,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Device Type Compliance on endpoint: "
+ "⚠️ Check Device Type Compliance on endpoint: "
||
(
SELECT
@@ -2981,7 +2981,7 @@
AND
NOTICE_MESSAGE LIKE
(
- "⚠ Check Cluster Compliance on endpoint: "
+ "%Check Cluster Compliance on endpoint: "
||
(
SELECT
diff --git a/src-electron/generator/generation-engine.js b/src-electron/generator/generation-engine.js
index f681358..7c04ec9 100644
--- a/src-electron/generator/generation-engine.js
+++ b/src-electron/generator/generation-engine.js
@@ -1030,30 +1030,39 @@
}
if (!fs.existsSync(outputDirectory)) {
- options.logger(`✅ Creating directory: ${outputDirectory}`)
+ options.logger(
+ env.formatEmojiMessage('✅', `Creating directory: ${outputDirectory}`)
+ )
fs.mkdirSync(outputDirectory, { recursive: true })
}
- options.logger('🤖 Generating files:')
+ options.logger(env.formatEmojiMessage('🤖', 'Generating files:'))
let promises = []
for (const f of Object.keys(genResult.content)) {
let content = genResult.content[f]
let fileName = path.join(outputDirectory, f)
- options.logger(` ✍ ${fileName}`)
+ options.logger(env.formatEmojiMessage('✍', fileName))
env.logDebug(`Preparing to write file: ${fileName}`)
promises.push(writeFileWithBackup(fileName, content, options.backup))
}
if (genResult.hasErrors) {
- options.logger('⚠️ Errors:')
+ options.logger(env.formatEmojiMessage('⚠️', 'Errors:'))
for (const f of Object.keys(genResult.errors)) {
let err = genResult.errors[f]
let fileName = path.join(outputDirectory, f)
- options.logger(` 👎 ${fileName}: ⛔ ${err}\nStack trace:\n`)
+ options.logger(
+ `${env.formatEmojiMessage('👎', `${fileName}:`)} ${env.formatEmojiMessage('⛔', err)}\nStack trace:\n`
+ )
options.logger(err)
}
}
let nsDuration = process.hrtime.bigint() - hrstart
- options.logger(`🕐 Generation time: ${util.duration(nsDuration)} `)
+ options.logger(
+ env.formatEmojiMessage(
+ '🕐',
+ `Generation time: ${util.duration(nsDuration)} `
+ )
+ )
timing.generation = {
nsDuration: Number(nsDuration),
readableDuration: util.duration(nsDuration)
@@ -1062,7 +1071,7 @@
generateGenerationContent(genResult, timing).then((generatedContent) => {
if (options.genResultFile) {
let resultPath = path.join(outputDirectory, 'genResult.json')
- options.logger(` ✍ Result: ${resultPath}`)
+ options.logger(env.formatEmojiMessage('✍', `Result: ${resultPath}`))
return writeFileWithBackup(resultPath, generatedContent, options.backup)
} else {
return
@@ -1193,7 +1202,7 @@
}
}
if (postProcessPromises.length > 0)
- logger('🤖 Executing post-processing actions:')
+ logger(env.formatEmojiMessage('🤖', 'Executing post-processing actions:'))
return Promise.all(postProcessPromises).then(() => genResult)
}
diff --git a/src-electron/importexport/import-json.js b/src-electron/importexport/import-json.js
index 0c265ee..c190765 100644
--- a/src-electron/importexport/import-json.js
+++ b/src-electron/importexport/import-json.js
@@ -864,14 +864,16 @@
(ma) => !endpointTypeAttributeIds.includes(ma.id)
)
for (let i = 0; i < mandatoryAttributesNotEnabled.length; i++) {
- let clusterSpecComplianceMessageForAttributes =
- '⚠ Check Cluster Compliance on endpoint: ' +
- endpointId +
- ', cluster: ' +
- mandatoryAttributesNotEnabled[i].clusterName +
- ', mandatory attribute: ' +
- mandatoryAttributesNotEnabled[i].name +
- ' needs to be enabled'
+ let clusterSpecComplianceMessageForAttributes = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Cluster Compliance on endpoint: ' +
+ endpointId +
+ ', cluster: ' +
+ mandatoryAttributesNotEnabled[i].clusterName +
+ ', mandatory attribute: ' +
+ mandatoryAttributesNotEnabled[i].name +
+ ' needs to be enabled'
+ )
clusterSpecCheckComplianceMessage =
clusterSpecCheckComplianceMessage.concat(
@@ -928,16 +930,18 @@
}
}
if (isIncoming && !isCommandEnabled) {
- let clusterSpecComplianceMessageForCommands =
- '⚠ Check Cluster Compliance on endpoint: ' +
- endpointId +
- ', cluster: ' +
- allMandatoryCommands[i].clusterName +
- ' ' +
- allMandatoryCommands[i].clusterSide +
- ', mandatory command: ' +
- allMandatoryCommands[i].name +
- ' incoming needs to be enabled'
+ let clusterSpecComplianceMessageForCommands = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Cluster Compliance on endpoint: ' +
+ endpointId +
+ ', cluster: ' +
+ allMandatoryCommands[i].clusterName +
+ ' ' +
+ allMandatoryCommands[i].clusterSide +
+ ', mandatory command: ' +
+ allMandatoryCommands[i].name +
+ ' incoming needs to be enabled'
+ )
clusterSpecCheckComplianceMessage =
clusterSpecCheckComplianceMessage.concat(
@@ -955,16 +959,18 @@
)
}
if (!isIncoming && !isCommandEnabled) {
- let clusterSpecComplianceMessageForCommands =
- '⚠ Check Cluster Compliance on endpoint: ' +
- endpointId +
- ', cluster: ' +
- allMandatoryCommands[i].clusterName +
- ' ' +
- allMandatoryCommands[i].clusterSide +
- ', mandatory command: ' +
- allMandatoryCommands[i].name +
- ' outgoing needs to be enabled'
+ let clusterSpecComplianceMessageForCommands = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Cluster Compliance on endpoint: ' +
+ endpointId +
+ ', cluster: ' +
+ allMandatoryCommands[i].clusterName +
+ ' ' +
+ allMandatoryCommands[i].clusterSide +
+ ', mandatory command: ' +
+ allMandatoryCommands[i].name +
+ ' outgoing needs to be enabled'
+ )
clusterSpecCheckComplianceMessage =
clusterSpecCheckComplianceMessage.concat(
@@ -1092,14 +1098,16 @@
!isDeviceTypeClientClusterFound &&
deviceTypeClustersOnEndpointType[dtc].lockClient
) {
- clusterSpecComplianceMessage =
- '⚠ Check Device Type Compliance on endpoint: ' +
- endpointId +
- ', device type: ' +
- deviceType.name +
- ', cluster: ' +
- deviceTypeClustersOnEndpointType[dtc].clusterName +
- ' client needs to be enabled'
+ clusterSpecComplianceMessage = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Device Type Compliance on endpoint: ' +
+ endpointId +
+ ', device type: ' +
+ deviceType.name +
+ ', cluster: ' +
+ deviceTypeClustersOnEndpointType[dtc].clusterName +
+ ' client needs to be enabled'
+ )
deviceTypeSpecCheckComplianceMessage =
deviceTypeSpecCheckComplianceMessage.concat(
specMessageIndent,
@@ -1119,14 +1127,16 @@
!isDeviceTypeServerClusterFound &&
deviceTypeClustersOnEndpointType[dtc].lockServer
) {
- clusterSpecComplianceMessage =
- '⚠ Check Device Type Compliance on endpoint: ' +
- endpointId +
- ', device type: ' +
- deviceType.name +
- ', cluster: ' +
- deviceTypeClustersOnEndpointType[dtc].clusterName +
- ' server needs to be enabled'
+ clusterSpecComplianceMessage = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Device Type Compliance on endpoint: ' +
+ endpointId +
+ ', device type: ' +
+ deviceType.name +
+ ', cluster: ' +
+ deviceTypeClustersOnEndpointType[dtc].clusterName +
+ ' server needs to be enabled'
+ )
deviceTypeSpecCheckComplianceMessage =
deviceTypeSpecCheckComplianceMessage.concat(
specMessageIndent,
@@ -1215,16 +1225,18 @@
}
// Leaving out global attributes
- let attributeSpecComplianceMessage =
- '⚠ Check Device Type Compliance on endpoint: ' +
- endpointId +
- ', device type: ' +
- deviceType.name +
- ', cluster: ' +
- cluster.name +
- ', attribute: ' +
- deviceTypeAttributesOnEndpointType[dta].name +
- ' needs to be enabled'
+ let attributeSpecComplianceMessage = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Device Type Compliance on endpoint: ' +
+ endpointId +
+ ', device type: ' +
+ deviceType.name +
+ ', cluster: ' +
+ cluster.name +
+ ', attribute: ' +
+ deviceTypeAttributesOnEndpointType[dta].name +
+ ' needs to be enabled'
+ )
deviceTypeSpecCheckComplianceMessage =
deviceTypeSpecCheckComplianceMessage.concat(
specMessageIndent,
@@ -1297,16 +1309,18 @@
commandSource == 'client' &&
!isCommandOutgoingFound
) {
- commandSpecComplianceMessage =
- '⚠ Check Device Type Compliance on endpoint: ' +
- endpointId +
- ', device type: ' +
- deviceType.name +
- ', cluster: ' +
- cluster.name +
- ' client, command: ' +
- deviceTypeCommandsOnEndpointType[dtc].name +
- ' outgoing needs to be enabled'
+ commandSpecComplianceMessage = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Device Type Compliance on endpoint: ' +
+ endpointId +
+ ', device type: ' +
+ deviceType.name +
+ ', cluster: ' +
+ cluster.name +
+ ' client, command: ' +
+ deviceTypeCommandsOnEndpointType[dtc].name +
+ ' outgoing needs to be enabled'
+ )
deviceTypeSpecCheckComplianceMessage =
deviceTypeSpecCheckComplianceMessage.concat(
specMessageIndent,
@@ -1327,16 +1341,18 @@
commandSource == 'server' &&
!isCommandIncomingFound
) {
- commandSpecComplianceMessage =
- '⚠ Check Device Type Compliance on endpoint: ' +
- endpointId +
- ', device type: ' +
- deviceType.name +
- ', cluster: ' +
- cluster.name +
- ' client, command: ' +
- deviceTypeCommandsOnEndpointType[dtc].name +
- ' incoming needs to be enabled'
+ commandSpecComplianceMessage = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Device Type Compliance on endpoint: ' +
+ endpointId +
+ ', device type: ' +
+ deviceType.name +
+ ', cluster: ' +
+ cluster.name +
+ ' client, command: ' +
+ deviceTypeCommandsOnEndpointType[dtc].name +
+ ' incoming needs to be enabled'
+ )
deviceTypeSpecCheckComplianceMessage =
deviceTypeSpecCheckComplianceMessage.concat(
specMessageIndent,
@@ -1357,16 +1373,18 @@
commandSource == 'client' &&
!isCommandIncomingFound
) {
- commandSpecComplianceMessage =
- '⚠ Check Device Type Compliance on endpoint: ' +
- endpointId +
- ', device type: ' +
- deviceType.name +
- ', cluster: ' +
- cluster.name +
- ' server, command: ' +
- deviceTypeCommandsOnEndpointType[dtc].name +
- ' incoming needs to be enabled'
+ commandSpecComplianceMessage = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Device Type Compliance on endpoint: ' +
+ endpointId +
+ ', device type: ' +
+ deviceType.name +
+ ', cluster: ' +
+ cluster.name +
+ ' server, command: ' +
+ deviceTypeCommandsOnEndpointType[dtc].name +
+ ' incoming needs to be enabled'
+ )
deviceTypeSpecCheckComplianceMessage =
deviceTypeSpecCheckComplianceMessage.concat(
specMessageIndent,
@@ -1387,16 +1405,18 @@
commandSource == 'server' &&
!isCommandOutgoingFound
) {
- commandSpecComplianceMessage =
- '⚠ Check Device Type Compliance on endpoint: ' +
- endpointId +
- ', device type: ' +
- deviceType.name +
- ', cluster: ' +
- cluster.name +
- ' server, command: ' +
- deviceTypeCommandsOnEndpointType[dtc].name +
- ' outgoing needs to be enabled'
+ commandSpecComplianceMessage = env.formatEmojiMessage(
+ '⚠️',
+ 'Check Device Type Compliance on endpoint: ' +
+ endpointId +
+ ', device type: ' +
+ deviceType.name +
+ ', cluster: ' +
+ cluster.name +
+ ' server, command: ' +
+ deviceTypeCommandsOnEndpointType[dtc].name +
+ ' outgoing needs to be enabled'
+ )
deviceTypeSpecCheckComplianceMessage =
deviceTypeSpecCheckComplianceMessage.concat(
specMessageIndent,
diff --git a/src-electron/main-process/startup.js b/src-electron/main-process/startup.js
index eebddf5..6c4ddf6 100644
--- a/src-electron/main-process/startup.js
+++ b/src-electron/main-process/startup.js
@@ -31,6 +31,7 @@
const dbCache = require('../db/db-cache.js')
const dbEnum = require('../../src-shared/db-enum.js')
const env = require('../util/env')
+const emojiUtil = require('../util/emoji-util')
const zclLoader = require('../zcl/zcl-loader.js')
const httpServer = require('../server/http-server.js')
const ipcServer = require('../server/ipc-server')
@@ -185,10 +186,10 @@
*/
async function noopConvert(resultsFile, logger) {
if (resultsFile != null) {
- logger(`😎 No-op conversion: ${resultsFile}`)
+ logger(env.formatEmojiMessage('😎', `No-op conversion: ${resultsFile}`))
return writeConversionResultsFile(resultsFile)
} else {
- logger(`😎 No-op, no result, conversion.`)
+ logger(env.formatEmojiMessage('😎', 'No-op, no result, conversion.'))
}
}
@@ -234,18 +235,27 @@
let upgrade_results = argv.results
for (let i = 0; i < zapFiles.length; i++) {
let zapFile = zapFiles[i]
- options.logger(`🤖 Update started for file: ${zapFile}`)
+ options.logger(
+ env.formatEmojiMessage('🤖', `Update started for file: ${zapFile}`)
+ )
let dbFile = env.sqliteFile('upgrade')
let db = await dbApi.initDatabaseAndLoadSchema(
dbFile,
env.schemaFile(),
env.zapVersion()
)
- options.logger(' 🐝 database and schema initialized')
+ options.logger(
+ env.formatEmojiMessage('🐝', 'database and schema initialized')
+ )
await zclLoader.loadZclMetafiles(db, argv.zclProperties, {
failOnLoadingError: !argv.noLoadingFailure
})
- options.logger(` 🐝 New zcl package loaded: ${argv.zclProperties}`)
+ options.logger(
+ env.formatEmojiMessage(
+ '🔧',
+ `New zcl package loaded: ${argv.zclProperties}`
+ )
+ )
if (argv.generationTemplate != null) {
let ctx = await generatorEngine.loadTemplates(
db,
@@ -257,7 +267,12 @@
if (ctx.error) {
throw ctx.error
}
- options.logger(` 🐝 New templates loaded: ${argv.generationTemplate}`)
+ options.logger(
+ env.formatEmojiMessage(
+ '🔧',
+ `New templates loaded: ${argv.generationTemplate}`
+ )
+ )
}
let state = await importJs.readDataFromFile(zapFile)
let upgradeZclPackages = await util.getUpgradePackageMatch(
@@ -291,7 +306,7 @@
upgradeZclPackages: upgradeZclPackages,
upgradeTemplatePackages: upgradeTemplatePackages
})
- options.logger(` 👈 read in: ${zapFile}`)
+ options.logger(env.formatEmojiMessage('👈', `read in: ${zapFile}`))
let of = outputFile(zapFile, zapFile)
let parent = path.dirname(of)
if (!fs.existsSync(parent)) {
@@ -309,7 +324,7 @@
createBackup: true,
fileFormat: argv.saveFileFormat
})
- options.logger(` 👉 write out: ${outputPath}`)
+ options.logger(env.formatEmojiMessage('👉', `write out: ${outputPath}`))
try {
if (upgrade_results != null) {
if (!fs.existsSync(path.dirname(upgrade_results))) {
@@ -320,11 +335,15 @@
importResult.upgradeMessages
)
}
- options.logger(` 👉 write out: ${upgrade_results}`)
+ options.logger(
+ env.formatEmojiMessage('🔧', `write out: ${upgrade_results}`)
+ )
} catch (error) {
- options.logger(` ⚠️ failed to write out: ${upgrade_results}`)
+ options.logger(
+ env.formatEmojiMessage('⚠️', `failed to write out: ${upgrade_results}`)
+ )
}
- options.logger('😎 Upgrade done!')
+ options.logger(env.formatEmojiMessage('🎉', 'Upgrade done!'))
}
if (options.quitFunction != null) {
@@ -348,15 +367,17 @@
let zapFiles = argv.zapFiles
let files = gatherFiles(zapFiles, { suffix: '.zap', doBlank: true })
if (files.length == 0) {
- options.logger(` 👎 no zap files found in: ${zapFiles}`)
- throw `👎 no zap files found in: ${zapFiles}`
+ options.logger(
+ env.formatEmojiMessage('⚠️', 'no zap files found in: ' + zapFiles)
+ )
+ throw env.formatEmojiMessage('⛔', 'no zap files found in: ' + zapFiles)
}
if (argv.output == null) throw 'You need to specify output file.'
let output = argv.output
let conversion_results = argv.results
- options.logger(`🤖 Conversion started
- 🔍 input files: ${files}
- 🔍 output pattern: ${output}`)
+ options.logger(`${env.formatEmojiMessage('🔧', 'Conversion started')}
+ ${env.formatEmojiMessage('🔍', `input files: ${files}`)}
+ ${env.formatEmojiMessage('🔍', `output pattern: ${output}`)}`)
let dbFile = env.sqliteFile('convert')
let db = await dbApi.initDatabaseAndLoadSchema(
@@ -364,11 +385,15 @@
env.schemaFile(),
env.zapVersion()
)
- options.logger(' 🐝 database and schema initialized')
+ options.logger(
+ env.formatEmojiMessage('🐝', 'database and schema initialized')
+ )
await zclLoader.loadZclMetafiles(db, argv.zclProperties, {
failOnLoadingError: !argv.noLoadingFailure
})
- options.logger(` 🐝 zcl package loaded: ${argv.zclProperties}`)
+ options.logger(
+ env.formatEmojiMessage('🔧', `zcl package loaded: ${argv.zclProperties}`)
+ )
if (argv.generationTemplate != null) {
let ctx = await generatorEngine.loadTemplates(db, argv.generationTemplate, {
failOnLoadingError: !argv.noLoadingFailure
@@ -376,7 +401,12 @@
if (ctx.error) {
throw ctx.error
}
- options.logger(` 🐝 templates loaded: ${argv.generationTemplate}`)
+ options.logger(
+ env.formatEmojiMessage(
+ '🔧',
+ `templates loaded: ${argv.generationTemplate}`
+ )
+ )
}
await util.executePromisesSequentially(files, async (singlePath, index) => {
@@ -401,7 +431,7 @@
)
}
- options.logger(` 👈 read in: ${singlePath}`)
+ options.logger(env.formatEmojiMessage('👈', `read in: ${singlePath}`))
let of = outputFile(singlePath, output, index)
let parent = path.dirname(of)
if (!fs.existsSync(parent)) {
@@ -420,18 +450,22 @@
fileFormat: argv.saveFileFormat
})
- options.logger(` 👉 write out: ${outputPath}`)
+ options.logger(env.formatEmojiMessage('👉', `write out: ${outputPath}`))
})
try {
if (conversion_results != null)
await writeConversionResultsFile(conversion_results)
- options.logger(` 👉 write out: ${conversion_results}`)
+ options.logger(
+ env.formatEmojiMessage('🔧', `write out: ${conversion_results}`)
+ )
} catch (error) {
- options.logger(` ⚠️ failed to write out: ${conversion_results}`)
+ options.logger(
+ env.formatEmojiMessage('⚠️', `failed to write out: ${conversion_results}`)
+ )
}
- options.logger('😎 Conversion done!')
+ options.logger(env.formatEmojiMessage('🔧', 'Conversion done!'))
if (options.quitFunction != null) {
options.quitFunction()
}
@@ -470,10 +504,15 @@
* @param {*} options
*/
async function startRegenerateSdk(argv, options) {
- options.logger('🤖 Regenerating whole SDK.')
+ options.logger(env.formatEmojiMessage('🔧', 'Regenerating whole SDK.'))
let sdkPath = argv.sdk
if (!sdkPath) {
- options.logger(`⛔ regenerateSdk requires the --sdk <sdkFile> argument`)
+ options.logger(
+ env.formatEmojiMessage(
+ '⛔',
+ 'regenerateSdk requires the --sdk <sdkFile> argument'
+ )
+ )
} else {
let dbFile = env.sqliteFile('regenerateSdk')
let db = await dbApi.initDatabaseAndLoadSchema(
@@ -484,29 +523,29 @@
let sdk = await sdkUtil.readSdkJson(sdkPath, options)
- options.logger('🐝 Loading ZCL information')
+ options.logger(env.formatEmojiMessage('🔧', 'Loading ZCL information'))
sdk.zclPackageId = {}
for (let key of Object.keys(sdk.rt.zclMetafiles)) {
let p = sdk.rt.zclMetafiles[key]
- options.logger(` 👈 ${p}`)
+ options.logger(env.formatEmojiMessage('🔧', `${p}`))
let loadData = await zclLoader.loadZcl(db, p)
sdk.zclPackageId[key] = loadData.packageId
}
- options.logger('🐝 Loading generation templates')
+ options.logger(env.formatEmojiMessage('🔧', 'Loading generation templates'))
sdk.templatePackageId = {}
for (let key of Object.keys(sdk.rt.genTemplates)) {
let p = sdk.rt.genTemplates[key]
- options.logger(` 👈 ${p}`)
+ options.logger(env.formatEmojiMessage('🔧', `${p}`))
let loadData = await generatorEngine.loadTemplates(db, p, {
failOnLoadingError: !argv.noLoadingFailure
})
sdk.templatePackageId[key] = loadData.packageId
}
- options.logger('🐝 Performing generation')
+ options.logger(env.formatEmojiMessage('🔧', 'Performing generation'))
for (let gen of sdk.rt.generateCommands) {
let inputFile = gen.inputFile
let outputDirectory = gen.outputDirectory
- options.logger(` 👈 loading: ${inputFile} `)
+ options.logger(env.formatEmojiMessage('🔧', `loading: ${inputFile}`))
let loaderResult = await importJs.importDataFromFile(db, inputFile)
let sessionId = loaderResult.sessionId
let templateKeys = []
@@ -518,7 +557,12 @@
}
}
for (let tK of templateKeys) {
- options.logger(` 👉 generating: ${tK} => ${outputDirectory}`)
+ options.logger(
+ env.formatEmojiMessage(
+ '🔧',
+ `generating: ${tK} => ${outputDirectory}`
+ )
+ )
await generatorEngine.generateAndWriteFiles(
db,
sessionId,
@@ -537,7 +581,7 @@
)
}
}
- options.logger('😎 Regeneration done!')
+ options.logger(env.formatEmojiMessage('🔧', 'Regeneration done!'))
}
if (options.quitFunction != null) options.quitFunction()
}
@@ -551,9 +595,9 @@
async function startAnalyze(argv, options) {
let paths = argv.zapFiles
let dbFile = env.sqliteFile('analysis')
- options.logger(`🤖 Starting analysis: ${paths}`)
+ options.logger(env.formatEmojiMessage('🤖', `Starting analysis: ${paths}`))
if (options.cleanDb && fs.existsSync(dbFile)) {
- options.logger(' 👉 remove old database file')
+ options.logger(env.formatEmojiMessage('🔧', 'remove old database file'))
fs.unlinkSync(dbFile)
}
let db = await dbApi.initDatabaseAndLoadSchema(
@@ -561,7 +605,9 @@
env.schemaFile(),
env.zapVersion()
)
- options.logger(' 👉 database and schema initialized')
+ options.logger(
+ env.formatEmojiMessage('🐝', 'database and schema initialized')
+ )
await zclLoader.loadZclMetafiles(db, argv.zclProperties, {
failOnLoadingError: !argv.noLoadingFailure
})
@@ -574,11 +620,11 @@
})
.then((importResult) => util.sessionReport(db, importResult.sessionId))
.then((report) => {
- options.logger(`🤖 File: ${singlePath}\n`)
+ options.logger(env.formatEmojiMessage('🤖', ` File: ${singlePath}\n`))
options.logger(report)
})
)
- options.logger('😎 Analysis done!')
+ options.logger(env.formatEmojiMessage('🔧', '🔧 Analysis done!'))
if (options.quitFunction != null) options.quitFunction()
}
@@ -637,10 +683,10 @@
}
) {
env.logInitStdout()
- options.logger('🤖 Starting self-check')
+ options.logger(env.formatEmojiMessage('🔧', '🔧 Starting self-check'))
let dbFile = env.sqliteFile('self-check')
if (options.cleanDb && fs.existsSync(dbFile)) {
- options.logger(' 👉 remove old database file')
+ options.logger(env.formatEmojiMessage('🔧', '🔧 remove old database file'))
fs.unlinkSync(dbFile)
}
let mainDb = await dbApi.initDatabaseAndLoadSchema(
@@ -648,7 +694,9 @@
env.schemaFile(),
env.zapVersion()
)
- options.logger(' 👉 database and schema initialized')
+ options.logger(
+ env.formatEmojiMessage('🐝', '🐝 database and schema initialized')
+ )
let zclPackageIds = await zclLoader.loadZclMetafiles(
mainDb,
argv.zclProperties,
@@ -656,7 +704,12 @@
failOnLoadingError: !argv.noLoadingFailure
}
)
- options.logger(` 👉 zcl metadata packages loaded: ${zclPackageIds.length}`)
+ options.logger(
+ env.formatEmojiMessage(
+ '🔧',
+ `zcl metadata packages loaded: ${zclPackageIds.length}`
+ )
+ )
let ctx = await generatorEngine.loadTemplates(
mainDb,
argv.generationTemplate,
@@ -665,20 +718,25 @@
}
)
if (ctx.nop) {
- options.logger(` 👉 no generation template packages loaded`)
+ options.logger(
+ env.formatEmojiMessage('🔧', `no generation template packages loaded`)
+ )
} else if (ctx.error) {
- options.logger(` ⚠️ ${ctx.error}`)
+ options.logger(env.formatEmojiMessage('⚠️', ` ${ctx.error}`))
} else {
options.logger(
- ` 👉 generation template packages loaded: ${ctx.packageIds.length}`
+ env.formatEmojiMessage(
+ '👉',
+ `generation template packages loaded: ${ctx.packageIds.length}`
+ )
)
}
// This is a hack to prevent too quick shutdown that causes core dumps.
dbApi.closeDatabaseSync(mainDb)
- options.logger(' 👉 database closed')
+ options.logger(env.formatEmojiMessage('🔧', 'database closed'))
await util.waitFor(2000)
- options.logger('😎 Self-check done!')
+ options.logger(env.formatEmojiMessage('🔧', 'Self-check done!'))
if (options.quitFunction != null) {
options.quitFunction()
}
@@ -791,7 +849,7 @@
}
}
if (zapFile === BLANK_SESSION) {
- options.logger(`👉 using empty configuration`)
+ options.logger(env.formatEmojiMessage('🔧', `🔧 using empty configuration`))
sessionId = await querySession.createBlankSession(db)
await util.ensurePackagesAndPopulateSessionOptions(
db,
@@ -805,7 +863,9 @@
)
output = outputPattern
} else {
- options.logger(`👉 using input file: ${zapFile}`)
+ options.logger(
+ env.formatEmojiMessage('🔧', `🔧 using input file: ${zapFile}`)
+ )
let importResult = await importJs.importDataFromFile(db, zapFile, {
defaultZclMetafile: options.zcl,
postImportScript: options.postImportScript,
@@ -818,7 +878,9 @@
sessionId = importResult.sessionId
output = outputFile(zapFile, outputPattern, index)
}
- options.logger(`👉 using output destination: ${output}`)
+ options.logger(
+ env.formatEmojiMessage('🔧', `using output destination: ${output}`)
+ )
let sessPkg = await util.ensurePackagesAndPopulateSessionOptions(
db,
@@ -833,7 +895,12 @@
}
let nsDuration = process.hrtime.bigint() - hrstart
- options.logger(`🕐 File loading time: ${util.duration(nsDuration)}`)
+ options.logger(
+ env.formatEmojiMessage(
+ '🔧',
+ `File loading time: ${util.duration(nsDuration)}`
+ )
+ )
options.fileLoadTime = nsDuration
@@ -904,13 +971,13 @@
let hrstart = process.hrtime.bigint()
options.logger(
- `🤖 ZAP generation started:
- 🔍 input files: ${zapFiles}
- 🔍 input Extension files: ${zapFileExtensions}
- 🔍 output pattern: ${output}
- 🔍 using templates: ${templateMetafile}
- 🔍 using zcl data: ${zclProperties}
- 🔍 zap version: ${env.zapVersionAsString()}`
+ `${env.formatEmojiMessage('🤖', 'ZAP generation started:')}
+ ${env.formatEmojiMessage('🔍', `input files: ${zapFiles}`)}
+ ${env.formatEmojiMessage('🔍', `input Extension files: ${zapFileExtensions}`)}
+ ${env.formatEmojiMessage('🔍', `output pattern: ${output}`)}
+ ${env.formatEmojiMessage('🔍', `using templates: ${templateMetafile}`)}
+ ${env.formatEmojiMessage('🔍', `using zcl data: ${zclProperties}`)}
+ ${env.formatEmojiMessage('🔍', `zap version: ${env.zapVersionAsString()}`)}`
)
let dbFile = env.sqliteFile('generate')
@@ -939,8 +1006,10 @@
doBlank: false
})
if (files.length == 0) {
- options.logger(` 👎 no zap files found in: ${zapFiles}`)
- throw `👎 no zap files found in: ${zapFiles}`
+ options.logger(
+ env.formatEmojiMessage('🔧', `🔧 no zap files found in: ${zapFiles}`)
+ )
+ throw env.formatEmojiMessage('👎', `no zap files found in: ${zapFiles}`)
}
options.zcl = zclProperties
@@ -962,7 +1031,9 @@
}
let nsDuration = process.hrtime.bigint() - hrstart
- options.logger(`🕐 Setup time: ${util.duration(nsDuration)} `)
+ options.logger(
+ env.formatEmojiMessage('🔧', 'Setup time: ' + util.duration(nsDuration))
+ )
await util.executePromisesSequentially(files, (f, index) =>
generateSingleFile(
@@ -1051,7 +1122,12 @@
} else if (argv._.includes('stop')) {
ipcClient.emit(ipcServer.eventType.stop)
} else if (argv._.includes('regenerateSdk')) {
- console.log('⛔ SDK regeneration from client process is not yet supported.')
+ console.log(
+ env.formatEmojiMessage(
+ '⛔',
+ 'SDK regeneration from client process is not yet supported.'
+ )
+ )
process.exit(0)
} else if (argv._.includes('generate') && argv.zapFiles != null) {
let data = {
@@ -1099,7 +1175,7 @@
}
if (argv.disableDbCaching) {
- console.log('⛔ Dabatase caching is disabled.')
+ console.log(env.formatEmojiMessage('⛔', 'Dabatase caching is disabled.'))
dbCache.disable()
}
@@ -1109,7 +1185,7 @@
}
if (argv._.includes('status')) {
- console.log('⛔ Server is not running.')
+ console.log(env.formatEmojiMessage('⛔', 'Server is not running.'))
logRemoteData({ zapServerStatus: 'missing' })
cleanExit(argv.cleanupDelay, 0)
} else if (argv._.includes('selfCheck')) {
diff --git a/src-electron/util/args.js b/src-electron/util/args.js
index b55d6cf..2df31cd 100644
--- a/src-electron/util/args.js
+++ b/src-electron/util/args.js
@@ -236,6 +236,11 @@
type: 'boolean',
deafult: false
})
+ .option('noEmoji', {
+ desc: 'Disable emoji characters in console output.',
+ type: 'boolean',
+ default: false
+ })
.usage('Usage: $0 <command> [options] ... [file.zap] ...')
.version(
`Version: ${zapVersion.version}\nFeature level: ${
@@ -259,7 +264,10 @@
// Apply Jenkins logic.
if (ret.jenkins) {
console.log(
- '🔧 Detected Jenkins environment. Making necessary adjustments.'
+ env.formatEmojiMessage(
+ '🔧',
+ 'Detected Jenkins environment. Making necessary adjustments.'
+ )
)
if (process.env[env.environmentVariable.skipPostGen.name] == null) {
ret.skipPostGen = true
@@ -271,6 +279,11 @@
env.setSaveFileFormat(ret.saveFileFormat)
+ // Set emoji preference via environment variable
+ if (ret.noEmoji) {
+ process.env.NO_EMOJI = '1'
+ }
+
// Collect files that are passed as loose arguments
let allFiles = ret._.filter((arg, index) => {
if (index == 0) return false
@@ -294,11 +307,17 @@
if (ret.tempState) {
let tempDir = fs.mkdtempSync(`${os.tmpdir()}${path.sep}zap.`)
console.log(
- `🔧 Using temporary state directory: ${env.setAppDirectory(tempDir)}`
+ env.formatEmojiMessage(
+ '🔧',
+ `Using temporary state directory: ${env.setAppDirectory(tempDir)}`
+ )
)
} else {
console.log(
- `🔧 Using state directory: ${env.setAppDirectory(ret.stateDirectory)}`
+ env.formatEmojiMessage(
+ '🔧',
+ `Using state directory: ${env.setAppDirectory(ret.stateDirectory)}`
+ )
)
}
diff --git a/src-electron/util/emoji-util.js b/src-electron/util/emoji-util.js
new file mode 100644
index 0000000..3291ef1
--- /dev/null
+++ b/src-electron/util/emoji-util.js
@@ -0,0 +1,46 @@
+/**
+ * Simple emoji utility that works without module system changes
+ * Uses environment variable to control emoji output
+ */
+
+// State for emoji control - can be overridden for testing
+let emojiDisabled = null
+
+/**
+ * Set emoji disabled state (for testing)
+ * @param {boolean} value
+ */
+function setEmojiDisabled(value) {
+ emojiDisabled = value
+}
+
+/**
+ * Reset emoji disabled state to environment/argv detection (for testing)
+ */
+function resetEmojiState() {
+ emojiDisabled = null
+}
+
+/**
+ * Check if emojis should be disabled
+ * @returns {boolean} true if emojis should be disabled
+ */
+function isEmojiDisabled() {
+ // If explicitly set (for testing), use that value
+ if (emojiDisabled !== null) {
+ return emojiDisabled
+ }
+
+ // Otherwise check environment and command line
+ return (
+ process.env.NO_EMOJI === '1' ||
+ process.argv.includes('--no-emoji') ||
+ process.argv.includes('--noEmoji')
+ )
+}
+
+module.exports = {
+ isEmojiDisabled,
+ setEmojiDisabled,
+ resetEmojiState
+}
diff --git a/src-electron/util/env.js b/src-electron/util/env.js
index bfca742..7a87bcd 100644
--- a/src-electron/util/env.js
+++ b/src-electron/util/env.js
@@ -25,6 +25,7 @@
const os = require('os')
const fs = require('fs')
const pino = require('pino')
+const emojiUtil = require('./emoji-util')
const zapBaseUrl = 'http://localhost:'
let saveFileFormat = 2 // This is the enabled only .zap file format
@@ -33,7 +34,7 @@
* Set save file format.
* @param {*} n
*/
-export function setSaveFileFormat(n) {
+function setSaveFileFormat(n) {
saveFileFormat = n
}
@@ -42,7 +43,7 @@
*
* @returns saveFileFormat
*/
-export function defaultFileFormat() {
+function defaultFileFormat() {
return saveFileFormat
}
@@ -50,7 +51,7 @@
*
* @returns path to zcl.json file
*/
-export function builtinSilabsZclMetafile() {
+function builtinSilabsZclMetafile() {
return locateProjectResource('./zcl-builtin/silabs/zcl.json')
}
@@ -58,7 +59,7 @@
*
* @returns path to gen-templates.json file
*/
-export function builtinSilabsTemplatesMetaFile() {
+function builtinSilabsTemplatesMetaFile() {
return locateProjectResource('./test/gen-template/zigbee/gen-templates.json')
}
@@ -67,7 +68,7 @@
*
* @returns path to zcl-special.json file used by zcl-loader.test.js
*/
-export function builtinSilabsZclSpecialMetafile() {
+function builtinSilabsZclSpecialMetafile() {
return locateProjectResource('./zcl-builtin/silabs/zcl-special.json')
}
@@ -76,7 +77,7 @@
*
* @returns path to general.xml file
*/
-export function builtinSilabsZclGeneralXmlFile() {
+function builtinSilabsZclGeneralXmlFile() {
return locateProjectResource('./zcl-builtin/silabs/general.xml')
}
@@ -85,7 +86,7 @@
*
* @returns path to general-special.xml file used by zcl-loader.test.js
*/
-export function builtinSilabsSpecialZclGeneralSpecialXmlFile() {
+function builtinSilabsSpecialZclGeneralSpecialXmlFile() {
return locateProjectResource('./zcl-builtin/silabs/general-special.xml')
}
@@ -93,7 +94,7 @@
* Get builtin matter ZCL json file
* @returns matter ZCL json file
*/
-export function builtinMatterZclMetafile() {
+function builtinMatterZclMetafile() {
return locateProjectResource('./zcl-builtin/matter/zcl.json')
}
@@ -101,7 +102,7 @@
* Get builtin matter ZCL json file
* @returns matter ZCL json file
*/
-export function builtinNewMatterZclMetafile() {
+function builtinNewMatterZclMetafile() {
return locateProjectResource('./zcl-builtin/matter/zcl-new-data-model.json')
}
@@ -109,7 +110,7 @@
*
* @returns path to templates.json file
*/
-export function builtinMatterTemplatesMetaFile() {
+function builtinMatterTemplatesMetaFile() {
return locateProjectResource('./test/gen-template/matter2/templates.json')
}
@@ -117,7 +118,7 @@
* Get builtin dotdot ZCL json file
* @returns dotdot ZCL json file
*/
-export function builtinDotdotZclMetafile() {
+function builtinDotdotZclMetafile() {
return locateProjectResource('./zcl-builtin/dotdot/library.xml')
}
@@ -125,7 +126,7 @@
* Get builtin Matter ZCL json file
* @returns matter ZCL json file
*/
-export function builtinMatterZclMetafile2() {
+function builtinMatterZclMetafile2() {
return locateProjectResource(
'./zcl-builtin/matter/zcl-with-test-extensions.json'
)
@@ -135,11 +136,11 @@
* No builtin meta template file.
* @returns null
*/
-export function builtinTemplateMetafile() {
+function builtinTemplateMetafile() {
return null // No default.
}
-export const environmentVariable = {
+const environmentVariable = {
logLevel: {
name: 'ZAP_LOGLEVEL',
description: 'Sets the log level. If unset, then default is: warn.'
@@ -220,7 +221,7 @@
/**
* Set up the devlopment environment.
*/
-export function setDevelopmentEnv() {
+function setDevelopmentEnv() {
// @ts-ignore
process.env.DEV = true
// @ts-ignore
@@ -233,7 +234,7 @@
/**
* Set up the production environment.
*/
-export function setProductionEnv() {
+function setProductionEnv() {
// @ts-ignore
global.__statics = path.join(__dirname, 'statics').replace(/\\/g, '\\\\')
// @ts-ignore
@@ -246,7 +247,7 @@
/**
* set explicit_logger_set
*/
-export function logInitStdout() {
+function logInitStdout() {
if (!explicit_logger_set) {
pino_logger = pino(pinoOptions, pino.destination(1))
explicit_logger_set = true
@@ -256,7 +257,7 @@
/**
* Create zap.log file for logging.
*/
-export function logInitLogFile() {
+function logInitLogFile() {
if (!explicit_logger_set) {
pino_logger = pino(
pinoOptions,
@@ -273,7 +274,7 @@
*
* @param {*} path Absolute path. Typically '~/.zap'.
*/
-export function setAppDirectory(directoryPath) {
+function setAppDirectory(directoryPath) {
let appDir
if (directoryPath.startsWith('~/')) {
appDir = path.join(os.homedir(), directoryPath.substring(2))
@@ -292,7 +293,7 @@
*
* @returns state directory, which is guaranteed to be already existing
*/
-export function appDirectory() {
+function appDirectory() {
if (applicationStateDirectory == null) {
let appDir = path.join(os.homedir(), '.zap')
if (!fs.existsSync(appDir)) {
@@ -309,7 +310,7 @@
*
* @returns path to icons directory
*/
-export function iconsDirectory() {
+function iconsDirectory() {
// @ts-ignore
return path.join(global.__backend, '/icons')
}
@@ -319,7 +320,7 @@
*
* @returns path to sqlite schema file
*/
-export function schemaFile() {
+function schemaFile() {
// @ts-ignore
return path.join(global.__backend, '/db/zap-schema.sql')
}
@@ -330,7 +331,7 @@
* @param {*} filename
* @returns sqlite file path
*/
-export function sqliteFile(filename = 'zap') {
+function sqliteFile(filename = 'zap') {
return path.join(appDirectory(), `${filename}.sqlite`)
}
@@ -341,7 +342,7 @@
* @param {*} deleteExistingFile
* @returns sqlite test file name
*/
-export function sqliteTestFile(id, deleteExistingFile = true) {
+function sqliteTestFile(id, deleteExistingFile = true) {
let dir = path.join(__dirname, '../../test/.zap')
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir)
@@ -355,7 +356,7 @@
* Returns a version as a single on-line string.
*
*/
-export function zapVersionAsString() {
+function zapVersionAsString() {
let vo = zapVersion()
return `ver. ${vo.version}, featureLevel ${vo.featureLevel}, commit: ${
vo.hash
@@ -372,7 +373,7 @@
* @param filePath
* @returns located project resource
*/
-export function locateProjectResource(filePath) {
+function locateProjectResource(filePath) {
if (fs.existsSync(path.join(__dirname, '../../zcl-builtin/'))) {
return path.join(__dirname, '../../', filePath)
} else if (fs.existsSync(path.join(__dirname, '../../../zcl-builtin/'))) {
@@ -389,7 +390,7 @@
* @returns zap version, which is an object that
* contains 'version', 'featureLevel', 'hash', 'timestamp' and 'date'
*/
-export function zapVersion() {
+function zapVersion() {
if (versionObject == null) {
versionObject = {
version: '',
@@ -435,7 +436,7 @@
*
* @returns zapBaseUrl
*/
-export function baseUrl() {
+function baseUrl() {
return zapBaseUrl
}
@@ -443,7 +444,7 @@
* Prints the data to stderr, without much fuss.
* @param msg
*/
-export function printToStderr(msg) {
+function printToStderr(msg) {
console.error(msg)
}
@@ -454,14 +455,14 @@
* @param {*} msg
* @param {*} err
*/
-export function log(level, msg, err = null) {
+function log(level, msg, err = null) {
let objectToLog = {
msg: msg
}
if (err != null) {
objectToLog.err = err
// @ts-ignore
- objectToLog.err.alert = '⛔'
+ objectToLog.err.alert = emojiUtil.isEmojiDisabled() ? '' : '⛔'
}
pino_logger[level](objectToLog)
}
@@ -472,7 +473,7 @@
* @param {*} msg
* @param {*} err
*/
-export function logInfo(msg, err = null) {
+function logInfo(msg, err = null) {
log('info', msg, err)
}
@@ -482,7 +483,7 @@
* @param {*} msg
* @param {*} err
*/
-export function logError(msg, err = null) {
+function logError(msg, err = null) {
log('error', msg, err)
}
@@ -492,7 +493,7 @@
* @param {*} msg
* @param {*} err
*/
-export function logWarning(msg, err = null) {
+function logWarning(msg, err = null) {
log('warn', msg, err)
}
@@ -502,7 +503,7 @@
* @param {*} msg
* @param {*} err
*/
-export function logSql(msg, query, args) {
+function logSql(msg, query, args) {
if (query == null) {
log('sql', msg)
} else {
@@ -521,7 +522,7 @@
* @param {*} msg
* @param {*} err
*/
-export function logBrowser(msg, err = null) {
+function logBrowser(msg, err = null) {
log('browser', msg, err)
}
@@ -531,7 +532,7 @@
* @param {*} msg
* @param {*} err
*/
-export function logIpc(msg, err = null) {
+function logIpc(msg, err = null) {
log('ipc', msg, err)
}
@@ -541,7 +542,7 @@
* @param {*} msg
* @param {*} err
*/
-export function logDebug(msg, err = null) {
+function logDebug(msg, err = null) {
log('debug', msg, err)
}
@@ -550,7 +551,7 @@
*
* @param {*} msg
*/
-export function logWarningToFile(msg) {
+function logWarningToFile(msg) {
let objectToLog = {
msg: msg
}
@@ -564,7 +565,7 @@
* @param {*} providedVersion
* @returns boolean
*/
-export function isMatchingVersion(versionsArray, providedVersion) {
+function isMatchingVersion(versionsArray, providedVersion) {
let ret = false
let v2 = providedVersion.split('.')
versionsArray.forEach((element) => {
@@ -588,7 +589,7 @@
*
* @returns true or false, depending on match
*/
-export function versionsCheck() {
+function versionsCheck() {
let expectedNodeVersion = ['v14.x.x', 'v16.x.x', 'v18.x.x', 'v20.x.x']
let expectedElectronVersion = [
'17.4.x',
@@ -627,6 +628,64 @@
*
* @returns full path to HTTP static content
*/
-export function httpStaticContent() {
+function httpStaticContent() {
return httpStaticContentPath
}
+
+/**
+ * Format a message with emoji if enabled, without if disabled.
+ * @param {string} emoji - the emoji character
+ * @param {string} message - the text message
+ * @returns {string} formatted message
+ */
+function formatEmojiMessage(emoji, message) {
+ if (emojiUtil.isEmojiDisabled()) {
+ return message
+ }
+ return `${emoji} ${message}`
+}
+
+// Complete exports for all functions
+exports.environmentVariable = environmentVariable
+exports.setSaveFileFormat = setSaveFileFormat
+exports.defaultFileFormat = defaultFileFormat
+exports.builtinSilabsZclMetafile = builtinSilabsZclMetafile
+exports.builtinSilabsZclSpecialMetafile = builtinSilabsZclSpecialMetafile
+exports.builtinSilabsZclGeneralXmlFile = builtinSilabsZclGeneralXmlFile
+exports.builtinSilabsSpecialZclGeneralSpecialXmlFile =
+ builtinSilabsSpecialZclGeneralSpecialXmlFile
+exports.builtinMatterZclMetafile = builtinMatterZclMetafile
+exports.builtinNewMatterZclMetafile = builtinNewMatterZclMetafile
+exports.builtinDotdotZclMetafile = builtinDotdotZclMetafile
+exports.builtinMatterZclMetafile2 = builtinMatterZclMetafile2
+exports.builtinTemplateMetafile = builtinTemplateMetafile
+exports.builtinSilabsTemplatesMetaFile = builtinSilabsTemplatesMetaFile
+exports.builtinMatterTemplatesMetaFile = builtinMatterTemplatesMetaFile
+exports.setDevelopmentEnv = setDevelopmentEnv
+exports.setProductionEnv = setProductionEnv
+exports.logInitStdout = logInitStdout
+exports.logInitLogFile = logInitLogFile
+exports.setAppDirectory = setAppDirectory
+exports.appDirectory = appDirectory
+exports.iconsDirectory = iconsDirectory
+exports.schemaFile = schemaFile
+exports.sqliteFile = sqliteFile
+exports.sqliteTestFile = sqliteTestFile
+exports.zapVersionAsString = zapVersionAsString
+exports.locateProjectResource = locateProjectResource
+exports.zapVersion = zapVersion
+exports.baseUrl = baseUrl
+exports.printToStderr = printToStderr
+exports.log = log
+exports.logInfo = logInfo
+exports.logError = logError
+exports.logWarning = logWarning
+exports.logSql = logSql
+exports.logBrowser = logBrowser
+exports.logIpc = logIpc
+exports.logDebug = logDebug
+exports.logWarningToFile = logWarningToFile
+exports.isMatchingVersion = isMatchingVersion
+exports.versionsCheck = versionsCheck
+exports.httpStaticContent = httpStaticContent
+exports.formatEmojiMessage = formatEmojiMessage
diff --git a/src-electron/util/post-import-api.js b/src-electron/util/post-import-api.js
index ec37740..41baa04 100644
--- a/src-electron/util/post-import-api.js
+++ b/src-electron/util/post-import-api.js
@@ -27,6 +27,7 @@
const dbEnum = require('../../src-shared/db-enum.js')
const querySessionZcl = require('../db/query-session-zcl.js')
const restApi = require('../../src-shared/rest-api.js')
+const env = require('./env')
/**
* Prints a text to console.
@@ -43,7 +44,7 @@
* @param {*} text
*/
function printError(text) {
- console.log(`⛔ SCRIPT API ERROR: ${text}`)
+ console.log(env.formatEmojiMessage('⛔', `SCRIPT API ERROR: ${text}`))
}
/**
diff --git a/src-electron/util/sdk-util.js b/src-electron/util/sdk-util.js
index f611856..4ed398f 100644
--- a/src-electron/util/sdk-util.js
+++ b/src-electron/util/sdk-util.js
@@ -24,6 +24,7 @@
const path = require('path')
const util = require('./util')
const fastGlob = require('fast-glob')
+const env = require('./env')
/**
* This function reads in the sdk.json that is passed as sdkPath,
@@ -39,43 +40,47 @@
logger: (msg) => {}
}
) {
- options.logger(` 👈 read in: ${sdkPath}`)
+ options.logger(env.formatEmojiMessage('👈', `read in: ${sdkPath}`))
let data = await fsp.readFile(sdkPath)
let sdk = JSON.parse(data)
// Runtime derived data goes here
sdk.rt = {}
- options.logger(` 👉 sdk information: ${sdk.meta.description}`)
+ options.logger(
+ env.formatEmojiMessage('👉', `sdk information: ${sdk.meta.description}`)
+ )
let sdkRoot = path.join(path.dirname(sdkPath), sdk.meta.sdkRoot)
- options.logger(` 👉 sdk location: ${sdkRoot}`)
+ options.logger(env.formatEmojiMessage('👉', `sdk location: ${sdkRoot}`))
let featureLevelMatch = util.matchFeatureLevel(
sdk.meta.requiredFeatureLevel,
sdk.meta.description
)
if (!featureLevelMatch.match) {
- options.logger(`⛔ ${featureLevelMatch.message}`)
+ options.logger(env.formatEmojiMessage('⛔', featureLevelMatch.message))
throw featureLevelMatch.message
}
- options.logger('🐝 Resolving ZCL metafiles')
+ options.logger(env.formatEmojiMessage('🐝', 'Resolving ZCL metafiles'))
sdk.rt.zclMetafiles = {}
for (let key of Object.keys(sdk.zcl)) {
let p = path.join(sdkRoot, sdk.zcl[key])
- options.logger(` 👈 ${p}`)
+ options.logger(env.formatEmojiMessage('👈', p))
sdk.rt.zclMetafiles[key] = p
}
- options.logger('🐝 Resolving generation template metafiles')
+ options.logger(
+ env.formatEmojiMessage('🐝', 'Resolving generation template metafiles')
+ )
sdk.rt.genTemplates = {}
for (let key of Object.keys(sdk.templates)) {
let p = path.join(sdkRoot, sdk.templates[key])
- options.logger(` 👈 ${p}`)
+ options.logger(env.formatEmojiMessage('👈', p))
sdk.rt.genTemplates[key] = p
}
- options.logger('🐝 Resolving generation patterns')
+ options.logger(env.formatEmojiMessage('🐝', 'Resolving generation patterns'))
sdk.rt.generateCommands = []
for (let gen of sdk.generation) {
let globPattern = sdk.zapFiles[gen.zapFile]
diff --git a/src-electron/util/util.js b/src-electron/util/util.js
index 3923589..772508b 100644
--- a/src-electron/util/util.js
+++ b/src-electron/util/util.js
@@ -702,39 +702,37 @@
routeErrToOut: false
}
) {
- console.log(` ✍ ${cmd}`)
- try {
- const stdout = childProcess.execSync(cmd, {
- cwd: workingDirectory,
- windowsHide: true,
- timeout: 20000,
- encoding: 'utf-8'
- })
- if (stdout) console.log(stdout)
- // execSync throws on non-zero exit code, so we don't need to check for error explicitly here.
- // It returns stdout buffer, stderr is printed to parent process stderr by default.
- } catch (error) {
- // execSync throws an error that contains stdout and stderr.
- if (error.stdout) console.log(error.stdout)
- if (error.stderr) {
- if (options.routeErrToOut) {
- console.log(error.stderr)
- } else {
- console.error(error.stderr)
+ console.log(env.formatEmojiMessage('✍', ` ${cmd}`))
+ return new Promise((resolve, reject) => {
+ childProcess.exec(
+ cmd,
+ {
+ cwd: workingDirectory,
+ windowsHide: true,
+ timeout: 20000
+ },
+ (error, stdout, stderr) => {
+ // With exec, stdout and stderr are available in the callback even on error
+ if (stdout) console.log(stdout)
+ if (stderr) {
+ if (options.routeErrToOut) {
+ console.log(stderr)
+ } else {
+ console.error(stderr)
+ }
+ }
+ if (error) {
+ if (options.rejectOnFail) {
+ reject(toErrorObject(error))
+ } else {
+ resolve()
+ }
+ } else {
+ resolve()
+ }
}
- }
-
- if (options.rejectOnFail) {
- // We return a rejected promise to allow the caller to handle it.
- return Promise.reject(toErrorObject(error))
- } else {
- // If we're not rejecting on fail, we just log the error and continue.
- console.error(error.message)
- }
- }
- // Since the original function returned a promise, we'll return a resolved promise
- // to maintain compatibility with any callers that might be using .then()
- return Promise.resolve()
+ )
+ })
}
/**
diff --git a/src-electron/validation/conformance-checker.js b/src-electron/validation/conformance-checker.js
index 0083294..d210823 100644
--- a/src-electron/validation/conformance-checker.js
+++ b/src-electron/validation/conformance-checker.js
@@ -28,6 +28,7 @@
const queryEndpointType = require('../db/query-endpoint-type')
const queryZcl = require('../db/query-zcl')
const dbEnum = require('../../src-shared/db-enum')
+const env = require('../util/env')
/**
* Generate warning messages based on conformance checks of the updated feature and related elements.
@@ -62,8 +63,11 @@
// build warning prefix string for the given feature
let buildWarningPrefix = (featureData) =>
- `⚠ Check Feature Compliance on endpoint: ${endpointId}, cluster: ${featureData.cluster}, ` +
- `feature: ${featureData.name} (${featureData.code}) (bit ${featureData.bit} in featureMap attribute)`
+ env.formatEmojiMessage(
+ '⚠️',
+ `Check Feature Compliance on endpoint: ${endpointId}, cluster: ${featureData.cluster}, ` +
+ `feature: ${featureData.name} (${featureData.code}) (bit ${featureData.bit} in featureMap attribute)`
+ )
let warningPrefix = buildWarningPrefix(featureData)
let updateDisabledString = `cannot be ${added ? 'enabled' : 'disabled'} as`
@@ -569,7 +573,10 @@
}
}
- let contextMessage = `⚠ Check Feature Compliance on endpoint: ${endpointId}, cluster: ${cluster.name}, `
+ let contextMessage = env.formatEmojiMessage(
+ '⚠️',
+ `Check Feature Compliance on endpoint: ${endpointId}, cluster: ${cluster.name}, `
+ )
/* If unsupported elements are enabled or required elements are disabled,
they are considered non-conforming. A corresponding warning message will be
diff --git a/src-script/build-backend.js b/src-script/build-backend.js
index 422c9c1..f5e475e 100644
--- a/src-script/build-backend.js
+++ b/src-script/build-backend.js
@@ -16,6 +16,7 @@
*/
const scriptUtil = require('./script-util.js')
+const env = require('../src-electron/util/env')
let startTime = process.hrtime()
@@ -27,7 +28,10 @@
.then(() => {
let endTime = process.hrtime(startTime)
console.log(
- `😎 All done: ${endTime[0]}s, ${Math.round(endTime[1] / 1000000)}ms.`
+ env.formatEmojiMessage(
+ '😎',
+ `All done: ${endTime[0]}s, ${Math.round(endTime[1] / 1000000)}ms.`
+ )
)
})
.catch((err) => {
diff --git a/src-script/gsdk-public-regen.js b/src-script/gsdk-public-regen.js
index 0d70223..5177cd1 100755
--- a/src-script/gsdk-public-regen.js
+++ b/src-script/gsdk-public-regen.js
@@ -21,6 +21,7 @@
const path = require('path')
const fs = require('fs')
const scriptUtil = require('./script-util')
+const env = require('../src-electron/util/env')
const process = require('process')
/**
@@ -44,19 +45,21 @@
}
fs.mkdirSync(outputDir, { recursive: true })
- console.log(`👉 Detecting GSDK at directory ${gsdkDir} ...`)
+ console.log(
+ env.formatEmojiMessage('👉', `Detecting GSDK at directory ${gsdkDir} ...`)
+ )
if (!fs.existsSync(path.join(gsdkDir, 'gecko_sdk.slcs'))) {
throw Error(
`Invalid location. Directory ${gsdkDir} does not look like a gecko sdk.`
)
}
- console.log(`👍 Gecko SDK detected.`)
+ console.log(env.formatEmojiMessage('👍', `Gecko SDK detected.`))
let zclJson = path.join(gsdkDir, 'app/zcl/zcl-zap.json')
if (!fs.existsSync(zclJson)) {
throw Error(`Invalid zcl.json. File ${zclJson} does not exist.`)
} else {
- console.log(`👍 ZCL metafile: ${zclJson}`)
+ console.log(env.formatEmojiMessage('👍', `ZCL metafile: ${zclJson}`))
}
let templateJson = path.join(
@@ -66,15 +69,19 @@
if (!fs.existsSync(templateJson)) {
throw Error(`Invalid template.json. File ${templateJson} does not exist.`)
} else {
- console.log(`👍 Templates metafile: ${templateJson}`)
+ console.log(
+ env.formatEmojiMessage('👍', `Templates metafile: ${templateJson}`)
+ )
}
let zapFileRoot = path.join(gsdkDir, 'protocol/zigbee/app/framework/')
let zapFiles = await scriptUtil.locateRecursively(zapFileRoot, '.*\\.zap$')
- console.log(`👍 Located ${zapFiles.length} zap files:`)
- zapFiles.forEach((f) => console.log(` 👉 ${f}`))
+ console.log(
+ env.formatEmojiMessage('👍', `Located ${zapFiles.length} zap files:`)
+ )
+ zapFiles.forEach((f) => console.log(env.formatEmojiMessage('👉', `${f}`)))
let cmdArgs = [
'node',
@@ -96,10 +103,12 @@
run(process.argv.slice(2))
.then(() => {
- console.log(`😎 Done!`)
+ console.log(env.formatEmojiMessage('😎', `Done!`))
})
.catch((err) => {
- console.log(`⛔ Error: ${err.message}\n========\n`)
+ console.log(
+ env.formatEmojiMessage('⛔', `Error: ${err.message}\n========\n`)
+ )
console.log(err)
process.exit(1)
})
diff --git a/src-script/license-check.js b/src-script/license-check.js
index baba7fb..df1c5fe 100644
--- a/src-script/license-check.js
+++ b/src-script/license-check.js
@@ -22,6 +22,7 @@
let checker = require('license-checker')
// The following line is needs to be looked at. We should not be extracting from under node modules.
let args = require('../node_modules/license-checker/lib/args').parse()
+const env = require('../src-electron/util/env')
let whiteList = fs
.readFileSync(path.join(__dirname, 'license-whitelist.txt'))
.toString()
@@ -42,9 +43,9 @@
}
}
if (fail) {
- console.log('⛔ License check FAILED')
+ console.log(env.formatEmojiMessage('⛔', 'License check FAILED'))
process.exit(1)
} else {
- console.log('😎 License check SUCCESS')
+ console.log(env.formatEmojiMessage('😎', 'License check SUCCESS'))
}
})
diff --git a/src-script/script-util.js b/src-script/script-util.js
index 1897c2b..fb8fe7a 100644
--- a/src-script/script-util.js
+++ b/src-script/script-util.js
@@ -21,6 +21,7 @@
const path = require('path')
const scriptUtil = require('./script-util.js')
const readline = require('readline')
+const env = require('../src-electron/util/env')
const spaDir = path.join(__dirname, '../spa')
const backendDir = path.join(__dirname, '../dist')
@@ -41,17 +42,27 @@
*/
async function executeCmd(ctx, cmd, args) {
return new Promise((resolve, reject) => {
- console.log(`🚀 Executing: ${cmd} ${args.join(' ')}`)
+ console.log(
+ env.formatEmojiMessage('🚀', `Executing: ${cmd} ${args.join(' ')}`)
+ )
let c = spawn(cmd, args)
c.on('exit', (code) => {
if (code == 0) resolve(ctx)
else {
if (code) {
- console.log(`👎 Program ${cmd} exited with error code: ${code}`)
+ console.log(
+ env.formatEmojiMessage(
+ '👎',
+ `Program ${cmd} exited with error code: ${code}`
+ )
+ )
reject(code)
} else {
console.log(
- `👎 Program ${cmd} exited with signal code: ${c.signalCode}`
+ env.formatEmojiMessage(
+ '👎',
+ `Program ${cmd} exited with signal code: ${c.signalCode}`
+ )
)
reject(c.signalCode)
}
@@ -78,13 +89,20 @@
*/
async function getStdout(onError, cmd, args) {
return new Promise((resolve, reject) => {
- console.log(`🚀 Executing: ${cmd} ${args.join(' ')}`)
+ console.log(
+ env.formatEmojiMessage('🚀', `Executing: ${cmd} ${args.join(' ')}`)
+ )
let c = spawn(cmd, args)
let str = ''
c.on('exit', (code) => {
if (code == 0) resolve(str)
else {
- console.log(`👎 Program ${cmd} exited with error code: ${code}`)
+ console.log(
+ env.formatEmojiMessage(
+ '👎',
+ `Program ${cmd} exited with error code: ${code}`
+ )
+ )
reject(code)
}
})
@@ -108,12 +126,17 @@
path.join(__dirname, '../src'),
hashOptions
)
- console.log(`🔍 Current src hash: ${srcHash.hash}`)
+ console.log(env.formatEmojiMessage('🔍', `Current src hash: ${srcHash.hash}`))
let srcSharedHash = await folderHash.hashElement(
path.join(__dirname, '../src-shared'),
hashOptions
)
- console.log(`🔍 Current src-shared hash: ${srcSharedHash.hash}`)
+ console.log(
+ env.formatEmojiMessage(
+ '🔍',
+ `Current src-shared hash: ${srcSharedHash.hash}`
+ )
+ )
let ctx = {
hash: {
srcHash: srcHash.hash,
@@ -127,13 +150,26 @@
fs.readFile(spaHashFileName, (err, data) => {
let oldHash = null
if (err) {
- console.log(`👎 Error reading old hash file: ${spaHashFileName}`)
+ console.log(
+ env.formatEmojiMessage(
+ '👎',
+ `Error reading old hash file: ${spaHashFileName}`
+ )
+ )
ctx.needsRebuild = true
} else {
oldHash = JSON.parse(data)
- console.log(`🔍 Previous src hash: ${oldHash.srcHash}`)
console.log(
- `🔍 Previous src-shared hash: ${oldHash.srcSharedHash}`
+ env.formatEmojiMessage(
+ '🔍',
+ `Previous src hash: ${oldHash.srcHash}`
+ )
+ )
+ console.log(
+ env.formatEmojiMessage(
+ '🔍',
+ `Previous src-shared hash: ${oldHash.srcSharedHash}`
+ )
)
ctx.needsRebuild =
oldHash.srcSharedHash != ctx.hash.srcSharedHash ||
@@ -145,7 +181,10 @@
)
} else {
console.log(
- `👍 There were no changes to front-end code, so we don't have to rebuild the SPA.`
+ env.formatEmojiMessage(
+ '👍',
+ "There were no changes to front-end code, so we don't have to rebuild the SPA."
+ )
)
}
resolve(ctx)
@@ -161,7 +200,9 @@
(ctx) =>
new Promise((resolve, reject) => {
if (ctx.needsRebuild) {
- console.log('✍ Writing out new hash file.')
+ console.log(
+ env.formatEmojiMessage('✍', 'Writing out new hash file.')
+ )
fs.writeFile(spaHashFileName, JSON.stringify(ctx.hash), (err) => {
if (err) reject(err)
else resolve(ctx)
@@ -208,7 +249,12 @@
version.date = d
version.zapVersion = result.version
let versionFile = path.join(__dirname, '../.version.json')
- console.log(`🔍 Git commit: ${version.hash} from ${version.date}`)
+ console.log(
+ env.formatEmojiMessage(
+ '🔍',
+ `Git commit: ${version.hash} from ${version.date}`
+ )
+ )
await fsp.writeFile(versionFile, JSON.stringify(version))
} catch (err) {
console.log(`Error retrieving version: ${err}`)
@@ -304,7 +350,9 @@
*/
async function doneStamp(startTime) {
let nsDuration = process.hrtime.bigint() - startTime
- console.log(`😎 All done: ${duration(nsDuration)}.`)
+ console.log(
+ env.formatEmojiMessage('😎', `All done: ${duration(nsDuration)}.`)
+ )
return setPackageJsonVersion(null, 'fake')
}
diff --git a/src-script/zap-combine-reports.js b/src-script/zap-combine-reports.js
index c0102e3..726b829 100755
--- a/src-script/zap-combine-reports.js
+++ b/src-script/zap-combine-reports.js
@@ -18,6 +18,7 @@
const scriptUtil = require('./script-util.js')
const fsExtra = require('fs-extra')
+const env = require('../src-electron/util/env')
//workaround: executeCmd()/spawn() fails silently without complaining about missing path to electron
process.env.PATH = process.env.PATH + ':/usr/local/bin/'
@@ -59,7 +60,10 @@
)
console.log(
- `✅ Please find the combined report (Jest & Cypress) at ./coverage/lcov-report/index.html`
+ env.formatEmojiMessage(
+ '✅',
+ 'Please find the combined report (Jest & Cypress) at ./coverage/lcov-report/index.html'
+ )
)
} catch (err) {
console.log(
diff --git a/src-script/zap-package-metadata.js b/src-script/zap-package-metadata.js
index cf34f6e..f08b8e6 100755
--- a/src-script/zap-package-metadata.js
+++ b/src-script/zap-package-metadata.js
@@ -24,6 +24,7 @@
// apack_zap.package
const fs = require('fs')
const path = require('path')
+const env = require('../src-electron/util/env')
const packageJson = path.join(__dirname, '../package.json')
const zapPackage = path.join(__dirname, '../apack_zap.package')
@@ -46,6 +47,11 @@
version="${version}"/>
`
- console.log(`🐝 Generating ${zapPackage} with version number ${version}`)
+ console.log(
+ env.formatEmojiMessage(
+ '🐝',
+ `Package metadata: ${JSON.stringify(metadata)}`
+ )
+ )
fs.writeFileSync(zapPackage, template)
})
diff --git a/src-script/zap-start.js b/src-script/zap-start.js
index 040b634..8b45a41 100755
--- a/src-script/zap-start.js
+++ b/src-script/zap-start.js
@@ -17,6 +17,7 @@
*/
const scriptUtil = require('./script-util.js')
+const env = require('../src-electron/util/env')
//workaround: executeCmd()/spawn() fails silently without complaining about missing path to electron
process.env.PATH = process.env.PATH + ':/usr/local/bin/'
@@ -72,8 +73,8 @@
if (process.platform == 'linux' && executable == 'electron') {
if (!process.env.DISPLAY) {
console.log(`
-⛔ You are on Linux and you are attempting to run zap in UI mode without DISPLAY set.
-⛔ Please set your DISPLAY environment variable or run zap-start.js with a command that does not require DISPLAY.`)
+${env.formatEmojiMessage('⛔', 'You are on Linux and you are attempting to run zap in UI mode without DISPLAY set.')}
+${env.formatEmojiMessage('⛔', 'Please set your DISPLAY environment variable or run zap-start.js with a command that does not require DISPLAY.')}`)
process.exit(1)
}
}
diff --git a/src-script/zap-uitest.js b/src-script/zap-uitest.js
index 31e7bdd..6687184 100755
--- a/src-script/zap-uitest.js
+++ b/src-script/zap-uitest.js
@@ -17,6 +17,7 @@
*/
const scriptUtil = require('./script-util.js')
+const env = require('../src-electron/util/env')
let browserToUse = 'chrome'
let cypressMode = 'run'
@@ -90,15 +91,28 @@
svr.then(() => {
if (returnCode == 0) {
- console.log('😎 All done: Cypress tests passed and server shut down.')
+ console.log(
+ env.formatEmojiMessage(
+ '😎',
+ 'All done: Cypress tests passed and server shut down.'
+ )
+ )
process.exit(0)
} else if (ignoreErrorCode) {
console.log(
- '⚠️ There was an error code, but will be ignored. Please check logs.'
+ env.formatEmojiMessage(
+ '⚠️',
+ 'There was an error code, but will be ignored. Please check logs.'
+ )
)
process.exit(0)
} else {
- console.log('⛔ Error: Cypress tests failed, server shut down.')
+ console.log(
+ env.formatEmojiMessage(
+ '⛔',
+ 'Error: Cypress tests failed, server shut down.'
+ )
+ )
process.exit(returnCode)
}
})
diff --git a/src-script/zap-update-package-version.js b/src-script/zap-update-package-version.js
index d5af8c7..2e63b7a 100755
--- a/src-script/zap-update-package-version.js
+++ b/src-script/zap-update-package-version.js
@@ -24,6 +24,7 @@
const path = require('path')
const readline = require('readline')
const scriptUtil = require('./script-util')
+const env = require('../src-electron/util/env')
if (
process.argv[2] == '-?' ||
@@ -57,6 +58,6 @@
process.exit(result.wasChanged ? 1 : 0)
})
.catch((err) => {
- console.log(`⛔ Error: ${err}`)
+ console.log(env.formatEmojiMessage('⛔', `Error: ${err}`))
process.exit(1)
})
diff --git a/test/emoji-util.test.js b/test/emoji-util.test.js
new file mode 100644
index 0000000..4db4036
--- /dev/null
+++ b/test/emoji-util.test.js
@@ -0,0 +1,258 @@
+const emojiUtil = require('../src-electron/util/emoji-util')
+const env = require('../src-electron/util/env')
+
+describe('Emoji Utility Tests', () => {
+ beforeEach(() => {
+ // Reset emoji state before each test
+ emojiUtil.resetEmojiState()
+ })
+
+ test('formatMessage with emoji enabled (default)', () => {
+ const result1 = env.formatEmojiMessage('🚀', 'Starting application')
+ const result2 = env.formatEmojiMessage('✅', 'Success')
+ const result3 = env.formatEmojiMessage('⚠️', 'Warning message')
+
+ expect(result1).toBe('🚀 Starting application')
+ expect(result2).toBe('✅ Success')
+ expect(result3).toBe('⚠️ Warning message')
+ })
+
+ test('formatMessage with emoji disabled', () => {
+ emojiUtil.setEmojiDisabled(true)
+
+ const result1 = env.formatEmojiMessage('🚀', 'Starting application')
+ const result2 = env.formatEmojiMessage('✅', 'Success')
+ const result3 = env.formatEmojiMessage('⚠️', 'Warning message')
+
+ expect(result1).toBe('Starting application')
+ expect(result2).toBe('Success')
+ expect(result3).toBe('Warning message')
+ })
+
+ test('formatMessage with emoji re-enabled', () => {
+ emojiUtil.setEmojiDisabled(true)
+ emojiUtil.setEmojiDisabled(false)
+
+ const result = env.formatEmojiMessage('🚀', 'Starting application')
+ expect(result).toBe('🚀 Starting application')
+ })
+
+ test('emoji state reset functionality', () => {
+ emojiUtil.setEmojiDisabled(true)
+ emojiUtil.resetEmojiState()
+
+ const result = env.formatEmojiMessage('🔄', 'Reset complete')
+ expect(result).toBe('🔄 Reset complete')
+ })
+
+ test('isEmojiDisabled function states', () => {
+ // Default state (should be false unless NO_EMOJI env var is set)
+ expect(emojiUtil.isEmojiDisabled()).toBe(false)
+
+ // Explicitly disabled
+ emojiUtil.setEmojiDisabled(true)
+ expect(emojiUtil.isEmojiDisabled()).toBe(true)
+
+ // Explicitly enabled
+ emojiUtil.setEmojiDisabled(false)
+ expect(emojiUtil.isEmojiDisabled()).toBe(false)
+
+ // Reset to environment detection
+ emojiUtil.resetEmojiState()
+ expect(emojiUtil.isEmojiDisabled()).toBe(false)
+ })
+
+ test('NO_EMOJI environment variable detection', () => {
+ const originalEnv = process.env.NO_EMOJI
+ const originalArgv = process.argv
+
+ try {
+ // Set NO_EMOJI environment variable
+ process.env.NO_EMOJI = '1'
+ emojiUtil.resetEmojiState()
+
+ expect(emojiUtil.isEmojiDisabled()).toBe(true)
+ expect(env.formatEmojiMessage('🚀', 'Test message')).toBe('Test message')
+
+ // Unset NO_EMOJI
+ delete process.env.NO_EMOJI
+ emojiUtil.resetEmojiState()
+
+ expect(emojiUtil.isEmojiDisabled()).toBe(false)
+ expect(env.formatEmojiMessage('🚀', 'Test message')).toBe(
+ '🚀 Test message'
+ )
+ } finally {
+ // Restore original state
+ if (originalEnv) {
+ process.env.NO_EMOJI = originalEnv
+ } else {
+ delete process.env.NO_EMOJI
+ }
+ process.argv = originalArgv
+ emojiUtil.resetEmojiState()
+ }
+ })
+
+ test('--no-emoji command line argument detection', () => {
+ const originalArgv = process.argv
+ const originalEnv = process.env.NO_EMOJI
+
+ try {
+ // Remove NO_EMOJI env var if it exists
+ delete process.env.NO_EMOJI
+
+ // Test with --no-emoji flag
+ process.argv = ['node', 'script.js', '--no-emoji']
+ emojiUtil.resetEmojiState()
+
+ expect(emojiUtil.isEmojiDisabled()).toBe(true)
+ expect(env.formatEmojiMessage('✅', 'Success')).toBe('Success')
+
+ // Test without flag
+ process.argv = ['node', 'script.js']
+ emojiUtil.resetEmojiState()
+
+ expect(emojiUtil.isEmojiDisabled()).toBe(false)
+ expect(env.formatEmojiMessage('✅', 'Success')).toBe('✅ Success')
+ } finally {
+ // Restore original state
+ process.argv = originalArgv
+ if (originalEnv) {
+ process.env.NO_EMOJI = originalEnv
+ } else {
+ delete process.env.NO_EMOJI
+ }
+ emojiUtil.resetEmojiState()
+ }
+ })
+
+ test('--noEmoji command line argument detection', () => {
+ const originalArgv = process.argv
+ const originalEnv = process.env.NO_EMOJI
+
+ try {
+ // Remove NO_EMOJI env var if it exists
+ delete process.env.NO_EMOJI
+
+ // Test with --noEmoji flag
+ process.argv = ['node', 'script.js', '--noEmoji']
+ emojiUtil.resetEmojiState()
+
+ expect(emojiUtil.isEmojiDisabled()).toBe(true)
+ expect(env.formatEmojiMessage('⚠️', 'Warning')).toBe('Warning')
+
+ // Test without flag
+ process.argv = ['node', 'script.js']
+ emojiUtil.resetEmojiState()
+
+ expect(emojiUtil.isEmojiDisabled()).toBe(false)
+ expect(env.formatEmojiMessage('⚠️', 'Warning')).toBe('⚠️ Warning')
+ } finally {
+ // Restore original state
+ process.argv = originalArgv
+ if (originalEnv) {
+ process.env.NO_EMOJI = originalEnv
+ } else {
+ delete process.env.NO_EMOJI
+ }
+ emojiUtil.resetEmojiState()
+ }
+ })
+
+ test('formatEmojiMessage with various emojis', () => {
+ emojiUtil.setEmojiDisabled(false)
+
+ expect(env.formatEmojiMessage('🚀', 'Starting')).toBe('🚀 Starting')
+ expect(env.formatEmojiMessage('✅', 'Success')).toBe('✅ Success')
+ expect(env.formatEmojiMessage('⚠️', 'Warning')).toBe('⚠️ Warning')
+ expect(env.formatEmojiMessage('⛔', 'Error')).toBe('⛔ Error')
+ expect(env.formatEmojiMessage('🔧', 'Config')).toBe('🔧 Config')
+ expect(env.formatEmojiMessage('😎', 'Done')).toBe('😎 Done')
+ expect(env.formatEmojiMessage('🤖', 'Robot')).toBe('🤖 Robot')
+ expect(env.formatEmojiMessage('🐝', 'Bee')).toBe('🐝 Bee')
+ expect(env.formatEmojiMessage('👈', 'Left')).toBe('👈 Left')
+ expect(env.formatEmojiMessage('👉', 'Right')).toBe('👉 Right')
+ expect(env.formatEmojiMessage('🔍', 'Search')).toBe('🔍 Search')
+ expect(env.formatEmojiMessage('🎉', 'Celebrate')).toBe('🎉 Celebrate')
+ expect(env.formatEmojiMessage('👍', 'Thumbs up')).toBe('👍 Thumbs up')
+ expect(env.formatEmojiMessage('🔄', 'Reset')).toBe('🔄 Reset')
+ expect(env.formatEmojiMessage('✍', 'Write')).toBe('✍ Write')
+ expect(env.formatEmojiMessage('👎', 'Thumbs down')).toBe('👎 Thumbs down')
+ expect(env.formatEmojiMessage('🕐', 'Time')).toBe('🕐 Time')
+
+ emojiUtil.setEmojiDisabled(true)
+
+ expect(env.formatEmojiMessage('🚀', 'Starting')).toBe('Starting')
+ expect(env.formatEmojiMessage('✅', 'Success')).toBe('Success')
+ expect(env.formatEmojiMessage('⚠️', 'Warning')).toBe('Warning')
+ expect(env.formatEmojiMessage('⛔', 'Error')).toBe('Error')
+ })
+
+ test('formatEmojiMessage with empty message', () => {
+ emojiUtil.setEmojiDisabled(false)
+ expect(env.formatEmojiMessage('🚀', '')).toBe('🚀 ')
+
+ emojiUtil.setEmojiDisabled(true)
+ expect(env.formatEmojiMessage('🚀', '')).toBe('')
+ })
+
+ test('formatEmojiMessage with multiline message', () => {
+ emojiUtil.setEmojiDisabled(false)
+ const multiline = 'Line 1\nLine 2\nLine 3'
+ expect(env.formatEmojiMessage('🚀', multiline)).toBe(`🚀 ${multiline}`)
+
+ emojiUtil.setEmojiDisabled(true)
+ expect(env.formatEmojiMessage('🚀', multiline)).toBe(multiline)
+ })
+
+ test('explicit setEmojiDisabled overrides environment', () => {
+ const originalEnv = process.env.NO_EMOJI
+ const originalArgv = process.argv
+
+ try {
+ // Set environment to disable emojis
+ process.env.NO_EMOJI = '1'
+ process.argv = ['node', 'script.js', '--no-emoji']
+ emojiUtil.resetEmojiState()
+
+ expect(emojiUtil.isEmojiDisabled()).toBe(true)
+
+ // Explicitly enable should override
+ emojiUtil.setEmojiDisabled(false)
+ expect(emojiUtil.isEmojiDisabled()).toBe(false)
+ expect(env.formatEmojiMessage('🚀', 'Test')).toBe('🚀 Test')
+
+ // Explicitly disable should override
+ emojiUtil.setEmojiDisabled(true)
+ expect(emojiUtil.isEmojiDisabled()).toBe(true)
+ expect(env.formatEmojiMessage('🚀', 'Test')).toBe('Test')
+ } finally {
+ if (originalEnv) {
+ process.env.NO_EMOJI = originalEnv
+ } else {
+ delete process.env.NO_EMOJI
+ }
+ process.argv = originalArgv
+ emojiUtil.resetEmojiState()
+ }
+ })
+
+ test('log function alert property respects no-emoji setting', () => {
+ try {
+ // Test with emojis enabled
+ emojiUtil.setEmojiDisabled(false)
+ const testError1 = new Error('Test error 1')
+ env.logError('Test message', testError1)
+ expect(testError1.alert).toBe('⛔')
+
+ // Test with emojis disabled
+ emojiUtil.setEmojiDisabled(true)
+ const testError2 = new Error('Test error 2')
+ env.logError('Test message', testError2)
+ expect(testError2.alert).toBe('')
+ } finally {
+ emojiUtil.resetEmojiState()
+ }
+ })
+})
diff --git a/test/feature.test.js b/test/feature.test.js
index 3ed81a9..5a2d4bf 100644
--- a/test/feature.test.js
+++ b/test/feature.test.js
@@ -636,7 +636,7 @@
let endpointId = 1
let result = {}
let expectedWarning = ''
- let warningPrefix = `⚠ Check Feature Compliance on endpoint: ${endpointId}, cluster: ${cluster}, `
+ let warningPrefix = `⚠️ Check Feature Compliance on endpoint: ${endpointId}, cluster: ${cluster}, `
let featureBitMessage = `(bit ${featureBit} in featureMap attribute)`
// 1. test enable an optional feature
diff --git a/test/importexport.test.js b/test/importexport.test.js
index f0ebf6e..7437d65 100644
--- a/test/importexport.test.js
+++ b/test/importexport.test.js
@@ -514,24 +514,24 @@
// Their element conformance warnings should be added to the notification table.
expect(
notificationMessages.includes(
- '⚠ Check Feature Compliance on endpoint: 1, cluster: On/Off, command: OffWithEffect has mandatory conformance to LT and should be enabled, when feature: LT is enabled.'
+ '⚠️ Check Feature Compliance on endpoint: 1, cluster: On/Off, command: OffWithEffect has mandatory conformance to LT and should be enabled, when feature: LT is enabled.'
)
).toBeTruthy()
expect(
notificationMessages.includes(
- '⚠ Check Feature Compliance on endpoint: 1, cluster: On/Off, attribute: OnTime has mandatory conformance to LT and should be enabled, when feature: LT is enabled.'
+ '⚠️ Check Feature Compliance on endpoint: 1, cluster: On/Off, attribute: OnTime has mandatory conformance to LT and should be enabled, when feature: LT is enabled.'
)
).toBeTruthy()
expect(
notificationMessages.includes(
- '⚠ Check Feature Compliance on endpoint: 1, cluster: On/Off, attribute: GlobalSceneControl has mandatory conformance to LT and should be enabled, when feature: LT is enabled.'
+ '⚠️ Check Feature Compliance on endpoint: 1, cluster: On/Off, attribute: GlobalSceneControl has mandatory conformance to LT and should be enabled, when feature: LT is enabled.'
)
).toBeTruthy()
// disabled mandatory device type feature OnOff should trigger a notification
expect(
notificationMessages.includes(
- '⚠ Check Feature Compliance on endpoint: 1, cluster: Level Control, feature: OnOff (OO) (bit 0 in featureMap attribute) should be enabled, as it is mandatory for device type: Matter Dimmable Light.'
+ '⚠️ Check Feature Compliance on endpoint: 1, cluster: Level Control, feature: OnOff (OO) (bit 0 in featureMap attribute) should be enabled, as it is mandatory for device type: Matter Dimmable Light.'
)
).toBeTruthy()
},
diff --git a/test/multi-protocol.test.js b/test/multi-protocol.test.js
index 611d82f..8b31aed 100644
--- a/test/multi-protocol.test.js
+++ b/test/multi-protocol.test.js
@@ -186,20 +186,20 @@
// Tests for device type feature conformance
expect(
sessionNotificationMessages.includes(
- '⚠ Check Feature Compliance on endpoint: 1, cluster: Level Control, feature: Lighting (LT) (bit 1 in featureMap attribute) should be enabled, as it is mandatory for device type: Matter Dimmable Light.'
+ '⚠️ Check Feature Compliance on endpoint: 1, cluster: Level Control, feature: Lighting (LT) (bit 1 in featureMap attribute) should be enabled, as it is mandatory for device type: Matter Dimmable Light.'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Feature Compliance on endpoint: 1, cluster: Level Control, feature: OnOff (OO) (bit 0 in featureMap attribute) should be enabled, as it is mandatory for device type: Matter Dimmable Light.'
+ '⚠️ Check Feature Compliance on endpoint: 1, cluster: Level Control, feature: OnOff (OO) (bit 0 in featureMap attribute) should be enabled, as it is mandatory for device type: Matter Dimmable Light.'
)
).toBeTruthy()
// warnings for same feature across different device types should be merged
expect(
sessionNotificationMessages.includes(
- '⚠ Check Feature Compliance on endpoint: 1, cluster: On/Off, feature: Lighting (LT) (bit 0 in featureMap attribute) should be enabled, as it is mandatory for device type: Matter On/Off Light, Matter Dimmable Light.'
+ '⚠️ Check Feature Compliance on endpoint: 1, cluster: On/Off, feature: Lighting (LT) (bit 0 in featureMap attribute) should be enabled, as it is mandatory for device type: Matter On/Off Light, Matter Dimmable Light.'
)
).toBeTruthy()
@@ -224,7 +224,7 @@
for (const element of nonConformElements) {
expect(
sessionNotificationMessages.includes(
- `⚠ Check Feature Compliance on endpoint: 1, cluster: On/Off, ${element.type}: ${element.name} has mandatory conformance to LT and should be disabled, when feature: LT is disabled.`
+ `⚠️ Check Feature Compliance on endpoint: 1, cluster: On/Off, ${element.type}: ${element.name} has mandatory conformance to LT and should be disabled, when feature: LT is disabled.`
)
).toBeTruthy()
}
diff --git a/test/notification.test.js b/test/notification.test.js
index 57edca8..173a60f 100644
--- a/test/notification.test.js
+++ b/test/notification.test.js
@@ -320,14 +320,14 @@
'Notification: set notification on feature change result',
async () => {
let sessionId = await querySession.createBlankSession(db)
- let warningPrefix = `⚠ Check Feature Compliance on endpoint: 1, cluster: Color Control,
+ let warningPrefix = `⚠️ Check Feature Compliance on endpoint: 1, cluster: Color Control,
feature: Hue And Saturation (HS) (bit 0 in featureMap attribute)`
let warningMessage = `${warningPrefix} has mandatory conformance to OO and needs to be enabled.`
let disableMessage1 = `${warningPrefix} cannot be enabled because of reason 1.`
let disableMessage2 = `${warningPrefix} cannot be disabled because of reason 2.`
let descMessage = `${warningPrefix} cannot be enabled as its conformance is too complex for ZAP to parse, or it includes 'desc'.`
let messageOfOtherPattern = `${warningPrefix} is still provisional.`
- let messageOfOtherFeature = `⚠ Check Feature Compliance on endpoint: 1, cluster: Color Control,
+ let messageOfOtherFeature = `⚠️ Check Feature Compliance on endpoint: 1, cluster: Color Control,
feature: Color Loop (CL) (bit 2 in featureMap attribute) cannot be enabled because of reason 1`
let messageOfOtherType = `On endpoint 1, support for cluster: Scenes Management server is provisional.`
diff --git a/test/spec-check.test.js b/test/spec-check.test.js
index d759c90..284988a 100644
--- a/test/spec-check.test.js
+++ b/test/spec-check.test.js
@@ -103,47 +103,47 @@
)
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor server needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor server needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor server needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor server needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor, attribute: ServerList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor, attribute: ClientList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: PartsList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: PartsList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
@@ -206,33 +206,33 @@
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor server needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-rootdevice, cluster: Descriptor server needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor server needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor server needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
+ '⚠️ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
@@ -321,23 +321,23 @@
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, device type: MA-powersource, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 1, device type: MA-onofflight, cluster: Identify, attribute: IdentifyTime needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
+ '⚠️ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
)
).toBeFalsy()
@@ -387,29 +387,29 @@
sessionNotificationMessages = sessionNotifications.map((sn) => sn.message)
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, cluster: Descriptor, attribute: ServerList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, cluster: Descriptor, attribute: ServerList needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, cluster: Descriptor, attribute: ClientList needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, cluster: Descriptor, attribute: ClientList needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, cluster: Descriptor server needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, cluster: Descriptor server needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 1, cluster: Identify, attribute: IdentifyTime needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 1, cluster: Identify, attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
+ '⚠️ Check Cluster Compliance on endpoint: 1, cluster: Identify, mandatory attribute: IdentifyTime needs to be enabled'
)
).toBeTruthy()
@@ -448,7 +448,7 @@
sessionNotificationMessages = sessionNotifications.map((sn) => sn.message)
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
)
).toBeTruthy()
@@ -474,7 +474,7 @@
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
)
).toBeFalsy()
@@ -488,12 +488,12 @@
)
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration server needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration server needs to be enabled'
)
).toBeFalsy()
expect(
sessionNotificationMessages.includes(
- '⚠ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
+ '⚠️ Check Device Type Compliance on endpoint: 0, cluster: Localization Configuration, attribute: ActiveLocale needs to be enabled'
)
).toBeFalsy()