react-native-navigation的迁移库

LayoutTreeCrawler.test.ts 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import { LayoutType } from './LayoutType';
  2. import { LayoutTreeCrawler, LayoutNode } from './LayoutTreeCrawler';
  3. import { UniqueIdProvider } from '../adapters/UniqueIdProvider.mock';
  4. import { Store } from '../components/Store';
  5. describe('LayoutTreeCrawler', () => {
  6. let uut;
  7. let store;
  8. beforeEach(() => {
  9. store = new Store();
  10. uut = new LayoutTreeCrawler(new UniqueIdProvider(), store);
  11. });
  12. it('crawls a layout tree and adds unique id to each node', () => {
  13. const node: any = { type: LayoutType.Stack, children: [{ type: LayoutType.BottomTabs }] };
  14. uut.crawl(node);
  15. expect(node.id).toEqual('Stack+UNIQUE_ID');
  16. expect(node.children[0].id).toEqual('BottomTabs+UNIQUE_ID');
  17. });
  18. it('does not generate unique id when already provided', () => {
  19. const node = { id: 'user defined id', type: LayoutType.Stack };
  20. uut.crawl(node);
  21. expect(node.id).toEqual('user defined id');
  22. });
  23. it('crawls a layout tree and ensures data exists', () => {
  24. const node: any = { type: LayoutType.Stack, children: [{ type: LayoutType.BottomTabs }] };
  25. uut.crawl(node);
  26. expect(node.data).toEqual({});
  27. expect(node.children[0].data).toEqual({});
  28. });
  29. it('crawls a layout tree and ensures children exists', () => {
  30. const node: any = { type: LayoutType.Stack, children: [{ type: LayoutType.BottomTabs }] };
  31. uut.crawl(node);
  32. expect(node.children[0].children).toEqual([]);
  33. });
  34. it('crawls a layout tree and asserts known layout type', () => {
  35. const node = { type: LayoutType.Stack, children: [{ type: 'Bob' }] };
  36. expect(() => uut.crawl(node)).toThrowError('Unknown layout type Bob');
  37. });
  38. it('saves passProps into store for Component nodes', () => {
  39. const node = {
  40. type: LayoutType.BottomTabs, children: [
  41. { type: LayoutType.Component, data: { name: 'the name', passProps: { myProp: 123 } } }]
  42. };
  43. expect(store.getPropsForId('Component+UNIQUE_ID')).toEqual({});
  44. uut.crawl(node);
  45. expect(store.getPropsForId('Component+UNIQUE_ID')).toEqual({ myProp: 123 });
  46. });
  47. it('Components: injects options from original component class static property', () => {
  48. const theStyle = {};
  49. const MyComponent = class {
  50. static get options() {
  51. return theStyle;
  52. }
  53. };
  54. const node: any = { type: LayoutType.Component, data: { name: 'theComponentName' } };
  55. store.setOriginalComponentClassForName('theComponentName', MyComponent);
  56. uut.crawl(node);
  57. expect(node.data.options).toEqual(theStyle);
  58. });
  59. it('Components: merges options from component class static property with passed options, favoring passed options', () => {
  60. const theStyle = {
  61. bazz: 123,
  62. inner: {
  63. foo: 'bar'
  64. },
  65. opt: 'exists only in static'
  66. };
  67. const MyComponent = class {
  68. static get options() {
  69. return theStyle;
  70. }
  71. };
  72. const passedOptions = {
  73. aaa: 'exists only in passed',
  74. bazz: 789,
  75. inner: {
  76. foo: 'this is overriden'
  77. }
  78. };
  79. const node = { type: LayoutType.Component, data: { name: 'theComponentName', options: passedOptions } };
  80. store.setOriginalComponentClassForName('theComponentName', MyComponent);
  81. uut.crawl(node);
  82. expect(node.data.options).toEqual({
  83. aaa: 'exists only in passed',
  84. bazz: 789,
  85. inner: {
  86. foo: 'this is overriden'
  87. },
  88. opt: 'exists only in static'
  89. });
  90. });
  91. it('Component: deepClones options', () => {
  92. const theStyle = {};
  93. const MyComponent = class {
  94. static get options() {
  95. return theStyle;
  96. }
  97. };
  98. const node: any = { type: LayoutType.Component, data: { name: 'theComponentName' } };
  99. store.setOriginalComponentClassForName('theComponentName', MyComponent);
  100. uut.crawl(node);
  101. expect(node.data.options).not.toBe(theStyle);
  102. });
  103. it('Components: must contain data name', () => {
  104. const node = { type: LayoutType.Component, data: {} };
  105. expect(() => uut.crawl(node)).toThrowError('Missing component data.name');
  106. });
  107. it('Components: options default obj', () => {
  108. const MyComponent = class { };
  109. const node: any = { type: LayoutType.Component, data: { name: 'theComponentName' } };
  110. store.setOriginalComponentClassForName('theComponentName', MyComponent);
  111. uut.crawl(node);
  112. expect(node.data.options).toEqual({});
  113. });
  114. describe('navigation options', () => {
  115. let options;
  116. let node;
  117. beforeEach(() => {
  118. options = {};
  119. node = { type: LayoutType.Component, data: { name: 'theComponentName', options } };
  120. });
  121. it('processes colors into numeric AARRGGBB', () => {
  122. options.someKeyColor = 'red';
  123. uut.crawl(node);
  124. expect(node.data.options.someKeyColor).toEqual(0xffff0000);
  125. });
  126. it('processes colors into numeric AARRGGBB', () => {
  127. options.someKeyColor = 'yellow';
  128. uut.crawl(node);
  129. expect(node.data.options.someKeyColor).toEqual(0xffffff00);
  130. });
  131. it('processes numeric colors', () => {
  132. options.someKeyColor = '#123456';
  133. uut.crawl(node);
  134. expect(node.data.options.someKeyColor).toEqual(0xff123456);
  135. });
  136. it('processes numeric colors with rrggbbAA', () => {
  137. options.someKeyColor = 0x123456ff; // wut
  138. uut.crawl(node);
  139. expect(node.data.options.someKeyColor).toEqual(0xff123456);
  140. });
  141. it('process colors with rgb functions', () => {
  142. options.someKeyColor = 'rgb(255, 0, 255)';
  143. uut.crawl(node);
  144. expect(node.data.options.someKeyColor).toEqual(0xffff00ff);
  145. });
  146. it('process colors with special words', () => {
  147. options.someKeyColor = 'fuchsia';
  148. uut.crawl(node);
  149. expect(node.data.options.someKeyColor).toEqual(0xffff00ff);
  150. });
  151. it('process colors with hsla functions', () => {
  152. options.someKeyColor = 'hsla(360, 100%, 100%, 1.0)';
  153. uut.crawl(node);
  154. expect(node.data.options.someKeyColor).toEqual(0xffffffff);
  155. });
  156. it('unknown colors return undefined', () => {
  157. options.someKeyColor = 'wut';
  158. uut.crawl(node);
  159. expect(node.data.options.someKeyColor).toEqual(undefined);
  160. });
  161. it('any keys ending with Color', () => {
  162. options.otherKeyColor = 'red';
  163. options.yetAnotherColor = 'blue';
  164. options.andAnotherColor = 'rgb(0, 255, 0)';
  165. uut.crawl(node);
  166. expect(node.data.options.otherKeyColor).toEqual(0xffff0000);
  167. expect(node.data.options.yetAnotherColor).toEqual(0xff0000ff);
  168. expect(node.data.options.andAnotherColor).toEqual(0xff00ff00);
  169. });
  170. it('keys ending with Color case sensitive', () => {
  171. options.otherKey_color = 'red'; // eslint-disable-line camelcase
  172. uut.crawl(node);
  173. expect(node.data.options.otherKey_color).toEqual('red');
  174. });
  175. it('any nested recursive keys ending with Color', () => {
  176. options.innerObj = { theKeyColor: 'red' };
  177. options.innerObj.innerMostObj = { anotherColor: 'yellow' };
  178. uut.crawl(node);
  179. expect(node.data.options.innerObj.theKeyColor).toEqual(0xffff0000);
  180. expect(node.data.options.innerObj.innerMostObj.anotherColor).toEqual(0xffffff00);
  181. });
  182. });
  183. describe('LayoutNode', () => {
  184. it('convertable from same data structure', () => {
  185. const x = {
  186. id: 'theId',
  187. type: LayoutType.Component,
  188. data: {},
  189. children: []
  190. };
  191. let got;
  192. function expectingLayoutNode(param: LayoutNode) {
  193. got = param;
  194. }
  195. expectingLayoutNode(x);
  196. expect(got).toBe(x);
  197. });
  198. });
  199. });