@zohodesk/react-cli 1.1.14-kubernetes → 1.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/.vscode/settings.json +25 -0
  2. package/README.md +294 -16
  3. package/bin/cli.js +30 -55
  4. package/docs/ComposeMinification.md +13 -0
  5. package/docs/CustomChunks.md +12 -9
  6. package/docs/MarkdownParser.md +18 -0
  7. package/docs/ReactLive.md +14 -0
  8. package/docs/SelectorWeight.md +3 -0
  9. package/docs/ValueReplacer.md +27 -0
  10. package/docs/VariableConversion.md +6 -1
  11. package/docs/patternFiltering.md +57 -0
  12. package/lib/common/buildEs.js +12 -0
  13. package/lib/common/runPreProcess.js +71 -0
  14. package/lib/common/splitChunks.js +65 -45
  15. package/lib/common/testPattern.js +9 -11
  16. package/lib/common/valueReplacer.js +1 -3
  17. package/lib/configs/resolvers.js +16 -5
  18. package/lib/configs/webpack.css.umd.config.js +3 -2
  19. package/lib/configs/webpack.dev.config.js +15 -5
  20. package/lib/configs/webpack.docs.config.js +17 -5
  21. package/lib/configs/webpack.impact.config.js +11 -4
  22. package/lib/configs/webpack.prod.config.js +15 -5
  23. package/lib/constants.js +3 -3
  24. package/lib/deprecationLogger.js +40 -0
  25. package/lib/loaderUtils/getCSSLoaders.js +98 -49
  26. package/lib/loaderUtils/tests/windowsModification.test.js +10 -0
  27. package/lib/loaderUtils/windowsModification.js +6 -1
  28. package/lib/loaders/__test__/markdownLoader.spec.js +145 -0
  29. package/lib/loaders/composeLoader.js +298 -0
  30. package/lib/loaders/docsLoader.js +18 -7
  31. package/lib/loaders/markdownLoader.js +71 -0
  32. package/lib/loaders/reactLiveConvertor.js +105 -0
  33. package/lib/loaders/selectorMappingLoader.js +9 -9
  34. package/lib/logger.js +27 -0
  35. package/lib/pluginUtils/getDevPlugins.js +25 -6
  36. package/lib/pluginUtils/getProdPlugins.js +32 -5
  37. package/lib/pluginUtils/getUMDCSSPlugins.js +1 -1
  38. package/lib/pluginUtils/getUMDComponentPlugins.js +1 -1
  39. package/lib/plugins/CustomAttributePlugin.js +82 -0
  40. package/lib/plugins/CustomAttributePlugin.md +35 -0
  41. package/lib/plugins/EFCPlugin.js +9 -9
  42. package/lib/plugins/EFCTemplatePlugin.js +10 -12
  43. package/lib/plugins/EfcResourceCleanupPlugin.js +43 -0
  44. package/lib/plugins/I18NInjectIntoIndexPlugin.js +8 -9
  45. package/lib/plugins/I18nSplitPlugin/I18nDebugPlugin.js +2 -3
  46. package/lib/plugins/I18nSplitPlugin/I18nKeysIdentifer.js +2 -7
  47. package/lib/plugins/I18nSplitPlugin/index.js +1 -1
  48. package/lib/plugins/I18nSplitPlugin/utils/propertiesUtils.js +8 -8
  49. package/lib/plugins/{UglifyCSSPlugin.js → MinifyPlugin.js} +3 -3
  50. package/lib/plugins/ReportGeneratePlugin.js +8 -6
  51. package/lib/plugins/ResourceHintsPlugin.js +13 -3
  52. package/lib/plugins/SelectorPlugin.js +77 -37
  53. package/lib/plugins/StatsPlugin.js +82 -0
  54. package/lib/plugins/UnusedFilesFindPlugin.js +7 -5
  55. package/lib/plugins/VariableConversionCollector.js +40 -101
  56. package/lib/plugins/index.js +7 -7
  57. package/lib/plugins/utils/classHandling.js +35 -0
  58. package/lib/plugins/utils/fileHandling.js +92 -0
  59. package/lib/plugins/utils/tests/fileHandling.test.js +30 -0
  60. package/lib/plugins/variableConvertorUtils.js +133 -0
  61. package/lib/postcss-plugins/EmptyPlugin.js +8 -0
  62. package/lib/postcss-plugins/ExcludePlugin.js +1 -1
  63. package/lib/postcss-plugins/IncludePlugin.js +23 -0
  64. package/lib/postcss-plugins/RTLSplitPlugin.js +4 -10
  65. package/lib/postcss-plugins/SelectorReplace.js +80 -0
  66. package/lib/postcss-plugins/ValueReplacer.js +8 -29
  67. package/lib/postcss-plugins/__test__/selectorReplace.test.js +28 -0
  68. package/lib/postcss-plugins/__test__/valueReplacer.spec.js +43 -0
  69. package/lib/postcss-plugins/hoverActivePlugin.js +0 -6
  70. package/lib/postcss-plugins/variableModificationPlugin/ErrorHandler.js +0 -1
  71. package/lib/postcss-plugins/variableModificationPlugin/index.js +94 -38
  72. package/lib/schemas/index.js +95 -18
  73. package/lib/servers/devBuild.js +13 -11
  74. package/lib/servers/getCliPath.js +3 -5
  75. package/lib/servers/httpsOptions.js +12 -13
  76. package/lib/servers/nowatchserver.js +62 -55
  77. package/lib/servers/requireLocalOrGlobal.js +61 -0
  78. package/lib/servers/server.js +53 -52
  79. package/lib/utils/cssClassNameGenerate.js +70 -13
  80. package/lib/utils/deprecationSupport.js +134 -0
  81. package/lib/utils/getOptions.js +35 -28
  82. package/lib/utils/getServerURL.js +1 -9
  83. package/lib/utils/index.js +14 -12
  84. package/lib/utils/initPreCommitHook.js +5 -5
  85. package/lib/utils/log.js +11 -0
  86. package/lib/utils/object-manipulation.js +88 -0
  87. package/lib/utils/pullOrigin.js +3 -3
  88. package/lib/utils/reinstallDependencies.js +3 -3
  89. package/lib/utils/selectorReplacer.js +47 -0
  90. package/lib/utils/switchBranch.js +4 -2
  91. package/lib/utils/variableConverter.js +104 -0
  92. package/npm-shrinkwrap.json +33485 -0
  93. package/package.json +5 -3
  94. package/templates/docs/all.html +1 -0
  95. package/templates/docs/component.html +1 -0
  96. package/templates/docs/components.html +1 -0
  97. package/templates/docs/css/markdown.css +202 -0
  98. package/templates/docs/css/style.css +136 -169
  99. package/templates/docs/index.html +796 -632
  100. package/lib/plugins/composeCommonPlugin.js +0 -30
  101. package/lib/postcss-plugins/variableModifier.js +0 -244
package/lib/constants.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.cliRootPath = exports.cliNodemodulesPath = exports.appPath = exports.CONFIG_ROOT = exports.BASE_CONFIG_KEY = void 0;
6
+ exports.cliRootPath = exports.cliNodeModulesPath = exports.appPath = exports.CONFIG_ROOT = exports.BASE_CONFIG_KEY = void 0;
7
7
 
8
8
  var _path = _interopRequireDefault(require("path"));
9
9
 
@@ -18,10 +18,10 @@ exports.cliRootPath = cliRootPath;
18
18
  const CONFIG_ROOT = 'react-cli';
19
19
  exports.CONFIG_ROOT = CONFIG_ROOT;
20
20
 
21
- const cliNodemodulesPath = _path.default.resolve(cliRootPath, 'node_modules'); // export const babelrcPath = join(cliRootPath, '.babelrc');
21
+ const cliNodeModulesPath = _path.default.resolve(cliRootPath, 'node_modules'); // export const babelrcPath = join(cliRootPath, '.babelrc');
22
22
 
23
23
 
24
- exports.cliNodemodulesPath = cliNodemodulesPath;
24
+ exports.cliNodeModulesPath = cliNodeModulesPath;
25
25
  const appPath = process.cwd(); // export const appInitialHTMLTemplatePath = path.join(
26
26
  // process.cwd(),
