@mcpher/gas-fakes 1.0.11 → 1.0.12

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.
package/README.md CHANGED
@@ -794,9 +794,10 @@ The Sheets API doesn't know about these, so all r1c1 style methods such as setFo
794
794
 
795
795
  #### Intial verdict on using Gemini to generate some of this stuff
796
796
 
797
- I'm torn. On the one hand, it's been great at doing busy work like writing test cases and detecting dependencies that I might otherwise have missed. It can often be pretty good at refactoring/renaming things. On the other hand, if it gets it wrong, it's very hard to get it back on track as it tries bury itself deeper and deeper into previous misconceptions. It also has huge difficulty in updating large files no matter the detailed guidance. The usual end game is to restart a fresh context and/or copy and paste the content into a file you create manually.
797
+ I'm torn. On the one hand, it's been great at doing busy work like writing test cases and detecting dependencies that I might otherwise have missed. It can often be pretty good at refactoring/renaming things. On the other hand, if it gets it wrong, it's very hard to get it back on track as it tries bury itself deeper and deeper into previous misconceptions. It also has huge difficulty in updating large files no matter the detailed guidance. The usual end game is to restart a fresh context and/or copy and paste the content into a file you create manually.
798
+
799
+ There were ocassions when the content Gemini provided content to be copied and pasted that was invalid syntax, or worse, dropped lines of code in sections it didn't plan to make any changes. In particular, code that had something like `ob[method](args)` was regularily truncated to just `ob`. Another issue is that Gemini can take 10-15 mins to create the full content for a large class in its chat window, sometimes ending in the gray screen of death. It's best to avoid using Gemini to make minor changes, but to just make them manually.
798
800
 
799
- There were ocassions when the content Gemini provided content to be copied and pasted that was invalid syntax, or worse, dropped lines of code in sections it didn't plan to make any changes. In particular, code that had something like `ob[method](args)` was regularily truncated to just `ob`
800
801
 
801
802
  Overall it saves some time, for sure. However, the result is often suboptimal, wordy, lacking in reusability and not something I would be be happy to put my name to. From a coder perspective, the role becomes one of repetetive specification, debugging, checking and testing, while failing to develop a deep understanding of the work in hand. I like coding, so from a satisfaction perspective, I'm not entirely convinced yet. I've found it's very impressive when creating small, standalone scripts but deteriorates rapidly both in speed and effectiveness as the codebase and dependencies grows. There's a point at which it becomes more trouble than it's worth.
802
803
 
package/package.json CHANGED
@@ -41,7 +41,7 @@
41
41
  "pub": "cp mainlocal.js main.js && npm publish --access public"
42
42
  },
43
43
  "name": "@mcpher/gas-fakes",
44
- "version": "1.0.11",
44
+ "version": "1.0.12",
45
45
  "license": "MIT",
46
46
  "main": "main.js",
47
47
  "description": "A proof of concept implementation of Apps Script Environment on Node",
@@ -3,6 +3,8 @@ import { newFakeDriveFile } from './fakedrivefile.js'
3
3
  import { newFakeFolderApp } from './fakefolderapp.js'
4
4
  import { notYetImplemented, isFolder } from '../../support/helpers.js'
5
5
  import { Proxies } from '../../support/proxies.js'
6
+ import { getPerformance } from '../../support/filecache.js';
7
+
6
8
  /**
7
9
  * basic fake DriveApp
8
10
  * @class FakeDriveApp
@@ -17,6 +19,10 @@ export class FakeDriveApp {
17
19
  this.__settleClass = (file) => isFolder(file) ? newFakeDriveFolder(file) : newFakeDriveFile(file)
18
20
  }
19
21
 
22
+ // exposes cache performance to tests
23
+ __getPerformance() {
24
+ return getPerformance()
25
+ }
20
26
 
21
27
  toString() {
22
28
  return 'Drive'
@@ -80,7 +80,6 @@ export class FakeSheetRange {
80
80
  'getDataSourceFormula',
81
81
  'activateAsCurrentCell',
82
82
  'setComments',
83
- 'setShowHyperlink',
84
83
 
85
84
  'createDataSourceTable',
86
85
  'getComments',
@@ -1310,7 +1309,7 @@ export class FakeSheetRange {
1310
1309
  const unionLeft = Math.min(startCol0, left);
1311
1310
  const unionBottom = Math.max(endRow0, bottom);
1312
1311
  const unionRight = Math.max(endCol0, right);
1313
- return sheet.getRange(unionTop + 1, unionLeft + 1, unionBottom - unionTop + 1, unionRight - unionLeft + 1);
1312
+ return sheet.getRange(unionTop + 1, unionLeft + 1, unionBottom - unionTop + 1, unionRight - left + 1);
1314
1313
  }
1315
1314
  return sheet.getRange(top + 1, left + 1, bottom - top + 1, right - left + 1);
1316
1315
  }
@@ -32,17 +32,17 @@ export class FakeSheetRangeList {
32
32
  const props = [
33
33
  'clearDataValidations',
34
34
  'setFontWeight',
35
-
35
+
36
36
  'activate',
37
37
  'breakApart',
38
38
  'setFormulaR1C1',
39
-
39
+
40
40
  'setBorder',
41
41
  'setFontColor',
42
42
  'setFontLine',
43
43
  'setFontStyle',
44
44
  'setWrap',
45
- 'setShowHyperlink',
45
+
46
46
  'setVerticalText',
47
47
  'setWrapStrategy',
48
48
  'uncheck',
@@ -76,6 +76,11 @@ export class FakeSheetRangeList {
76
76
  return 'RangeList'
77
77
  }
78
78
 
79
+ setShowHyperlink(showHyperlink) {
80
+ this.__ranges.forEach(r => r.setShowHyperlink(showHyperlink));
81
+ return this;
82
+ }
83
+
79
84
  /**
80
85
  * getRanges() https://developers.google.com/apps-script/reference/spreadsheet/range-list#getranges
81
86
  * Returns a list of one or more Range instances in the same sheet.
@@ -94,12 +99,12 @@ export class FakeSheetRangeList {
94
99
  return this;
95
100
  }
96
101
 
97
- setBackground (color) {
102
+ setBackground(color) {
98
103
  this.__ranges.forEach(r => r.setBackground(color))
99
104
  return this
100
105
  }
101
-
102
- setBackgroundRGB (red, green, blue) {
106
+
107
+ setBackgroundRGB(red, green, blue) {
103
108
  this.__ranges.forEach(r => r.setBackgroundRGB(red, green, blue))
104
109
  return this
105
110
  }
@@ -8,6 +8,8 @@ import { newFakeTextStyleBuilder } from '../commonclasses/faketextstylebuilder.j
8
8
  import { newFakeFilterCriteriaBuilder } from './fakefiltercriteriabuilder.js'
9
9
  import { newFakeDataValidationBuilder } from './fakedatavalidationbuilder.js'
10
10
  import { newFakeDataSourceSpecBuilder } from './fakedatasourcespecbuilder.js';
11
+ import { getSheetsPerformance } from '../../support/sheetscache.js';
12
+
11
13
 
12
14
  import * as Enums from '../enums/sheetsenums.js'
13
15
 
@@ -90,7 +92,7 @@ export class FakeSpreadsheetApp {
90
92
  'setActiveRangeList',
91
93
  'newCellImage',
92
94
  'getUi',
93
- 'flush',
95
+
94
96
  'open',
95
97
 
96
98
  'ChartAggregationType',
@@ -105,6 +107,12 @@ export class FakeSpreadsheetApp {
105
107
  })
106
108
 
107
109
  }
110
+
111
+ // exposes cache performance to tests
112
+ __getSheetsPerformance() {
113
+ return getSheetsPerformance()
114
+ }
115
+
108
116
 
109
117
  enableBigQueryExecution() {
110
118
  const { nargs, matchThrow } = signatureArgs(arguments, "SpreadsheetApp.enableBigQueryExecution");
@@ -123,7 +131,10 @@ export class FakeSpreadsheetApp {
123
131
  if (nargs) matchThrow();
124
132
  // This is a no-op in the fake environment.
125
133
  }
126
-
134
+ // currently no-op - probably not required as all ops are synchronous and currently not bundled
135
+ flush () {
136
+ return this
137
+ }
127
138
  /**
128
139
  * this one is probably deprecated
129
140
  * @param {string} id file id
@@ -317,7 +317,20 @@ export const setterList = [{
317
317
  maker: (_, value) => makeCellDataFromRichTextValue(value),
318
318
  fields: 'userEnteredValue,textFormatRuns,userEnteredFormat',
319
319
  typeChecker: isRichTextValue
320
- }]
320
+ }, {
321
+ name: 'showHyperlink',
322
+ type: "boolean",
323
+ nullAllowed: false,
324
+ maker: (_, value) => {
325
+ // The API uses LINKED for true (show) and PLAIN_TEXT for false (hide).
326
+ // The live environment throws an error for a null argument, contrary to documentation.
327
+ const displayType = value ? 'LINKED' : 'PLAIN_TEXT';
328
+ return makeCellData('setHyperlinkDisplayType', displayType);
329
+ },
330
+ fields: 'userEnteredFormat.hyperlinkDisplayType',
331
+ plural: false
332
+ }
333
+ ]
321
334
 
322
335
  // this is a list of all the range format getters and how to generate them
323
336
  export const attrGetList = [{
@@ -743,6 +756,7 @@ const isJagged = ({ range, cleaned }) => {
743
756
  return cleaned.length !== nr || cleaned.some(row => row.length !== nc)
744
757
  }
745
758
 
759
+
746
760
  const makeCellData = (method, value) => {
747
761
  const cellFormat = Sheets.newCellFormat()[method](value)
748
762
  const cellData = Sheets.newCellData().setUserEnteredFormat(cellFormat)
@@ -813,7 +827,7 @@ export const makeCellTextFormatData = (prop, value) => {
813
827
  if (!is.function(textFormat[prop])) {
814
828
  throw new Error(`tied to call ${prop} method on textFormat but it's not a function}`)
815
829
  }
816
- if (!is.null(value)) textFormat[prop](value)
830
+ if (!is.null(value)) textFormatprop
817
831
  return makeCellData('setTextFormat', textFormat)
818
832
  }
819
833
 
@@ -114,7 +114,7 @@ const getWhat = (item) => getFakeType(item) || Utils.is(item)
114
114
  */
115
115
  export const argsMatchThrow = ( items, mess = "") => {
116
116
  // limit the error message
117
- const passedTypes = items.map(getWhat).map(Utils.capital).join(",")
117
+ const passedTypes = items.map(getWhat).map(capital).join(",")
118
118
  throw new Error(`The parameters (${passedTypes}) don't match the method ${mess}`)
119
119
  }
120
120
 
@@ -136,14 +136,13 @@ export const signatureArgs = (received, method, objectType = 'Object') => {
136
136
  const nargs = args.length
137
137
 
138
138
  // let's update the passedTypes for the error message to match what GAS does - https://github.com/brucemcpherson/gas-fakes/issues/25
139
- // this throws an error if it inspects an ENUM
140
- // TODO probably need to remove the guard on fake enums
141
- // for now we;ll just catch and ignore
139
+ // this throws an error if it inspects an ENUM - this was an error in sindre's is() which is now fixed
140
+ // we'll just catch and ignore
142
141
  let passedTypes
143
142
  try {
144
- passedTypes = args.map(is).map(capital).map(f=>f==='Object' ? objectType : f)
143
+ passedTypes = args.map(f=>is.null(f) ? 'null' : is(f)).map(f=>f==='null'? f :capital(f)).map(f=>f==='Object' ? objectType : f)
145
144
  } catch (err) {
146
- console.log ("...warning failed signature check- probably an is. probe of an enum - ignoring", args)
145
+ console.log ("...warning failed signature check- probably an unsupported probe. probe of an enum - ignoring", args)
147
146
  passedTypes=[]
148
147
  }
149
148
  const matchThrow = (mess = method) => {