rescript-polished 2.0.0 → 2.1.0

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.
@@ -1,31 +1,34 @@
1
- name: Release
2
-
1
+ name: Release and Publish
3
2
  on:
4
3
  push:
5
- branches: [main]
6
- pull_request:
7
- branches: [main]
8
-
4
+ branches:
5
+ - main
6
+ permissions:
7
+ contents: write
8
+ issues: write
9
+ pull-requests: write
10
+ id-token: write # Required for npm provenance
9
11
  jobs:
10
- build:
11
- runs-on: macos-latest
12
+ release:
13
+ name: Release
14
+ runs-on: ubuntu-latest
12
15
  steps:
13
16
  - name: Checkout
14
- uses: actions/checkout@v2
15
- - name: Setup node
16
- uses: actions/setup-node@v1
17
+ uses: actions/checkout@v4
17
18
  with:
18
- node-version: "14.x"
19
+ fetch-depth: 0
20
+ persist-credentials: false
21
+ - name: Setup Node.js
22
+ uses: actions/setup-node@v4
23
+ with:
24
+ node-version: 'lts/*'
19
25
  - name: Install dependencies
20
- run: yarn --frozen-lockfile --ignore-engines
21
- - name: Compile ReScript files
22
- run: yarn res:build
26
+ run: npm ci
27
+ - name: Build
28
+ run: npm run res:build
23
29
  - name: Run tests
24
- run: yarn test:ci
25
- - name: Report to codecov
26
- uses: codecov/codecov-action@v1
30
+ run: npm run test:ci
27
31
  - name: Release
28
32
  env:
29
33
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
31
- run: yarn global add semantic-release && semantic-release
34
+ run: npx semantic-release
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env sh
2
+ . "$(dirname -- "$0")/_/husky.sh"
3
+
4
+ npx --no -- commitlint --edit $1
@@ -0,0 +1 @@
1
+ npm test
@@ -0,0 +1,79 @@
1
+ {
2
+ "branches": ["main"],
3
+ "plugins": [
4
+ [
5
+ "@semantic-release/commit-analyzer",
6
+ {
7
+ "preset": "conventionalcommits",
8
+ "releaseRules": [
9
+ { "type": "feat", "release": "minor" },
10
+ { "type": "fix", "release": "patch" },
11
+ { "type": "perf", "release": "patch" },
12
+ { "type": "revert", "release": "patch" },
13
+ { "type": "docs", "release": false },
14
+ { "type": "style", "release": false },
15
+ { "type": "refactor", "release": "patch" },
16
+ { "type": "test", "release": false },
17
+ { "type": "build", "release": false },
18
+ { "type": "ci", "release": false },
19
+ { "type": "chore", "release": false },
20
+ { "breaking": true, "release": "major" }
21
+ ]
22
+ }
23
+ ],
24
+ [
25
+ "@semantic-release/release-notes-generator",
26
+ {
27
+ "preset": "conventionalcommits",
28
+ "presetConfig": {
29
+ "types": [
30
+ { "type": "feat", "section": "Features" },
31
+ { "type": "fix", "section": "Bug Fixes" },
32
+ { "type": "perf", "section": "Performance Improvements" },
33
+ { "type": "revert", "section": "Reverts" },
34
+ { "type": "docs", "section": "Documentation" },
35
+ { "type": "style", "section": "Styles" },
36
+ { "type": "refactor", "section": "Code Refactoring" },
37
+ { "type": "test", "section": "Tests" },
38
+ { "type": "build", "section": "Build System" },
39
+ { "type": "ci", "section": "Continuous Integration" }
40
+ ]
41
+ }
42
+ }
43
+ ],
44
+ [
45
+ "@semantic-release/changelog",
46
+ {
47
+ "changelogFile": "CHANGELOG.md",
48
+ "changelogTitle": "# Changelog\n\nAll notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines."
49
+ }
50
+ ],
51
+ [
52
+ "@semantic-release/npm",
53
+ {
54
+ "npmPublish": true,
55
+ "pkgRoot": ".",
56
+ "tarballDir": "dist",
57
+ "provenance": true
58
+ }
59
+ ],
60
+ [
61
+ "@semantic-release/github",
62
+ {
63
+ "assets": [
64
+ {
65
+ "path": "CHANGELOG.md",
66
+ "label": "Changelog"
67
+ }
68
+ ]
69
+ }
70
+ ],
71
+ [
72
+ "@semantic-release/git",
73
+ {
74
+ "assets": ["CHANGELOG.md", "package.json", "package-lock.json"],
75
+ "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
76
+ }
77
+ ]
78
+ ]
79
+ }
@@ -1,83 +1,72 @@
1
- open Jest
2
- open Expect
3
1
  open PolishedCss
2
+ open TestFramework
4
3
 
5
- let toEqual = (x, y) => x |> toEqual(y)
6
-
7
- describe("Color", () => {
4
+ let colorTests = () => {
8
5
  open Color
9
6
 
10
- test("shade with hex", () => {
11
- #hex("ff0000")->shade(~amount=0.25)->expect->toEqual(#hex("bf0000"))
12
- })
13
-
14
- test("shade with rgb", () => {
15
- Css_AtomicTypes.Color.rgb(255, 0, 0)->shade(~amount=0.25)->expect->toEqual(#hex("bf0000"))
16
- })
17
-
18
- test("shade with rgba", () => {
19
- Css_AtomicTypes.Color.rgba(255, 0, 0, #num(0.25))
20
- ->shade(~amount=0.25)
21
- ->expect
22
- ->toEqual(Css_AtomicTypes.Color.rgba(76, 0, 0, #num(0.4375)))
23
- })
24
-
25
- test("tint with hex", () => {
26
- #hex("ff0000")->tint(~amount=0.25)->expect->toEqual(#hex("ff3f3f"))
27
- })
28
-
29
- test("tint with rgb", () => {
30
- Css_AtomicTypes.Color.rgb(255, 0, 0)->tint(~amount=0.25)->expect->toEqual(#hex("ff3f3f"))
31
- })
32
-
33
- test("darken with hex", () => {
34
- #hex("ff0000")->darken(~amount=0.25)->expect->toEqual(#hex("800000"))
35
- })
36
-
37
- test("lighten with hex", () => {
38
- #hex("ff0000")->lighten(~amount=0.25)->expect->toEqual(#hex("ff8080"))
39
- })
40
-
41
- test("transparentize with hex", () => {
42
- #hex("ff0000")
43
- ->transparentize(~amount=0.5)
44
- ->expect
45
- ->toEqual(Utils.Rgba.fromString("rgba(255, 0, 0, 0.5)"))
46
- })
47
-
48
- test("getContrast with hex", () => {
49
- #hex("ff0000")->getContrast(#hex("0000ff"))->expect->toEqual(2.16)
50
- })
51
-
52
- test("getLuminance with hex", () => {
53
- #hex("ff0000")->getLuminance->expect->toEqual(0.213)
54
- })
55
-
56
- test("grayscale with hex", () => {
57
- #hex("ff0000")->grayscale->expect->toEqual(#hex("808080"))
58
- })
59
-
60
- test("desaturate with hex", () => {
61
- #hex("ff0000")->desaturate(~amount=0.3)->expect->toEqual(#hex("d92626"))
62
- })
63
-
64
- test("complement with hex", () => {
65
- #hex("ff0000")->complement->expect->toEqual(#hex("0ff"))
66
- })
67
-
68
- test("adjustHue with hex", () => {
69
- #hex("ff0000")->adjustHue(~degree=0.3)->expect->toEqual(#hex("ff0100"))
70
- })
71
-
72
- describe("Utils", () => {
73
- open Color.Utils
74
-
7
+ [
8
+ test("shade with hex", () => {
9
+ assertEqual(#hex("ff0000")->shade(~amount=0.25), #hex("bf0000"))
10
+ }),
11
+ test("shade with rgb", () => {
12
+ assertEqual(Css_Js_Core.Types.Color.rgb(255, 0, 0)->shade(~amount=0.25), #hex("bf0000"))
13
+ }),
14
+ test("shade with rgba", () => {
15
+ assertEqual(
16
+ Css_Js_Core.Types.Color.rgba(255, 0, 0, #num(0.25))->shade(~amount=0.25),
17
+ Css_Js_Core.Types.Color.rgba(76, 0, 0, #num(0.4375)),
18
+ )
19
+ }),
20
+ test("tint with hex", () => {
21
+ assertEqual(#hex("ff0000")->tint(~amount=0.25), #hex("ff3f3f"))
22
+ }),
23
+ test("tint with rgb", () => {
24
+ assertEqual(Css_Js_Core.Types.Color.rgb(255, 0, 0)->tint(~amount=0.25), #hex("ff3f3f"))
25
+ }),
26
+ test("darken with hex", () => {
27
+ assertEqual(#hex("ff0000")->darken(~amount=0.25), #hex("800000"))
28
+ }),
29
+ test("lighten with hex", () => {
30
+ assertEqual(#hex("ff0000")->lighten(~amount=0.25), #hex("ff8080"))
31
+ }),
32
+ test("transparentize with hex", () => {
33
+ assertEqual(
34
+ #hex("ff0000")->transparentize(~amount=0.5),
35
+ Utils.Rgba.fromString("rgba(255, 0, 0, 0.5)"),
36
+ )
37
+ }),
38
+ test("getContrast with hex", () => {
39
+ assertEqual(#hex("ff0000")->getContrast(#hex("0000ff")), 2.16)
40
+ }),
41
+ test("getLuminance with hex", () => {
42
+ assertEqual(#hex("ff0000")->getLuminance, 0.213)
43
+ }),
44
+ test("grayscale with hex", () => {
45
+ assertEqual(#hex("ff0000")->grayscale, #hex("808080"))
46
+ }),
47
+ test("desaturate with hex", () => {
48
+ assertEqual(#hex("ff0000")->desaturate(~amount=0.3), #hex("d92626"))
49
+ }),
50
+ test("complement with hex", () => {
51
+ assertEqual(#hex("ff0000")->complement, #hex("0ff"))
52
+ }),
53
+ test("adjustHue with hex", () => {
54
+ assertEqual(#hex("ff0000")->adjustHue(~degree=0.3), #hex("ff0100"))
55
+ }),
56
+ ]
57
+ }
58
+
59
+ let utilsTests = () => {
60
+ open Color.Utils
61
+
62
+ [
75
63
  test("fromString with hex", () => {
76
- "#ff0000"->fromString->expect->toEqual(#hex("ff0000"))
77
- })
78
-
64
+ assertEqual("#ff0000"->fromString, #hex("ff0000"))
65
+ }),
79
66
  test("fromString with rgba", () => {
80
- "rgba(255, 0, 0, 0.5)"->fromString->expect->toEqual(#rgba(255, 0, 0, #num(0.5)))
81
- })
82
- })
83
- })
67
+ assertEqual("rgba(255, 0, 0, 0.5)"->fromString, #rgba(255, 0, 0, #num(0.5)))
68
+ }),
69
+ ]
70
+ }
71
+
72
+ let suites = [suite("Color", colorTests()), suite("Color.Utils", utilsTests())]
@@ -1,245 +1,239 @@
1
- open Jest
2
- open Expect
1
+ open TestFramework
3
2
  open Polished
4
3
 
5
- let keepGoing = _ => ()
6
-
7
- describe("Color", () => {
4
+ let colorTests = () => {
8
5
  open Color
9
6
 
10
- test("shade", () => {
11
- "#ed5051"->shade(~amount=0.25)->expect |> toBe("#b13c3c")
12
- })
13
-
14
- test("tint", () => {
15
- "#ed5051"->tint(~amount=0.25)->expect |> toBe("#f17b7c")
16
- })
17
-
18
- test("lighten", () => {
19
- "#ed5051"->lighten(~amount=0.25)->expect |> toBe("#f9c4c4")
20
- })
21
-
22
- test("darken", () => {
23
- "#ed5051"->darken(~amount=0.25)->expect |> toBe("#ac1213")
24
- })
25
-
26
- test("hsl", () => {
27
- hsl(~hue=30., ~saturation=0.5, ~lightness=0.3)->expect |> toBe("#734d26")
28
- })
29
-
30
- test("adjustHue", () => {
31
- "#ed5051"->adjustHue(~degree=30.5)->expect |> toBe("#ed9f50")
32
- })
33
-
34
- test("complement", () => {
35
- "#ed5051"->complement->expect |> toBe("#50edec")
36
- })
37
-
38
- test("desaturate", () => {
39
- "#ed5051"->desaturate(~amount=25.5)->expect |> toBe("#9f9f9f")
40
- })
41
-
42
- test("getContrast", () => {
43
- "#ed5051"->getContrast("#fff")->expect |> toBe(3.58)
44
- })
45
-
46
- test("getLuminance", () => {
47
- "#ed5051"->getLuminance->expect |> toBe(0.243)
48
- })
49
-
50
- test("grayscale", () => {
51
- "#ed5051"->grayscale->expect |> toBe("#9f9f9f")
52
- })
53
-
54
- test("hsla", () => {
55
- hsla(~hue=130., ~saturation=0.25, ~lightness=0.5, ~alpha=0.5)->expect
56
- |> toBe("rgba(96,159,106,0.5)")
57
- })
58
-
59
- test("invert", () => {
60
- "#ed5951"->invert->expect |> toBe("#12a6ae")
61
- })
62
-
63
- test("meetsContrastGuidelines", () => {
64
- let expected: contrastScores = {
65
- "AA": true,
66
- "AALarge": true,
67
- "AAA": true,
68
- "AAALarge": true,
69
- }
70
-
71
- "#000000"->meetsContrastGuidelines("#ffffff")->expect |> toEqual(expected)
72
- })
73
-
74
- test("transparentize", () => {
75
- "#ed5051"->transparentize(~amount=0.5)->expect |> toBe("rgba(237,80,81,0.5)")
76
- })
77
-
78
- test("hslToColorString", () => {
79
- let hsl = {
80
- "hue": 240.,
81
- "lightness": 1.0,
82
- "saturation": 0.5,
83
- }
84
-
85
- hsl->hslToColorString->expect |> toBe("#fff")
86
- })
87
-
88
- test("mix", () => {
89
- "#ed5051"->mix("#bc9090", ~weight=0.2)->expect |> toBe("#c58383")
90
- })
91
-
92
- test("opacify", () => {
93
- "#ed505100"->opacify(~amount=0.5)->expect |> toBe("rgba(237,80,81,0.5)")
94
- })
95
-
96
- test("parseToHsl", () => {
97
- let expected: hslColor = {
98
- "hue": 0.0,
99
- "lightness": 0.5,
100
- "saturation": 1.0,
101
- }
102
-
103
- "#FF0000"->parseToHsl->expect |> toEqual(expected)
104
- })
105
-
106
- test("parseToRgb", () => {
107
- let expected: rgbColor = {
108
- "red": 237,
109
- "green": 80,
110
- "blue": 81,
111
- }
112
-
113
- "#ed5051"->parseToRgb->expect |> toEqual(expected)
114
- })
115
-
116
- test("readableColor", () => {
117
- "#ed5051"->readableColor(~strict=false, ())->expect |> toBe("#fff") |> keepGoing
118
-
119
- "#000"->readableColor()->expect |> toBe("#000") |> keepGoing
120
-
121
- "black"->readableColor(~darkReturnColor="#ff8", ())->expect |> toBe("#ff8") |> keepGoing
122
-
123
- "white"->readableColor(~lightReturnColor="#001", ())->expect |> toBe("#001") |> keepGoing
124
-
125
- "red"
126
- ->readableColor(~lightReturnColor="#333", ~darkReturnColor="#ddd", ~strict=true, ())
127
- ->expect
128
- |> toBe("#000")
129
- |> keepGoing
130
-
131
- "yellow"
132
- ->readableColor(~lightReturnColor="#333", ~darkReturnColor="#ddd", ~strict=true, ())
133
- ->expect
134
- |> toBe("#333")
135
- |> keepGoing
136
-
137
- "blue"
138
- ->readableColor(~lightReturnColor="#333", ~darkReturnColor="#ddd", ~strict=true, ())
139
- ->expect |> toBe("#ddd")
140
- })
141
-
142
- test("rgb", () => {
143
- let subject: rgbColor = {
144
- "red": 255,
145
- "green": 255,
146
- "blue": 255,
147
- }
148
-
149
- subject->rgb->expect |> toBe("#fff")
150
- })
151
-
152
- test("rgba", () => {
153
- let subject: rgbaColor = {
154
- "red": 255,
155
- "green": 205,
156
- "blue": 100,
157
- "alpha": 0.7,
158
- }
159
-
160
- subject->rgba->expect |> toBe("rgba(255,205,100,0.7)")
161
- })
162
-
163
- test("saturate", () => {
164
- "#ed5051"->saturate(~amount=0.5)->expect |> toBe("#ff3e3f")
165
- })
166
-
167
- test("setHue", () => {
168
- "#CCCD64"->setHue(~hue=42)->expect |> toBe("#cdae64")
169
- })
170
-
171
- test("setLightness", () => {
172
- "#CCCD64"->setLightness(~lightness=0.2)->expect |> toBe("#4d4d19")
173
- })
174
-
175
- test("setSaturation", () => {
176
- "#CCCD64"->setSaturation(~saturation=0.2)->expect |> toBe("#adad84")
177
- })
178
- })
179
-
180
- describe("Math", () => {
7
+ [
8
+ test("shade", () => {
9
+ assertEqual("#ed5051"->shade(~amount=0.25), "#b13c3c")
10
+ }),
11
+ test("tint", () => {
12
+ assertEqual("#ed5051"->tint(~amount=0.25), "#f17b7c")
13
+ }),
14
+ test("lighten", () => {
15
+ assertEqual("#ed5051"->lighten(~amount=0.25), "#f9c4c4")
16
+ }),
17
+ test("darken", () => {
18
+ assertEqual("#ed5051"->darken(~amount=0.25), "#ac1213")
19
+ }),
20
+ test("hsl", () => {
21
+ assertEqual(hsl(~hue=30., ~saturation=0.5, ~lightness=0.3), "#734d26")
22
+ }),
23
+ test("adjustHue", () => {
24
+ assertEqual("#ed5051"->adjustHue(~degree=30.5), "#ed9f50")
25
+ }),
26
+ test("complement", () => {
27
+ assertEqual("#ed5051"->complement, "#50edec")
28
+ }),
29
+ test("desaturate", () => {
30
+ assertEqual("#ed5051"->desaturate(~amount=25.5), "#9f9f9f")
31
+ }),
32
+ test("getContrast", () => {
33
+ assertEqual("#ed5051"->getContrast("#fff"), 3.58)
34
+ }),
35
+ test("getLuminance", () => {
36
+ assertEqual("#ed5051"->getLuminance, 0.243)
37
+ }),
38
+ test("grayscale", () => {
39
+ assertEqual("#ed5051"->grayscale, "#9f9f9f")
40
+ }),
41
+ test("hsla", () => {
42
+ assertEqual(
43
+ hsla(~hue=130., ~saturation=0.25, ~lightness=0.5, ~alpha=0.5),
44
+ "rgba(96,159,106,0.5)",
45
+ )
46
+ }),
47
+ test("invert", () => {
48
+ assertEqual("#ed5951"->invert, "#12a6ae")
49
+ }),
50
+ test("meetsContrastGuidelines", () => {
51
+ let expected: contrastScores = {
52
+ "AA": true,
53
+ "AALarge": true,
54
+ "AAA": true,
55
+ "AAALarge": true,
56
+ }
57
+ assertEqual("#000000"->meetsContrastGuidelines("#ffffff"), expected)
58
+ }),
59
+ test("transparentize", () => {
60
+ assertEqual("#ed5051"->transparentize(~amount=0.5), "rgba(237,80,81,0.5)")
61
+ }),
62
+ test("hslToColorString", () => {
63
+ let hsl = {
64
+ "hue": 240.,
65
+ "lightness": 1.0,
66
+ "saturation": 0.5,
67
+ }
68
+ assertEqual(hsl->hslToColorString, "#fff")
69
+ }),
70
+ test("mix", () => {
71
+ assertEqual("#ed5051"->mix("#bc9090", ~weight=0.2), "#c58383")
72
+ }),
73
+ test("opacify", () => {
74
+ assertEqual("#ed505100"->opacify(~amount=0.5), "rgba(237,80,81,0.5)")
75
+ }),
76
+ test("parseToHsl", () => {
77
+ let expected: hslColor = {
78
+ "hue": 0.0,
79
+ "lightness": 0.5,
80
+ "saturation": 1.0,
81
+ }
82
+ assertEqual("#FF0000"->parseToHsl, expected)
83
+ }),
84
+ test("parseToRgb", () => {
85
+ let expected: rgbColor = {
86
+ "red": 237,
87
+ "green": 80,
88
+ "blue": 81,
89
+ }
90
+ assertEqual("#ed5051"->parseToRgb, expected)
91
+ }),
92
+ test("readableColor", () => {
93
+ combineResults([
94
+ assertEqual("#ed5051"->readableColor(~strict=false, ()), "#000"),
95
+ assertEqual("#000"->readableColor(), "#fff"),
96
+ assertEqual("black"->readableColor(~darkReturnColor="#ff8", ()), "#ff8"),
97
+ assertEqual("white"->readableColor(~lightReturnColor="#001", ()), "#001"),
98
+ assertEqual(
99
+ "red"->readableColor(
100
+ ~lightReturnColor="#333",
101
+ ~darkReturnColor="#ddd",
102
+ ~strict=true,
103
+ (),
104
+ ),
105
+ "#000",
106
+ ),
107
+ assertEqual(
108
+ "yellow"->readableColor(
109
+ ~lightReturnColor="#333",
110
+ ~darkReturnColor="#ddd",
111
+ ~strict=true,
112
+ (),
113
+ ),
114
+ "#333",
115
+ ),
116
+ assertEqual(
117
+ "blue"->readableColor(
118
+ ~lightReturnColor="#333",
119
+ ~darkReturnColor="#ddd",
120
+ ~strict=true,
121
+ (),
122
+ ),
123
+ "#ddd",
124
+ ),
125
+ ])
126
+ }),
127
+ test("rgb", () => {
128
+ let subject: rgbColor = {
129
+ "red": 255,
130
+ "green": 255,
131
+ "blue": 255,
132
+ }
133
+ assertEqual(subject->rgb, "#fff")
134
+ }),
135
+ test("rgba", () => {
136
+ let subject: rgbaColor = {
137
+ "red": 255,
138
+ "green": 205,
139
+ "blue": 100,
140
+ "alpha": 0.7,
141
+ }
142
+ assertEqual(subject->rgba, "rgba(255,205,100,0.7)")
143
+ }),
144
+ test("saturate", () => {
145
+ assertEqual("#ed5051"->saturate(~amount=0.5), "#ff3e3f")
146
+ }),
147
+ test("setHue", () => {
148
+ assertEqual("#CCCD64"->setHue(~hue=42), "#cdae64")
149
+ }),
150
+ test("setLightness", () => {
151
+ assertEqual("#CCCD64"->setLightness(~lightness=0.2), "#4d4d19")
152
+ }),
153
+ test("setSaturation", () => {
154
+ assertEqual("#CCCD64"->setSaturation(~saturation=0.2), "#adad84")
155
+ }),
156
+ ]
157
+ }
158
+
159
+ let mathTests = () => {
181
160
  open Math
182
161
 
183
- test("math", () => {
184
- "12px + 8px"->math()->expect |> toBe("20px") |> keepGoing
185
-
186
- "12rem + 8rem"->math()->expect |> toBe("20rem") |> keepGoing
187
-
188
- math("10px + 8rem")->expect |> toThrow
189
- })
190
- })
191
-
192
- describe("Mixins", () => {
162
+ [
163
+ test("math", () => {
164
+ combineResults([
165
+ assertEqual("12px + 8px"->math(), "20px"),
166
+ assertEqual("12rem + 8rem"->math(), "20rem"),
167
+ {
168
+ let result = try {
169
+ let _ = math("10px + 8rem", ())
170
+ Fail("Expected exception to be thrown")
171
+ } catch {
172
+ | _ => Pass
173
+ }
174
+ result
175
+ },
176
+ ])
177
+ }),
178
+ ]
179
+ }
180
+
181
+ let mixinTests = () => {
193
182
  open Mixins
194
183
 
195
- test("between", () => {
196
- between(
197
- ~fromSize=Size.makeString("16px"),
198
- ~toSize=Size.makeString("100px"),
199
- ~minScreen="400px",
200
- ~maxScreen="1000px",
201
- (),
202
- )->expect |> toMatchSnapshot
203
- })
204
-
205
- test("clearfix", () => {
206
- clearFix(~parent="div")->expect |> toMatchSnapshot
207
- })
208
-
209
- test("cover", () => {
210
- cover(~offset=Size.makeString("16px"), ())->expect |> toMatchSnapshot
211
- })
212
-
213
- test("ellipsis", () => {
214
- ellipsis(~width=Size.makeString("16px"), ~lines=10, ())->expect |> toMatchSnapshot
215
- })
216
-
217
- test("fluidRange", () => {
218
- {
219
- prop: "padding",
220
- fromSize: Size.makeString("20px"),
221
- toSize: Size.makeString("20px"),
222
- }
223
- ->fluidRange(~minScreen="320px", ~maxScreen="1024px")
224
- ->expect
225
- ->toMatchSnapshot
226
- })
227
-
228
- test("fluidRangeWithArray", () => {
229
- [
230
- {
231
- prop: "padding",
232
- fromSize: Size.makeString("16px"),
233
- toSize: Size.makeString("32px"),
234
- },
235
- {
236
- prop: "margin",
237
- fromSize: Size.makeString("16px"),
238
- toSize: Size.makeString("32px"),
239
- },
240
- ]
241
- ->fluidRangeWithArray(~minScreen="320px", ~maxScreen="1024px")
242
- ->expect
243
- ->toMatchSnapshot
244
- })
245
- })
184
+ [
185
+ test("between", () => {
186
+ let result = between(
187
+ ~fromSize=Size.makeString("16px"),
188
+ ~toSize=Size.makeString("100px"),
189
+ ~minScreen="400px",
190
+ ~maxScreen="1000px",
191
+ (),
192
+ )
193
+ assertTrue(result != "", ~message="between should return non-empty string")
194
+ }),
195
+ test("clearfix", () => {
196
+ let result = clearFix(~parent="div")
197
+ assertTrue(result != "", ~message="clearFix should return non-empty string")
198
+ }),
199
+ test("cover", () => {
200
+ let result = cover(~offset=Size.makeString("16px"), ())
201
+ assertTrue(result != "", ~message="cover should return non-empty string")
202
+ }),
203
+ test("ellipsis", () => {
204
+ let result = ellipsis(~width=Size.makeString("16px"), ~lines=10, ())
205
+ assertTrue(result != "", ~message="ellipsis should return non-empty string")
206
+ }),
207
+ test("fluidRange", () => {
208
+ let result =
209
+ {
210
+ prop: "padding",
211
+ fromSize: Size.makeString("20px"),
212
+ toSize: Size.makeString("20px"),
213
+ }->fluidRange(~minScreen="320px", ~maxScreen="1024px")
214
+ assertTrue(result != "", ~message="fluidRange should return non-empty string")
215
+ }),
216
+ test("fluidRangeWithArray", () => {
217
+ let result =
218
+ [
219
+ {
220
+ prop: "padding",
221
+ fromSize: Size.makeString("16px"),
222
+ toSize: Size.makeString("32px"),
223
+ },
224
+ {
225
+ prop: "margin",
226
+ fromSize: Size.makeString("16px"),
227
+ toSize: Size.makeString("32px"),
228
+ },
229
+ ]->fluidRangeWithArray(~minScreen="320px", ~maxScreen="1024px")
230
+ assertTrue(result != "", ~message="fluidRangeWithArray should return non-empty string")
231
+ }),
232
+ ]
233
+ }
234
+
235
+ let suites = [
236
+ suite("Color", colorTests()),
237
+ suite("Math", mathTests()),
238
+ suite("Mixins", mixinTests()),
239
+ ]
@@ -0,0 +1,5 @@
1
+ open TestFramework
2
+
3
+ let allSuites = Array.concat(PolishedTest.suites, PolishedCssTest.suites)
4
+
5
+ runSuites(allSuites)
@@ -0,0 +1,170 @@
1
+ // Simple test framework
2
+
3
+ type testResult = Pass | Fail(string)
4
+
5
+ type testCase = {
6
+ name: string,
7
+ run: unit => testResult,
8
+ }
9
+
10
+ type testSuite = {
11
+ name: string,
12
+ tests: array<testCase>,
13
+ }
14
+
15
+ let test = (name: string, run: unit => testResult): testCase => {
16
+ {name, run}
17
+ }
18
+
19
+ let suite = (name: string, tests: array<testCase>): testSuite => {
20
+ {name, tests}
21
+ }
22
+
23
+ let assertEqual = (actual: 'a, expected: 'a, ~message: option<string>=?): testResult => {
24
+ if actual == expected {
25
+ Pass
26
+ } else {
27
+ let msg = switch message {
28
+ | Some(m) => m
29
+ | None => `Expected ${String.make(expected)}, got ${String.make(actual)}`
30
+ }
31
+ Fail(msg)
32
+ }
33
+ }
34
+
35
+ let assertNotEqual = (actual: 'a, expected: 'a, ~message: option<string>=?): testResult => {
36
+ if actual != expected {
37
+ Pass
38
+ } else {
39
+ let msg = switch message {
40
+ | Some(m) => m
41
+ | None => `Expected values to not be equal`
42
+ }
43
+ Fail(msg)
44
+ }
45
+ }
46
+
47
+ let assertTrue = (condition: bool, ~message: option<string>=?): testResult => {
48
+ if condition {
49
+ Pass
50
+ } else {
51
+ let msg = switch message {
52
+ | Some(m) => m
53
+ | None => "Expected true, got false"
54
+ }
55
+ Fail(msg)
56
+ }
57
+ }
58
+
59
+ let assertFalse = (condition: bool, ~message: option<string>=?): testResult => {
60
+ if !condition {
61
+ Pass
62
+ } else {
63
+ let msg = switch message {
64
+ | Some(m) => m
65
+ | None => "Expected false, got true"
66
+ }
67
+ Fail(msg)
68
+ }
69
+ }
70
+
71
+ let combineResults = (results: array<testResult>): testResult => {
72
+ let failures = results->Array.filter(r =>
73
+ switch r {
74
+ | Fail(_) => true
75
+ | Pass => false
76
+ }
77
+ )
78
+
79
+ if Array.length(failures) > 0 {
80
+ failures->Array.get(0)->Option.getOr(Pass)
81
+ } else {
82
+ Pass
83
+ }
84
+ }
85
+
86
+ let runSuite = (suite: testSuite): unit => {
87
+ Console.log(`\n📦 Running test suite: ${suite.name}`)
88
+ Console.log("=" ++ String.repeat("-", String.length(suite.name) + 23))
89
+
90
+ let passed = ref(0)
91
+ let failed = ref(0)
92
+
93
+ suite.tests->Array.forEach(testCase => {
94
+ switch testCase.run() {
95
+ | Pass => {
96
+ Console.log(` ✓ ${testCase.name}`)
97
+ passed := passed.contents + 1
98
+ }
99
+ | Fail(message) => {
100
+ Console.log(` ✗ ${testCase.name}`)
101
+ Console.log(` ${message}`)
102
+ failed := failed.contents + 1
103
+ }
104
+ }
105
+ })
106
+
107
+ Console.log("")
108
+ Console.log(
109
+ `Results: ${Int.toString(passed.contents)} passed, ${Int.toString(failed.contents)} failed`,
110
+ )
111
+
112
+ if failed.contents > 0 {
113
+ Console.log("❌ Some tests failed")
114
+ } else {
115
+ Console.log("✅ All tests passed!")
116
+ }
117
+ }
118
+
119
+ let runSuites = (suites: array<testSuite>): unit => {
120
+ Console.log("\n🧪 Running all test suites")
121
+ Console.log("========================\n")
122
+
123
+ let totalPassed = ref(0)
124
+ let totalFailed = ref(0)
125
+
126
+ suites->Array.forEach(suite => {
127
+ Console.log(`\n📦 ${suite.name}`)
128
+ Console.log("-" ++ String.repeat("-", String.length(suite.name) + 3))
129
+
130
+ let suitePassed = ref(0)
131
+ let suiteFailed = ref(0)
132
+
133
+ suite.tests->Array.forEach(testCase => {
134
+ switch testCase.run() {
135
+ | Pass => {
136
+ Console.log(` ✓ ${testCase.name}`)
137
+ suitePassed := suitePassed.contents + 1
138
+ totalPassed := totalPassed.contents + 1
139
+ }
140
+ | Fail(message) => {
141
+ Console.log(` ✗ ${testCase.name}`)
142
+ Console.log(` ${message}`)
143
+ suiteFailed := suiteFailed.contents + 1
144
+ totalFailed := totalFailed.contents + 1
145
+ }
146
+ }
147
+ })
148
+
149
+ Console.log(
150
+ ` ${Int.toString(suitePassed.contents)} passed, ${Int.toString(
151
+ suiteFailed.contents,
152
+ )} failed`,
153
+ )
154
+ })
155
+
156
+ Console.log("\n" ++ String.repeat("=", 50))
157
+ Console.log(
158
+ `Total: ${Int.toString(totalPassed.contents)} passed, ${Int.toString(
159
+ totalFailed.contents,
160
+ )} failed`,
161
+ )
162
+
163
+ if totalFailed.contents > 0 {
164
+ Console.log("❌ Some tests failed\n")
165
+ %raw(`process.exit(1)`)
166
+ } else {
167
+ Console.log("✅ All tests passed!\n")
168
+ %raw(`process.exit(0)`)
169
+ }
170
+ }
File without changes
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "rescript-polished",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
+ "type": "module",
4
5
  "description": "ReScript bindings for polished.",
5
6
  "main": "dist/index.js",
6
7
  "repository": "https://github.com/brnrdog/rescript-polished",
@@ -23,27 +24,25 @@
23
24
  },
24
25
  "scripts": {
25
26
  "res:start": "rescript build -w",
26
- "res:build": "rescript build -with-deps",
27
- "res:clean": "rescript clean -with-deps",
28
- "test": "jest",
29
- "test:ci": "jest --collect-coverage"
27
+ "res:build": "rescript build",
28
+ "res:clean": "rescript clean",
29
+ "test": "rescript build && node lib/bs/__tests__/RunTests.res.js",
30
+ "test:ci": "rescript build && node lib/bs/__tests__/RunTests.res.js"
30
31
  },
31
32
  "dependencies": {
32
- "bs-css": "^15.0.1",
33
+ "bs-css": "^18.1.1",
33
34
  "polished": "^4.0.3",
34
- "rescript": "^9.1.4"
35
+ "rescript": "^12.0.2"
35
36
  },
36
37
  "devDependencies": {
37
- "@glennsl/bs-jest": "^0.7.0",
38
- "jest": "^27.0.4",
39
- "semantic-release": "^18.0.0"
40
- },
41
- "jest": {
42
- "collectCoverageFrom": [
43
- "<rootDir>/{lib/js/src/**/*.js",
44
- "!<rootDir>/lib/js/src/Polished.js",
45
- "!<rootDir>/lib/js/src/PolishedCss.js"
46
- ],
47
- "verbose": true
38
+ "@commitlint/cli": "^20.1.0",
39
+ "@commitlint/config-conventional": "^20.0.0",
40
+ "@rescript/core": "^1.6.1",
41
+ "@semantic-release/changelog": "^6.0.3",
42
+ "@semantic-release/git": "^10.0.1",
43
+ "@semantic-release/github": "^12.0.2",
44
+ "@semantic-release/npm": "^13.1.2",
45
+ "husky": "^9.1.7",
46
+ "semantic-release": "^25.0.2"
48
47
  }
49
48
  }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "name": "rescript-polished",
3
- "version": "0.0.0-semantic-released",
4
3
  "sources": [
5
4
  {
6
5
  "dir": "src",
@@ -13,12 +12,11 @@
13
12
  ],
14
13
  "package-specs": [
15
14
  {
16
- "module": "commonjs"
15
+ "module": "es6"
17
16
  }
18
17
  ],
19
- "suffix": ".bs.js",
20
- "bs-dev-dependencies": ["@glennsl/bs-jest"],
21
- "bs-dependencies": ["bs-css"],
18
+ "suffix": ".res.js",
19
+ "dependencies": ["bs-css"],
22
20
  "warnings": {
23
21
  "error": "+101"
24
22
  }
@@ -1,26 +1,26 @@
1
1
  module Utils = {
2
- open Css_AtomicTypes
2
+ module StdFloat = Float
3
+ module StdInt = Int
3
4
 
4
5
  module Rgba = {
5
- let regex = "rgba\(\s*(-?\d+|-?\d*\.\d+(?=%))\s*,\s*(-?\d+|-?\d*\.\d+(?=%))\s*,\s*(-?\d+|-?\d*\.\d+(?=%))\s*,\s*(-?\d+|-?\d*.\d+)\s*\)"
6
- let rgbaRegexGroups = (_, i) => [1, 2, 3, 4]->Js.Array2.includes(i)
7
- let rgbValue = v => v->Js.Nullable.toOption->Belt.Option.getExn->int_of_string
8
- let alphaValue = v => v->Js.Nullable.toOption->Belt.Option.getUnsafe->float_of_string
6
+ let regex = "rgba\\(\\s*(-?\\d+|-?\\d*\\.\\d+(?=%))\\s*,\\s*(-?\\d+|-?\\d*\\.\\d+(?=%))\\s*,\\s*(-?\\d+|-?\\d*\\.\\d+(?=%))\\s*,\\s*(-?\\d+|-?\\d*\\.\\d+)\\s*\\)"
7
+ let rgbValue = v => v->StdInt.fromString->Belt.Option.getExn
8
+ let alphaValue = v => v->StdFloat.fromString->Belt.Option.getExn
9
+
10
+ @get_index external unsafeGet: (RegExp.Result.t, int) => string = ""
9
11
 
10
12
  let fromString = string => {
11
- let result = regex->Js.Re.fromString->Js.Re.exec_(string)
13
+ let result = regex->RegExp.fromString->RegExp.exec(string)
12
14
 
13
15
  switch result {
14
16
  | None => None
15
17
  | Some(result) => {
16
- let values = result->Js.Re.captures->Js.Array2.filteri(rgbaRegexGroups)
17
-
18
- let red = values->Array.get(0)->rgbValue
19
- let green = values->Array.get(1)->rgbValue
20
- let blue = values->Array.get(2)->rgbValue
21
- let alpha = values->Array.get(3)->alphaValue
18
+ let red = result->unsafeGet(1)->rgbValue
19
+ let green = result->unsafeGet(2)->rgbValue
20
+ let blue = result->unsafeGet(3)->rgbValue
21
+ let alpha = result->unsafeGet(4)->alphaValue
22
22
 
23
- Some(Color.rgba(red, green, blue, #num(alpha)))
23
+ Some(Css_Js_Core.Types.Color.rgba(red, green, blue, #num(alpha)))
24
24
  }
25
25
  }
26
26
  }
@@ -28,13 +28,13 @@ module Utils = {
28
28
 
29
29
  module Hex = {
30
30
  let fromString = string =>
31
- #hex(string->Js.String2.slice(~from=1, ~to_=Js.String.length(string)))
31
+ #hex(string->String.slice(~start=1, ~end=String.length(string)))
32
32
  }
33
33
 
34
- let toString = Color.toString
34
+ let toString = Css_Js_Core.Types.Color.toString
35
35
 
36
36
  let fromString = string => {
37
- switch string->Js.String2.slice(~from=0, ~to_=4) {
37
+ switch string->String.slice(~start=0, ~end=4) {
38
38
  | "rgba" => string->Rgba.fromString->Belt.Option.getExn
39
39
  | _ => string->Hex.fromString
40
40
  }
@@ -10,19 +10,19 @@ type rgbaColor = {"red": int, "green": int, "blue": int, "alpha": float}
10
10
 
11
11
  @module("polished")
12
12
  external shade: (float, color) => color = "shade"
13
- let shade = (color, ~amount) => color |> shade(amount)
13
+ let shade = (color, ~amount) => shade(amount, color)
14
14
 
15
15
  @module("polished")
16
16
  external tint: (float, color) => color = "tint"
17
- let tint = (color, ~amount) => color |> tint(amount)
17
+ let tint = (color, ~amount) => tint(amount, color)
18
18
 
19
19
  @module("polished")
20
20
  external lighten: (float, color) => color = "lighten"
21
- let lighten = (color, ~amount) => color |> lighten(amount)
21
+ let lighten = (color, ~amount) => lighten(amount, color)
22
22
 
23
23
  @module("polished")
24
24
  external darken: (float, color) => color = "darken"
25
- let darken = (color, ~amount) => color |> darken(amount)
25
+ let darken = (color, ~amount) => darken(amount, color)
26
26
 
27
27
  @module("polished")
28
28
  external hsl: (float, float, float) => color = "hsl"
@@ -30,7 +30,7 @@ let hsl = (~hue, ~saturation, ~lightness) => hsl(hue, saturation, lightness)
30
30
 
31
31
  @module("polished")
32
32
  external extAdjustHue: (float, color) => color = "adjustHue"
33
- let adjustHue = (color, ~degree) => color |> extAdjustHue(degree)
33
+ let adjustHue = (color, ~degree) => extAdjustHue(degree, color)
34
34
 
35
35
  @module("polished")
36
36
  external complement: color => color = "complement"
@@ -38,7 +38,7 @@ let complement = complement
38
38
 
39
39
  @module("polished")
40
40
  external desaturate: (float, color) => color = "desaturate"
41
- let desaturate = (color, ~amount) => color |> desaturate(amount)
41
+ let desaturate = (color, ~amount) => desaturate(amount, color)
42
42
 
43
43
  @module("polished")
44
44
  external getContrast: (color, color) => float = "getContrast"
@@ -66,7 +66,7 @@ let meetsContrastGuidelines = meetsContrastGuidelines
66
66
 
67
67
  @module("polished")
68
68
  external extTransparentize: (float, color) => color = "transparentize"
69
- let transparentize = (color, ~amount) => color |> extTransparentize(amount)
69
+ let transparentize = (color, ~amount) => extTransparentize(amount, color)
70
70
 
71
71
  @module("polished")
72
72
  external hslToColorString: hslColor => color = "hslToColorString"
@@ -74,11 +74,11 @@ let hslToColorString = hslToColorString
74
74
 
75
75
  @module("polished")
76
76
  external mix: (float, color, color) => color = "mix"
77
- let mix = (color1, color2, ~weight) => color2 |> mix(weight, color1)
77
+ let mix = (color1, color2, ~weight) => mix(weight, color1, color2)
78
78
 
79
79
  @module("polished")
80
80
  external opacify: (float, color) => color = "opacify"
81
- let opacify = (color, ~amount) => color |> opacify(amount)
81
+ let opacify = (color, ~amount) => opacify(amount, color)
82
82
 
83
83
  @module("polished")
84
84
  external parseToHsl: color => hslColor = "parseToHsl"
@@ -90,7 +90,7 @@ let parseToRgb = parseToRgb
90
90
 
91
91
  @module("polished")
92
92
  external readableColor: (color, color, color, bool) => color = "readableColor"
93
- let readableColor = (color, ~lightReturnColor="#fff", ~darkReturnColor="#000", ~strict=true, ()) =>
93
+ let readableColor = (color, ~lightReturnColor="#000", ~darkReturnColor="#fff", ~strict=true, ()) =>
94
94
  readableColor(color, lightReturnColor, darkReturnColor, strict)
95
95
 
96
96
  @module("polished")
@@ -103,16 +103,16 @@ let rgba = rgba
103
103
 
104
104
  @module("polished")
105
105
  external saturate: (float, color) => color = "saturate"
106
- let saturate = (color, ~amount) => color |> saturate(amount)
106
+ let saturate = (color, ~amount) => saturate(amount, color)
107
107
 
108
108
  @module("polished")
109
109
  external setHue: (int, color) => color = "setHue"
110
- let setHue = (color, ~hue) => color |> setHue(hue)
110
+ let setHue = (color, ~hue) => setHue(hue, color)
111
111
 
112
112
  @module("polished")
113
113
  external setLightness: (float, color) => color = "setLightness"
114
- let setLightness = (color, ~lightness) => color |> setLightness(lightness)
114
+ let setLightness = (color, ~lightness) => setLightness(lightness, color)
115
115
 
116
116
  @module("polished")
117
117
  external setSaturation: (float, color) => color = "setSaturation"
118
- let setSaturation = (color, ~saturation) => color |> setSaturation(saturation)
118
+ let setSaturation = (color, ~saturation) => setSaturation(saturation, color)
@@ -26,37 +26,37 @@ external clearFix: option<string> => 'styles = "clearFix"
26
26
  let clearFix = (~parent=?) => parent->clearFix
27
27
 
28
28
  @module("polished")
29
- external cover: (~offset: Js.undefined<Size.t>) => 'styles = "cover"
30
- let cover = (~offset=?, ()) => cover(~offset=Js.Undefined.fromOption(offset))
29
+ external cover: (~offset: Nullable.t<Size.t>) => 'styles = "cover"
30
+ let cover = (~offset=?, ()) => cover(~offset=Nullable.fromOption(offset))
31
31
 
32
32
  @module("polished")
33
- external ellipsis: (~width: Js.undefined<Size.t>, ~lines: option<int>) => 'styles = "ellipsis"
33
+ external ellipsis: (~width: Nullable.t<Size.t>, ~lines: option<int>) => 'styles = "ellipsis"
34
34
  let ellipsis = (~width=?, ~lines=?, ()) => {
35
- ellipsis(~width=Js.Undefined.fromOption(width), ~lines)
35
+ ellipsis(~width=Nullable.fromOption(width), ~lines)
36
36
  }
37
37
 
38
38
  @module("polished")
39
39
  external fluidRange: (
40
40
  fluidRangeConfiguration,
41
- ~minScreen: Js.undefined<string>,
42
- ~maxScreen: Js.undefined<string>,
41
+ ~minScreen: Nullable.t<string>,
42
+ ~maxScreen: Nullable.t<string>,
43
43
  ) => 'styles = "fluidRange"
44
44
  let fluidRange = (~minScreen=?, ~maxScreen=?, cssProp) =>
45
45
  fluidRange(
46
46
  cssProp,
47
- ~minScreen=Js.Undefined.fromOption(minScreen),
48
- ~maxScreen=Js.Undefined.fromOption(maxScreen),
47
+ ~minScreen=Nullable.fromOption(minScreen),
48
+ ~maxScreen=Nullable.fromOption(maxScreen),
49
49
  )
50
50
 
51
51
  @module("polished")
52
52
  external fluidRangeWithArray: (
53
53
  array<fluidRangeConfiguration>,
54
- ~minScreen: Js.undefined<string>,
55
- ~maxScreen: Js.undefined<string>,
54
+ ~minScreen: Nullable.t<string>,
55
+ ~maxScreen: Nullable.t<string>,
56
56
  ) => 'styles = "fluidRange"
57
57
  let fluidRangeWithArray = (~minScreen=?, ~maxScreen=?, cssProps) =>
58
58
  fluidRangeWithArray(
59
59
  cssProps,
60
- ~minScreen=Js.Undefined.fromOption(minScreen),
61
- ~maxScreen=Js.Undefined.fromOption(maxScreen),
60
+ ~minScreen=Nullable.fromOption(minScreen),
61
+ ~maxScreen=Nullable.fromOption(maxScreen),
62
62
  )