Skip to content

Version 1.6.0 - #212

Merged
melnalex merged 12 commits into
masterfrom
dev
Sep 19, 2026
Merged

melnalex merged 12 commits into
masterfrom
dev

Conversation

@melnalex

Copy link
Copy Markdown
Collaborator

No description provided.

melnalex and others added 12 commits August 5, 2026 22:33
The default string cell renderer swapped \n for a visible U+21B5 glyph but left
the \r of a CRLF behind. The innerText setter then turned that stray \r into a
<br>, which overrides the cell's `white-space: nowrap` and pushes the rest of the
value onto a second line that the fixed row height clips. Northwind employee
addresses are stored with a CRLF in them and rendered exactly that way, so
widening the column never revealed any more text.

Match CRLF, lone CR and lone LF, and keep the original value in the tooltip so
the full multi-line text stays readable on hover.

Co-Authored-By: Claude <noreply@anthropic.com>
…0-rc01 / 1.6.0.1)

The .NET version is declared in easydata.net/version.json and copied into
src/Directory.Build.props by tools/SetVersionInCsproj.ps1. That step was last
run for 1.5.9, so the props file kept stamping 1.5.9 / 1.5.9.1 through the
1.5.10, 1.5.11, 1.5.12 and 1.6.0-rc01 releases.

Anything that project-references EasyData from source while also resolving an
EasyData.* NuGet package - the EasyQuery playground, for one - then mixed
1.5.9.1 assemblies with code compiled against 1.6.0.1 and failed at startup
with FileNotFoundException for EasyData.Core 1.6.0.1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…m ci

`npm install` failed with "Cannot read properties of null (reading 'edgesOut')"
inside arborist's #loadPeerSet. The unused @vitest/ui@4 devDependency pins
vitest@4.1.11, while an optional peer chain through vite's @vitejs/devtools
asks for vitest@*, which now resolves to the newly published vitest 5.0.0.
The two vitest versions collide in one peer set and npm crashes instead of
reporting ERESOLVE. Tests run on @olton/latte, so @vitest/ui is removed.

@easydata/bundle-crud depended on @easydata/crud@^1.5.2, which the workspace
version 1.6.0-rc01 (a prerelease) does not satisfy, so npm pulled crud 1.5.11
from the registry instead of linking the local package. It now uses "*", like
the playground projects and the packs' peer dependencies.

The root package-lock.json is now committed (nested lockfiles stay ignored)
and CI (js-build.yml) and setup-dev.bat restore with `npm ci`, so a registry
release can no longer change the dependency tree of a build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… merge

Merge 4fe564a doubled 23 lines in this file, including eight `it(...)`
openers. Each doubled opener left one callback unclosed, so esbuild failed
with "Unexpected end of file" and the @easydata/crud test run aborted.
Drop the duplicates and keep the four comment translations the merge
brought in. Test intent is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The crud tests still called jest.spyOn / restoreAllMocks / fake timers,
which do not exist under latte, so every beforeEach threw
"jest is not defined". Add tests/helpers/mocks.ts with latte-based
equivalents and use it throughout:

- spyOn / restoreAllMocks, with Jest's persistent mockReturnValue
  (latte's version queues a value for a single call); setReturnValue
  gives existing latte mocks the same behaviour.
- useFakeTimers / advanceTimersByTime / runAllTimers / useRealTimers,
  patching both globalThis and window since they differ under latte.
- stubSetLocation: this package's own module exports are read-only
  getters under tsx and cannot be spied on, so setLocation is observed
  through the history.pushState call it makes. For the same reason the
  validators test mocks i18n.getLocaleSettings instead of
  getEditDateTimeFormat.

Also wrap toHaveBeenCalledWith arguments in an array (latte's form),
replace expect.anything() with a check on the path argument, and
re-enable the spies that had been commented out in entity_data_view
and easy_data_view_dispatcher. The prototype 'constructor' spies were
dropped: they never intercepted `new`, even under jest.

Result: 94 of 134 tests pass (was 64). The re-enabled "should start and
load metadata" test now fails like its siblings on
"XMLHttpRequest is not a constructor". The remaining 40 failures are
unrelated to jest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
EasyDataBasicDemo.React.Net6 becomes EasyDataBasicDemo.React.Net10. The server targets net10.0 with EF Core / SpaProxy 10.0.12, EasyData 1.5.12 and Korzh.DbUtils 1.4.3; the unused Razor Error page is removed and the app maps controllers instead of views.

The client moves from create-react-app 4 to Vite 8 with React 19.3, react-router 7.18, Bootstrap 5.3 and @easydata/* 1.5.11. The dev proxy and the ASP.NET Core dev certificate setup now live in vite.config.js, which removes http-proxy-middleware 0.19 (Dependabot alert #13, CVE-2024-21536) together with the service worker, workbox, web-vitals, jquery, oidc-client and eslint 7 leftovers. Components are function components; the EasyData route matches /easydata/* so the view survives EasyData's own navigation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Most failures came from assumptions that do not hold under latte and its
jsdom environment:
- toBeObject(expected) compares two objects and toThrow(msg) takes a
  failure message, so a bare toBeObject() always failed and
  toThrow(pattern) never checked the error. Use toBeType('object') and a
  thrownMessage() helper (the sources throw plain strings, which
  toThrowError() cannot read).
- window.location cannot be replaced and a class prototype cannot be
  redefined, so two beforeEach hooks threw halfway. Navigate with
  history.replaceState, and stub `new EasyGrid()` through the CommonJS
  exports of @easydata/ui.
- latte's mockReturnValue answers a single call: use mock(() => value).
- jsdom ignores innerText: tests/helpers/dom.ts maps it to textContent.
- The entity view builds its grid asynchronously: flush pending promises
  before asserting and before a test ends.
- The DataContext HTTP mock was a fake thenable that passed the raw
  response to every callback: use a resolved Promise.

Some expectations did not match the code and were corrected without
changing what they test: the invalid-time example ('14.30' is accepted,
as any separator is), the multiple-matches node count (the ends are
empty text nodes), the clear-icon test (the filter must hold a value for
clearing to apply it), the DataFilter instanceof check (an interface),
the 'fruit' search (Orange is "Juicy citrus"), the edit-form date (typed
in the locale's edit format), history.state (read-only) and the table's
columns (no setter).

Also fix EasyDataTable: rows given in options.rows went through
createRow, which reads values by column id, so array rows came out as
all undefined. Pass them to addRow, which handles arrays, objects and
DataRows. The core suite is unchanged (the same 84 failures before and
after).

@easydata/crud: 134 of 134 tests pass (was 94).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Source bugs:
- TimeValue.asTime() did not return the special date, and the `name`
  getter called itself forever.
- strEndsWith() returned '' or null instead of false, and reported that
  'a' ends with 'ab'. combinePath() doubled the slash when both parts had
  one.
- getFirstPrimaryAttr() returned undefined instead of the declared null.
- MetaEntityAttr ignored `ivis: false` (`ivis || sov` dropped the false).
- ValueEditor.loadFromData() overwrote the defaults with undefined for
  whatever an incomplete DTO left out.
- MetaData never initialized `editors` (addDefaultValueEditors crashed),
  and checkAttrProperty() could return a string instead of a boolean.
- assignDeep() lost a reference back to its top-level source.
- strToTime() read the minutes again for the seconds.
- A table built from `rows` with no loader threw on reads past its data;
  it now holds all its data in memory.
- HttpRequest encoded the whole query with encodeURI, so ',' '&' '=' in
  values were not escaped; encode each key and value instead.
- HttpClient created a throwaway XMLHttpRequest to detect the IE
  fallback, and an operator-precedence slip ignored options.contentType.
- addAggregateColumn() reported a column already in use as an invalid
  aggregation function.
- i18n.resetLocales() only initialized the locales once and never reset
  them. It now always resets to the default en-US locale (its only
  caller, at load, behaves as before).

Test fixes for latte: error checks through a thrown()/thrownMessage()
helper (toThrow() takes no expected value), plain objects instead of
mock({...}) (which returns a function), deep/array matchers instead of
toBeEqual(), toHaveBeenCalledWith() arguments as one array, mockReset()
instead of mockClear(), a local fail(), the XMLHttpRequest stub on the
global object, a Date mock that keeps `instanceof Date` working, and i18n
initialized as the package entry point does.

Expectations corrected to what the code does by design: the real
HttpMethod/EditorTag members, the scan() stop flag (opts.stop), the
squeezed generateId() prefix, '#' vs '0' number masks, browser-derived
short date/time formats, a null value in isPropSet(), and the tree root
id (the root entity's name).

@easydata/core: 322 of 322 tests pass (was 238). @easydata/crud still
passes 134 of 134 against the rebuilt core.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
__tests__/ui.test.js only logged a message, imported Vitest (no longer a
dependency) and never ran: the test script includes *.test.ts only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
44c73d5 moved the declaration output of core, ui and crud from dist/types
to dist, and 0d1f533 updated core's "types" field to match, but ui and
crud still pointed at dist/types/public_api.d.ts, which is never built.
TypeScript then fell back to the bundled JS and lost the inherited
members of DomElementBuilder, so the @easyquery/ui build reported TS2339
errors for DomDropDownElementBuilder (attr, on, element, addText).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both sides go final: packageVersion 1.6.0 / assemblyVersion 1.6.0.2 on the
.NET side, version 1.6.0 on the JS side with the npm dist-tag switched from
beta to latest - without that switch 1.6.0 would publish under the beta tag
and latest would stay on 1.5.11. The pack manifests are stamped by
`npm run setver`, and Directory.Build.props is synced the way CI stamps it.

assetVersion stays at 01_06_01: it is set once when a cycle opens and no
final-release commit has ever changed it.

The changelog entry below belongs to ad164be, which landed without a tag
prefix. AistDoc collects such entries from commit bodies too, so the line
reaches the 1.6.0 release notes without rewriting that commit.

[fix]: Multi-line grid cells no longer split into a clipped second line - a CR left over from a CRLF was rendered as a <br> by the default cell renderer
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
19.8% Duplication on New Code (required ≤ 3%)
B Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@melnalex
melnalex merged commit c17d417 into master Sep 19, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants