Skip to content

Commit

Permalink
Supporting a new set methods (#3853)
Browse files Browse the repository at this point in the history
  • Loading branch information
inoyakaigor authored Jul 2, 2024
1 parent 5c8066d commit 3efb345
Show file tree
Hide file tree
Showing 9 changed files with 3,837 additions and 3,145 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
- name: Checkout Repo
uses: actions/checkout@master

- name: Setup Node.js 20.x
- name: Setup Node.js 22.x
uses: actions/setup-node@master
with:
node-version: 20.x
node-version: 22.x

- name: Install Dependencies
run: yarn --frozen-lockfile --ignore-scripts
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/coveralls.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0

- name: Setup Node.js 20.x
- name: Setup Node.js 22.x
uses: actions/setup-node@master
with:
node-version: 20.x
node-version: 22.x

- name: Install Dependencies
run: yarn --frozen-lockfile --ignore-scripts
Expand Down
2 changes: 1 addition & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ For verification insert this piece of code at the beginning of your sources (eg.
if (!new class { x }().hasOwnProperty('x')) throw new Error('Transpiler is not configured correctly');
```

Note that for Next.js you must [customize Babel](https://nextjs.org/docs/advanced-features/customizing-babel-config) instead of TypeScript, even if your project is set up to use TypeScript.
Note that for Next.js you must [customize Babel](https://nextjs.org/docs/advanced-features/customizing-babel-config) instead of TypeScript, even if your project is set up to use TypeScript.

## MobX on older JavaScript environments

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
],
"resolutions": {
"jest": "^29.5.0",
"typescript": "^5.0.2",
"typescript": "^5.5.2",
"recast": "^0.23.1"
},
"repository": {
Expand Down Expand Up @@ -68,7 +68,7 @@
"tape": "^5.0.1",
"ts-jest": "^29.0.5",
"tsdx": "^0.14.1",
"typescript": "^5.0.2"
"typescript": "^5.5.2"
},
"husky": {
"hooks": {
Expand Down
10 changes: 5 additions & 5 deletions packages/mobx/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,7 @@ A deprecation message will now be printed if creating computed properties while

```javascript
const x = observable({
computedProp: function() {
computedProp: function () {
return someComputation
}
})
Expand All @@ -1427,7 +1427,7 @@ or alternatively:

```javascript
observable({
computedProp: computed(function() {
computedProp: computed(function () {
return someComputation
})
})
Expand All @@ -1445,7 +1445,7 @@ N.B. If you want to introduce actions on an observable that modify its state, us
```javascript
observable({
counter: 0,
increment: action(function() {
increment: action(function () {
this.counter++
})
})
Expand Down Expand Up @@ -1571,10 +1571,10 @@ function Square() {
extendObservable(this, {
length: 2,
squared: computed(
function() {
function () {
return this.squared * this.squared
},
function(surfaceSize) {
function (surfaceSize) {
this.length = Math.sqrt(surfaceSize)
}
)
Expand Down
139 changes: 139 additions & 0 deletions packages/mobx/__tests__/v5/base/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,142 @@ test("set.forEach is reactive", () => {
s.add(2)
expect(c).toBe(3)
})

describe("The Set object methods do what they are supposed to do", () => {
const reactiveSet = set([1, 2, 3, 4, 5])

test("Observable Set methods returns correct result", () => {
const intersectionObservableResult = reactiveSet.intersection(new Set([1, 2, 6]))
const unionObservableResult = reactiveSet.union(new Set([1, 2, 6]))
const differenceObservableResult = reactiveSet.difference(new Set([1, 2, 3, 4, 5, 6, 7]))
const symmetricDifferenceObservableResult = reactiveSet.symmetricDifference(new Set([3, 4]))
const isSubsetOfObservableResult = reactiveSet.isSubsetOf(new Set([1, 2, 3]))
const isSupersetOfObservableResult = reactiveSet.isSupersetOf(new Set([1, 2, 3, 4, 5, 6]))
const isDisjointFromObservableResult = reactiveSet.isDisjointFrom(new Set([6, 7]))

expect(intersectionObservableResult).toEqual(new Set([1, 2]))
expect(unionObservableResult).toEqual(new Set([1, 2, 3, 4, 5, 6]))
expect(differenceObservableResult).toEqual(new Set())
expect(symmetricDifferenceObservableResult).toEqual(new Set([1, 2, 5]))
expect(isSubsetOfObservableResult).toBeFalsy()
expect(isSupersetOfObservableResult).toBeFalsy()
expect(isDisjointFromObservableResult).toBeTruthy()
})

test("Observable Set proper works with Set-like objects", () => {
const intersectionObservableResult = reactiveSet.intersection(
new Map([1, 2, 6].map(i => [i, i]))
)
const unionObservableResult = reactiveSet.union(new Map([1, 2, 6].map(i => [i, i])))
const differenceObservableResult = reactiveSet.difference(
new Map([1, 2, 3, 4, 5, 6, 7].map(i => [i, i]))
)
const symmetricDifferenceObservableResult = reactiveSet.symmetricDifference(
new Map([3, 4].map(i => [i, i]))
)
const isSubsetOfObservableResult = reactiveSet.isSubsetOf(
new Map([1, 2, 3].map(i => [i, i]))
)
const isSupersetOfObservableResult = reactiveSet.isSupersetOf(
new Map([1, 2, 3, 4, 5, 6].map(i => [i, i]))
)
const isDisjointFromObservableResult = reactiveSet.isDisjointFrom(
new Map([6, 7].map(i => [i, i]))
)

expect(intersectionObservableResult).toEqual(new Set([1, 2]))
expect(unionObservableResult).toEqual(new Set([1, 2, 3, 4, 5, 6]))
expect(differenceObservableResult).toEqual(new Set())
expect(symmetricDifferenceObservableResult).toEqual(new Set([1, 2, 5]))
expect(isSubsetOfObservableResult).toBeFalsy()
expect(isSupersetOfObservableResult).toBeFalsy()
expect(isDisjointFromObservableResult).toBeTruthy()
})
})

describe("Observable Set methods are reactive", () => {
let c = 0
let s = set()

beforeEach(() => {
c = 0
s = set()
})

test("Intersection method is reactive", () => {
autorun(() => {
s.intersection(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("Union method is reactive", () => {
autorun(() => {
s.union(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("Difference method is reactive", () => {
autorun(() => {
s.difference(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("symmetricDifference method is reactive", () => {
autorun(() => {
s.symmetricDifference(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("isSubsetOf method is reactive", () => {
autorun(() => {
s.isSubsetOf(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("isSupersetOf method is reactive", () => {
autorun(() => {
s.isSupersetOf(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("isDisjointFrom method is reactive", () => {
autorun(() => {
s.isDisjointFrom(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})
})
48 changes: 48 additions & 0 deletions packages/mobx/src/types/observableset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,54 @@ export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillCh
} as any)
}

intersection<U>(otherSet: ReadonlySetLike<U> | Set<U>): Set<T & U> {
if (isES6Set(otherSet)) {
return otherSet.intersection(this)
} else {
const dehancedSet = new Set(this)
return dehancedSet.intersection(otherSet)
}
}

union<U>(otherSet: ReadonlySetLike<U> | Set<U>): Set<T | U> {
if (isES6Set(otherSet)) {
return otherSet.union(this)
} else {
const dehancedSet = new Set(this)
return dehancedSet.union(otherSet)
}
}

difference<U>(otherSet: ReadonlySetLike<U>): Set<T> {
return new Set(this).difference(otherSet)
}

symmetricDifference<U>(otherSet: ReadonlySetLike<U> | Set<U>): Set<T | U> {
if (isES6Set(otherSet)) {
return otherSet.symmetricDifference(this)
} else {
const dehancedSet = new Set(this)
return dehancedSet.symmetricDifference(otherSet)
}
}

isSubsetOf(otherSet: ReadonlySetLike<unknown>): boolean {
return new Set(this).isSubsetOf(otherSet)
}

isSupersetOf(otherSet: ReadonlySetLike<unknown>): boolean {
return new Set(this).isSupersetOf(otherSet)
}

isDisjointFrom(otherSet: ReadonlySetLike<unknown> | Set<unknown>): boolean {
if (isES6Set(otherSet)) {
return otherSet.isDisjointFrom(this)
} else {
const dehancedSet = new Set(this)
return dehancedSet.isDisjointFrom(otherSet)
}
}

replace(other: ObservableSet<T> | IObservableSetInitialValues<T>): ObservableSet<T> {
if (isObservableSet(other)) {
other = new Set(other)
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"target": "es6",
"module": "esnext",
"moduleResolution": "node",
"lib": ["es6"],
"lib": ["esnext"],
"downlevelIteration": true,
"alwaysStrict": true,
"sourceMap": true,
Expand Down
Loading

0 comments on commit 3efb345

Please sign in to comment.