27
27
  // 'src',
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.deprecateMessage = deprecateMessage;
7
+ exports.deprecateOption = deprecateOption;
8
+ exports.deprecationLoggerEnd = deprecationLoggerEnd;
9
+
10
+ var _logger = require("./logger");
11
+
12
+ function deprecateMessage(message) {
13
+ // eslint-disable-next-line no-use-before-define
14
+ deprecationLoggerStart();
15
+ (0, _logger.messageLogger)('\x1b[36m%s\x1b[0m', message);
16
+ }
17
+
18
+ function printLine() {
19
+ deprecateMessage('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n ');
20
+ }
21
+
22
+ let isFirstDeprecation = false;
23
+
24
+ function deprecateOption(previousObjPath = '', newObjPath = '', message = '') {
25
+ deprecateMessage(`Please move "${previousObjPath.split('.').join(' > ')}" to "${newObjPath.split('.').join(' > ')}" following option ${message}`);
26
+ }
27
+
28
+ function deprecationLoggerStart() {
29
+ if (!isFirstDeprecation) {
30
+ isFirstDeprecation = true;
31
+ printLine();
32
+ }
33
+ }
34
+
35
+ function deprecationLoggerEnd() {
36
+ if (isFirstDeprecation) {
37
+ isFirstDeprecation = false;
38
+ printLine();
39
+ }
40
+ }
@@ -11,41 +11,42 @@ var _cssClassNameGenerate = _interopRequireDefault(require("../utils/cssClassNam
11
11
 
12
12
  var _utils = require("../utils");
13
13
 
14
- var _windowsModification = require("./windowsModification");
14
+ var _fileHandling = require("../plugins/utils/fileHandling");
15
15
 
16
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
17
 
18
18
  const fs = require('fs');
19
19
 
20
20
  const options = (0, _utils.getOptions)();
21
+ const defaultPostCssPluginOrder = ['valueReplacer', 'selectorReplace', 'hasRTL', 'hoverActive', 'combinerMediaQuery', 'cssVariableReplacement', 'selectorWeight', 'minifier', 'composeMinification'];
21
22
 
22
- function excludeEmptyCheckPlugin({
23
- enable,
24
- ignore,
25
- plugins
26
- }) {
27
- return enable ? ignore.length === 0 ? plugins : [require('../postcss-plugins/ExcludePlugin')({
28
- ignore,
29
- plugins
30
- })] : [];
23
+ function calculatePostCssPluginOrder(postCssPluginOrder, pluginOrder) {
24
+ // if(typeof postCssPluginOrder === Boolean)
25
+ if (Array.isArray(postCssPluginOrder)) {
26
+ return postCssPluginOrder;
27
+ }
28
+
29
+ if (postCssPluginOrder) {
30
+ return pluginOrder;
31
+ }
32
+
33
+ return defaultPostCssPluginOrder.filter(value => pluginOrder.includes(value));
31
34
  }
32
35
 
33
36
  const getCSSLoaders = optionsObj => {
34
37
  const {
35
38
  plugins,
36
- exclude,
39
+ patterns,
37
40
  mediaQueryHoverActiveString,
38
41
  cssVariableReplacementConfig,
39
42
  classNameBlob,
40
43
  cssUniqueness,
41
44
  selectorReplace,
42
45
  cssHashSelectors,
43
- classNamePrefix
44
- } = optionsObj; // console.log('plugins:')
45
- // console.log(plugins)
46
- // console.log('exclude:')
47
- // console.log(exclude)
48
-
46
+ classNamePrefix,
47
+ postCssPluginOrder,
48
+ customClassNamePrefix
49
+ } = optionsObj;
49
50
  const {
50
51
  devCssFileBountry
51
52
  } = options.app;
@@ -55,10 +56,6 @@ const getCSSLoaders = optionsObj => {
55
56
  const {
56
57
  cssSelectorZipPath
57
58
  } = options.impactService;
58
- const rtlExcludeLocal = (0, _windowsModification.windowsModification)(exclude.rtl);
59
- const hoverActiveExcludeLocal = (0, _windowsModification.windowsModification)(exclude.hoverActive);
60
- const combinerMediaQueryExcludeLocal = (0, _windowsModification.windowsModification)(exclude.combinerMediaQuery);
61
- const cssVariableReplacementExcludeLocal = (0, _windowsModification.windowsModification)(exclude.cssVariableReplacement);
62
59
  const cssLoaderOptions = {
63
60
  // importLoaders: hasRTL||hoverActive ? 1 : 0,
64
61
  importLoaders: 1,
@@ -69,35 +66,23 @@ const getCSSLoaders = optionsObj => {
69
66
  if (classNameBlob) {
70
67
  cssLoaderOptions.modules.localIdentName = classNameBlob;
71
68
  } else {
72
- cssLoaderOptions.modules.getLocalIdent = (0, _cssClassNameGenerate.default)(cssUniqueness, cssHashSelectors, classNamePrefix);
73
- } // console.log('selector weight config : ', selectorWeightConfig);
69
+ cssLoaderOptions.modules.getLocalIdent = (0, _cssClassNameGenerate.default)(cssUniqueness, cssHashSelectors, classNamePrefix, customClassNamePrefix, patterns);
70
+ }
74
71
 
72
+ const pluginOrder = calculatePostCssPluginOrder(postCssPluginOrder, Object.keys(plugins).filter(x => plugins[x] === true)); // console.log('selector weight config : ', selectorWeightConfig);
75
73
 
76
- const postcssPlugins = [valueReplacer && require('../postcss-plugins/ValueReplacer')(valueReplacer), selectorReplace && require('postcss-selector-replace')(selectorReplace), ...excludeEmptyCheckPlugin({
77
- enable: plugins.hasRTL,
78
- ignore: rtlExcludeLocal,
79
- plugins: [require('@zohodesk/postcss-rtl')({
80
- addPrefixToSelector: function addPrefixToSelector(selector, prefix) {
81
- if (prefix === '[dir]') {
82
- return selector;
83
- }
84
-
85
- return `${prefix} ${selector}`; // Make selectors like [dir=rtl] > .selector
74
+ const postcssPlugins = [plugins.valueReplacer && require('../postcss-plugins/ValueReplacer')(valueReplacer), plugins.hasRTL && require('@zohodesk/postcss-rtl')({
75
+ addPrefixToSelector: function addPrefixToSelector(selector, prefix) {
76
+ if (prefix === '[dir]') {
77
+ return selector;
86
78
  }
87
- })]
88
- }), ...excludeEmptyCheckPlugin({
89
- enable: plugins.combinerMediaQuery,
90
- ignore: combinerMediaQueryExcludeLocal,
91
- plugins: [require('postcss-combine-media-query')]
92
- }), ...excludeEmptyCheckPlugin({
93
- enable: plugins.hoverActive,
94
- ignore: hoverActiveExcludeLocal,
95
- plugins: [require('../postcss-plugins/hoverActivePlugin')(mediaQueryHoverActiveString)]
96
- }), ...excludeEmptyCheckPlugin({
97
- enable: plugins.cssVariableReplacement,
98
- ignore: cssVariableReplacementExcludeLocal,
99
- plugins: [fs.existsSync(cssVariableReplacementConfig) && require('../postcss-plugins/variableModificationPlugin/index').plugin(cssVariableReplacementConfig)]
100
- })].filter(Boolean);
79
+
80
+ return `${prefix} ${selector}`; // Make selectors like [dir=rtl] > .selector
81
+ }
82
+ }), plugins.selectorReplace && require('../postcss-plugins/SelectorReplace')(selectorReplace), plugins.combinerMediaQuery && require('postcss-combine-media-query')(), plugins.hoverActive && require('../postcss-plugins/hoverActivePlugin')(mediaQueryHoverActiveString), plugins.cssVariableReplacement && fs.existsSync(cssVariableReplacementConfig) && require('../postcss-plugins/variableModificationPlugin/index').plugin(cssVariableReplacementConfig) // ,
83
+ // plugins.composeMinification &&
84
+ // require('../postcss-plugins/composePlugin')()
85
+ ].filter(Boolean);
101
86
  return [cssSelectorZipPath && {
102
87
  loader: require.resolve('../loaders/selectorMappingLoader')
103
88
  }, {
@@ -117,10 +102,74 @@ const getCSSLoaders = optionsObj => {
117
102
  loader: 'postcss-loader',
118
103
  options: {
119
104
  ident: 'postcss',
120
- plugins: function () {
121
- return postcssPlugins;
105
+ plugins: function (params) {
106
+ // console.log('check here : ', params.resourcePath);
107
+ // getCSSLoaders for all postcss filtering
108
+
109
+ /*
110
+ input :
111
+ params.resourcePath : 'D:/MyWork/..../desk_client_app/supportapp/src/components/Avatar/Avatar.module.css,
112
+ patterns : [
113
+ // include all files
114
+ "valueReplacer": [
115
+ "*"
116
+ ],
117
+ // include all files
118
+ "selectorReplace": [
119
+ "*"
120
+ ],
121
+ // include src folder, include deskapp folder, exclude node modules
122
+ "hoverActive": [
123
+ "src",
124
+ "deskapp",
125
+ "!node_modules"
126
+ ],
127
+ // include src folder, include deskapp folder, exclude node modules
128
+ "combinerMediaQuery": [
129
+ "src",
130
+ "deskapp",
131
+ "!node_modules"
132
+ ],
133
+ // include src folder, include deskapp folder, exclude node modules
134
+ "hasRTL": [
135
+ "src",
136
+ "deskapp",
137
+ "!node_modules"
138
+ ],
139
+ // include src folder, include deskapp folder, exclude node modules
140
+ "cssVariableReplacement": [
141
+ "src",
142
+ "deskapp",
143
+ "!node_modules"
144
+ ],
145
+ // include src folder, include deskapp folder, exclude node modules
146
+ "selectorWeight": [
147
+ "src",
148
+ "deskapp",
149
+ "!node_modules"
150
+ ],
151
+ // include all files
152
+ "cssUniqueness": [
153
+ "*"
154
+ ]
155
+ ],
156
+
157
+ [ postcssPlugins that are implemented ]
158
+ */
159
+ // console.log(params.resourcePath);
160
+ // console.log(postcssPlugins);
161
+ const finalPostcssPlugins = (0, _fileHandling.isFileNameMatchingPattern)({
162
+ filename: params.resourcePath,
163
+ filterObject: patterns,
164
+ plugins: postcssPlugins,
165
+ order: pluginOrder
166
+ }); // postcssPlugins that are allowed
167
+
168
+ return finalPostcssPlugins.length > 0 ? finalPostcssPlugins : [require('../postcss-plugins/EmptyPlugin')()];
122
169
  }
123
170
  }
171
+ } : null, plugins.composeMinification ? {
172
+ loader: require.resolve('../loaders/composeLoader')
124
173
  } : null].filter(Boolean);
125
174
  };
126
175
 
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ const {
4
+ windowsModificationFile
5
+ } = require('../windowsModification');
6
+
7
+ const tests = ['D:\\MyWork\\React Build\\desk_client_app\\jsapps\\supportapp\\src\\components\\Accessibility\\Accessibility.module.css', 'D:/MyWork/React Build/desk_client_app/jsapps/supportapp/src/components/Accessibility/Accessibility.module.css', 'desk_client_app\\jsapps\\supportapp\\src\\components\\Accessibility\\Accessibility.module.css', 'desk_client_app/jsapps/supportapp/src/components/Accessibility/Accessibility.module.css', 'src\\components\\Accessibility\\Accessibility.module.css', 'src/components/Accessibility/Accessibility.module.css', 'Accessibility.module.css', ''];
8
+ tests.forEach(test => {
9
+ console.log(windowsModificationFile(test));
10
+ });
@@ -4,8 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.windowsModification = windowsModification;
7
+ exports.windowsModificationFile = windowsModificationFile;
7
8
  const isWin = process.platform === 'win32';
8
9
 
9
10
  function windowsModification(array) {
10
11
  return isWin ? array && Array.isArray(array) && array.map(r => r.replace(/\//g, '\\')) : array;
11
- }
12
+ }
13
+
14
+ function windowsModificationFile(filename) {
15
+ return isWin ? filename.replace(/\//g, '\\') : filename;
16
+ } // module.exports = { windowsModification, windowsModificationFile };
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+
3
+ const {
4
+ markdownParser
5
+ } = require('../markdownLoader'); // Replace './your-file' with the correct file path
6
+
7
+
8
+ describe('markdownParser', () => {
9
+ test('For {}(braces) case', () => {
10
+ const source = `
11
+ /* MD:START
12
+ # {Hi, This is Test Case :)}
13
+ MD:END */
14
+ `;
15
+ const expectedOutput = `
16
+ <><div class="markDown"><h1>&#123;Hi, This is Test Case :)&#125;</h1>
17
+ </div></>
18
+ `;
19
+ expect(markdownParser(source)).toEqual(expectedOutput);
20
+ });
21
+ test('For $ (dollor) case', () => {
22
+ const source = `
23
+ /* MD:START
24
+ # $Hi, This is Test Case :)
25
+ MD:END */
26
+ `;
27
+ const expectedOutput = `
28
+ <><div class="markDown"><h1>&#36;Hi, This is Test Case :)</h1>
29
+ </div></>
30
+ `;
31
+ expect(markdownParser(source)).toEqual(expectedOutput);
32
+ });
33
+ test('For All kind of Tag Cases', () => {
34
+ const source = `
35
+ /* MD:START
36
+ # Markdown File with Variety of Data
37
+
38
+ ## Text
39
+
40
+ This is a paragraph of text.
41
+
42
+ ## Headings
43
+
44
+ ### Heading 1
45
+
46
+ ### Heading 2
47
+
48
+ #### Heading 2.1
49
+
50
+ #### Heading 2.2
51
+
52
+ ## Lists
53
+
54
+ ### Unordered List
55
+
56
+ - Item 1
57
+ - Item 2
58
+ - Item 3
59
+
60
+ ### Ordered List
61
+
62
+ 1. First item
63
+ 2. Second item
64
+ 3. Third item
65
+
66
+ ## Links
67
+
68
+ Here's a link to [OpenAI's website](https://openai.com).
69
+
70
+ ## Images
71
+
72
+ ![Markdown Logo](https://upload.wikimedia.org/wikipedia/commons/4/48/Markdown-mark.svg)
73
+
74
+ ## Tables
75
+
76
+ | Name | Age | Gender |
77
+ |-------|-----|--------|
78
+ | John | 25 | Male |
79
+ | Sarah | 30 | Female |
80
+ | Mark | 35 | Male |
81
+
82
+ MD:END */
83
+ `;
84
+ const expectedOutput = `
85
+ <><div class="markDown"><h1>Markdown File with Variety of Data</h1>
86
+ <h2>Text</h2>
87
+ <p>This is a paragraph of text.</p>
88
+ <h2>Headings</h2>
89
+ <h3>Heading 1</h3>
90
+ <h3>Heading 2</h3>
91
+ <h4>Heading 2.1</h4>
92
+ <h4>Heading 2.2</h4>
93
+ <h2>Lists</h2>
94
+ <h3>Unordered List</h3>
95
+ <ul>
96
+ <li>Item 1</li>
97
+ <li>Item 2</li>
98
+ <li>Item 3</li>
99
+ </ul>
100
+ <h3>Ordered List</h3>
101
+ <ol>
102
+ <li>First item</li>
103
+ <li>Second item</li>
104
+ <li>Third item</li>
105
+ </ol>
106
+ <h2>Links</h2>
107
+ <p>Here's a link to <a href="https://openai.com">OpenAI's website</a>.</p>
108
+ <h2>Images</h2>
109
+ <p><img src="https://upload.wikimedia.org/wikipedia/commons/4/48/Markdown-mark.svg" alt="Markdown Logo"/></p>
110
+ <h2>Tables</h2>
111
+ <table>
112
+ <thead>
113
+ <tr>
114
+ <th>Name</th>
115
+ <th>Age</th>
116
+ <th>Gender</th>
117
+ </tr>
118
+ </thead>
119
+ <tbody>
120
+ <tr>
121
+ <td>John</td>
122
+ <td>25</td>
123
+ <td>Male</td>
124
+ </tr>
125
+ <tr>
126
+ <td>Sarah</td>
127
+ <td>30</td>
128
+ <td>Female</td>
129
+ </tr>
130
+ <tr>
131
+ <td>Mark</td>
132
+ <td>35</td>
133
+ <td>Male</td>
134
+ </tr>
135
+ </tbody>
136
+ </table>
137
+ </div></>
138
+ `;
139
+ expect(markdownParser(source)).toEqual(expectedOutput);
140
+ });
141
+ test('For Source null case', () => {
142
+ expect(markdownParser(null)).toEqual('');
143
+ expect(markdownParser('')).toEqual('');
144
+ });
145
+ });